LangChain处理超长文本时的Token超限问题及动态分词优化咨询
解决LangChain LLMChain处理长文本的Token超限问题
针对长文本超出LLM Token限制导致的运行失败或性能下降问题,LangChain提供了内置的文本分割与链式处理方案,无需手动干预即可动态适配模型的上下文窗口:
方法1:文本分割器 + MapReduce 摘要链
将长文本拆分为符合Token限制的小块,分别生成子摘要后再合并为最终结果,兼顾效率与完整性。
from langchain.chains.summarize import load_summarize_chain from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.llms import OpenAI # 初始化LLM和文本分割器 llm = OpenAI(model="gpt-3.5-turbo") # 根据模型Token限制设置分割参数,gpt-3.5-turbo默认4k窗口,预留空间给prompt text_splitter = RecursiveCharacterTextSplitter( chunk_size=3500, chunk_overlap=200, length_function=len, ) # 分割长文本 long_text = "This is a very long document..." # 你的超长文本 split_docs = text_splitter.create_documents([long_text]) # 加载MapReduce链 chain = load_summarize_chain(llm, chain_type="map_reduce") # 执行摘要 response = chain.run(split_docs) print(response)
说明:
RecursiveCharacterTextSplitter会按段落、句子等自然边界分割文本,避免语义断裂- MapReduce模式先对每个文本块生成独立摘要(map阶段),再将所有子摘要合并为最终结果(reduce阶段),处理速度较快
方法2:文本分割器 + Refine 摘要链
如果需要更连贯、逻辑一致的摘要,可使用Refine模式:它会基于前一个文本块的结果,迭代优化后续内容的摘要,适合对上下文连贯性要求高的场景。
from langchain.chains.summarize import load_summarize_chain from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.llms import OpenAI llm = OpenAI(model="gpt-3.5-turbo") text_splitter = RecursiveCharacterTextSplitter(chunk_size=3500, chunk_overlap=200) split_docs = text_splitter.create_documents([long_text]) # 加载Refine链 chain = load_summarize_chain(llm, chain_type="refine") response = chain.run(split_docs) print(response)
方法3:自定义Token感知的动态处理
如果需要更精细的Token控制,可以结合OpenAI的tiktoken库,动态计算文本Token数并自动分割:
import tiktoken from langchain.chains.summarize import load_summarize_chain from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.llms import OpenAI def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int: """计算文本的Token数量""" encoding = tiktoken.encoding_for_model(model) return len(encoding.encode(text)) llm = OpenAI(model="gpt-3.5-turbo") long_text = "This is a very long document..." # 动态设置分割大小,预留1000 Token给prompt max_input_tokens = 4096 - 1000 if count_tokens(long_text) > max_input_tokens: text_splitter = RecursiveCharacterTextSplitter( chunk_size=max_input_tokens, chunk_overlap=200, length_function=lambda x: count_tokens(x) ) split_docs = text_splitter.create_documents([long_text]) chain = load_summarize_chain(llm, chain_type="map_reduce") response = chain.run(split_docs) else: # 文本长度符合要求,直接用原LLMChain处理 from langchain.chains import LLMChain from langchain.prompts import PromptTemplate prompt = PromptTemplate(template="Analyze the following text and summarize it: {text}", input_variables=["text"]) llm_chain = LLMChain(llm=llm, prompt=prompt) response = llm_chain.run(text=long_text) print(response)
关键注意事项:
- 根据使用的LLM调整
chunk_size:比如gpt-3.5-turbo-16k的窗口是16384,可将chunk_size设为15000左右 chunk_overlap设置为200-300,确保文本块之间的语义衔接- 若处理非摘要类任务(如问答),可替换为
RetrievalQA链结合向量数据库,实现长文本的精准问答
内容的提问来源于stack exchange,提问作者user26855093
相关产品推荐
相关产品推荐

