DeepSeek Harness 编程最佳实践
版本标注:本文已对照 DSH v0.1.5-rc.1 修订(初稿基于 v0.1.2-alpha.4)。DSH 处于 pre-stable 阶段(官方口径:”Public APIs are pre-stable”),破坏兼容性变更不可避免,使用前请核对当前版本。涉及社区插件的能力均标注”社区插件”,非 DSH 原生功能。
引子
DSH 不是工具,是新同事。
新同事需要 onboarding——你要告诉他项目是什么、约束是什么、禁区是什么。没人 onboarding,新同事就靠猜,猜错了就要么”顺手重构”要么”夹带私货”。
本文不讲理论,只讲”在 DSH Web 界面里能做什么、怎么做”。
6 件事(另有第 8 章工程规范补充 + 附录 A 速查表):
- 5 分钟最小工作流(第 0 章)——先跑通一个闭环,再回头搭文档
- 项目文档怎么搭(第 1 章)——从 DSH 开发视角,区分核心必需 / 推荐 / 条件必需
- 4 种 agent 模式 + 运行基础(第 2 章)——模型选择 + 界面里所有 slash 命令 + sandbox 权限
- 工作流决策树(第 3 章)——什么时候走哪条路
- 场景实操(第 4~6 章)——标准模式 7 个(4.4 起含组合形态)+ 其他模式 3 个 + 高级工具 2 个
- plan/spec 自动检查(第 7 章)——原生 hooks 方案 + 社区插件增强 + CI 门禁
假设你是 3~8 人中型项目的主程,用 DSH web 模式,长期使用标准模式。
第 0 章:5 分钟最小工作流
目的:在搭文档之前,先亲手跑通一个 DSH 闭环。
如果你是第一次用 DSH,不要从第 1 章的文档结构开始。先做这件事:
- 打开 DSH Web(
npx @deepseek-ai/dsh web) - 确认顶栏模式为标准模式
- 在 chat 里粘贴:
1 | Bug: src/utils/format.ts 的 formatDate 对 null 输入返回 "NaN" |
- 观察 DSH 执行序列:
read→bash(复现)→read(定位)→edit(修复)→bash(验证)→bash(commit) - 全程不调
/plan、不派 subagent。这就是最简单的任务路径。
跑通之后,你就能理解本文后面所有场景的”最小单元”。再回头看第 1 章搭文档,会更有方向感。
第 1 章:项目文档与协作基建
目的:从 DSH 开发视角,明确哪些文档是核心必需、哪些是推荐、哪些是条件必需。
核心原则:“必需”不等于”启动时就必须存在”,而是”在 DSH 工作流触发到它时,它必须已经存在”。
1.1 核心必需(2 个)
DSH 官方仓库的 AGENTS.md 中明确写着:
Read
docs/architecture.mdbefore changingpackages/; followdocs/AGENTS.mdfor documentation.
这是 DSH 官方仓库对自身的约定,也揭示了可复用的机制。注意区分两层:DSH 产品只自动注入 AGENTS.md(首个请求时注入用户全局 $DSH_HOME/AGENTS.md + 项目根到工作目录的 AGENTS.md/CLAUDE.md 链,约 64KB 预算);architecture 文档不会自动加载,要靠 AGENTS.md 里写明规则、驱动 Agent 去读(见 1.5 模板)——这正是 DSH 官方仓库自己的做法。在此机制上,对任何 DSH 项目,核心必需只有两个:
| 文件 | 为什么核心必需 | 核心内容 |
|---|---|---|
AGENTS.md |
DSH 自动注入上下文的唯一项目文档(见上),是 Agent 全程遵守的持久化长期指令。它定义了项目的硬规则和禁区。 | 项目约束、命令约定、禁止事项、协作流程。 |
docs/architecture/overview.md + decisions.md |
在 AGENTS.md 中约定后,成为 Agent 修改核心代码前的必读材料(DSH 官方仓库即采用此模式,其入口为单文件 docs/architecture.md)。提供系统上下文,避免破坏架构完整性。 |
系统图谱、模块职责、非功能性要求、所有 ADR。 |
缺失后果:
- 缺
AGENTS.md→ DSH 可能违反项目规则,做出未授权的修改或操作。 - 缺
architecture/→ DSH 在不理解系统全貌的情况下修改代码,可能引入架构性错误。
1.2 推荐文档(1 个)
| 文件 | 为什么推荐 | 何时创建 |
|---|---|---|
README.md |
DSH 启动时的项目入口。缺失不影响协作,但降低效率——DSH 需要从 AGENTS.md 和 architecture.md 中反推项目入口。 |
项目启动时。 |
1.3 条件必需(1 个)
| 文件 | 必需条件 | 为什么 |
|---|---|---|
docs/specs/ |
当项目进入多任务并行阶段(>1 天的复杂任务、跨模块重构、性能优化)后,变为必需。 | DSH 调用 exit_plan_mode 时提交的 plan 必须写入 docs/specs/,这是 DSH 工作流的核心落点。 |
判定标准:
- 要进
docs/specs/:工作量 > 1 天、跨模块、需要设计决策、影响接口或数据。 - 不进:工作量 < 1 天的简单任务,PR 描述里写清 AC 即可。
1.4 按需扩展(其余文件)
| 文件 | 何时新建 |
|---|---|
CHANGELOG.md |
第一次发版前 |
docs/runbooks.md |
第一次线上事故后 |
docs/postmortems/ |
第一次故障复盘时 |
docs/instructions.md |
团队觉得”每次都要翻 AGENTS.md 找流程”时 |
1.5 AGENTS.md 模板(最小版)
1 | # DSH 协作守则 |
两条铁律:
- 每条规则必须映射到具体 DSH 指令/命令——否则就是空话
- AGENTS.md 跟随项目演进——团队踩的坑必须反馈回来
1.6 docs/specs/ 模板(plan 文件归宿)
按”类型 + 名称”命名:
| 类型 | 文件命名 | 判定标准 |
|---|---|---|
| feature | feature-<name>.md |
> 1 天、跨模块、有设计决策 |
| refactor | refactor-<title>.md |
跨模块重构、行为不变 |
| perf | perf-<topic>.md |
需量化对比、有基线 |
| bugfix | bugfix-<id>.md |
涉及设计/多模块的 bug |
通用模板:
1 | # <标题> |
DSH 校验约束:plan 参数必须 markdown + # 标题开头,否则 exit_plan_mode 调用失败。
1.7 维护节奏
| 时点 | 必做 |
|---|---|
| 项目启动 | 写 AGENTS.md + docs/architecture/overview.md + decisions.md(+ 推荐 README.md) |
| 每个 > 1 天任务 | 提前写 docs/specs/feature-<name>.md |
| 每个架构决策 | 追加 decisions.md |
| 每次发版 | 更新 CHANGELOG.md |
| 每次事故 | 48h 内写 postmortems/ + 更新 runbooks.md |
| 团队踩坑 | 反馈回 AGENTS.md |
第 2 章:DSH 运行基础
目的:4 种 agent 模式 + 模型选择 + slash 命令 + sandbox 权限,一次讲清。
2.1 4 种 agent 模式与选择建议
DSH 内置四种 Agent Preset——极简(Minimal)、标准(Standard)、PTC、创造(Cordis)——每个 Preset 是一份 agent.cordis.yml 组装文件,决定当前会话拥有哪些工具、提示词段落和 Skill。不同 Preset 的会话在同一进程中隔离运行。
| 模式 | 工具集 | 中型项目建议 |
|---|---|---|
| 标准模式 | 文件编辑、Shell、网页检索、Skills、计划、目标、子代理、工作流 | ✅ 90% 时间用这个 |
| PTC 模式 | 标准模式全部能力 + run_code(TypeScript SDK),无 workflow(自 v0.1.2-alpha.4 起) |
需要编程化组合工具时切换 |
| 极简模式 | 仅持久 PTY Shell 一个工具(POSIX 为 bash,Windows 为 pwsh),无文件编辑工具、无网页检索、无子 Agent、无规划模式、无目标、无上下文压缩 |
训练 / 基准测试 / 单文件轻量任务 |
| 创造模式 | 标准模式 + cordis_* 运行时自检工具 |
写自定义 preset / 二次开发 DSH |
PTC 模式在标准模式全部能力基础上增加 run_code 工具,模型不再每步发出一个 tool-call,而是写一段 TypeScript 程序一次性提交,由沙箱运行时执行,把原本需要五次往返的操作压缩为一次。极简模式的 shell 是持久 PTY 版本,状态在多次调用之间保持,不随每次调用重置工作目录和变量;改文件只能用 sed、cat 等 shell 命令,且 shell 后端仍受宿主 sandbox policy 约束。极简模式无上下文压缩,不适合长任务。
PTC 模式 workflow 移除的官方来源:v0.1.2-alpha.4 发布说明中明确记录——“Web PTC Mode 默认不再向模型提供通用 workflow 工具”。
两个常见误区:
- “切到 PTC 看起来很酷”——PTC 缺 workflow 工具,多数中型项目用不上。
- “切到创造模式更强大”——创造模式是为二次开发 DSH 设计的,日常编码反而引入不必要的工具噪音。
模式锁定规则:Preset 在会话启动后无法更换,一旦发出了第一条消息,Preset 就锁定了。但可以开一个新会话选不同的 Preset。
验证当前模式:看 Web GUI 顶栏的状态指示区。
2.2 模型选择
DSH 中模型可在 4 个层级指定:
| 层级 | 配置位置 | 适用 |
|---|---|---|
| Profile 默认模型 | profile 配置 | 整个部署 |
| Session 级别 | session 设置 | 当前会话 |
| Subagent | subagent(spawn)的调用参数 provider + model(可选 reasoning_effort;先用 list_subagent_models 查可用目录);subagent_fork 锁定父路由、不可选模型(见 4.7) |
派生子 agent |
| Workflow | workflow 脚本的 phase.model |
workflow 各阶段 |
任务分级:
| 任务特征 | 推荐 |
|---|---|
| 短上下文 + 简单任务 + 大量重复 | 弱模型 |
| 跨文件推理 + 架构设计 + 性能优化 | 强模型 |
| 安全相关 + 算法核心 | 强模型 |
一句话原则:模型选择是性价比,不是越强越好。错的 AC,再强的模型也救不了;写好的 plan + specs,弱模型也能干出 80 分的活。
2.3 slash 命令
| 命令 | 作用 | 关键约束 |
|---|---|---|
/plan / /plan <msg> |
进入计划模式 | 可附文件/图片 |
/plan off |
退出计划模式 | — |
/compact |
手动压缩历史 | idle-only、不接受参数、不消耗模型回合 |
/goal / /goal <obj> |
创建长期目标 | 4 阶段(active/paused/blocked/complete),默认 256 轮上限 |
/goal edit <obj> |
改目标 | 阶段不变 |
/goal pause |
暂停 + disarm | — |
/goal resume |
恢复 / 重新武装 | 受轮次上限约束 |
/goal clear |
清除当前目标 | 历史保留在 session log |
/permission |
切换权限预设 | 配合 sandbox 模式 |
/feedback <text> |
记录会话反馈 | 必须带文本;不进入模型历史、不打断模型工作 |
/export |
下载当前会话日志为 ZIP | Web-only、不接受参数、不进入模型历史 |
以上即当前 Web 界面的全部内建 slash 命令(安装社区插件可能追加,如 dsh-plan-doc 的 /plan-doc)。
关键事实:命令输出不进入模型历史——DSH 渲染给用户看,不污染上下文。命令和参数严格按字面解析——/goal pause after verification 会创建目标”pause after verification”,不是暂停。
/goal 状态机:
1 | create |
active状态才能续推(自动武装)paused/blocked会 disarm——/goal resume重新武装;complete是终态(不可 resume),clear后目标已删除无从 resume- session resume / fork 后默认 disarmed——必须
/goal resume才会继续推进 - 人类消息不增加 Round 数,只有目标驱动的工作轮次才计数
2.4 sandbox 与权限
DSH 通过 @deepseek-ai/dsh-bash-sandbox 和 @deepseek-ai/dsh-permission-presets 提供文件访问隔离。
| 模式 | 文件效果 | 推荐场景 |
|---|---|---|
read-only(fail-safe 默认) |
拒绝写入,必需 sink(如 /dev/null)除外 |
探索、纯调研式 plan(不落盘 spec) |
workspace-write |
允许写入工作区根目录及后端定义的临时区域 | 编码、重构、性能优化 |
danger-full-access |
绕过隔离 | 系统运维(慎用) |
关于默认模式的精确说明:read-only 是 sandbox 的 fail-safe 默认模式(包级兜底)。预设表要区分两层:插件代码级默认只有 workspace-write(workspace-write + ask)和 danger-full-access(danger-full-access + never)两个预设,但发货的 Web 组合覆盖了整张表,实际 /permission 可选三个预设(另含 read-only + ask)。一个全新会话创建时,permission/preset 会被固定为 workspace-write。这意味着通过 /permission 切换预设后,当前会话的 sandbox 模式随所选预设生效。
关键机制:被 sandbox 拒绝的命令,结果里携带 sandbox: {mode, denied: true},DSH 不静默重试——失败就是失败,模型看到结果自己调整。模型可在工具调用中加 sandbox_permissions: "workspace-write" + justification,系统弹出审批提示给用户,一次批准只对被问的那一次操作生效。
与 plan mode 的协同(关键事实):
plan mode 不限制工具——它只是”在 plan 阶段不写代码”的软性提示词指导。官方文档明确说明:”计划模式是软性指引。沙箱模式与审批策略分别强制限制;两者都不读写计划状态,因此部署需要分别配置它们。”exit_plan_mode 在计划模式未激活时仍保持注册,进入或离开计划模式只改变提示词段落,绝不改变请求的工具目录。要强制限制,必须配合 sandbox:
- 探索/调研:
/plan+read-onlysandbox - 落地编码:审批后切
workspace-write - 注意:第 4 章的 plan 场景要在 plan 阶段把 spec 落盘到
docs/specs/,read-only下write会被拒——这类任务直接保持workspace-write(见 4.2 前置权限),read-only只配纯调研。
简单 bug 的 sandbox 前提:即便不调 /plan,也需确认 sandbox 为 workspace-write,否则 edit 会被拒绝。
第 3 章:工作流决策与纪律
目的:一张决策树 + 一张纪律表,告诉你”什么场景走哪条路”。
3.1 主决策树
嵌套优先级:多个分支同时命中时,按外层 → 内层组装而不是二选一——跨多轮?最外层套
/goal;单个里程碑复杂?内层走/plan;里程碑内有独立子任务?执行层派 subagent;token 压力大是全程状态,任何分支里都随时/compact(先落盘)。完整的组合案例见 4.5(跨天项目标准栈)。
1 | 任务来了 |
3.2 纪律速查表
| 触发 | 必用 | 禁止 |
|---|---|---|
| 启动任何任务 | read AGENTS.md + architecture | 直接动手 |
| AC 歧义 > 2 处 | ask_user_question |
自己脑补 |
| 复杂任务 | chat 输 /plan + exit_plan_mode |
只口头”我会先 plan” |
| 任务 ≥ 3 步 | todo_write(整列表替换) |
一口气干完不勾选 |
| 跨多轮 | /goal <obj> |
单轮能做完的事硬上 goal |
| 长会话 | 用户 /compact |
回合中调(busy) |
| 改架构 | edit decisions.md | 默默改了不记录 |
| 出事故 | 48h 内 write postmortems | 拖延或跳过 |
| 子 agent 问用户 | 把问题写进最终结果 | 子 agent 调 ask_user_question |
| 派子代理 | 任务决策完备再派;能自包含就 spawn,离不开上下文就 fork | 指望子代理来问人澄清 |
| 跨轮记忆 | AC / 进展 / 决策落盘到 specs / decisions.md | 只靠对话记录当跨轮记忆 |
| goal 自动轮次 | 只执行已批准的 plan | 无人值守轮次里等 exit_plan_mode 审批 |
| sandbox 写文件 | 确认当前会话 preset(发货默认 workspace-write,可直接写);只读调研切 read-only | 上来就 danger-full-access |
| workflow / ralph | 仅在用户明确要求时使用 | 普通任务硬上 |
第 4 章:标准模式场景实操
目的:7 个场景——4.1~4.3 为单机制场景,4.4 起进入组合形态(4.5 跨天标准栈、4.7 委派选型范式)。每场景给”用户消息 + 指令序列 + 真实约束”。
统一模板:适用条件 → 前置权限 → 用户消息 → 指令序列 → 验收 → 回滚 → 常见坑。
示例中的测试命令(jest / pytest)仅为示意,实操时替换为项目实际命令。
4.1 修复 Bug(无 plan)
适用:单文件改、AC 清晰、根因明确。
前置权限:workspace-write(必须,否则 edit 被拒)
用户消息:
1 | Bug: <一句话> |
指令序列:
1 | read 源文件 |
关键纪律:
- 先写失败测试,再改——避免”修了一个 bug 引入另一个”
- 最小修改——不改无关代码,不”顺手重构”
- 一次 PR 只修一个 bug
验收:全量测试绿灯 + 回归测试覆盖原 bug。
回滚:git revert <commit>。
常见坑:sandbox 为 read-only 时 edit 被拒——先 /permission 切 workspace-write。
4.2 开发新功能(plan mode)
适用:新功能 + 需要设计 + 跨多个文件。
对应文件:docs/specs/feature-<name>.md
前置权限:workspace-write(plan 阶段就要落盘 spec 文件,read-only 下 write 会被 sandbox 拒绝;plan mode 软约束 + exit_plan_mode 人工审批已构成双保险。read-only 仅用于不写文件的纯调研,见 2.4)
用户消息:
1 | /plan 新功能: <一句话> |
指令序列:
1 | 用户输 /plan → 进入 plan mode |
关键约束:
- plan 参数必 markdown +
#标题 - 子 agent 不能调
ask_user_question——必须把问题写进最终结果 - subagent 嵌套 ≤ 3 层(
maxDepth默认 3)
验收:plan 中所有 AC 勾选 + 全量测试绿 + CHANGELOG 更新。
回滚:按 plan 中每步独立 commit 逐个 revert。
常见坑:plan 文件缺少 # 标题导致 exit_plan_mode 失败。
4.3 实施重构(plan mode)
适用:跨模块重构、行为不变、需要分步执行。
对应文件:docs/specs/refactor-<title>.md
前置权限:workspace-write(理由同 4.2:plan 阶段需落盘 spec 文件)
用户消息:
1 | /plan 重构: <bad smell 一句话> |
指令序列:
1 | 用户输 /plan → 进入 plan mode |
关键约束:
- plan 必含”行为不变”承诺 + 测试基线(覆盖率数字写明)
- 每步独立 commit——失败可单独 revert
- 禁止夹带 feat——
refactor:和feat:必须拆 PR
验收:全量测试绿 + 行为不变 + 覆盖率不降。
回滚:git revert <step-commit> 单独回滚任一步。
4.4 优化性能(plan mode + subagent 并行)
适用:需量化对比 + 多方案实验。
对应文件:docs/specs/perf-<topic>.md
前置权限:workspace-write(理由同 4.2:plan 阶段需落盘 spec 文件与基线数字)
用户消息:
1 | /plan 优化: <指标 + 现状> |
指令序列:
1 | 用户输 /plan → 进入 plan mode |
关键约束:
- 每个 subagent 任务必须足够独立——避免整合成本 > 收益
- 后台 subagent 的结果靠完成通知收集(
job_output/job_kill只适用于bash后台任务,不适用于 subagent) - 保留回滚开关(feature flag / 配置项)
- 落地前后必有数字对比——没基线就不算”优化”
验收:实际指标 ≤ 目标 + benchmark 数字记录在 plan。
回滚:关闭 feature flag 或 git revert。
4.5 跨天项目标准栈:goal + plan + specs
适用:一个目标跨多轮会话 / 跨多天才能完成——这是中型项目最常见的大任务形态,也是 goal、plan、specs 三者的标准组合,而非三个孤立功能。
分层职责:
/goal是跨轮总线——记住”最终要什么”,持久化到 session log,默认 256 轮预算;/plan是单里程碑交付单元——每次有人值守时交付一个可审批、可回滚的里程碑;docs/specs/文件是跨轮记忆——会话会关、历史会被/compact折叠,只有落盘的进展可靠。
用户消息:
1 | /goal 完成订单模块重构:拆 3 个里程碑,行为不变,全量测试保持绿 |
完整流程:
1 | 用户: /goal <obj> → 创建 active 目标(持久化到 session log) |
组合纪律(每条都对应一个真实机制约束):
/compact前先落盘——折叠只保留总结,细节只能靠 session log 重放找回;AC、进展、决策先写进 specs / decisions.md 再压。- 无人值守的轮次不碰
exit_plan_mode——plan 审批走 user-questions 通道、必须等人回答,会成为自动轮次的阻塞点;plan 审批安排在有人值守的里程碑边界,自动轮次内只执行已批准的 plan。 - 澄清完再派子代理——子代理不能调
ask_user_question(调用会收到错误,问题只能写进最终结果);AC 澄清在主代理 plan 阶段完成,派出去的子任务必须决策完备。 - 每会话一个当前 goal——
active目标在新建前必须 pause / complete / clear;session resume / fork 后默认 disarmed,必须/goal resume;人类消息不增加 Round 数。
验收:目标 complete + spec”最终结果”段更新 + 全量测试绿。
常见坑:resume 后忘记 /goal resume,以为目标还在推进;只靠聊天记录当跨轮记忆,/compact 后细节丢失。
4.6 管理长会话(/compact)
适用:上下文接近 token 上限、或模型开始”忘事”。
用户消息:
1 | /compact |
完整流程:
1 | // 会话上下文变长 |
与自动压缩的关系:DSH 默认带 dsh-compaction-basic 后端,token 压力到阈值时自动触发(默认阈值是 context window 的 0.8)。/compact 是”提前手动”。
关键约束:
- idle-only——模型回合中调用返回
busy - 不接受参数——
/compact <anything>会被拒 - 不消耗模型回合——但会做一次辅助请求生成总结
- 可重复——压完觉得还长,可以再
/compact一次
4.7 组合范式:subagent 还是 subagent_fork
标准模式注册了两个委派工具,一句话选型:任务能脱离当前对话说清楚就 spawn,说不清楚就 fork。
subagent(spawn) |
subagent_fork |
|
|---|---|---|
| 上下文 | 全新,只看到 prompt | 继承父会话全部历史 |
| 模型 | 可选 provider / model / reasoning_effort |
锁定父路由(保留 KV cache 复用) |
| 典型用途 | 隔离执行:并行写独立模块、并行试方案(见 4.4) | 上下文内委派:”就刚才这堆改动做一次评审””基于当前讨论查一个分支问题” |
| 代价 | prompt 要自带完整上下文,写不清就做歪 | 继承冗余历史,token 成本高 |
通用原则:这等同于团队里的交接决策——能写成自包含 ticket 的活交给陌生人,离不开现场讨论的活拉人结对。无论哪种,子代理都不能问人,派单即终稿(见 4.5 组合纪律 3)。
约束沿用:maxDepth=3;后台模式(run_in_background: true)结果靠完成通知回收,send_message 可继续 steer。
第 5 章:其他模式实操
目的:补齐 PTC / 极简 / 创造模式的最小案例。如果你只用标准模式,可跳过本章。
5.1 PTC 模式:用 TypeScript 程序批量组合工具调用
适用:需要把 5~10 个工具调用串成一次操作,减少往返。
核心机制:PTC 模式在标准模式全部工具之外增加 run_code 工具,模型不再每步发 tool-call,而是写一段 TypeScript 程序一次性提交,由沙箱运行时执行。
最小案例:批量读取 3 个文件并汇总关键信息。
用户消息(新建 PTC preset 会话后输入——preset 在会话创建时锁定,见 2.1;不要在现有标准会话里发这条):
1 | 用 PTC 模式:读取 src/api/auth.ts、src/api/user.ts、src/api/order.ts, |
预期 DSH 行为:调用 run_code,提交一段 TypeScript 程序,一次性完成 3 次 read + 3 次分析,返回结构化汇总。而不是标准模式下的 6 次往返 tool-call。
关键约束:
- PTC 模式无 workflow 工具(自 v0.1.2-alpha.4 起)
- 模式在会话启动时锁定,发出第一条消息后无法切换——但可以开一个新会话选不同的 Preset
run_code在沙箱 worker thread 中执行
验收:返回结构化汇总 + 工具调用次数显著少于标准模式。
5.2 极简模式:最小环境下的单文件操作
适用:训练 / 基准测试 / 单文件快速修改。
工具清单:仅持久 PTY Shell 一个工具(POSIX 为 bash,Windows 为 pwsh)。无文件编辑工具、无网页检索、无 Skill、无子 Agent、无规划模式、无目标、无上下文压缩。
最小案例:修改一个配置文件并验证。
用户消息(新建极简 preset 会话后输入):
1 | 把 config/env.json 的 apiTimeout 从 30000 改成 60000, |
预期 DSH 行为:bash 用 sed -i 's/"apiTimeout": 30000/"apiTimeout": 60000/' config/env.json 改文件 → bash 执行验证。两步完成,全部通过 shell。
关键约束:
- 持久 shell:状态在多次调用间保持,工作目录和变量不重置
- 没有
edit/write工具——一切文件改动都走 shell 命令,模型需自己保证替换的精确性 - shell 后端仍消费宿主 sandbox policy——写文件受当前 sandbox 模式约束,
read-only下sed -i同样会被拒 - 无上下文压缩,不适合长任务——长会话会超出模型窗口
验收:验证命令输出 60000。
5.3 创造模式:运行时自检与 preset 创作
适用:写自定义 preset / 二次开发 DSH。
工具清单:标准模式 + cordis_* 运行时自检工具集,让模型直接读写自身运行的 Harness 组装。
最小案例:创建一个自定义 preset,继承标准模式但移除 web_search 和 web_fetch。
用户消息(新建创造 preset 会话后输入):
1 | 用创造模式:创建一个名为 "no-web" 的 preset, |
预期 DSH 行为:调用 cordis_* 工具检查当前运行时工具注册表 → 复制标准模式的组装并删去 web 工具行 → 在 ${DSH_HOME:-$HOME/.dsh}/.agent-presets/no-web/ 下生成 agent.cordis.yml + preset.yml(一个 preset 一个目录,不是单个 yml 文件)。不要改动 shipped preset 的安装目录——升级会被覆盖,应复制后改副本。
关键约束:
- 创造模式的
cordis_*工具等同于 shell 级访问权限(cordis_mount会对 live 运行时执行模型写的 JavaScript)——谨慎使用 - preset 是
agent.cordis.yml组装文件,不同 preset 的会话在同一进程中隔离运行 - 新 preset 需要新开会话才能在 UI 选择器中看到
第 6 章:高级工具——workflow 与 ralph
本章说明:workflow 和 ralph 是工具而非模式,在标准模式下即可使用。之所以独立成章,是因为其复杂度高于日常场景,仅在用户明确要求时使用。
6.1 workflow:多阶段 / 多角度编排
适用:跨多个文件的审计、一次迁移、多角度研究。一两项委派应使用普通 subagent。
核心机制:模型运行 JavaScript 编排脚本,把工作委派给多个 subagent,并返回脚本的最终 JSON 值。脚本可用 agent()、parallel()、pipeline()、phase() 和 log()。
最小案例:并行审查 3 个文件的正确性。
用户消息:
1 | 用 workflow 并行审查 src/a.ts、src/b.ts、src/c.ts 的正确性问题。 |
预期 DSH 行为:提交 workflow 工具调用,script 中包含:
1 | const reviews = await parallel([ |
关键约束:
- 父级轮次等待所有委派结束;取消或异常返回错误,不报部分成功
- 模型只看到最终结果,永远看不到中间子 agent 消息
maxResultChars默认 50000,更长 JSON 被截断
6.2 ralph:每轮全新 agent 迭代
适用:用户明确要求“每轮全新 agent 迭代”。普通长任务用 /goal,有界委派用 subagent / workflow。
核心机制:固定前台循环——每轮一个全新子 agent 针对同一个不可变目标工作,只传递上一轮的 bounded structured report 和共享工作区状态。
最小案例:一个需要多轮迭代才能稳定的算法优化。
用户消息:
1 | 用 ralph 迭代优化 src/algo.ts 的性能, |
预期 DSH 行为:调用 ralph({ objective: "...", maxRounds: 10 }),阻塞直到整个运行结束。每轮新 agent 读上一轮报告继续推进。
关键约束:
- 子 agent 的
complete/blocked报告不经过独立验证——worker 自报完成 - 父对话和之前子会话永远不复制到新一轮
maxRounds的配置值既是默认也是单次调用的上限:包级默认 256,但 shipped 的 standard / PTC preset 均配为 64——Web GUI 里实际默认与上限是 64(需更高上限要改 preset 配置)- 返回
complete/blocked/budget-limited,携带最后一轮报告和轮数
第 7 章:plan/spec 自动检查
重要说明:plan/spec 章节完整性检查不是 DSH 内建功能,但自 v0.1.5 起发行版原生内置 Claude Code 兼容 hooks 桥(
@deepseek-ai/dsh-hooks-claude-code),可直接在PreToolUse拦截exit_plan_mode实现检查,无需第三方插件;社区插件在此之上提供项目层自动发现等增强。CI 门禁为另一独立方案。
7.1 方案总览
| 方案 | 实现方式 | 拦截时机 | 适用阶段 |
|---|---|---|---|
| A:原生 hooks 拦截 | 官方 @deepseek-ai/dsh-hooks-claude-code(随发行版内置) |
PreToolUse 匹配 exit_plan_mode |
会话内,plan 提交时 |
| A+:社区 hooks 增强 | 社区插件 @dennisrongo/dsh-hooks |
同上 | 同上(要项目层自动发现时选它) |
| B:CI 门禁 | GitHub Actions job | PR 提交时 | 代码提交后 |
| C:专用插件 | 社区插件 @hilariouhiss/dsh-plan-doc |
exit_plan_mode 时渲染侧边面板 |
会话内,人工审查 |
7.2 方案 A:原生 hooks 拦截 plan 提交
官方桥 dsh-hooks-claude-code 复用 Claude Code 的 hooks 协议,把事件接到 DSH 的生命周期缝上。关键事件:
| 事件 | DSH 事件缝 | 能力 |
|---|---|---|
PreToolUse |
tools/pre-execute |
工具执行前允许/拒绝/询问 |
PostToolUse |
tools/post-execute |
阻断已结算结果或附加上下文 |
UserPromptSubmit |
agent/pre-step |
拒绝步骤或附加上下文 |
落地步骤:
- 在 profile 的 cordis 组合中挂载官方桥(在
$DSH_HOME/profiles/web/cordis.patch.yml追加一行),显式指定配置文件(原生桥无自动发现):
1 | - name: '@deepseek-ai/dsh-hooks-claude-code' |
- 创建
hooks.json:
1 | { |
- 编写检查脚本
scripts/check-plan-sections.mjs:
1 | // 从 stdin 读取 JSON payload |
工作原理:钩子脚本从 stdin 接收 JSON payload(含 tool_input),取 plan 内容检查必需章节。缺失时以 Exit 2 返回,stderr 中的提示信息作为反馈交给模型,模型自动修订 plan 后重新调用 exit_plan_mode,钩子重新校验。
路径两个坑:
- 钩子命令的工作目录是会话 cwd,不是
projectDir——projectDir只喂${CLAUDE_PROJECT_DIR}变量替换和同名环境变量,所以脚本路径要用${CLAUDE_PROJECT_DIR}锚定(如上例),裸写相对路径在会话目录 ≠ 项目根时找不到脚本。 configPath: ./hooks.json的相对基准是 dsh 宿主进程的启动目录,多工作区混用时建议写绝对路径。
原生桥的两个边界:PreToolUse 的 deny / ask 生效,但 allow 不预批准、updatedInput 不生效;payload 中 transcript_path 恒为空字符串。钩子超时默认 600 秒,可用条目级 timeout(秒)覆盖。
7.3 方案 A+:社区插件增强
上述 JSON 配置与检查脚本对社区插件 @dennisrongo/dsh-hooks 同样适用(同一 Claude Code 协议)。需要以下增强时改装它:
- 项目层自动发现:
<workspace>/.dsh/hooks.json随仓库提交即生效,无需改 profile 组合; - 双层叠加:用户层(
$DSH_HOME/settings.yaml的dsh-hooks命名空间)与项目层同时生效; failClosed:条目加"failClosed": true后,钩子崩溃/超时按阻断处理(原生桥无此字段);- 支持 8 种事件(另含
SessionStart/SessionEnd/Stop/SubagentStop/Notification)与 skill hints。
安装:dsh plugin add @dennisrongo/dsh-hooks(或 dsh plugin --profile web add ...),装完重启 profile。
7.4 方案 B:CI 门禁
将 spec 完整性检查写成 GitHub Actions job,作为 PR 的必需检查项。核心逻辑:解析 docs/specs/*.md 的 markdown 结构,验证必需章节是否存在且非空。
1 | # .github/workflows/spec-check.yml |
7.5 方案 C:专用插件人工审查
@hilariouhiss/dsh-plan-doc 是社区插件,拦截 exit_plan_mode 并将 markdown plan 渲染在右侧抽屉中,供你预览和编辑。面板底部有”确认实施”和”交由模型修改”两个按钮。点击后者时,修改意见作为反馈交回模型,plan mode 保持激活,模型修订后的新稿自动重新打开面板。
能力边界:/plan-doc 只接收面板的 approve / reject 决策,面板仅在拦截 exit_plan_mode 时出现——它不能对任意文件发起审查。因此 spec 审查的可行约定是:在 AGENTS.md 中约定 docs/specs/ 文件的创建或重大修改必须伴随一次 plan mode 流程,把 spec 内容作为 plan 经 exit_plan_mode 提交评审(面板自然渲染该稿),而不是”写完文件再 /plan-doc 审查”。
7.6 规则清单与 AGENTS.md 的对应
自动检查的规则必须与 AGENTS.md 中定义的模板章节一一对应。建议在 AGENTS.md 中新增”自动检查规则”一节(见 1.5 节模板),明确列出:
exit_plan_mode的 plan 必须包含:目标、验收标准、实施步骤、风险与回滚。docs/specs/*.md必须包含:背景、验收标准、实施步骤、风险与回滚。- 实施步骤中每个 Step 必须声明
指令和验证字段。
把这份规则同时写入 AGENTS.md 和钩子脚本,DSH 在修订 plan 时会主动对照规则补全。
第 8 章:项目工程规范(按需)
本章说明:本章不属于 DSH 功能,是对中型团队有价值的项目管理建议,按需阅读。
8.1 CI 守卫
1 | # ⚠️ 项目自身的 CI 守卫(GitHub Actions 通用写法) |
8.2 其他文件维护
runbooks.md / postmortems/ / CHANGELOG.md / README.md 较简单,按需维护即可。
附录 A:速查表
A.1 全部 slash 命令
| 命令 | 作用 | 关键约束 |
|---|---|---|
/plan / /plan <msg> |
进入计划模式 | 可附文件/图片 |
/plan off |
退出计划模式 | — |
/compact |
手动压缩历史 | idle-only、不接受参数 |
/goal / /goal <obj> |
创建长期目标 | 4 阶段,默认 256 轮 |
/goal edit <obj> |
改目标 | 阶段不变 |
/goal pause |
暂停 + disarm | — |
/goal resume |
恢复 / 重新武装 | 受轮次上限约束 |
/goal clear |
清除当前目标 | 历史保留 |
/permission |
切换权限预设 | 配合 sandbox 模式 |
/feedback <text> |
记录会话反馈 | 必须带文本;不进模型历史 |
/export |
下载会话日志 ZIP | Web-only、不接受参数 |
A.2 主用工具
| 类别 | 工具 | 关键约束 |
|---|---|---|
| 文件 | read / write / edit |
默认编辑工具 |
grep / glob |
搜索 | |
| Shell | bash |
走 sandbox |
| 网络 | web_search / web_fetch |
抓公开 HTTP(S) |
| 任务 | todo_write |
整列表替换,单 owner |
exit_plan_mode |
plan 必 markdown + # 标题 |
|
ask_user_question |
子 agent 不能调 | |
| 协作 | subagent / subagent_fork |
maxDepth=3、run_in_background;fork 继承父会话历史 |
workflow |
JS 脚本,agent/parallel/pipeline/phase/log |
A.3 高级工具
| 工具 | 何时用 | 关键约束 |
|---|---|---|
create_goal / get_goal / update_goal |
跨多轮目标 | CAS 带 revision |
ralph |
用户明确要求”每轮全新 agent” | 报告无独立验证;maxRounds 包级默认 256,Web preset 实为 64 |
send_message / interrupt_agent / list_agents |
continuable 子 agent 通信 | — |
job_output / job_kill / job_list |
后台任务管理 | 配合 run_in_background: true |
skill |
按需加载 skill | — |
present |
标记可交付文件 | — |
A.4 sandbox 模式
| 模式 | 文件效果 | 推荐场景 |
|---|---|---|
read-only(fail-safe 默认) |
拒绝写入,必需 sink 除外 | 探索、纯调研式 plan(不落盘) |
workspace-write |
工作区 + 临时区域可写 | 编码、重构 |
danger-full-access |
无隔离 | 系统运维(慎用) |
A.5 4 种 agent 模式一句话选择指南
| 场景 | 选什么 |
|---|---|
| 日常开发 | 标准模式 |
| 编程化组合工具 | PTC 模式 |
| 训练 / 单文件脚本 | 极简模式 |
| 二次开发 DSH | 创造模式 |
| 跨多日任务中途 | 不要切(preset 随会话锁定,切换 = 开新会话,当前会话的 goal 与上下文带不走) |
收尾
一句话:模式选对(90% 标准模式)+ 文档到位(AGENTS.md + architecture + README + 条件 specs)+ 指令纪律(决策树 + 真实约束)= 80% 的稳定性。
剩下 20%——靠团队踩坑反馈、持续更新文档、复杂任务用 plan mode 走流程。