KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

09. 完成一个有预算、可恢复的事故诊断 Agent — keel 龙骨

结课项目把前八章放回同一条 Harness 运行。目标不是再写一个孤立的 summarize() 函数,而是让系统能够回答:模型本轮看到了什么、为什么没看到另一条材料、压缩改变了什么、工具轨迹是否合法、worker 重启后从哪里继续,以及质量收益是否值得。

结课项目把前八章放回同一条 Harness 运行。目标不是再写一个孤立的 summarize() 函数,而是让系统能够回答:模型本轮看到了什么、为什么没看到另一条材料、压缩改变了什么、工具轨迹是否合法、worker 重启后从哪里继续,以及质量收益是否值得。

1. 最终任务

用户输入:

支付服务今天又超时,和上次事故有关吗?
判断现在是否恢复,给出证据和下一步,但不要执行写操作。

系统可访问:

正确回答不能仅凭“相似事故”宣布根因,也不能因为 error rate 下降就忽略订单仍失败。结论必须带当前证据 ID,并明确不确定性和下一步只读调查。

2. 最终架构

flowchart TD
    A[用户目标 + Run State] --> B[身份/租户/ACL 过滤]
    C[工具结果 / 监控 / 记忆] --> B
    B --> D[Candidate 标准化]
    D --> E[TokenCounter]
    E --> F[BudgetPlan]
    F --> G[Dependency-aware Selector]
    G --> H{达到触发条件?}
    H -->|否| J[Tool Trace Validator]
    H -->|是| I[Compaction]
    I --> J
    J --> K[Provider Adapter / Model]
    K --> L[Usage Reconcile]
    L --> M[Event + Checkpoint]
    M --> A

每个方框只有一个主要责任。MCP、向量库或供应商 conversation state 可以接入某些边界,但不能替代整条管线的预算、权限和恢复契约。

3. 阶段一:测量与预算

交付:

{
  "window_limit": 8192,
  "output_reserve": 800,
  "fixed_reserve": 128,
  "safety_margin": 256,
  "system_tokens": 420,
  "tool_schema_tokens": 760,
  "dynamic_budget": 5828,
  "counter_version": "teaching-counter@v1"
}

先用 CharTokenCounter 跑通,再明确替换成哪个真实 tokenizer。必须测试固定部分超过 input budget 时不会调用模型;不能通过删用户原始目标来让请求勉强成立。

4. 阶段二:候选与完整工具轨迹

候选至少包含当前任务、最新监控、部署记录、INC-42 记忆、tool call/result。执行顺序:

  1. 在候选产生前过滤 tenant 与权限;
  2. 为每项分配稳定 ID、kind、freshness、source;
  3. 把 call/result 建立 dependency;
  4. selector 输出 selected、dropped、by-kind token;
  5. 组装后运行 tool trace validator。

必须制造预算不足,证明 call/result 要么同时保留,要么同时被转换为带来源的旧轨迹摘要。

5. 阶段三:Compaction 与恢复

初始实验可以在 input budget 80% 触发,目标压到 55%,但报告中标明这是待校准策略,不是行业标准。

摘要输出至少分为:

已知当前事实
历史事实与来源
未决问题
证据 IDs
失败/未知工具结果
禁止推断的空白

保存 context.measured、context.compacted 和 versioned checkpoint。模拟 worker 在摘要生成后崩溃并重放同一任务,证明:同版本相同内容幂等;同版本不同内容冲突;旧版本无法覆盖新版本。

6. 阶段四:真实模型与生产替换

只有确定性不变量通过后才接真实模型:

模型负责语义选择和生成,不负责绕过身份、预算、call ID、版本与停止条件。

7. 一次运行必须留下的证据

run-42
  context.measured         6120 / budget 7000
  context.selected         selected=8 dropped=2
  context.compacted        6120 -> 3810 sources=...
  context.validated        tool_trace=valid
  model.completed          response_schema=valid
  provider.usage           estimate=3810 actual=3924 output=486
  checkpoint.saved         history_version=7

最终回答中的每个关键结论能回到 monitor:*、deployment:* 或 incident:*。摘要文本本身不能成为唯一证据。

8. 故障矩阵

故障 期望动作 必须保存的证据
tokenizer 不可用 拒绝或保守降级 counter error、未调用模型
dynamic budget < 0 减工具/缩任务/拒绝 budget report
摘要为空或超时 按风险降级或暂停 strategy、reason、deadline
orphan tool result 拒绝装配 offending call ID
outcome unknown 保留未知并对账 idempotency/evidence ID
checkpoint 重放 返回同版本或冲突 run/version/hash
迟到结果到达取消运行 丢弃状态变更 current run status
跨租户记忆候选 在选择前过滤 policy decision,不记录敏感正文

9. 评估报告

对 full history、recent trim、structured summary、evidence retrieval 做同数据对照。报告至少包含:

只有收益覆盖新增复杂度、延迟和错误风险后,策略才能进入生产 Harness。

10. 运行现有证据

python courses/foundation/context-engineering/course/project/examples/01_measure_and_budget.py
python courses/foundation/context-engineering/course/project/examples/02_select_context.py
python courses/foundation/context-engineering/course/project/examples/03_compaction_strategies.py
python courses/foundation/context-engineering/course/project/examples/04_compact_tool_trace.py
python courses/foundation/context-engineering/course/project/examples/05_trigger_and_events.py
python courses/foundation/context-engineering/course/project/examples/06_recover_after_compaction.py
python -m unittest discover -s courses/foundation/context-engineering/course/project/tests -v

这些示例是可重复教学切片,不是完整生产服务。结课实现要把它们串进一个 Harness,并补真实 provider adapter 与运行存储。

11. 最终验收

如果项目只能回答“摘要从 6120 变成 3810”,它仍然只是压缩演示;当它能解释每一次选择、失败和恢复时,才形成了 Context Engineering 系统。

回到课程说明 · 运行配套项目

进入 keel 阅读