跳到主要内容

第 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):

  1. description —— agent 的自我描述(:236)
  2. <your_role> —— 角色,用 XML 标签包(:239)
  3. <instructions> —— 指令列表(:243),多条时逐条 - 列出
  4. <additional_information> —— 附加信息(:258)
  5. 工具指令(:263)
  6. <expected_output>additional_context、skills 片段(:277-285)
  7. <memories_from_previous_interactions> —— 用户记忆(:299)
  8. <...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/readerloaders把 PDF/网页/文件读成文档
分块knowledge/chunking切成可检索的小块
嵌入knowledge/embedder向量化
存储/检索vectordb/(独立目录)向量库(Postgres/Pinecone/…)
重排knowledge/reranker检索后重排

Agent 侧的开关:knowledge(挂知识库)、add_knowledge_to_context(把检索结果塞进 prompt)、knowledge_filtersenable_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.pyget_run_messagesget_system_message
状态变量插值libs/agno/agno/agent/_messages.pyformat_message_with_state_variables
记忆libs/agno/agno/memory/manager.pyMemoryManagercreate_user_memoriesget_user_memories
知识/RAGlibs/agno/agno/knowledge/knowledge.pyKnowledge(及 chunking/embedder/reranker 子目录)
向量库libs/agno/agno/vectordb/各后端
会话/记忆存储libs/agno/agno/db/base.pyBaseDbupsert_sessionupsert_user_memory
会话摘要libs/agno/agno/session/summary.pySessionSummarySessionSummaryManager