第 3 章 · 上下文、记忆与知识
这章讲「发给模型的那串 messages 是怎么拼出来的」。一个 agent 之所以「记得你、查得到资料、记得上次聊到哪」,全靠在这一步把记忆、知识、会话状态、历史注入上下文。
3.1 主线:get_run_messages 组装上下文
第 1 章说过,_run 在调模型前先调 get_run_messages(agent/_run.py:474)。它产出一个 RunMessages,里面是按顺序排好的 messages 列表。最重要的两块是 system message(身份、规则、记忆、知识)和 user message(本次输入)。
3.2 system message 怎么拼(分层叠加)
get_system_message(agent/_messages.py:106)是个「按固定顺序往一个字符串里叠加」的过程。如果你直接给了 agent.system_message,它就直接用(_messages.py:130);否则它从零拼。
拼装顺序(节选自 _messages.py:233 往后,编号对应源码注释 3.3.x):
description—— agent 的自我描述(:236)<your_role>—— 角色,用 XML 标签包(:239)<instructions>—— 指令列表(:243),多条时逐条-列出<additional_information>—— 附加信息(:258)- 工具指令(
:263) <expected_output>、additional_context、skills 片段(:277-285)<memories_from_previous_interactions>—— 用户记忆(:299)<...cultural knowledge...>—— 文化知识(:336)
看记忆是怎么变成一段提示的(_messages.py:297):
# agent/_messages.py:299 —— 把用户记忆拼进 system message(节选)
system_message_content += "<memories_from_previous_interactions>"
for _memory in user_memories:
system_message_content += f"\n- {_memory.memory}"
system_message_content += "\n</memories_from_previous_interactions>\n\n"
system_message_content += (
"Note: this information is from previous interactions ... "
"You should always prefer information from this conversation over the past memories.\n"
)
为什么用 XML 风格标签(<instructions>、<memories...>):给模型清晰的分区边界,比纯散文更不容易让模型混淆「哪段是规则、哪段是历史事实」。注意 use_instruction_tags 可关掉标签,退回成普通 - 列表(_messages.py:242)。
3.3 记忆(Memory):从对话里抽笔记
记忆解决的小问题:跨会话「记住用户是谁、偏好什么」。MemoryManager(memory/manager.py:46)管两件事:
- 写入:
create_user_memories(memory/manager.py:377)/ 异步acreate_user_memories(:432)——从本轮对话里抽取值得记的事实,存进 DB。第 1 章提过,这是在_run里后台 future 并发跑的(_run.py:497),不阻塞主回答。 - 回放:
get_user_memories(memory/manager.py:174)在拼 system message 时被调,把记忆塞进上下文(就是上面 3.2 第 7 步)。
两个相关开关(agent/agent.py):update_memory_on_run(运行结束时更新记忆,:122)、enable_agentic_memory(给模型一个 update_user_memory 工具让它自己记,:120)。开了 agentic memory,system message 里会多一段 <updating_user_memories> 教模型怎么用这个工具(_messages.py:315-325)。
3.4 知识(Knowledge / RAG):查外部资料
知识解决的小问题:让 agent 回答时引用文档库,而不是只靠模型记忆。knowledge/ 目录是一条完整 RAG 流水线:
| 阶段 | 目录/文件 | 作用 |
|---|---|---|
| 读取 | knowledge/reader、loaders | 把 PDF/网页/文件读成文档 |
| 分块 | knowledge/chunking | 切成可检索的小块 |
| 嵌入 | knowledge/embedder | 向量化 |
| 存储/检索 | vectordb/(独立目录) | 向量库(Postgres/Pinecone/…) |
| 重排 | knowledge/reranker | 检索后重排 |
Agent 侧的开关:knowledge(挂知识库)、add_knowledge_to_context(把检索结果塞进 prompt)、knowledge_filters、enable_agentic_knowledge_filters(让模型自己定过滤条件)、以及 knowledge_retriever(自定义检索函数,签名见 agent/agent.py:160-163)。默认 RAG 走「检索→把片段拼进 user prompt」;开 agentic filter 则给模型 search_knowledge 工具自己查。
3.5 会话状态与历史
两个容易混的概念:
session_state—— 一个跨 run 持久化的 dict(agent/agent.py:90)。add_session_state_to_context把它注入上下文;enable_agentic_state给模型工具去改它(:92-94)。加载逻辑在load_session_state(_run.py:419),默认把传入的 state 与 DB 里的合并(overwrite_db_session_state可改成覆盖,agent.py:96)。- 历史(history) —— 过往的对话消息。
add_history_to_context开启(agent.py:142),num_history_runs/num_history_messages控制带多少(:143-146)。注意:没配 DB 时开历史会被警告并忽略(_run.py:1328)。
3.6 存储抽象:BaseDb
会话、记忆、知识最终落到哪由 BaseDb(db/base.py:30)抽象,它定义了一组 upsert/get 方法,被各后端实现(Postgres/SQLite/Mongo/Redis/Dynamo/… 见 db/ 目录):
upsert_session/get_session(db/base.py:201、:163)upsert_user_memory(:268)upsert_knowledge_content(:345)
同步与异步各一套(异步版在 db/base.py:1315 起,如 async get_session)——这也是第 1 章说的「同步 DB 走 run、异步 DB 走 arun」的根源。
3.7 会话摘要
开 enable_session_summaries(agent.py:104)后,run 收尾时会生成/更新一段会话摘要(SessionSummaryManager),下次可用 add_session_summary_to_context 注入——这样长会话不必把全部历史塞进上下文,用摘要替代。
3.8 巧妙之处
- 上下文是「分层叠加的字符串」,顺序固定且可读。
get_system_message的每一步都有编号注释(3.3.1…3.3.10),改起来一目了然(_messages.py:233+)。 - 记忆抽取与主回答并发。 写记忆是后台 future(
_run.py:497),不拖慢用户拿到答案的时间。 - 「优先本轮对话、记忆仅供参考」写进了提示。 记忆块末尾明确告诉模型「以本次对话为准」(
_messages.py:303-306),降低陈旧记忆带偏回答的风险。 - RAG 两种姿势。 静态注入(
add_knowledge_to_context)vs 让模型自己查(agentic filter +search_knowledge工具),按需选。
3.9 代码地图
| 主题 | 文件 | 符号 |
|---|---|---|
| 消息组装 | libs/agno/agno/agent/_messages.py | get_run_messages、get_system_message |
| 状态变量插值 | libs/agno/agno/agent/_messages.py | format_message_with_state_variables |
| 记忆 | libs/agno/agno/memory/manager.py | MemoryManager、create_user_memories、get_user_memories |
| 知识/RAG | libs/agno/agno/knowledge/knowledge.py | Knowledge(及 chunking/embedder/reranker 子目录) |
| 向量库 | libs/agno/agno/vectordb/ | 各后端 |
| 会话/记忆存储 | libs/agno/agno/db/base.py | BaseDb、upsert_session、upsert_user_memory |
| 会话摘要 | libs/agno/agno/session/summary.py | SessionSummary、SessionSummaryManager |