cognition-log.md 15 KB

Cognition Log 与知识反馈

状态:已实现(2026-04)。本文档同时承担设计理由使用规范。 实现入口与代码位置见文末"七、实现与入口"。

文档维护规范

  1. 先改文档,再动代码 - 新功能或重大修改需先完成文档更新、并完成审阅后,再进行代码实现;除非改动较小、不被文档涵盖
  2. 文档分层,链接代码 - 重要或复杂设计可以另有详细文档;关键实现需标注代码文件路径;格式:module/file.py:function_name
  3. 简洁快照,日志分离 - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议、决策历史、修改日志、大量代码;决策依据或修改日志若有必要,可在 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

{
  "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], ... }
  ]
}

所有事件按写入顺序追加(queryreflection 关联 trace 中 message 的 sequenceevaluation / extraction_* 不强依赖 sequence)。框架自动给每个事件写入 timestamp


事件类型

query:知识查询

Agent 通过 POST /api/knowledge/ask 查询知识时记录。一次查询返回 KM Agent 的整合回答及引用的各 source,作为一个整体记录。

{
  "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_goalPOST /api/knowledge/ask 返回后。

evaluation:知识评估

对某次 query 中各 source 的使用效果评估。通过 query_sequence 关联到对应的 query 事件。实际按 knowledge_id 逐条写入(每条知识一个 evaluation 事件)。

{
  "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 通过后字段透传)。

{
  "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。

{
  "type": "extraction_reviewed",
  "extraction_id": "pending-a1b2c3d4",
  "decision": "approve",
  "timestamp": "2026-04-15T14:00:00"
}

decision 取值:approve / edit / discardedit 时附加 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 里。

{
  "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 记忆反思。

{
  "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 变为 completedabandoned

触发逻辑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:

{
  "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 重构等历史决策的背景