Day 18 / 共 20 天 · 第 4 周 Agent/Workflow/生态
聊天引擎与记忆(单轮→多轮)
QueryEngine 是"单轮问答",但真实对话是多轮的——"它多少钱?"里的"它"指上文。今天看 ChatEngine(多轮对话)和 Memory(管理对话历史),让 RAG/Agent 记住上下文。
📍 你在整条链的位置
Agent D17→
ChatEngine + Memory(多轮)→
观测评估 D19
L01
多轮对话的"指代"难题
🤔 QueryEngine 每次 query 是独立的,不记上一句
但对话有上下文——
📝 "指代"翻车现场
第 1 轮:
第 2 轮:
→ 如果直接拿"那需要多久到账"去检索——"那"指什么?检索不到东西!(丢了"退款"这个上下文)
公司的退款政策是什么? → 答"7 天内可退"第 2 轮:
那需要多久到账?→ 如果直接拿"那需要多久到账"去检索——"那"指什么?检索不到东西!(丢了"退款"这个上下文)
💡 ChatEngine 维护对话历史,把当前问题结合历史处理
比如把"那需要多久到账"改写成"退款到账需要多久"再检索。这是从"问答"到"对话"的关键升级。
L02
ChatEngine 模式
chat_engine/:simple.py(纯聊天,无 RAG)、condense_question.py、context.py、condense_plus_context.py(默认推荐)。index.as_chat_engine(chat_mode=...) 创建。
读法:不同模式 = 不同的"结合历史 + RAG"策略。Condense(浓缩问题再检索)、Context(每轮检索、塞进 system)、CondensePlusContext(两者结合,默认)。下面拆两个主要的。
L03
condense_question:改写问题
chat_engine/condense_question.py:先用 LLM 把"历史 + 当前问题"浓缩成一个独立问题,再走 RAG。
📝 改写解决指代
历史 + "那需要多久到账?" → LLM 改写 →
退款到账需要多久?(独立、无指代)→ 用它检索 → 命中"退款到账时长"。优点:检索的问题总是完整独立的
缺点:多一次 LLM 调用(改写)。适合"每轮都需要检索"的知识问答。
L04
context 模式:带资料聊天
chat_engine/context.py:每轮用当前消息检索相关 Node,塞进 system 提示,连同完整对话历史给 LLM。
保留完整上下文,LLM 自己理解指代
不改写问题——每轮检索资料作为"背景知识"放进 system 提示,LLM 看着"资料 + 完整对话历史"回答。好处:保留完整对话上下文、资料实时相关。CondensePlusContext(默认)= 浓缩问题做精准检索 + 保留对话上下文——兼顾两者。
L05
Memory:对话历史的管理者
memory/:memory.py(新版统一 Memory)、chat_memory_buffer.py、chat_summary_memory_buffer.py、vector_memory.py + memory_blocks/。存对话历史(ChatMessage 列表,Day 15)。
🤔 对话越长,历史越长,塞不下 LLM 上下文
聊了 50 轮,全部历史几万 token——塞不进提示词。核心难题:记多少、怎么记?
💡 Memory 存历史,用不同策略管理"记多少"
ChatEngine/Agent 每轮从 Memory 取历史、处理完写回。不同 Memory 策略解决"塞不下"(下面)。回想你学过的 SuperAGI 滚动记忆压缩、crewAI 统一记忆——同一问题的不同解法。
L06
缓冲区:只记最近的
memory/chat_memory_buffer.py 的 ChatMemoryBuffer:保留最近消息,用 token_limit 控制——超了丢最老的。
最简单:滑动窗口
只保留最近 N token 的对话,老的丢弃。简单有效,适合大多数场景(远古对话通常不重要)。缺点:丢掉的彻底忘(10 轮前说的名字现在想不起)。这是"记忆容量"和"上下文限制"的最朴素折中。
L07
摘要与向量记忆:越来越像人
- ChatSummaryMemoryBuffer:历史超限时用 LLM 把旧对话摘要成一段,保留摘要 + 最近消息——不彻底忘,压缩记忆。
- VectorMemory:把历史也向量化存起来,需要时检索相关历史(而非全带)——长期记忆。
- memory_blocks(新版):组合短期缓冲 + 长期向量 + 静态事实块。
三层策略,越来越像人的记忆
Buffer(只记最近)→ Summary(旧的压成摘要)→ Vector(旧对话存起来、按需回忆)。越往后越像人——近的记得清、远的记要点、需要时能"回忆"。新版可组合记忆块是当前 Agent 记忆的前沿。选哪种看对话长度和"要不要记住远期信息"。
Buffer / Summary / Vector 三种 Memory 策略应对"历史太长",代价与"记住远期"能力逐级递增
L08
今日小结 + 动手
🧠 今天你应该能回答
- 多轮对话的"指代"难题?ChatEngine 怎么解决?
- condense_question 和 context 模式的区别?
- Memory 的核心难题(历史太长塞不下)?
- Buffer/Summary/Vector 三种记忆策略的取舍?
✋ 动手
cd /Users/bitmart/work/codes/github/llama_index/llama-index-core/llama_index/core
ls chat_engine/ memory/
grep -n "class ChatMemoryBuffer\|token_limit" memory/chat_memory_buffer.py | head
grep -n "chat_mode\|CondensePlusContext" chat_engine/types.py | head
明天预告 · Day 19:RAG/Agent 是"黑盒"——怎么看内部、怎么衡量好坏?可观测(callbacks/instrumentation 追踪)+ 评估(用 LLM 给答案打分)。这是从"能跑"到"能上线"的关键。