共计 1556 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点:为什么 ChatGPT 会 ” 失忆 ”
ChatGPT 的上下文记忆能力实际上受限于 token 数量(如 GPT-3.5 的 4096 token 限制)。当对话长度超过这个限制时,模型会自动丢弃最早的对话内容,导致三个典型问题:

- 上下文丢失:当讨论需要长期记忆的复杂话题时(如调试代码、产品需求讨论),模型会 ” 忘记 ” 早期的关键信息
- 逻辑断层:连续追问时可能出现答非所问的情况,因为被截断的上下文包含重要前提条件
- 性能下降:处理长文本时需要消耗更多计算资源,响应时间明显增长
技术方案对比
方案一:会话分块策略
优点:
– 实现简单,无需额外 NLP 处理
– 适合线性对话场景(如客服记录)
缺点:
– 可能切断逻辑关联
– 需要手动维护分块边界
方案二:关键信息提取
- 使用 NER 识别实体(人名 / 时间 / 产品名)
- 用摘要生成压缩历史对话
- 保留关键信息的元数据(出现频率 / 位置)
适用场景:
– 技术文档讨论
– 会议纪要整理
方案三:外部向量数据库
- 将历史对话编码为向量存入 Pinecone 等数据库
- 通过相似度检索关联上下文
- 典型工具链:LangChain + OpenAI 嵌入
核心实现演示
会话分块实现(LangChain)
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 配置分块参数
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 每个分块 token 数
chunk_overlap=200, # 分块间重叠部分
length_function=len # 长度计算函数
)
# 处理长文本
with open('dialogue.txt') as f:
chunks = text_splitter.split_text(f.read())
print(f'生成 {len(chunks)} 个对话分块')
关键实体提取(OpenAI API)
import openai
def extract_entities(text: str) -> list[str]:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{
"role": "system",
"content": "请提取以下文本中的关键实体(技术术语 / 产品名 / 日期)"
}, {
"role": "user",
"content": text
}]
)
return response.choices[0].message.content.split(',')
# 示例用法
entities = extract_entities("2023 年我们发布了 AI 产品 X,采用 Transformer 架构")
print(entities) # 输出:['2023 年', 'AI 产品 X', 'Transformer 架构']
性能考量
通过 locust 压力测试获得的数据(100 并发):
- 原始长对话:
- 平均延迟:2.3 秒
-
Token 使用率:98%
-
分块策略:
- 平均延迟:1.1 秒
-
Token 使用率:65%
-
向量数据库方案:
- 平均延迟:1.8 秒(含检索时间)
- Token 使用率:45%
避坑指南
信息校验机制
- 每次截断前检查是否包含未完成的指令
- 对关键实体设置保护名单(如产品型号)
- 使用校验和验证信息完整性
连贯性保障
- 在分块边界添加过渡句(” 接上文关于 XX 的讨论 …”)
- 维护对话状态机跟踪话题切换
- 对重要结论进行二次确认
开放性问题
在超长对话场景(如持续多天的技术支持)中,如何平衡以下因素:
– 需要保留多少历史上下文?
– 实时性要求与计算成本的 trade-off
– 不同行业对话的特征差异(法律 vs 客服)
建议尝试用 LlamaIndex 实现以下优化:
1. 动态上下文窗口调整
2. 基于话题的自动分片
3. 混合存储策略(热数据内存 + 冷数据磁盘)
正文完
