Comprehensive Agent

最终 Harness 仍然是一个循环,周围环绕着让它生产化的系统。

s01–s19 的全部机制,加上入口、后端与 UI。

组装

问题

你已经亲手搭出了 19 个机制。现在把它们组装成一个完整的 Agent

  • 模型要能用上全部工具(bash、文件、web、技能、todo、子代理、后台任务……);
  • 权限、沙箱、钩子、守卫环绕执行;
  • 记忆持久化、可恢复、可 fork;
  • 并且有一个人类能用的入口——CLI、Web UI、或者自动化协议(ACP)。

解决方案

组装清单(对照 s01–s19 逐个核销):

机制 课程 组装时它负责什么
Agent Loop s01 循环驱动者,turn/step 生命周期
Tool Use s02 注册表 + 执行管道 + 呈现模式
Permission & Sandbox s03 审批、权限预设、进程沙箱
Hooks s04 生命周期钩子桥 + 原生扩展点
TodoWrite s05 会话 todo 列表
Subagent s06/s17 子代理提供者族 + 委托工具
Skill Loading s07 技能目录 + 加载器
Context Compact s08 压缩缝 + 裁剪器 + 命令
Session Memory s09 事件日志(一切状态的地基)
System Prompt s10 区块组装 + 变量 + persona
Error Recovery s11 超时策略 + 重复提醒 + 重试
Plan Mode s12 计划状态 + 策略区块 + 退出工具
Background Jobs s13 后台任务注册表 + 通知
Schedule s14 会话本地提醒
Goal s15 持久目标 + 续轮
Workflow s16 模型编排的子代理流水线
Preset s18 按会话组合 Agent
MCP & Web s19 外部工具桥

工作原理

第 1 步:入口只是另一层组合。同一个 agent-spine(固定服务集:会话、提示词、工具、技能、目标、任务、循环……),配不同的入口插件,得到不同的产品形态:

                    ┌─────────────────────────────────────────┐
                    │        agent-spine(公共服务集)          │
                    │  会话日志 · 提示词组装 · 工具管道 · 技能    │
                    │  目标 · 后台任务 · 守卫 · 循环驱动者        │
                    └───────────────┬─────────────────────────┘
        ┌───────────────┬───────────┴───────────┬────────────────┐
        ▼               ▼                       ▼                ▼
   headless 入口    Web UI 入口             ACP 入口          JSON-RPC 入口
   (一次性任务)   (浏览器会话)        (自动化 Agent)     (SDK 客户端)

第 2 步:后端可换,入口不变。换模型适配器(ctx.llm)、换沙箱(本地 → E2B 远程)、换子代理后端——入口与模型侧工具都不变。这是贯穿全程的"能力缝"哲学的最终兑现。

第 3 步:一切状态可恢复。会话日志 + 事件订阅持久化 → 重启进程、恢复会话、fork 分支,全部状态(todo、计划、目标、调度、记忆)从日志还原。

试一下

现在跑真实的 DeepSeek Harness(见文末"下一步"):

  • dsh web 打开 Web UI,新建会话,让它做一件多步任务——观察 todo、工具调用、审批提示
  • 打开计划模式,观察"只出方案"的行为
  • 让模型后台跑一个长任务,同时继续对话

对比重点:你在 s01–s19 里亲手实现的每一个机制,都能在真实产品里找到对应物——这 20 课的收获,就是你读懂 DSH 源码与配置的完整地图。

以下内容基于 packages/examples/agent-spine-demodocs/architecture.md 的核查。

一、agent-spine 是"一个 bundle 插件"

agent-spine-demo默认的执行器无关、UI 无关的 Agent 主干——一个 Cordis bundle,挂载每个 harness Agent 都需要的一组服务:cordis-plugin-timerdsh-llmdsh-sessiondsh-system-promptdsh-toolsdsh-skilldsh-agentdsh-goaldsh-llm-retrydsh-jobs-localdsh-tool-bashdsh-agent-instructionsdsh-tool-jobsdsh-agent-loop 等——并把循环的 agents 列表作为自己的配置转发。

可互换的东西被刻意留在 bundle 外:模型适配器、沙箱后端、入口——由入口配置选择(headless-agentweb-cordisacp-agentjsonrpc-agent 都在 examples/)。

二、profile 与 bundle

  • bundle 是 Cordis 配置行 + 代码的分发格式(dsh.bundle 指向 patch 文件);
  • profile 是存储在 Harness home 的命名组合(列出它叠加的 bundles + 用户 patch)。webheadless 是自带模板;
  • 每一行配置都可以被上层 patch 覆盖——dsh --profile web --dump-config 打印实际启动的插件树,任何一行都能用 patch 替换。

三、这一切的哲学

"没有需要打补丁的特权核心:你通过在旁边挂一个插件来扩展 dsh,注册是可逆的 effect,插件卸载即撤销。"——这就是为什么 20 课里每一个机制都可以独立理解、独立替换。循环不变,世界可变。