如何将长名单按最大Token数拆分为完整条目组?
如何将长列表按Token数分块且不拆分单个条目
直接将整个列表转为字符串后按Token截断会破坏单个条目完整性(如测试中的Ogdensburg被拆分为Ogd和ensburg)。正确的做法是逐个计算每个条目(含必要分隔符)的Token消耗,逐步构建子列表,确保每个子列表的总Token数不超过设定的max_tokens。
解决代码实现
import tiktoken city_reprex = ['The Colony', 'Bridgeport', 'Toledo', 'Barre', 'Newburyport', 'Dover', 'Jonesboro', 'South Haven', 'Ogdensburg', 'Berkeley', 'Ray', 'Sugar Land', 'Telluride', 'Erwin', 'Milpitas', 'Jonesboro', 'Orem', 'Winnemucca', 'Calabash', 'Sugarcreek'] max_tokens = 25 encoding = tiktoken.encoding_for_model("gpt-3.5-turbo") # 预计算分隔符的Token数(', '在gpt-3.5-turbo编码下占2个Token) separator_token_count = len(encoding.encode(', ')) # 预计算每个城市名称的Token数 city_token_counts = [len(encoding.encode(city)) for city in city_reprex] chunks = [] current_chunk = [] current_total_tokens = 0 for city, token_count in zip(city_reprex, city_token_counts): # 计算加入当前城市后的总Token消耗 if current_chunk: required_tokens = current_total_tokens + separator_token_count + token_count else: required_tokens = token_count # 第一个元素无需分隔符 if required_tokens <= max_tokens: current_chunk.append(city) current_total_tokens = required_tokens else: # 加入当前城市会超限制,先保存当前chunk chunks.append(current_chunk) # 开启新chunk并加入当前城市 current_chunk = [city] current_total_tokens = token_count # 处理最后一个未保存的chunk if current_chunk: chunks.append(current_chunk) # 输出验证结果 for idx, chunk in enumerate(chunks, 1): chunk_str = ', '.join(chunk) actual_token_count = len(encoding.encode(chunk_str)) print(f"Chunk {idx}: --> {chunk_str}") print(f"实际Token数: {actual_token_count}\n")
输出示例
Chunk 1: --> The Colony, Bridgeport, Toledo, Barre, Newburyport, Dover, Jonesboro, South Haven 实际Token数: 24 Chunk 2: --> Ogdensburg, Berkeley, Ray, Sugar Land, Telluride, Erwin, Milpitas 实际Token数: 23 Chunk 3: --> Jonesboro, Orem, Winnemucca, Calabash, Sugarcreek 实际Token数: 21
核心逻辑说明
- 提前计算分隔符和每个条目单独的Token数,避免重复编码计算;
- 遍历过程中动态判断加入当前条目是否会超出Token限制,确保每个chunk仅包含完整条目;
- 处理边界情况:第一个条目无需分隔符,遍历结束后剩余的条目需单独作为最后一个chunk。
内容的提问来源于stack exchange,提问作者Marshall K
相关产品推荐
相关产品推荐

