第 03 章 · 解剖学:六个要素与事件流

本篇目标:能从一个会话日志,完整重建模型当时看到的每一次请求。 这一章决定你是「用 Agent 的人」还是「能修 Agent 的人」。


3.1 为什么日志不是聊天记录

第 02 章的 messages 是一个数组。它在进程里够用,但有三个致命缺陷:

缺陷 后果
进程崩溃即丢失 无法复盘,无法续跑
只存最终态 看不到「系统提示词当时到底拼了什么」
无法分叉 不能从第三步另开一条分支试不同方案

官方 DSH 的做法是把会话建模成 append-only 事件日志,而不是消息数组。官网原句:

模型看到的一切都会写入仅追加设计的会话日志,包括系统提示词、思维链、工具调用与结果、子 Agent 调度,以及每一次上下文注入。恢复、分叉、检索与回放也共享同一份事件流。

docs/architecture.md 里有一条极强的工程不变量:

"Model-visible means logged." —— 每一次模型请求都必须能从日志重建。新增任何模型可见的输入,都必须新增会话事件。

这句话是本章的核心。它意味着:日志不是观测的副产品,日志是上下文的唯一真相来源。模型看到的消息由 deriveMessages() 从日志投影出来,而不是另外维护一份。


3.2 一个最小事件流样例

