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 速查表):

  1. 5 分钟最小工作流(第 0 章)——先跑通一个闭环,再回头搭文档
  2. 项目文档怎么搭(第 1 章)——从 DSH 开发视角,区分核心必需 / 推荐 / 条件必需
  3. 4 种 agent 模式 + 运行基础(第 2 章)——模型选择 + 界面里所有 slash 命令 + sandbox 权限
  4. 工作流决策树(第 3 章)——什么时候走哪条路
  5. 场景实操(第 4~6 章)——标准模式 7 个(4.4 起含组合形态)+ 其他模式 3 个 + 高级工具 2 个
  6. plan/spec 自动检查(第 7 章)——原生 hooks 方案 + 社区插件增强 + CI 门禁

假设你是 3~8 人中型项目的主程,用 DSH web 模式,长期使用标准模式

第 0 章:5 分钟最小工作流

目的:在搭文档之前,先亲手跑通一个 DSH 闭环。

如果你是第一次用 DSH,不要从第 1 章的文档结构开始。先做这件事:

  1. 打开 DSH Web(npx @deepseek-ai/dsh web
  2. 确认顶栏模式为标准模式
  3. 在 chat 里粘贴:
1
2
3
4
Bug: src/utils/format.ts 的 formatDate 对 null 输入返回 "NaN"
复现: npx jest tests/format.test.ts
期望: 返回空字符串
实际: 返回 "NaN"
  1. 观察 DSH 执行序列:readbash(复现)→ read(定位)→ edit(修复)→ bash(验证)→ bash(commit)
  2. 全程不调 /plan、不派 subagent。这就是最简单的任务路径。

跑通之后,你就能理解本文后面所有场景的”最小单元”。再回头看第 1 章搭文档,会更有方向感。

第 1 章:项目文档与协作基建

目的:从 DSH 开发视角,明确哪些文档是核心必需、哪些是推荐、哪些是条件必需
核心原则:“必需”不等于”启动时就必须存在”,而是”在 DSH 工作流触发到它时,它必须已经存在”。

1.1 核心必需(2 个)

DSH 官方仓库的 AGENTS.md 中明确写着:

Read docs/architecture.md before changing packages/; follow docs/AGENTS.md for 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.mdarchitecture.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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# DSH 协作守则

## 项目
- 业务: <一句话>
- 关键约束: <性能 / 合规 / 技术栈>

## 启动规则
启动任何任务前:
1. read AGENTS.md
2. read docs/architecture/overview.md
3. read docs/architecture/decisions.md
4. 涉及已有功能 → read 对应 docs/specs/*.md

## 任务规则
- AC / 边界 / 约束不全 → ask_user_question
- 简单 bug → 直接执行(确保 sandbox = workspace-write)
- 重构 / 新功能 / 复杂优化 → /plan → write docs/specs/ → exit_plan_mode
- 跨多轮任务 → /goal <objective>

## 自动检查规则(可选,见第 7 章)
- plan 提交前必须包含:目标、验收标准、实施步骤、风险与回滚
- docs/specs/*.md 必须包含:背景、验收标准、实施步骤、风险与回滚
- 每个实施步骤必须声明「指令」和「验证」字段

## 交付规则
- edit plan "最终结果"段
- edit CHANGELOG.md

## 禁止
- ❌ 重构 commit 夹带 feat
- ❌ 改 src/legacy/
- ❌ 引入新依赖不写理由到 decisions.md

两条铁律

  1. 每条规则必须映射到具体 DSH 指令/命令——否则就是空话
  2. 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# <标题>
- 类型: feature / refactor / perf / bugfix
- 状态: 🟡 草案 / 🟢 批准 / 🚧 执行中 / ✅ 完成

## 背景
<为什么做>

## 目标(可度量)
- ✅ <目标>

## 验收标准
- [ ] AC-1: ...
- [ ] 测试: 全量绿

## 实施步骤(= DSH 指令序列)
- [ ] Step 1: <任务>
- 指令: `bash` 测基线 → `read` 确认
- 验证: 全量绿
- commit: `<type>(scope): ...`
- [ ] Step 2: ...

## 风险与回滚
| 风险 | 缓解 | 回滚指令 |
|---|---|---|
| ... | ... | `git revert <commit>` |

## 进展记录
<!-- DSH 追加 -->

## 最终结果
<!-- 完成后填 -->

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 版本,状态在多次调用之间保持,不随每次调用重置工作目录和变量;改文件只能用 sedcat 等 shell 命令,且 shell 后端仍受宿主 sandbox policy 约束。极简模式无上下文压缩,不适合长任务

PTC 模式 workflow 移除的官方来源:v0.1.2-alpha.4 发布说明中明确记录——“Web PTC Mode 默认不再向模型提供通用 workflow 工具”。

两个常见误区

  1. “切到 PTC 看起来很酷”——PTC 缺 workflow 工具,多数中型项目用不上。
  2. “切到创造模式更强大”——创造模式是为二次开发 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
2
3
4
5
6
     create
─────────────→ active ⇄ paused
edit │ ↑
│ resume

blocked / complete / clear
  • 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-only sandbox
  • 落地编码:审批后切 workspace-write
  • 注意:第 4 章的 plan 场景要在 plan 阶段把 spec 落盘到 docs/specs/read-onlywrite 会被拒——这类任务直接保持 workspace-write(见 4.2 前置权限),read-only 只配纯调研。

简单 bug 的 sandbox 前提:即便不调 /plan,也需确认 sandbox 为 workspace-write,否则 edit 会被拒绝。

第 3 章:工作流决策与纪律

目的:一张决策树 + 一张纪律表,告诉你”什么场景走哪条路”。

3.1 主决策树

嵌套优先级:多个分支同时命中时,按外层 → 内层组装而不是二选一——跨多轮?最外层套 /goal;单个里程碑复杂?内层走 /plan;里程碑内有独立子任务?执行层派 subagent;token 压力大是全程状态,任何分支里都随时 /compact(先落盘)。完整的组合案例见 4.5(跨天项目标准栈)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
任务来了

├─ 简单 bug(< 半天、根因清晰)?
│ └─ 是 → 确认 sandbox = workspace-write
│ → read → bash 复现 → edit → bash 测 → bash commit
│ (不调 /plan、不派 subagent)

├─ 重构 / 新功能 / 复杂优化?
│ └─ 是 → 用户输 /plan
│ → read 上下文 → ask_user_question 澄清
│ → write plan 到 docs/specs/<name>.md
│ → exit_plan_mode 等审批
│ → 批准后: todo_write 拆 3~7 步 → 循环执行

├─ 跨多轮 / 跨天任务?
│ └─ 是 → /goal <objective> 创建目标(标准组合见 4.5)

├─ 长会话 token 压力大?
│ └─ 是 → 用户在 chat 输 /compact(idle-only)

├─ 多个独立子任务可并行?
│ └─ 是 → subagent 工具(maxDepth=3)

├─ 多阶段 / 多角度 / 跨很多文件?
│ └─ 是 → workflow 工具(见 6.1 案例)

└─ 用户明确说"每轮全新 agent"?
└─ 是 → ralph 工具(见 6.2 案例)

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
2
3
4
5
Bug: <一句话>
复现: <可执行命令>
期望: <...>
实际: <...>
日志: <paste>

指令序列

1
2
3
4
5
6
7
8
read 源文件
read 相关测试
bash pytest tests/xxx -k "复现条件" # 复现失败(红灯)
read 定位根因
edit 最小修复
edit 补回归测试
bash pytest 全量 # 绿灯
bash git add + commit -m "fix(scope): ..."

关键纪律

  • 先写失败测试,再改——避免”修了一个 bug 引入另一个”
  • 最小修改——不改无关代码,不”顺手重构”
  • 一次 PR 只修一个 bug

验收:全量测试绿灯 + 回归测试覆盖原 bug。

回滚git revert <commit>

常见坑:sandbox 为 read-onlyedit 被拒——先 /permissionworkspace-write

4.2 开发新功能(plan mode)

适用:新功能 + 需要设计 + 跨多个文件。

对应文件docs/specs/feature-<name>.md

前置权限workspace-write(plan 阶段就要落盘 spec 文件,read-onlywrite 会被 sandbox 拒绝;plan mode 软约束 + exit_plan_mode 人工审批已构成双保险。read-only 仅用于不写文件的纯调研,见 2.4)

用户消息

1
2
/plan 新功能: <一句话>
用户故事: 作为 <角色>,我希望 <动作>,以便 <价值>

指令序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
用户输 /plan → 进入 plan mode

read docs/architecture/overview.md
read 已有 docs/specs/*.md(防重复设计)
read 相关模块 docstring
ask_user_question 澄清 AC / 边界 / 约束(3 个关键问题)
write plan 到 docs/specs/feature-<name>.md
(必 markdown + # 标题,否则 exit_plan_mode 失败)
exit_plan_mode → 提交评审

用户审批 → plan mode 关闭

todo_write 拆 3~7 步
可选: subagent (run_in_background: true) × N 并行写独立模块
循环: edit 改码 → bash 测 → edit plan checkbox → bash commit
edit 填 plan "最终结果" 段
edit CHANGELOG.md

关键约束

  • 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
2
/plan 重构: <bad smell 一句话>
按 AGENTS.md 流程

指令序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
用户输 /plan → 进入 plan mode

read 上下文
ask_user_question 澄清: 重构范围 / 兼容性 / 性能底线
write plan 到 docs/specs/refactor-<title>.md
plan 必含:
- 动机 + 证据
- "行为 100% 不变"承诺 + 测试基线
- 分步方案(每步独立可回滚)
- 风险 + 回滚方式
exit_plan_mode → 提交评审

todo_write 拆 N 步
// 每步: edit → bash pytest 全量 → edit 勾选 plan → bash commit
// 关键:每步独立 commit

edit 填 plan "最终结果" 段

关键约束

  • 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
2
3
/plan 优化: <指标 + 现状>
目标: <具体数值>
约束: <不改 API 协议 / 不引入新依赖>

指令序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
用户输 /plan → 进入 plan mode

read docs/architecture/ + 相关 specs/decisions
ask_user_question 澄清目标 / 约束 / 可接受风险
bash python bench/xxx.py # 跑基线
数字写入 docs/specs/perf-<topic>.md
write plan(含候选方案对比表 + 验证方法)
exit_plan_mode → 提交评审

用户审批

subagent × N 并行试方案(run_in_background: true)
每个子 agent: 独立改一份 → 输出 {diff, benchmark 结果}
主代理: 等子 agent 完成通知(必要时 send_message 追问)→ 选最优

edit 落地(用最优方案)→ bash 测 → bash commit
// 保留回滚开关: feature flag
edit 填 plan "最终结果" 段

关键约束

  • 每个 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
用户: /goal <obj> → 创建 active 目标(持久化到 session log)

// Day 1(有人值守):
用户: /plan 里程碑 1
DSH: ask_user_question 澄清 AC → plan 写入 docs/specs/refactor-order.md
用户: 审批通过(plan mode 关闭)
DSH: todo_write 拆步 → 执行 → 全量绿 → commit
→ edit spec "进展记录" 段: 已完成什么 / 下一步 / 已知的坑 ← 下一轮的恢复点
→ 收工(目标保持 active,会话可关)

// Day 2:
session resume → 目标 active 但默认 disarmed
用户: /goal resume → 重新武装(受 256 轮上限约束)
DSH: read docs/specs/refactor-order.md 的"进展记录"段
用户: /plan 里程碑 2 → 同 Day 1 循环

// 长会话中随时:
用户: /compact(先确认 AC / 进展 / 决策已落盘到 specs 或 decisions.md)

// 阻塞时:
goal 进入 blocked 阶段(带 lower-kebab-case policy code,如 provider-limit / budget-exhausted)

// 完成(注意:/goal 没有 complete 子命令,complete 只能由模型经 update_goal 完成):
DSH: update_goal complete → edit spec "最终结果" 段
用户: /goal clear(历史保留在 session log)

组合纪律(每条都对应一个真实机制约束):

  1. /compact 前先落盘——折叠只保留总结,细节只能靠 session log 重放找回;AC、进展、决策先写进 specs / decisions.md 再压。
  2. 无人值守的轮次不碰 exit_plan_mode——plan 审批走 user-questions 通道、必须等人回答,会成为自动轮次的阻塞点;plan 审批安排在有人值守的里程碑边界,自动轮次内只执行已批准的 plan。
  3. 澄清完再派子代理——子代理不能调 ask_user_question(调用会收到错误,问题只能写进最终结果);AC 澄清在主代理 plan 阶段完成,派出去的子任务必须决策完备。
  4. 每会话一个当前 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
2
3
4
5
6
7
8
9
10
11
12
// 会话上下文变长
用户评估: 接近 token 上限 / 模型表现下降

/compact(无参数)
DSH 检查: idle 且无待处理 compact → 执行
行为:
- 把"较老一段历史"折叠为一条 user 角色总结
- 保留最近历史
- 原事件保留在 session log(重放可还原)
报告: 压缩了多少条目、节省了多少 token

继续工作

与自动压缩的关系: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
2
3
用 PTC 模式:读取 src/api/auth.ts、src/api/user.ts、src/api/order.ts,
分别提取每个文件的 export 函数名和它们调用的外部依赖,
汇总成一个表格。

预期 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
2
3
把 config/env.json 的 apiTimeout 从 30000 改成 60000,
然后运行 node -e "console.log(require('./config/env.json').apiTimeout)"
验证结果。

预期 DSH 行为:bashsed -i 's/"apiTimeout": 30000/"apiTimeout": 60000/' config/env.json 改文件 → bash 执行验证。两步完成,全部通过 shell。

关键约束

  • 持久 shell:状态在多次调用间保持,工作目录和变量不重置
  • 没有 edit/write 工具——一切文件改动都走 shell 命令,模型需自己保证替换的精确性
  • shell 后端仍消费宿主 sandbox policy——写文件受当前 sandbox 模式约束,read-onlysed -i 同样会被拒
  • 无上下文压缩,不适合长任务——长会话会超出模型窗口

验收:验证命令输出 60000

5.3 创造模式:运行时自检与 preset 创作

适用:写自定义 preset / 二次开发 DSH。

工具清单:标准模式 + cordis_* 运行时自检工具集,让模型直接读写自身运行的 Harness 组装。

最小案例:创建一个自定义 preset,继承标准模式但移除 web_searchweb_fetch

用户消息(新建创造 preset 会话后输入):

1
2
3
用创造模式:创建一个名为 "no-web" 的 preset,
继承标准模式的全部工具,但移除 web_search 和 web_fetch。
写到 .agent-presets/no-web/ 目录。

预期 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
2
用 workflow 并行审查 src/a.ts、src/b.ts、src/c.ts 的正确性问题。
每个文件一个 subagent,最后汇总。

预期 DSH 行为:提交 workflow 工具调用,script 中包含:

1
2
3
4
5
6
const reviews = await parallel([
() => agent('Review src/a.ts for correctness'),
() => agent('Review src/b.ts for correctness'),
() => agent('Review src/c.ts for correctness'),
]);
return { reviews };

关键约束

  • 父级轮次等待所有委派结束;取消或异常返回错误,不报部分成功
  • 模型只看到最终结果,永远看不到中间子 agent 消息
  • maxResultChars 默认 50000,更长 JSON 被截断

6.2 ralph:每轮全新 agent 迭代

适用:用户明确要求“每轮全新 agent 迭代”。普通长任务用 /goal,有界委派用 subagent / workflow。

核心机制:固定前台循环——每轮一个全新子 agent 针对同一个不可变目标工作,只传递上一轮的 bounded structured report 和共享工作区状态。

最小案例:一个需要多轮迭代才能稳定的算法优化。

用户消息:

1
2
3
用 ralph 迭代优化 src/algo.ts 的性能,
目标:benchmark 从 120ms 降到 80ms 以下。
最多 10 轮。

预期 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 拒绝步骤或附加上下文

落地步骤

  1. 在 profile 的 cordis 组合中挂载官方桥(在 $DSH_HOME/profiles/web/cordis.patch.yml 追加一行),显式指定配置文件(原生桥无自动发现):
1
2
3
4
- name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: ./hooks.json # 也接受"hooks 键持有配置"的 settings 文件
projectDir: .
  1. 创建 hooks.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"PreToolUse": [
{
"matcher": "exit_plan_mode",
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PROJECT_DIR}/scripts/check-plan-sections.mjs\"",
"timeout": 10
}
]
}
]
}
  1. 编写检查脚本 scripts/check-plan-sections.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 从 stdin 读取 JSON payload
let input = '';
process.stdin.on('data', (chunk) => { input += chunk; });
process.stdin.on('end', () => {
const payload = JSON.parse(input);
const plan = payload.tool_input?.plan || '';
const required = ['## 目标', '## 验收标准', '## 实施步骤', '## 风险与回滚'];
const missing = required.filter((s) => !plan.includes(s));
if (missing.length > 0) {
console.error(`Plan 缺少章节:${missing.join('、')}。请补齐后重新提交。`);
process.exit(2); // Exit 2 = 阻断,stderr 作为反馈交给模型
}
process.exit(0);
});

工作原理:钩子脚本从 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 宿主进程的启动目录,多工作区混用时建议写绝对路径。

原生桥的两个边界PreToolUsedeny / 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.yamldsh-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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# .github/workflows/spec-check.yml
name: Spec Completeness Check
on: [pull_request]
jobs:
check-spec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check spec sections
run: |
shopt -s nullglob # specs 是条件必需(见 1.3);无文件时跳过而非误杀
for f in docs/specs/*.md; do
for section in "## 背景" "## 验收标准" "## 实施步骤" "## 风险与回滚"; do
if ! grep -q "$section" "$f"; then
echo "::error file=$f::$section 缺失"
exit 1
fi
done
done

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
2
3
4
5
# ⚠️ 项目自身的 CI 守卫(GitHub Actions 通用写法)
- 改了 src/api/** 必动 docs/architecture/overview.md specs/
- decisions.md 数量不能减少(防误删)
- AGENTS.md 至少 30
- specs/*.md 改了 必动 src/ 相关文件

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=3run_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 走流程。