LLM 每个会话都是无状态的,每次调用需要用记忆机制将往期聊天内容同时提交。通过为 ConversationChain 添加 memory 参数即可添加。
留给记忆的键通常为 {history}
| 记忆机制 | 优势 | 劣势 |
|---|---|---|
| ConversationBufferMemory (缓冲记忆) | 1.为 LLM 提供了最大量的信息 2.方法简单、直观 | 1.使用更多的Token,导致响应时间增加和更高的成本 2.长对话可能超过 Token 限制 |
| ConversationBufferWindowMemory (缓冲窗口记忆) | 1.只保留最近的互动,Token 使用量较少 2.窗口大小可调,灵活性高 | 1.无法记住早期互动 2.太大的窗口可能会导致 Token 使用量过多 |
| ConversationSummaryMemory (对话总结记忆) | 1.对于长对话,可以减少 Token 的使用 2.允许进行更长时间的对话 3.实现相对直接、直观 | 1.短对话可能增加 Token 使用量 2.对话记忆取决于中间LLM的汇总能力 3.需要为汇总 LLM 使用额外的 Token |
| ConversationSummaryBufferMemory (混合记忆) | 1.能够回忆起早期的互动 2.不会错过最近的信息 3. 灵活性高 | 1.对于短对话,总结器可能增加Token 数量 2.储存原始互动也可能增加 Token 使用量 |
ConversationBufferMemory
缓冲记忆是最简单的记忆机制实现。每次对话时,都将问答内容记录下来用于下次请求的上下文
通过 conversation.memory.buffer 可以查看往期对话历史记录。
问题:当长时间聊天后,上下文迅速增加
- 消耗大量 Token
- 传输更慢
- 可能有输入上限
ConversationBufferWindowMemory
在 ConversationBufferMemory 的基础上,额外需求一个窗口值 k,只保留最近 k 组互动数据以压缩请求长度
[!note] 即使没有保存全部的记忆,LLM 也会记住部分关键词
ConversationSummaryMemory
ConversationBufferWindowMemory 将历史记录进行汇总,将汇总后的数据传递给 history,适合长对话
- 优点:使用对话记录的总结作为上下文,减少 Token 用量
- 缺点:
- 对短对话优化程度不大
- 缺失时间戳,不能区分对话时间和先后顺序
- 需要额外加一个 LLM 调用以提取汇总信息,增加 Token 使用成本
- 不能限制对话长度
- 不能区分近期对话和长期对话
汇总功能也通过 AI 实现,因此往往需要另一个解析器
ConversationSummaryBufferMemory
对话总结缓冲记忆,是一种混合记忆,总结早期互动并尽量保留最近互动的原始内容
- 当记录的对话长度在 max_token_limit 字以内时,保留原始对话内容
- 当对话内容超过 max_token_limit 字时,将超过预设长度的内容提交 LLM 进行总结
- 优势:总结较早的互动,尽量保留近期互动
- 缺点:较短的对话中,总结会消耗更多 Token
总结
有些记忆机制(ConversationSummaryMemory,ConversationSummaryBufferMemory 等)在对话次数较少时会显著浪费一些 Token,但当对话次数增加,对 Token 的节省效果明显
ConversationBufferWindowMemory 最节省 Token,但会遗忘旧对话内容,在某些场合是最佳选择