官方 DSH 的 durable 事件包括 turn/*、step/*、system/message、user/message、assistant/message、assistant/attempt、tool/*。下面是概念化 JSONL(字段名用于说明结构,实际 schema 以 reference/persistence-catalog.md 为准):

{"t":0,"type":"session/created","session_id":"s-9f2","workspace":"/repo"}
{"t":1,"type":"turn/start","turn_id":"t-1","model_selection":"deepseek-v4-pro"}
{"t":2,"type":"system/message","sections":["identity","tool_schemas","workspace","clock"],"text":"..."}
{"t":3,"type":"user/message","text":"重构登录模块,先跑测试建基线"}
{"t":4,"type":"step/start","step_id":"st-1","admitted_tools":["bash","read_file","edit","plan"]}
{"t":5,"type":"request/header","reason":"series","model":"deepseek-v4-pro","effort":"high"}
{"t":6,"type":"request/context","injected":["AGENTS.md","git_status"],"token_estimate":10842}
{"t":7,"type":"tool/call","call_id":"c-1","name":"bash","args":{"cmd":"npm test"}}
{"t":8,"type":"tool/result","call_id":"c-1","exit":1,"stderr":"3 failing","bytes":2048}
{"t":9,"type":"assistant/message","text":"基线 3 个失败,先定位根因…","compact_stream":"..."}
{"t":10,"type":"step/end","step_id":"st-1"}
{"t":11,"type":"step/start","step_id":"st-2", ...}
{"t":20,"type":"assistant/attempt","reason":"cancelled","adds_model_history":false}
{"t":25,"type":"turn/end","turn_id":"t-1"}

三个关键设计:

  1. assistant/attempt 不进模型历史。失败、重试、取消、流错误的尝试被保留下来供诊断,但不污染后续上下文。
  2. 每次 attempt 会刷新运行时事实、重新协调提示词、冻结请求。官方 原文:「The loop sends immutable requests with live cancellation」。
  3. 上下文注入本身是事件(request/context)。这一条最容易被忽略,也是排查「模型为什么突然说了句莫名其妙的话」的入口。

3.3 六要素逐格展开

要素 关键问题 失败模式 DSH 的接缝 官方
Loop 何时算「欠一次请求」? 早停 / 死循环 / 过度扩张 agent/turn-stopping、agent/pre-step
Tools schema 由谁组装、何时准入 工具描述歧义、工具过多 ctx.tools、step-admitted tool schemas
State 什么必须跨 reload 存活 重启即失忆 SessionEvent、ctx.sessions
Context 每轮进窗口什么、什么被压缩 信息缺失 / 提示词互相冲突 ctx.systemPrompt、subsystems/compaction
Sandbox 生成代码在哪跑 越权、外联、凭据泄露 ctx.sandbox、subsystems/approval
Guardrails 谁能拦下一次调用 规则写成建议 permission-presets、tools/pre-execute

官方 架构文档给出一个更精确的抽象:Capability Seam(能力接缝)。一个 seam 有三个角色:

Service Definition(声明接口)  +  Service Provider(实现)  +  Consumer(通常是模型-facing 工具)

原文:"Seams are why one provider swap changes the whole product. Filesystem and subprocess providers share one execution world, so pointing them at a remote sandbox moves Bash, PTY, and LSP with them, with no provider forks."

这是「一切皆插件」能成立的机制:不是把代码拆散,是把依赖方向反转成「定义—实现—消费」三元组,让替换发生在配置层。


3.4 信息对等:一条常被忽略的判据

社区 Harness 工程里有个概念叫 information parity:

如果某条信息人能看到、Agent 看不到,Harness 就有一个洞。

每一份你读过的文档、每一个团队「大家默认都知道」的约定、每一次口头交代的部署步骤,只要没有编码进 Harness,Agent 就会犯一个人绝不会犯的错。

实操清单:

人知道什么 编码进哪里
构建/测试/格式化用什么命令 AGENTS.md 顶部 3–5 行
哪些目录是生成的、不能改 AGENTS.md + PreToolUse hook 双重
迁移必须放 prisma/migrations/、不许改已有迁移 规则 + coverage test
某个 API 的字段含义 Skill(按需加载,不常驻上下文)
上次这个任务为什么失败 Trajectory / MEMORY.md / 复盘文档
现在几点、什么时区 时钟上下文(原文 极简模式把「时钟上下文」也砍掉了)

判据 5:排查「模型怎么这么笨」之前,先问「这条信息它有没有地方能拿到」。绝大多数「能力不足」其实是「信息不对等」。

官方 架构文档还给出一个实现层的对应物:agent.inject() —— 新增模型可见上下文的正规入口,它落在下一次被准入的请求里。绕过它直接改消息,就会破坏「Model-visible means logged」。


3.5 三类事件,三种用途

官方 docs/architecture.md 把扩展点分成三个域:

域 例子 是否持久化 用途
Session events tool/result、user/message ✅ durable 必须跨 reload 存活的事实
Agent events agent/*(inbox / step / status / request / validation) ❌ live 观察或拦截进行中的工作
Capability events fs/*、tools/*、telemetry/* ❌ live 给接缝挂策略与适配器,不 import loop

另有水瀑布(waterfall)语义:agent/pre-step、agent/request、llm/stream、tools/* 三类监听器必须调用 next() 委托,否则会截断流水线;agent/turn-stopping 是串行且没有 next()。这是写插件时的高频坑。


3.6 本章产出与验收

核心产出:一张你当前系统的事件流图 + 一条真实会话的 JSONL,能指出每个 durable 事件的类型与消费者。

验收点:

  • 能从日志回答「这次请求的系统提示词由哪几节拼成」
  • 能解释为什么 assistant/attempt 不进模型历史
  • 能区分 durable session event 与 live agent event,并说明插件该挂哪个
  • 列出自己项目里 3 条「人知道、Agent 不知道」的信息,并给出编码位置

延伸阅读

来源 URL 等级
DSH 架构 · Session log / Events / Capability seams https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md 官方
官方文档 · 持久化事件目录 https://deepseek-harness.github.io/deepseek-harness/reference/persistence-catalog 官方
官方文档 · 能力服务接缝 https://deepseek-harness.github.io/deepseek-harness/reference/capability-seams 官方
官方文档 · 会话子系统 https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/session 官方
官方文档 · Tool 执行流水线 https://deepseek-harness.github.io/deepseek-harness/reference/tool-execution-pipeline 官方
官方站 llms.txt(95 页全量索引) https://deepseek-harness.github.io/deepseek-harness/llms.txt 官方
本系列为本站原创教程,基线为微信公众号《DeepSeek Harness 最新高阶指南》(2026-11-05),并汇总 DeepSeek 官方仓库与文档站、Cordis / arXiv:2608.25512、以及 OpenAI / Anthropic / LangChain / Martin Fowler 等一手资料。每条引用均标证据等级,完整清单见 附录 B;未定位到一手来源的线索单列,未编造补位。DeepSeek Harness 为 developer preview,官方 SAFETY.md 明确「未经过安全审计、不得视为生产就绪」,命令与配置键可能随版本失效。资料截止 2026-11-06。姊妹篇:《FDE 入门到精通》。