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-demo 与 docs/architecture.md 的核查。
一、agent-spine 是"一个 bundle 插件"
agent-spine-demo 是默认的执行器无关、UI 无关的 Agent 主干——一个 Cordis bundle,挂载每个 harness Agent 都需要的一组服务:cordis-plugin-timer、dsh-llm、dsh-session、dsh-system-prompt、dsh-tools、dsh-skill、dsh-agent、dsh-goal、dsh-llm-retry、dsh-jobs-local、dsh-tool-bash、dsh-agent-instructions、dsh-tool-jobs、dsh-agent-loop 等——并把循环的 agents 列表作为自己的配置转发。
可互换的东西被刻意留在 bundle 外:模型适配器、沙箱后端、入口——由入口配置选择(headless-agent、web-cordis、acp-agent、jsonrpc-agent 都在 examples/)。
二、profile 与 bundle
- bundle 是 Cordis 配置行 + 代码的分发格式(
dsh.bundle指向 patch 文件); - profile 是存储在 Harness home 的命名组合(列出它叠加的 bundles + 用户 patch)。
web与headless是自带模板; - 每一行配置都可以被上层 patch 覆盖——
dsh --profile web --dump-config打印实际启动的插件树,任何一行都能用 patch 替换。
三、这一切的哲学
"没有需要打补丁的特权核心:你通过在旁边挂一个插件来扩展 dsh,注册是可逆的 effect,插件卸载即撤销。"——这就是为什么 20 课里每一个机制都可以独立理解、独立替换。循环不变,世界可变。