第 08 章 · 四层递进与确定性护栏

本篇目标:把「建议」升级成「强制」。 一句话:规则文件约 70% 被遵循,hook 是 100%。社区


8.1 四层递进:不要一次上齐

社区 单人 / 团队 Harness 的通行分层(aiworkflowpro、amux 等指南的共同骨架):

层 加什么 难度 解决的失败 前置条件
L1 约束 AGENTS.md / CLAUDE.md,3–5 条起步 低 最常见的高频错误 无
L2 工具 MCP、自定义工具、脚本化传感器 中 Agent 看不见的信息 L1 稳定
L3 校验 hooks:PreToolUse / PostToolUse / Stop 中高 规则被静默跳过 L1/L2 稳定
L4 编排 子 Agent、多 Agent、worktree、任务板 高 单 Agent 上下文不够 L3 稳定

顺序不可跳。每一层都依赖下层已经稳定;四层一起上,出问题时无法定位是哪层的锅。社区反复出现的教训是「过度设计控制流」——为当前模型弱点写的复杂 pipeline,下一次模型升级就报废。

社区 一条克制的工具原则(Cat Wu):除非一个工具被证明能提升效果或准确率,否则不要加。工具更少 = Harness 更可控。第 09 章给出成本量化。


8.2 Guides / Sensors 四象限

社区 Böckeler 的框架按两个轴切分:Guide 事前引导,Sensor 事后反馈;每类再分确定性 / 推断性。

Computational(确定性) Inferential(模型判断)
Guide(行动前) 脚手架脚本、文件模板、typecheck 配置 AGENTS.md、Skill、系统提示词
Sensor(行动后) 测试、linter、行数限制、构建 LLM-as-judge、AI code review、eval suite

两条结论:

  1. 只有一半会失败:只有 sensors,Agent 会重复犯错;只有 guides,你永远不知道规则有没有生效。
  2. 能确定性就别用模型判断:「A test gives the same answer every time and costs nothing to rerun」。推断性 sensor 自身还需要被评估,且应固定 temperature=0。

判据 10:任何「必须 100% 生效」的约束,落在左侧(computational)。落在右侧的规则只是概率性建议。


8.3 Hooks:从建议到强制的机制

官方 Claude Agent SDK 的 hook 事件,按阶段分组(这是目前公开最完整的参考实现):

阶段 事件 能做什么
工具前 PreToolUse 阻断 / 修改工具调用(exit code 2 = 阻断)
工具后 PostToolUse、PostToolUseFailure、PostToolBatch 注入校验结果、写审计
回合 UserPromptSubmit、Stop、StopFailure 注入上下文、结束前自检
会话 SessionStart、SessionEnd、InstructionsLoaded 初始化、审计加载了哪些规则
压缩 PreCompact、PostCompact 压缩前归档完整 transcript
子 Agent SubagentStart、SubagentStop、TeammateIdle 并行任务追踪
任务 TaskCreated、TaskCompleted 任务关闭前要求测试通过
隔离 WorktreeCreate、WorktreeRemove 工作树生命周期
权限 PermissionRequest、PermissionDenied 自定义审批
其他 ConfigChange、FileChanged、CwdChanged、Notification 动态重载 / 告警

Hook 类型:command(shell,JSON 走 stdin/stdout)、http、mcp_tool、prompt、agent。

三个可直接改用的模式

① PreToolUse 拦截危险写操作 官方

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "if echo \"$TOOL_INPUT\" | grep -qi '\\.env'; then echo 'BLOCKED: .env 不允许写入' >&2; exit 2; fi"
      }]
    }]
  }
}

注意 matcher 的边界:只匹配 Write|Edit 时,用 Bash 写 .env 不会触发。要覆盖子进程,必须同时配 sandbox 的文件系统 deny 规则。官方 权限与沙箱是互补的两层:权限管「哪些工具/文件/域名」,沙箱管「OS 级 Bash 与其子进程」。

② PostToolUse 注入失败信号 社区

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{ "type": "command", "command": "npx tsc --noEmit 2>&1 | head -20" }]
    }]
  }
}

