# S09 Memory 代码讲解 这一节只讲相对 S08 新增的内容: **让 Agent 把用户偏好、项目事实和历史反馈保存下来,并在下一次对话中重新加载。** --- ## 1. 本节新增内容 - `.memory/`:记忆文件目录。 - `MEMORY.md`:记忆索引。 - `write_memory_file()`:写入单条记忆。 - `_rebuild_index()`:重建记忆索引。 - `list_memory_files()`:读取所有记忆及其元数据。 - `select_relevant_memories()`:从记忆列表中挑选相关记忆。 - `load_memories()`:把相关记忆注入当前上下文。 - `extract_memories()`:从最近对话中提取新记忆。 - `consolidate_memories()`:定期合并、去重、删除过期记忆。 --- ## 2. 记忆目录结构 ```text .memory/ MEMORY.md user-style.md project-facts.md feedback-tabs.md ``` `MEMORY.md` 是索引,里面只放简短描述。 每个单独的记忆文件存完整内容。 --- ## 3. 单条记忆的数据结构 一个记忆文件是 Markdown + YAML frontmatter: ```markdown --- name: user-style description: 用户喜欢中文解释,代码注释要适合教学 type: user --- 用户偏好: - 回答用中文 - 代码讲解要适合基础较弱的学生 ``` 程序读进来后,会变成字典: ```python { "filename": "user-style.md", "name": "user-style", "description": "用户喜欢中文解释,代码注释要适合教学", "type": "user", "body": "用户偏好:..." } ``` --- ## 4. `write_memory_file()` 作用:把一条记忆写成一个独立 `.md` 文件。 输入参数: ```python name: str mem_type: str description: str body: str ``` 写完后调用: ```python _rebuild_index() ``` 这样 `MEMORY.md` 会同步更新。 --- ## 5. `_rebuild_index()` 作用:扫描 `.memory/` 里所有记忆文件,重新生成索引。 索引内容类似: ```markdown - [user-style](user-style.md) — 用户喜欢中文解释 - [project-facts](project-facts.md) — 当前项目是 Coding Agent 教学项目 ``` System Prompt 里只放这个索引,而不是每次都塞完整记忆。 --- ## 6. `select_relevant_memories(messages)` 作用:根据最近几轮用户输入,从记忆目录里挑选相关文件。 流程: ```python 读取所有记忆文件元数据 提取最近 3 条用户消息 构建 memory catalog 让 LLM 返回相关记忆的下标数组 如果 LLM 失败,用关键词匹配兜底 ``` LLM 期望返回: ```python [0, 3] ``` 代表选择第 0 条和第 3 条记忆。 --- ## 7. `load_memories(messages)` 作用:把选中的记忆文件完整内容拼成一段文本: ```xml ...记忆 1... ...记忆 2... ``` 然后在当前用户消息前注入,让模型这轮能读到相关历史。 --- ## 8. `extract_memories(messages)` 作用:从最近对话中提取新的长期信息。 它会让模型返回 JSON 数组: ```python [ { "name": "user-prefers-short-docs", "type": "user", "description": "用户喜欢短而清晰的讲义", "body": "..." } ] ``` 如果没有新记忆,就返回: ```python [] ``` --- ## 9. `consolidate_memories()` 当记忆文件太多时,会触发整理: ```python 合并重复记忆 删除过期记忆 保留重要偏好 控制总数量 ``` 这类似 Agent 的“睡眠整理”或 “Dream” 机制。 --- ## 10. 本节课堂重点 Memory 不是把所有历史都永久塞进上下文。 更合理的结构是: ```python 索引常驻 System 相关记忆按需注入 新信息轮后提取 记忆过多时合并整理 ```