# Cognition Log 与知识反馈 > 状态:已实现(2026-04)。本文档同时承担**设计理由**和**使用规范**。 > 实现入口与代码位置见文末"七、实现与入口"。 ## 文档维护规范 0. **先改文档,再动代码** - 新功能或重大修改需先完成文档更新、并完成审阅后,再进行代码实现;除非改动较小、不被文档涵盖 1. **文档分层,链接代码** - 重要或复杂设计可以另有详细文档;关键实现需标注代码文件路径;格式:`module/file.py:function_name` 2. **简洁快照,日志分离** - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议、决策历史、修改日志、大量代码;决策依据或修改日志若有必要,可在 `knowhub/docs/decisions.md` 另行记录 --- ## 概述 每个 trace 维护一个 `cognition_log.json`,按时间顺序记录所有认知事件(知识查询、评估、提取三态、记忆反思),为知识质量反馈和 Memory 系统的 dream 操作(详见 `agent/docs/memory.md`)提供数据。 > 此文件原名 `knowledge_log.json`,扩展为统一事件流后更名。读取时仍兼容旧文件名和 `entries[]` 字段。 --- ## Cognition Log 数据结构 **位置**:`.trace/{trace_id}/cognition_log.json` ```json { "trace_id": "trace-xxx", "events": [ { "type": "query", "sequence": 42, ... }, { "type": "evaluation", "query_sequence": 42, ... }, { "type": "extraction_pending", "extraction_id": "pending-abc", ... }, { "type": "extraction_reviewed", "extraction_id": "pending-abc", "decision": "approve", ... }, { "type": "extraction_committed", "extraction_id": "pending-abc", "knowledge_id": "knowledge-xyz", ... }, { "type": "reflection", "sequence_range": [43, 120], ... } ] } ``` 所有事件按写入顺序追加(`query` 和 `reflection` 关联 trace 中 message 的 `sequence`;`evaluation` / `extraction_*` 不强依赖 sequence)。框架自动给每个事件写入 `timestamp`。 --- ## 事件类型 ### `query`:知识查询 Agent 通过 `POST /api/knowledge/ask` 查询知识时记录。一次查询返回 KM Agent 的整合回答及引用的各 source,作为一个整体记录。 ```json { "type": "query", "sequence": 42, "goal_id": "1", "query": "goal 的描述文本", "response": "KM Agent 整合后的回答...", "source_ids": ["knowledge-a1b2", "knowledge-c3d4", "knowledge-e5f6"], "sources": [ {"id": "knowledge-a1b2", "task": "...", "content": "...(截断500字)"}, {"id": "knowledge-c3d4", "task": "...", "content": "..."} ], "timestamp": "2026-03-20T10:00:00" } ``` **写入时机**:`agent/trace/goal_tool.py:inject_knowledge_for_goal`,`POST /api/knowledge/ask` 返回后。 ### `evaluation`:知识评估 对某次 query 中各 source 的使用效果评估。通过 `query_sequence` 关联到对应的 query 事件。实际按 knowledge_id 逐条写入(每条知识一个 evaluation 事件)。 ```json { "type": "evaluation", "query_sequence": 42, "knowledge_id": "knowledge-a1b2", "eval_result": {"status": "helpful", "reason": "准确定位了问题"}, "evaluated_at_trigger": "goal_completion", "timestamp": "2026-03-20T10:05:00" } ``` LLM 在侧分支内按 `{evaluations: [{query_sequence, assessments: [{knowledge_id, eval_status, reason}]}]}` 输出;runner 解析后分条写入(一个 evaluation 事件对应一条 knowledge)。 **`status` 可能的值**: | 状态 | 含义 | |---|---| | `irrelevant` | 知识与当前任务无关 | | `unused` | 知识相关但未被使用 | | `helpful` | 知识对任务有实质帮助 | | `harmful` | 知识对任务产生负面作用 | | `neutral` | 知识相关但无明显影响 | ### `extraction_pending` / `extraction_reviewed` / `extraction_committed`:知识提取三态 Agent 的反思侧分支不再直接 upload 到 KnowHub,而是暂存为 pending,经人工 review 后才 commit。详见 `agent/docs/memory.md` 第三节"提取-审核-提交两阶段"。 #### `extraction_pending` 反思 LLM 调用 `knowledge_save_pending` 工具时写入。payload 字段与 `knowledge_save` 参数一一对应(review 通过后字段透传)。 ```json { "type": "extraction_pending", "extraction_id": "pending-a1b2c3d4", "sequence": 88, "goal_id": "g1", "branch_id": "reflection-branch-xxx", "payload": { "task": "...", "content": "...", "types": ["tool"], "tags": {...}, "score": 4, "scopes": null, "owner": null, "resource_ids": [], "source_name": "", "source_category": "exp", "urls": [], "agent_id": "...", "submitted_by": "", "capability_ids": [], "tool_ids": [] }, "timestamp": "2026-03-20T10:10:00" } ``` **写入时机**:`agent/tools/builtin/knowledge.py:knowledge_save_pending` 工具调用时。 #### `extraction_reviewed` 人工审核决策。同一 `extraction_id` 可能被多次 review(以最新一条为准),`edit` 决策携带 `edited_payload` 覆盖原 payload。 ```json { "type": "extraction_reviewed", "extraction_id": "pending-a1b2c3d4", "decision": "approve", "timestamp": "2026-04-15T14:00:00" } ``` `decision` 取值:`approve` / `edit` / `discard`。`edit` 时附加 `edited_payload` 字段。 **写入时机**: - CLI:`python -m agent.cli.extraction_review --review` - Interactive 菜单第 8 项 - HTTP:`POST /api/traces/{tid}/extractions/{eid}/review` - 共享核心:`agent/trace/extraction_review.py:review_one` #### `extraction_committed` 将 approved/edited 的条目实际上传到 KnowHub 后写入。失败条目不写此事件,只记录在 CommitReport 里。 ```json { "type": "extraction_committed", "extraction_id": "pending-a1b2c3d4", "knowledge_id": "knowledge-new-1", "timestamp": "2026-04-15T14:05:00" } ``` **写入时机**:`agent/trace/extraction_review.py:commit_approved`(调用 `knowledge_save` 成功后)。`reflect_auto_commit=True` 时由反思侧分支退出 hook 自动触发 `auto_commit_branch`。 ### `reflection`:记忆反思 仅 memory-bearing Agent 使用(详见 `agent/docs/memory.md`)。Dream 操作触发的 per-trace 记忆反思。 ```json { "type": "reflection", "sequence_range": [43, 120], "summary": "这次执行中发现用户偏好XX方向...", "consumed_at": "2026-04-07T20:05:00", "timestamp": "2026-04-07T20:00:00" } ``` `sequence_range` 是本次反思覆盖的消息区间 `[start, end]`。`consumed_at` 在跨 trace 整合(dream 的第二阶段)消化了该反思后写入;未消化时此字段缺省。 **写入时机**:`agent/core/dream.py:per_trace_reflect`(写入时 `consumed_at` 缺省);`agent/core/dream.py:cross_trace_integrate`(整合后补 `consumed_at`)。 --- ## 评估触发机制 评估针对的是未评估的 query 事件(即存在 query 事件但没有对应 evaluation 事件的)。 **判断待评估条件**:查找 cognition_log 中所有 `type: "query"` 事件,检查是否存在 `query_sequence` 指向该 query 的 `type: "evaluation"` 事件。 ### 触发点 1:Goal 完成 **时机**:Goal status 变为 `completed` 或 `abandoned` **触发逻辑**(`agent/trace/store.py:update_goal`): ``` Goal 完成 ↓ 查询 cognition_log 中未评估的 query 事件 ↓ 如果有待评估 → 设置 trace.context["pending_knowledge_eval"] = true → 设置 trace.context["knowledge_eval_trigger"] = "goal_completion" ↓ Runner 主循环下一次迭代开头检测到标志(agent/core/runner.py:_agent_loop) → 清除标志 → 将 "knowledge_eval" 加入 force_side_branch 队列 ``` ### 触发点 2:压缩 **时机**:上下文 token 数超过阈值,即将执行压缩 **触发逻辑**(`agent/core/runner.py:_manage_context_usage`): ``` 压缩条件触发 ↓ 查询 cognition_log 中未评估的 query 事件 ↓ 如果有待评估 → 设置 trace.context["knowledge_eval_trigger"] = "compression" → 侧分支队列:["reflection", "knowledge_eval", "compression"](启用知识提取时) → 或 ["knowledge_eval", "compression"](未启用时) → 返回"需要进入侧分支"信号,暂缓压缩 ``` 压缩会删除消息历史,必须在压缩前完成评估。 ### 触发点 3:任务结束(兜底) **时机**:主路径无工具调用,Agent 即将结束 **触发逻辑**(`agent/core/runner.py:_agent_loop`): ``` 任务即将结束 ↓ 查询 cognition_log 中未评估的 query 事件 ↓ 如果有待评估 → 设置 trace.context["knowledge_eval_trigger"] = "task_completion" → 将 ["knowledge_eval"] 加入 force_side_branch 队列 → continue(不 break,下一轮执行评估) ``` --- ## 侧分支评估流程 ### 侧分支类型 复用 `SideBranchContext` 机制,类型 `"knowledge_eval"`(`agent/trace/models.py:Message.branch_type`)。 ### 评估 Prompt 结构 完整实现:`agent/core/runner.py:_build_knowledge_eval_prompt` ``` 你是知识评估助手。请评估以下知识查询结果在本次任务执行中的实际效果。 ## 当前任务(Mission) ← trace.task ## 当前 Goal ← goal_tree.current 的 description ## 待评估知识查询 ← 未评估的 query 事件列表 对每个 query:展示 query 文本、整合回答、各 source 的 id/task/content ## 评估要求 ← 按 source_id 逐一评估 ## 评估分类 ← 5 个 status 选项 ## 输出格式 ← JSON ``` Prompt 中**不包含消息历史**。LLM 依据对话上下文中已有的执行过程作出判断。 ### 评估输出格式 LLM 直接输出 JSON: ```json { "evaluations": [ { "query_sequence": 42, "assessments": [ {"source_id": "knowledge-a1b2", "status": "helpful", "reason": "..."}, {"source_id": "knowledge-c3d4", "status": "irrelevant", "reason": "..."} ] } ] } ``` ### 即时写入 每次 LLM 回复后立即解析,三种策略降级:整体 JSON → ` ```json ` 代码块 → 正则裸对象。 解析成功 → 为每个 query 写入对应的 `evaluation` 事件到 cognition_log。解析失败记日志,不中断。 --- ## 数据流 ``` 知识查询(agent/trace/goal_tool.py:inject_knowledge_for_goal) ↓ POST /api/knowledge/ask → KM Agent 整合回答 ↓ 写入 cognition_log: type="query"(含 response + source_ids) ↓ ┌─────────────────────────────────────────────┐ │ 触发点 A:Goal 完成(goal_completion) │ │ 触发点 B:压缩执行前(compression) │ │ 触发点 C:任务自然结束(task_completion) │ └─────────────────────────────────────────────┘ ↓ Runner 进入 knowledge_eval 侧分支 ↓ LLM 按 query 维度、逐 source 评估,输出 JSON ↓ 写入 cognition_log: type="evaluation"(含 assessments per source) ↓ 侧分支退出 → 恢复主路径 ··· 知识提取(reflection 侧分支 LLM 调 knowledge_save_pending) ↓ 写入 cognition_log: type="extraction_pending" ↓ ┌─ reflect_auto_commit=True ─→ 侧分支退出 hook 自动 approve + commit │ 写 extraction_reviewed + extraction_committed │ └─ reflect_auto_commit=False(默认) ↓ 人工 CLI / Interactive 菜单 / HTTP API 触发 ↓ review → 写 extraction_reviewed(approve/edit/discard) ↓ commit → 调 knowledge_save → 写 extraction_committed ··· Dream 触发(memory-bearing Agent,详见 agent/docs/memory.md) ↓ Phase 1: per_trace_reflect(逐 trace,reflected_at_sequence < last_sequence) ↓ 读取增量消息 + cognition_log 中 query/evaluation/extraction_* 事件 ↓ 写入 cognition_log: type="reflection"(consumed_at 暂缺) ↓ 更新 Trace.reflected_at_sequence Phase 2: cross_trace_integrate ↓ 汇总未消化的 reflection + 当前记忆文件 ↓ LLM 输出 {updates:[{path,new_content}]} JSON 计划 ↓ 写记忆文件 + 给参与的 reflection 补 consumed_at ``` --- ## 与现有系统的集成点 | 集成位置 | 文件 | 说明 | |---|---|---| | 知识查询时写 log | `agent/trace/goal_tool.py:inject_knowledge_for_goal` | `goal(focus=...)` 触发 ask → 写入 `query` 事件 | | Goal 完成时设置标志 | `agent/trace/store.py:update_goal` | 设置 `trace.context["pending_knowledge_eval"]` | | 主循环检测标志 | `agent/core/runner.py:_agent_loop` | 每轮迭代开头检测,触发 `["knowledge_eval"]` | | 压缩前触发评估 | `agent/core/runner.py:_manage_context_usage` | 压缩前检查 pending,先评估再压缩 | | 任务结束兜底 | `agent/core/runner.py:_agent_loop` | 退出前检查 pending,强制触发评估 | | 侧分支类型 | `agent/trace/models.py:Message.branch_type` | Literal 中包含 `"knowledge_eval"` | | 即时写入评估 | `agent/core/runner.py:_agent_loop` | 解析 JSON 后调 `store.update_knowledge_evaluation` | | 知识提取暂存 | `agent/tools/builtin/knowledge.py:knowledge_save_pending` | LLM 工具,写 `extraction_pending` 事件 | | 提取审核 / 提交 | `agent/trace/extraction_review.py` | 写 `extraction_reviewed` / `extraction_committed` 事件 | | 反思侧分支 auto-commit | `agent/core/runner.py`(反思分支退出分支) | `reflect_auto_commit=True` 时调 `auto_commit_branch` | | 记忆反思写入 | `agent/core/dream.py:per_trace_reflect` | 写 `reflection` 事件(consumed_at 缺省) | | Reflection 消化标记 | `agent/core/dream.py:cross_trace_integrate` | 整合后补 `consumed_at` | | Log 文件格式 | `agent/trace/store.py` | ✅ 已从 entries[] 迁移到 events[];读写兼容旧文件名 | --- ## 七、实现与入口 ### 7.1 存储与访问 | 职责 | 位置 | |---|---| | Cognition log 文件位置 | `.trace/{trace_id}/cognition_log.json`(新建时文件名);旧 trace 兼容读 `knowledge_log.json` | | 读取 | `store.py:get_cognition_log`(两种文件名都认;`entries[]` 自动迁移为 `events[]`) | | 追加 | `store.py:append_cognition_event`(接受任意 event type,自动补 `timestamp`) | | 事件 schema 权威清单 | `store.py:append_cognition_event` 的 docstring | ### 7.2 各事件类型的写入与读取 | 事件类型 | 主要写入者 | 主要读取者 | |---|---|---| | `query` | `goal_tool.py:inject_knowledge_for_goal` | `_build_knowledge_eval_prompt` 找待评估;`dream.py:_build_reflect_input` 组装反思上下文 | | `evaluation` | `store.py:update_knowledge_evaluation`(runner 解析 LLM JSON 后调用) | `dream.py:_build_reflect_input` | | `extraction_pending` | `knowledge_save_pending` 工具 | `extraction_review.py:list_pending`;CLI / HTTP API 显示 | | `extraction_reviewed` | `extraction_review.py:review_one` | `extraction_review.py:commit_approved`(决定要不要 commit) | | `extraction_committed` | `extraction_review.py:commit_approved` | `list_pending`(标记 committed 状态) | | `reflection` | `dream.py:per_trace_reflect` | `dream.py:cross_trace_integrate` | ### 7.3 相关文档 - **Memory 系统整体**:`agent/docs/memory.md` —— cognition_log 是其数据底座,Memory/Dream 设计与使用规范在那里 - **KnowHub 决策历史**:`knowhub/docs/decisions.md` —— 如果需要 knowledge_log → cognition_log 重构等历史决策的背景