社区 Addy Osmani 概括得好:"success is silent, failures are verbose"。通过时模型什么都听不到(零延迟),失败时错误文本被注入 loop,模型自纠。

③ Stop 前定义「Done」 社区

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "prompt",
        "prompt": "结束前确认:(1) 测试是否通过?不确定就跑一次。(2) typecheck 是否通过?(3) 是否改动了任务范围外的文件?任一为否,继续工作。"
      }]
    }]
  }
}

判据 11:「Done 必须是一个可判定的状态,不是一种感觉」。没有硬退出条件,Agent 要么过度扩张,要么在测试还是红的时候宣布完成。这与第 15 章 Terminal Bench 2.0 的 self-verification middleware 是同一个机制。


8.4 在 DSH 里的等价物

官方 docs/architecture.md 的扩展点表,可以直接对上:

通用模式 DSH 接缝
PreToolUse tools/pre-execute(waterfall,监听器需 next())
PostToolUse tools/post-execute、审批策略
Stop / 完成判定 agent/turn-stopping(串行事件,无 next())
请求前改写 / 拒绝 agent/pre-step(可 accept / rewrite / reject)
权限 allow/deny subsystems/permission-presets、subsystems/approval
沙箱 ctx.sandbox backend,消费者在 spawn 前包装 argv
注入上下文 agent.inject()(正规入口,落在下一次被准入的请求)

官方 提醒:waterfall 类监听器必须调用 next() 委托,否则截断流水线——这是写 DSH 插件时最常见的「加了插件后什么都不动」的原因。


8.5 反模式清单

反模式 为什么坏 替代
把禁令全写进系统提示词 概率性生效,长任务后半段会被压掉 迁到 hook + sandbox
每一步都弹人工审批 「A gate on every step trains reviewers to click Accept」社区 gate 只放 side effect 前
用 LLM 判断「格式对不对」 慢、贵、结果漂移 linter / typecheck / coverage test
为当前模型弱点写复杂 pipeline 下个版本模型升级即报废 写永久性约束,月度复审删除临时规则
hook 里跑长耗时的全量测试 每个 tool call 都触发,拖垮交互 分级:快检查每次跑,全量放 Stop / CI
静默 fallback 「A missing placement fails the build, and a missing sandbox fails the run」社区 fail closed

8.6 本章产出与验收

核心产出:一个 settings.json(或 DSH 对应 patch),含至少 1 条 PreToolUse 阻断、1 条 PostToolUse 反馈、1 条 Stop 自检;以及一次「故意违规被拦下」的截图。

验收点:

  • 能用 exit code 2 真的阻断一次危险操作,并确认模型收到了阻断原因
  • 能解释为什么 matcher 只写 Write|Edit 挡不住 Bash 写文件
  • 能把一条现有 AGENTS.md 规则,升级成确定性 hook
  • 能说出 waterfall 监听器忘记 next() 会发生什么
  • 能指出自己 Harness 里哪条 gate 是多余的

延伸阅读

来源 URL 等级
Claude Agent SDK · Hooks(完整事件表) https://code.claude.com/docs/en/agent-sdk/hooks 官方
Claude Code · 自定义子 Agent 与 hooks https://code.claude.com/docs/en/sub-agents 官方
Claude Code · 权限与沙箱互补 https://code.claude.com/docs/en/permissions 官方
Claude Code · Sandboxing https://code.claude.com/docs/en/sandboxing 官方
DSH 架构 · 扩展点表 / 事件域 https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md 官方
官方文档 · 审批 / 权限预设 https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/approval 官方
Böckeler, Guides / Sensors https://martinfowler.com/articles/harness-engineering.html 社区
Harness Engineering 完整指南(四层递进) https://aiworkflowpro.com/harness-engineering-guide/ 社区
amux, The Complete Guide(hook 示例) https://amux.io/guides/harness-engineering 社区
codeongrass, The Outer Harness(Stop hook) https://codeongrass.com/blog/outer-harness-real-work-ai-coding-agents 社区
本系列为本站原创教程,基线为微信公众号《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 入门到精通》。