# Memory 系统与元思考机制 > 状态:已实现(2026-04)。本文档同时承担**设计理由**和**使用规范**。 > 入口、工具、API 清单见文末"十、实现与入口"。 > 一~九节解释"为什么这么做",改动前请先读懂论证。 --- ## 概述 本文档设计两个紧密关联的能力: 1. **Memory**:为需要跨任务维持身份的 Agent 提供持久化记忆(Markdown 文件) 2. **统一元思考机制**:整合现有的知识提取(reflection)、知识评估(knowledge_eval)和新增的记忆反思(dream),形成完整的"Agent 自我认知"能力 --- ## 一、现有元思考机制梳理 当前框架已实现两种元思考能力,都基于侧分支(side branch)机制: ### 1.1 知识提取(reflection 侧分支) **目的**:从执行过程中提取客观知识,保存到 KnowHub(全局共享知识库)。 **触发时机**: - 压缩前(`_manage_context_usage`,`runner.py:825-829`) - 任务完成后(`runner.py:1834-1838`,`enable_completion_extraction`) **输出**:调用 `upload_knowledge` 工具,保存 experience/tool/strategy/case 到 KnowHub。 **Prompt**:`REFLECT_PROMPT`(压缩时)和 `COMPLETION_REFLECT_PROMPT`(任务完成后),定义在 `agent/core/prompts/knowledge.py`。 **已知问题**:任务完成时触发的 reflection 使用 `config.knowledge.get_reflect_prompt()`(`runner.py:1249`),没有区分压缩场景和完成场景。应该在完成场景使用 `get_completion_reflect_prompt()`。 ### 1.2 知识评估(knowledge_eval 侧分支) **目的**:评估被注入的知识是否有用,记录到本地 `knowledge_log.json`。 **触发时机**(详见 `knowhub/docs/cognition-log-plan.md`): - Goal 完成时(`store.py:update_goal`,设置 `pending_knowledge_eval` 标志) - 压缩前(必须在压缩前完成评估,否则执行上下文丢失) - 任务结束时(兜底) **输出**:每条被注入的知识获得评估(irrelevant / unused / helpful / harmful / neutral),写入 `knowledge_log.json`。 **当前局限**:评估结果只存本地,不自动回传 KnowHub。只有用户通过 API 手动反馈才同步。 ### 1.3 侧分支队列机制 两种元思考通过 `force_side_branch` 队列协调执行顺序(`runner.py:1198-1207`): ``` 压缩触发时的典型队列: ["reflection", "knowledge_eval", "compression"] 任务完成时: ["knowledge_eval"](先评估)→ ["reflection"](再提取) ``` 每个侧分支执行完后 pop 队首,继续下一个,直到队列清空回到主路径。 --- ## 二、缺失的能力:个人记忆 ### 问题 现有的两种元思考都面向**全局共享知识**(KnowHub)。但有一类 Agent 需要维护**主观的、属于自己的长期记忆**: - 品味偏好、策略判断、风格积累、用户反馈 - 属于特定 Agent 身份,不是公共知识 - 需要人类能直接阅读和修改 - 跨多次 trace 持续积累和演化 - 可能被同一身份下的多个 Agent run 共享读写 KnowHub 不适合承担这个职责——它是"大众点评",不是"个人日记"。 ### 记忆文件 记忆以 Markdown 文件存储在指定目录下。每个文件覆盖一个语义维度。 ``` {base_path}/ ├── taste.md # 偏好判断 ├── strategy.md # 当前策略 ├── skills.md # 积累的技巧 └── ... ``` **为什么是 Markdown 文件**: - 人类可直接阅读和修改(vim/VS Code 打开就能改) - Git 版本控制 - Agent 用 read_file/write_file 工具即可操作,无需新增工具 - 文件数量少(几个到十几个),不需要检索能力 **共享读写**:同一身份下的多个 Agent run 可以读写同一组记忆文件。哪个 Agent 该关注哪些文件、怎么更新,由 dream prompt 来定义。 --- ## 三、统一元思考模型 ### 三种元思考及其定位 | | 知识提取(已有) | 知识评估(已有) | 记忆反思(新增) | |---|---|---|---| | **回答的问题** | 我学到了什么客观知识? | 给我的知识有没有用? | 这些经历对我的偏好/策略意味着什么? | | **输出目的地** | KnowHub(全局共享) | knowledge_log.json(本地) | 记忆文件(Agent 身份私有) | | **触发时机** | 压缩前、任务完成后 | Goal 完成、压缩前、任务结束 | Dream 时(见下文) | | **时效性要求** | 高(压缩会丢上下文) | 高(压缩会丢上下文) | 低(可以延迟处理) | | **实现机制** | reflection 侧分支 | knowledge_eval 侧分支 | dream 操作(新增) | **关键区分**:知识提取和知识评估必须在上下文丢失前完成(压缩前/任务结束时),所以是侧分支、即时触发。记忆反思可以延迟——甚至应该延迟,因为用户可能还有反馈、Agent 可能继续执行。 ### 为什么记忆反思不在 trace 结束时做 trace 结束只意味着 Agent 行动完一个轮次。后续可能发生: - 用户在飞书里说"这个方向不对" - Agent 被唤醒在同一任务下继续执行 - 新的 trace 产生了推翻前一个 trace 结论的信息 如果 trace 一结束就做记忆反思,这些后续信息会被忽略。记忆反思的价值在于**综合一段时间的经历**,不是记录每次行动的即时感受。 ### 但知识提取仍然在压缩/完成时做(采用"提取-审核-提交"两阶段) 知识提取必须在压缩/完成时做,因为压缩会删除历史,不在压缩前提取,知识就永久丢失。 但"立即 upload 到 KnowHub"这一步并不需要立即做。所谓"客观知识"也可能被后续推翻: - 工具用法可能被后续 trace 发现是错的(例如某个参数其实有副作用) - 调研结论可能被用户反馈推翻 - 一次 trace 的"成功经验"在更长窗口看可能是反模式 如果 reflection 直接 upload 到 KnowHub,错误知识会立刻污染全局检索,影响所有 Agent。 **两阶段方案**: ``` Step 1: extract(自动,压缩前/任务结束) Reflection 侧分支提取知识 → 写 cognition_log: type="extraction_pending" 不调用 upload_knowledge(信息保全已完成) Step 2: review(人工,CLI 里逐条决策) approve / edit / discard → 写 cognition_log: type="extraction_reviewed" Step 3: commit(人工触发,批量上传) 把 reviewed=approved 的批量 upload_knowledge 写 cognition_log: type="extraction_committed" ``` review 和 commit 分开的理由:review 是逐条语义判断(要不要、内容对不对),commit 是机械批量动作。两者分离允许用户分批 review、最后一次 commit;也允许撤回 review 决策。 **默认行为**:所有 Agent(包括默认 Agent 和 memory-bearing Agent)`reflect_auto_commit` 默认关闭,pending 提取必须人工 review + commit 才会进 KnowHub。如需自动直通(保留旧行为),手动在 `KnowledgeConfig` 里打开 `reflect_auto_commit=True`。 这与"信息保全 vs 全局发布解耦"的原则一致 —— 压缩前必须做的是**保全**(写本地 cognition_log),**发布**到 KnowHub 可以延迟到有人确认时。 --- ## 四、Dream:记忆反思的触发与流程 ### 什么是 Dream Dream 是 memory-bearing Agent 的记忆整理操作。它不是一个侧分支(不在某个 trace 的执行过程中插入),而是一个**独立的顶层操作**,回顾多个 trace 的执行历史,更新记忆文件。 ### 触发方式 - Agent 主动调用 `dream` 工具("我觉得该整理一下了") - 外部调度触发(定时、或人工 CLI 触发) - 框架可以在 run 启动时检测距上次 dream 的时间/trace 数量,建议 Agent dream ### 反思状态追踪 ``` Trace 模型新增字段: - reflected_at_sequence: Optional[int] # 上次记忆反思时的最新 message sequence # None = 从未被记忆反思处理 ``` 反思摘要不存在 Trace 模型中,而是作为 `reflection` 事件写入 `cognition_log.json`(详见 `knowhub/docs/cognition-log-plan.md`)。 - Agent run 产生新 message → `reflected_at_sequence` 自然落后于实际 sequence - 记忆反思完成 → 更新 `reflected_at_sequence` 为当前最新 sequence - Dream 扫描 `reflected_at_sequence < latest_sequence` 的 trace ### Dream 流程 ``` Dream 触发 │ ├─ Step 1: 扫描该 Agent 身份下所有 trace │ 找到 reflected_at_sequence < latest_sequence 的 trace │ ├─ Step 2: Per-trace 记忆反思(逐个 trace) │ 对每个需要反思的 trace: │ a. 加载 reflected_at_sequence 之后的消息(增量) │ b. 同时加载该 trace 的 cognition_log.json(查询、评估、提取事件) │ c. 用 reflect_prompt 生成反思摘要 │ d. 摘要作为 reflection 事件写入 cognition_log.json │ e. 更新 reflected_at_sequence │ ├─ Step 3: 跨 trace 整合 │ a. 收集各 trace 的 reflection 事件(cognition_log 中 type="reflection") │ b. 读取当前记忆文件 │ c. 汇总 cognition_log 中的评估趋势(多次 harmful/unused 的 source 模式) │ d. 用 dream_prompt 指导 LLM 更新记忆文件 │ e. 标记 reflection 事件为已消化 │ └─ 完成 ``` ### Per-trace 反思的输入 反思 prompt 看到的不只是"发生了什么",还包括知识评估结果: ``` ## 执行过程 [该 trace 中 reflected_at_sequence 之后的消息] ## 知识使用情况(来自 cognition_log.json) 查询 1(sequence 42):"ControlNet 相关工具知识" → source knowledge-a1b2: helpful — "准确定位了问题" → source knowledge-c3d4: irrelevant — "与当前任务无关" → source knowledge-e5f6: harmful — "建议的方法已过时" ## 请反思 1. 这次执行中有什么值得记住的经验? 2. 哪些知识的评估结果反映了我的判断需要调整? 3. 用户的反馈(如果有)说明了什么? ``` 这样,已有的 knowledge_eval 结果直接成为记忆反思的输入,不需要重复评估。 ### Dream 整合的输入 Dream prompt 看到的是: ``` ## 最近的反思摘要 [各 trace 的 reflect_summary,每份几百 token] ## 知识评估趋势(汇总自各 trace 的 cognition_log) - 最近 N 个 trace 中,被评为 harmful 的 source:[列表] - 被评为 unused 的高频 source 类型:[统计] - 被评为 helpful 的查询模式:[统计] ## 当前记忆文件 [各文件内容] ## 请更新记忆 [dream_prompt 的具体指导] ``` --- ## 五、与现有实现的集成 ### 不改动的部分 | 现有机制 | 保持不变 | 原因 | |---|---|---| | reflection 侧分支 | ✅ | 知识提取到 KnowHub,时效性要求高,必须在压缩前做 | | knowledge_eval 侧分支 | ✅ | 知识评估,时效性要求高,必须在压缩前做 | | force_side_branch 队列 | ✅ | 侧分支排序机制,成熟可靠 | | cognition_log.json | ✅ | 统一事件流存储(原 knowledge_log.json 扩展),dream 直接读取 | | 三个评估触发点 | ✅ | Goal 完成/压缩前/任务结束 | ### 需要修改的部分 **1. 任务完成时的 reflection prompt 选择** 当前 `runner.py:1249` 始终使用 `get_reflect_prompt()`。应区分场景: ```python # runner.py:1248-1249 修改 if branch_type == "reflection": if break_after_side_branch: # 任务完成后的反思 prompt = config.knowledge.get_completion_reflect_prompt() else: # 压缩前的反思 prompt = config.knowledge.get_reflect_prompt() ``` 这是一个独立的 bug fix,不依赖 Memory 系统。 **2. Trace 模型扩展** `agent/trace/models.py:Trace` 新增字段: ```python reflected_at_sequence: Optional[int] = None # 上次记忆反思的 sequence # 反思摘要存在 cognition_log.json 中(type="reflection" 事件),不在 Trace 模型中 ``` **3. RunConfig 扩展** `agent/core/runner.py:RunConfig` 新增可选字段: ```python memory: Optional[MemoryConfig] = None ``` **4. KnowledgeConfig 扩展** `agent/core/runner.py:KnowledgeConfig`(或对应类)新增字段: ```python reflect_auto_commit: bool = False # False(默认,所有 Agent): reflection 只写 cognition_log: type="extraction_pending" # 人工通过 CLI review + commit 才进 KnowHub # True(手动开启) : reflection 直接 upload_knowledge,保留旧的"提取即上传"行为 ``` **5. Reflection 侧分支行为变更** 当前 reflection 的 prompt 直接指导 LLM 调用 `upload_knowledge`。需要改为: - `reflect_auto_commit=False` 时:prompt 指导 LLM 调用新的 `record_pending_extraction` 工具(仅写 cognition_log) - `reflect_auto_commit=True` 时:保持当前行为 或者更简洁的实现:reflection 始终调用 `record_pending_extraction`,由侧分支结束后的 hook 根据 `reflect_auto_commit` 决定是否立即调用 `commit_approved`(视为全部 approved)。这避免了 prompt 分叉。 ### 新增的部分 **1. MemoryConfig** ```python @dataclass class MemoryConfig: """持久化记忆配置""" base_path: str = "" # 记忆文件目录 files: Optional[Dict[str, str]] = None # {路径: 用途说明} # key 是相对 base_path 的路径,支持嵌套(如 "core/identity.md")或 glob # (如 "relationships/*.md")。框架只负责按 key 读文件内容注入上下文, # 组织结构由配置者决定。 dream_prompt: str = "" # Dream 整合 prompt(空用默认) reflect_prompt: str = "" # Per-trace 反思 prompt(空用默认) ``` **2. Run 启动时记忆加载** Memory-bearing Agent 的 run 启动时,框架按 `files` 的 key 依次解析(直接路径或 glob 匹配),读取命中的文件内容以字符串形式注入上下文。Agent 可用 write_file 新增文件;只要新文件的路径匹配某条 key(直接路径或 glob),下次 run 启动时自动加载。 **3. Dream 操作** 以 `dream` 工具形式提供,Agent 可主动调用: ```python @tool async def dream() -> ToolResult: """整理长期记忆。回顾最近的执行历史,更新记忆文件。""" # 1. 扫描需要反思的 trace # 2. 逐个 per-trace 反思 # 3. 跨 trace 整合,更新记忆文件 ``` 也可以作为 `AgentRunner` 的方法暴露,供外部调度直接调用。 **4. 提取审核 CLI 流程** 为支持"提取-审核-提交"两阶段(见第三节),新增 `agent/cli/extraction_review.py` 模块。**不是 Agent 工具**(Agent 不应自我审核),是 CLI 内部模块 + 独立可执行脚本: ```python # agent/cli/extraction_review.py async def list_pending(trace_id: str) -> list[PendingExtraction]: """读 cognition_log,返回 type=extraction_pending 且未 reviewed 的条目""" async def review_one( trace_id: str, extraction_id: str, decision: Literal["approve", "edit", "discard"], edited_content: Optional[str] = None, ) -> None: """写 reviewed 事件到 cognition_log""" async def commit_approved(trace_id: str) -> CommitReport: """批量上传 approved 条目到 KnowHub,写 committed 事件""" ``` 可独立调用: ```bash python -m agent.cli.extraction_review --trace XXX --list python -m agent.cli.extraction_review --trace XXX --commit ``` **集成到现有交互式 CLI**(`agent/cli/interactive.py:174` 的菜单)扩展两项: ``` 1. 插入干预消息并继续 2. 触发经验总结(reflect) ← 现有 ... 8. 审核待提交知识(review) ← 新增 9. 提交已审核知识到 KnowHub ← 新增 ``` `8` 进入交互式 review 循环: ``` [1/3] tool 经验 ───────────────────── nanobanana 工具的 strength 参数 < 0.3 时会丢失原图轮廓... ───────────────────── [a]pprove / [e]dit / [d]iscard / [s]kip / [q]uit: ``` `9` 显示 approved 列表 + 用户最终确认 → 调 `commit_approved`,输出 commit 报告(成功/失败条数、KnowHub 返回的 ID)。 **实现注意**: - 现有 `perform_reflection`(`interactive.py:269`)走 HTTP API(`/api/traces/{trace_id}/reflect`)。新流程同样应该走 API 端点(如 `POST /api/traces/{trace_id}/extractions/{id}/review`、`POST /api/traces/{trace_id}/extractions/commit`),让未来 Web UI 能复用同一套审核流,而不是 CLI 直接读写 cognition_log 文件。 - "edit" 分支允许用户直接修改 LLM 生成的 markdown 内容;初版只支持改正文文本,后续可扩展到改类型/metadata。 --- ## 六、完整的元思考数据流 ``` Agent 执行任务(Trace) │ ├─ 知识查询(ask)→ cognition_log: type="query"(含整合回答 + source_ids) │ ├─ Goal 完成 → 触发 knowledge_eval 侧分支 → cognition_log: type="evaluation" │ ├─ 压缩触发 → │ 队列: [reflection, knowledge_eval, compression] │ reflection: 提取客观知识 → cognition_log: type="extraction_pending" │ (默认不直接 upload,等人工 review) │ knowledge_eval: 评估各 source → cognition_log: type="evaluation" │ compression: 压缩上下文 │ ├─ 任务完成 → │ knowledge_eval(如有 pending)→ cognition_log: type="evaluation" │ reflection → cognition_log: type="extraction_pending" │ ├─ 人工审核(CLI 触发,可发生在任意时刻)→ │ 逐条 approve/edit/discard → cognition_log: type="extraction_reviewed" │ 批量 commit → upload_knowledge → KnowHub │ + cognition_log: type="extraction_committed" │ └─ Trace 状态更新(新消息使 reflected_at_sequence 落后) ···时间流逝,可能有多个 trace··· Dream 触发(Agent 主动调用 / 外部调度) │ ├─ Per-trace 记忆反思 │ 输入: 未反思的消息 + cognition_log 中的 query/evaluation/extraction 事件 │ 输出: cognition_log: type="reflection" │ ├─ 跨 trace 整合 │ 输入: 各 trace 的 reflection 事件 + evaluation 趋势 + 当前记忆文件 │ 输出: 更新后的记忆文件(taste.md, strategy.md, ...) │ └─ 记忆文件被下次 run 加载 → 影响 Agent 行为 → 新的 Trace → ... ``` ### 三种元思考的时间线 ``` Trace 执行中: ──[Goal完成]──knowledge_eval──[压缩]──reflection→knowledge_eval→compression── Trace 结束后: ──knowledge_eval──reflection(completion)── 之后某个时刻: ──dream──per-trace记忆反思──跨trace整合──更新记忆文件── ``` 即时的元思考(knowledge_eval、reflection)保护信息不被压缩丢失。 延迟的元思考(dream)在全局视角下更新个人记忆。两者互补。 --- ## 七、记忆模型全景 Memory 和 Knowledge 是**两条平行的线**,而不是抽象层级。区分维度是"主观 vs 客观"和"私有 vs 共享"。Memory 不会"升级"成 Knowledge,反过来也不会。 ``` ┌─────────────────────────────┐ │ Trace(任务状态 / 工作记忆) │ │ Messages + Goals │ │ + cognition_log │ └──────────┬──────────────────┘ │ dream 反思 │ reflection 提取(→ pending) (延迟、可选) │ knowledge_eval 评估 │ (即时、必做) ┌────────────┴───────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────────┐ │ Memory │ │ Knowledge │ │ Agent 身份私有 │ │ KnowHub 全局共享 │ ├──────────────────┤ ├──────────────────────┤ │ 主观 / 偏好 / 策略 │ │ 客观 / 工具 / 调研 │ │ Markdown 文件 │ │ DB + 向量索引 │ │ 人类可直接编辑 │ │ 经 review 才入库 │ │ 来源: dream │ │ 来源: reflection │ └────────┬─────────┘ └──────────┬───────────┘ │ │ └────注入下次 run──────────┘ ``` **两条线的交互**(不是层级关系,是同源 + 互相参考): - 都源自同一个 Trace(cognition_log 是共同的事件流) - dream 在生成记忆摘要时可以参考 cognition_log 中的 evaluation 趋势(来自 Knowledge 这条线) - reflection 也可以参考 Memory 来判断"这条经验我已经记过了" - 但二者的**读者不同**:Memory 只服务于同一身份的未来 run;Knowledge 服务于所有 Agent --- ## 八、两类 Agent | | 默认 Agent | Memory-bearing Agent | |---|---|---| | 知识提取(reflection) | ✅ 配置 KnowledgeConfig | ✅ 配置 KnowledgeConfig | | 知识评估(knowledge_eval) | ✅ 自动 | ✅ 自动 | | 个人记忆 | ❌ | ✅ 配置 MemoryConfig | | Dream | ❌ | ✅ 可调用 dream 工具 | | Run 启动加载记忆 | ❌ | ✅ 自动注入 | Memory 是 opt-in 的增量能力。但**知识提取的提交行为变了**:默认 Agent 也不再自动 upload 到 KnowHub,必须通过 CLI 人工 review + commit;如需保留旧的"提取即上传"行为,手动设置 `KnowledgeConfig.reflect_auto_commit=True`。 --- ## 九、开放与已决问题 `[DECIDED]` 已有落地结论;`[OPEN]` 尚未决定,等真实运行数据再定。 1. `[DECIDED]` **记忆注入方式** → system prompt 末尾追加。见 `runner.py:_build_system_prompt` 里调 `format_memory_injection`。代价:若记忆文件很大,每轮 LLM 调用都带 —— 暂时接受,等实际观察到膨胀再换方案。 2. `[OPEN]` **并发写冲突**:多个 Agent run 同时写同一个记忆文件怎么办?文件锁?还是 dream 统一写、其他 run 只读?当前没做并发保护,假设 dream 是单一写入方。 3. `[OPEN]` **记忆膨胀**:记忆文件越来越长怎么办?`DEFAULT_DREAM_PROMPT` 已写"在原有基础上演进不要重写",但是否真能控制住要看实际使用。 4. `[OPEN]` **Per-trace 反思的成本控制**:很短的 trace 不值得反思。当前 `per_trace_reflect` 无下限阈值,所有 `reflected_at_sequence < last_sequence` 的 trace 都会反思。 5. `[OPEN]` **Knowledge eval 结果回传 KnowHub**:仍然只存本地 cognition_log。 6. `[DECIDED]` **Dream 中评估趋势的呈现方式** → LLM 直接读 cognition_log 原始事件。见 `dream.py:_build_reflect_input`,把 query / evaluation / extraction_pending / extraction_committed 事件摘要化后一并塞给 LLM,不做预计算统计。 7. `[DECIDED]` **Dream 操作的实现形式** → 两者都提供。Agent 主动调用走 `dream` 工具(`agent/tools/builtin/memory.py`,`memory` 组),外部调度走 `AgentRunner.dream()` 方法。 8. `[OPEN]` **未 review 的 pending 提取何时清理**:目前没有 TTL,pending 无限期累积。等观察积压速度再定(例如 30 天未 review 自动 discard / 归档)。 9. `[OPEN]` **review 的"edit"分支允许多深**:初版只支持改 markdown 字段(task/content/score/tags)。改 type 或 metadata 目前需 discard 重写。 10. `[OPEN]` **批量 review 的辅助能力**:当前逐条看。未做批量 approve / 相似条目去重 / LLM 预筛。 11. `[OPEN]` **Dream 的 JSON 解析脆弱性**:`cross_trace_integrate` 依赖 LLM 严格输出 `{updates:[...]}` JSON(见 `dream.py:_parse_dream_output`)。真实 LLM 可能偶尔加前言、用不同键名。首次线上运行需监控 parse 失败率,必要时加重试 + 更严格 prompt。 --- ## 十、实现与入口 2026-04 落地清单,供看代码时快速定位。 ### 10.1 数据层 | 改动 | 位置 | |---|---| | Trace 新字段 `reflected_at_sequence` | `agent/trace/models.py:Trace` | | cognition_log 事件 schema(含新增的 extraction_pending/reviewed/committed + reflection) | `agent/trace/store.py:append_cognition_event` docstring | ### 10.2 提取-审核-提交两阶段 | 职责 | 位置 | |---|---| | LLM 暂存用工具(core 组默认可见) | `agent/tools/builtin/knowledge.py:knowledge_save_pending` | | 反思 prompts(已改为调 `knowledge_save_pending`) | `agent/core/prompts/knowledge.py` | | Auto-commit 开关(默认 False) | `KnowledgeConfig.reflect_auto_commit` | | 反思侧分支退出时的 auto-commit hook | `agent/core/runner.py` 反射分支退出分支内 | | 核心逻辑(list_pending / review_one / commit_approved / auto_commit_branch) | `agent/trace/extraction_review.py` | | **独立 CLI 入口** | `python -m agent.cli.extraction_review --trace [--list/--list-all/--review/--commit]` | | **交互式菜单入口** | `agent/cli/interactive.py` 菜单项 8(review)/ 9(commit) | | **HTTP API 入口** | `GET /api/traces/{tid}/extractions`、`POST .../extractions/{eid}/review`、`POST .../extractions/commit`(见 `agent/trace/run_api.py`) | 三种入口共享同一个核心模块 `agent/trace/extraction_review.py`。 ### 10.3 Memory + Dream | 职责 | 位置 | |---|---| | MemoryConfig 定义 | `agent/core/memory.py:MemoryConfig` | | 记忆文件加载(支持 glob + 去重) | `agent/core/memory.py:load_memory_files` | | 记忆注入格式 | `agent/core/memory.py:format_memory_injection` | | 注入到 system prompt | `agent/core/runner.py:_build_system_prompt`(memory 段落在 skills 段之后) | | Dream per-trace 反思 | `agent/core/dream.py:per_trace_reflect` | | Dream 跨 trace 整合 | `agent/core/dream.py:cross_trace_integrate` | | Dream 顶层入口 | `agent/core/dream.py:run_dream` | | **Agent 工具入口(memory 组)** | `agent/tools/builtin/memory.py:dream` | | **外部调度入口** | `AgentRunner.dream(memory_config, trace_filter=..., reflect_model=..., dream_model=...)` | | 默认 prompts | `dream.py:DEFAULT_REFLECT_PROMPT` / `DEFAULT_DREAM_PROMPT`(可通过 `MemoryConfig.reflect_prompt`/`dream_prompt` 覆盖) | ### 10.4 启用方式 默认 Agent 不启用 memory,但**提取审核仍然生效**(pending 不自动上传 KnowHub)。 要让某个 example 直接上传(恢复旧行为): ```python RunConfig(knowledge=KnowledgeConfig(reflect_auto_commit=True)) ``` 要让一个 Agent 变成 memory-bearing: ```python from agent.core.memory import MemoryConfig RunConfig( memory=MemoryConfig( base_path="/path/to/agent_memory", files={ "taste.md": "品味偏好", "strategy.md": "当前策略", "journals/*.md": "执行日记", }, ), tool_groups=["core", "memory"], # memory 组暴露 dream 工具 ) ``` 然后周期性(或 Agent 主动调用 `dream` 工具)触发: ```python await runner.dream(memory_config=rc.memory) ``` ### 10.5 已知 rough edges - 实施过程发现旧的 `upload_knowledge` 引用是悬空的(仓内无实现),未清理 `examples/*/prompt` 里的残留引用 - Dream 两次 LLM 调用(reflect + integrate)默认模型写死 `gpt-4o-mini` / `gpt-4o`,未接入 RunConfig 的 utility_llm_call - `trace_filter` 没提供按 `agent_type` / `owner` 过滤的便捷函数,调用方传 lambda