在使用LangChain开发聊天机器人时,平衡上下文长度和历史记忆可通过以下策略实现,结合技术方法和LangChain工具:
---
1. 摘要压缩法(Summary Compression)
- 实现方式:
- 使用`ConversationSummaryMemory`模块,自动生成历史对话的摘要。
- 在每轮对话后,用LLM生成简洁摘要(如“用户喜欢咖啡,曾询问订单状态”),替代原始长文本。
- 优点:显著减少token占用,保留核心信息。
- 示例代码:
python
from langchain.memory import ConversationSummaryMemory
from langchain.llms import OpenAI
llm = OpenAI()
memory = ConversationSummaryMemory(llm=llm)
memory.save_context({"input": "我喜欢喝咖啡"}, {"output": "已记录您的偏好"})
print(memory.load_memory_variables({})) 输出摘要
---
2. 关键实体提取(Entity Extraction)
- 实现方式:
- 使用`EntityMemory`模块,自动识别并存储用户、地点、偏好等实体。
- 结合数据库(如Redis)持久化存储关键信息。
- 优点:快速检索结构化数据,无需遍历历史。
- 示例代码:
python
from langchain.memory import EntityMemory
memory = EntityMemory(llm=llm)
memory.save_context({"input": "我叫张三"}, {"output": "你好,张三!"})
print(memory.load_memory_variables({"input": "我的名字是什么?"})) 返回"张三"
---
3. 滑动窗口+向量检索(Sliding Window + Vector Search)
- 实现方式:
- 用`ConversationBufferWindowMemory`保留最近N轮对话(如3轮)。
- 旧对话分块存入向量数据库(如FAISS),通过语义检索召回相关历史。
- 优点:动态控制长度,按需召回重要信息。
- 示例流程:
1. 最近对话:`buffer_window_memory.load_memory()`
2. 历史对话向量化存储:
python
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
embeddings = OpenAIEmbeddings()
vector_store = FAISS.from_texts("历史对话片段", embeddings)
3. 检索相关历史:
python
retriever = vector_store.as_retriever()
docs = retriever.get_relevant_documents("用户的问题")
---
4. 动态上下文管理(Dynamic Context Management)
- 实现方式:
- 根据当前对话意图(通过意图识别模型或关键词匹配),动态加载相关历史。
- 例如:用户问“订单状态”,则从数据库加载订单号、时间等字段。
- 工具建议:结合`langchain.chains.LLMRouterChain`实现意图路由。
---
5. 综合方案示例
python
from langchain.memory import (
ConversationSummaryMemory,
ConversationBufferWindowMemory,
EntityMemory,
CombinedMemory
)
from langchain.llms import OpenAI
llm = OpenAI()
组合多种记忆模块
memory = CombinedMemory(memories=
ConversationBufferWindowMemory(k=3), 保留最近3轮对话
ConversationSummaryMemory(llm=llm), 生成全局摘要
EntityMemory(llm=llm) 提取关键实体
)
模拟对话
memory.save_context({"input": "我叫李四"}, {"output": "你好,李四!"})
memory.save_context({"input": "喜欢咖啡"}, {"output": "已记录您的偏好"})
memory.save_context({"input": "订单状态"}, {"output": "请提供订单号"})
调用时,自动整合摘要、实体和最近对话
context = memory.load_memory_variables({"input": "我之前喜欢什么饮料?"})
print(context)
输出:{'history': '...', 'entities': {'李四', '咖啡'}, ...}
---
6. 优化方向
- Token计算:使用`langchain.llms.base.get_num_tokens`监控长度,接近限制时触发摘要。
- 提示词优化:改进摘要生成提示(如“请用100字总结对话,保留用户偏好和关键事实”)。
- 评估测试:通过人工测试或自动化评估(如BLEU分数)验证记忆准确性。
通过结合摘要、实体提取、滑动窗口和向量检索,可以在控制上下文长度的同时,精准召回关键历史信息。