DeepSeek Harness 开源的不只是代码:它还公开了一套 Vibe Coding 工程流水线
DeepSeek Harness 开源后迅速获得大量关注,一天收获 9 万个 Star,更值得关注的是,梁圣不仅开源了项目代码,还把内部使用的工程 SOP 一并公开,相当于把团队"吃饭的家伙"也分享出来 。
本文所说的 Vibe Coding,并不是让模型无约束地生成代码,而是让 Coding Agent 承担大量实现工作,再通过仓库规则、当前知识、操作协议、决策记录和质量门禁约束交付过程。
DeepSeek Harness 最值得研究的地方,不只是它实现了一个 Agent Runtime,而是它把"让 Coding Agent 写业务系统"这件事做成了一套仓库内的交付系统。
本文以快照 47f9438 作为分析对象。根据该快照历史统计:
- 从 2026-06-10 的首个提交到 2026-08-13 的公开预发布快照,约 64 天;
- 历史可追溯到12,293 个 commit;
- 日均约 189 个commit、每日提交数中位数约为 113 个;
- 核心贡献者约 8 名,其中 tianyicui 一个人提交了 5k 余次;
- 第一方生产源码约 23.9 万行,测试代码约 31.4 万行,开发过程中累计删除了 73w 行内容;
- 标准 GitHub merge commit 中,有 209 个来自明确
codex/分支。
如果不借助 Vibe Coding,沿用传统开发模式,很难在这么短的时间内达到这样的开发规模。即使能够做到,通常也需要投入更大的团队和组织成本。结合仓库公开的 AGENTS.md、Agent Notes、Skills 和质量门禁,可以判断,DeepSeek Harness 内部的 Vibe Coding 工程化设计在其中发挥了重要作用,并形成了一套类似自动化流水线的软件交付能力。本文就来拆解这套流水线是如何构建的。
本文的结论先写在前面:DeepSeek Harness 不是让 Agent 记住工程规范;它把规范拆成不同职责的仓库资产,并让每个资产把 Agent 导向下一步。
导读:先看五类资产在仓库中的位置
我们来看仓库中与 Agent 交付链直接相关的目录。
text
deepseek-harness/
├── AGENTS.md 根规则:全局约束与任务入口
├── packages/
│ ├── AGENTS.md Package 局部规则
│ └── */ Harness 运行时与能力插件
├── docs/
│ ├── AGENTS.md 文档分层与写作规则
│ ├── architecture.md 系统架构地图
│ ├── subsystems/ 子系统参考
│ ├── cookbook/ 操作教程
│ ├── testing.md 测试证据规则
│ └── postmortem/ 事故复盘
├── .agents/
│ ├── notes/ 有生命周期的 Agent 决策记忆
│ │ ├── AGENTS.md Agent Note 目录规则
│ │ ├── README.md 生命周期、分类与文件格式
│ │ ├── proposed/ 待评审的方案
│ │ ├── implemented/ 已落地、持续维护的决策
│ │ │ └── AGENTS.md
│ │ ├── rejected/ 被拒绝但仍值得保留的方案
│ │ └── archived/ 已归档、冻结的历史决策
│ │ └── AGENTS.md
│ └── skills/ 高风险任务执行协议
├── scripts/
│ └── run-gates.ts Gate 调度与质量检查
├── lefthook.yml 本地 Git Hook
├── examples/ 可运行应用组合
└── website/ docs 的网站投影
这不是完整的仓库目录,而是一张只保留 Agent 交付链相关部分的阅读地图。
每个位置回答的问题不同:
AGENTS.md是根规则全局约束和入口docs/说明系统当前怎样工作.agents/notes/通过生命周期管理保存为什么这样决定.agents/skills/规定高风险动作怎样执行scripts/、Hook 和测试则负责证明结果确实成立。
.agents/notes/ 不是一个普通的文档目录,而是一套有状态的决策记忆系统:README.md 定义分类和文件格式,AGENTS.md 规定维护规则,proposed/、implemented/、rejected/ 和 archived/ 分别保存不同状态的决策记录。
从一次任务看,Agent 通常先读取根 AGENTS.md 和目标目录规则,确定全局红线、代码归属与修改位置,再查阅 docs/ 了解系统当前状态;如果任务涉及推送、Review、简化或文档同步等高风险动作,就匹配相应的 .agents/skills/;如果会影响行为、架构或跨模块契约,则新增或更新 .agents/notes/;实现完成后,再通过测试、快照、run-gates.ts、Hook 和 CI 验证变更。
接下来不按目录逐项介绍,而是假设团队要完成一项会改变系统行为的非平凡需求,观察它如何被这套工程资产逐步约束、记录和验证。
一、规则资产:AGENTS.md 如何给任务定坐标
很多团队的 Agent 使用方式是:把需求交给模型,要求它"看看相关代码"。这是一个很弱的入口。模型会优先打开名称最相近的文件,却不知道那个文件是否真正拥有行为;它也不知道当前项目能否接受兼容层、数据格式变更或新增公共接口。
DeepSeek Harness 的根 AGENTS.md 开头先给出两条信息:Harness 基于 vendored Cordis,且"everything is a plugin";修改 packages/ 前必须阅读 docs/architecture.md,文档修改遵从 docs/AGENTS.md。
这段话看起来很短,却不是项目简介,而是任务分发器。它一次完成三个判断。
- 新行为应优先寻找插件和扩展点,而不是直接修改
agent-loop。 packages/不是一个普通源码目录;进入它之前,必须先建立系统装配模型。- 文档不是代码完成后的宣传材料,它也有自己的局部规则和验证入口。
根文件中的 Repository layout 继续把这种路由具体化。
-
core/是 Session、Prompt、Tool、Agent、Loop 的产品主干; -
llm/、shell/、fs/、subagent/等各自拥有能力; -
.agents/保存工作流和决策记录; -
scripts/保存门禁与生成器; -
examples/是可运行组合而不是可复用实现。
对 Agent 来说,这些说明回答的不是"文件在什么位置",而是"谁拥有这项行为"。
1.1 根规则先定义全局不变量
根规则紧接着声明项目仍处于预发布阶段:优先正确的基础结构,而不是兼容旧格式的补丁;可以重命名和重组,但要同步更新引用;旧磁盘格式可以直接拒绝。
这是一条特别 Agent 化的规则。没有明确边界时,模型往往会出于"安全"而加 deprecated alias、双格式解析、默认 fallback 和兼容包装层。单看某个 PR 这似乎稳妥,长期却会把未被使用的历史包袱写进产品。
因此,这一节不是让 Agent 随意做破坏性修改;它是在告诉 Agent 当前的兼容性责任是什么。一个已上线的业务系统应把同一位置换成自己的事实,例如公开 API 的版本策略、数据库迁移要求、审计数据保留和租户隔离规则。兼容性不是模型应当猜测的品味,而是项目必须声明的产品责任。
1.2 目录规则让约束随作用域收缩
根 AGENTS.md 还列出命令、密钥边界、测试策略、类型和文档要求,以及一组项目特有的架构不变量。值得注意的是它的写法:每条规则都很短,却尽量指向更具体的拥有者。
例如,生命周期、并发、子进程和 teardown 的复杂规则不复制在根文件中,而是要求先读 docs/defensive-patterns.md;推送前选择检查的细节不靠作者记忆,而是链接到 dsh-pre-push-checks。这使根文件保持在每个会话都值得加载的体积,而不会变成一本无法维护的手册。
这里可以把它理解为一个简单的协议:
根
AGENTS.md负责说明"你不能违反什么,以及下一步去哪里";它不负责把每种任务的所有细节重新讲一遍。
1.3 进入 packages/ 后,规则变得具体
任务确定要修改 Package(源码目录) 后,Agent 会读取 packages/AGENTS.md。这不是根文件的重复版,而是在全局原则之上补充 Package 边界的高风险约束。
其中有几条特别能说明"分层规则"怎样工作:
- 产品可见插件必须有真实组合测试。手工
ctx.plugin(...)的 unit test 不足以证明 Loader、cordis.yml和实际应用装配正确。 - Service Definition 要服务所有 Consumer;不能让单个 UI、Tool 或 Provider 的需求污染公共 Service。
- 一个异步操作应由一个生命周期控制器或事务拥有;分散的 ready、cancel、dispose 状态若没有独立结算点,应被收拢。
- 对权限、配置和公开操作的限制,必须在真正执行操作的位置实施,不能只在 UI、Schema 或 Prompt 中隐藏入口。
它们分别阻止了几种典型的 Agent 错误:只在局部 mock 中验证、把最近的调用方需求升格为公共抽象、为"看起来完整"而新增状态机、以及把访问控制做成可绕过的展示逻辑。
这里的关键并不是 Cordis 术语本身。真正可迁移的结构是:根规则定义跨仓库不变量;目录规则定义这个子树的所有权、测试入口和失败模式。规则随文件作用域收缩,而不是把整份公司规范塞进每次模型上下文。
二、当前知识资产:Docs 如何成为 Agent 的系统地图
规则只能给出边界,不能替代系统知识。若 Agent 接下来直接实现,它会遇到更隐蔽的风险:接口放在哪里、Session Event 是否已存在、什么是模型可见输入、哪种测试才算真实装配,仍然没有答案。
这就是 docs/ 的位置。
根规则要求改 packages/ 前先读 docs/architecture.md。它不罗列每个类型的细节,而是解释系统如何装配,各个部分如何协作,以及新增能力应该接入哪个扩展点。
换言之,architecture.md 解决的是"在系统地图的哪一处做这项事"。精确类型和单个子系统的语义,则继续下沉到 docs/subsystems/;单包配置和限制回到 Package README;新增 Package、Tool、Adapter 等操作步骤进入 docs/cookbook/。
2.1 docs/AGENTS.md:文档目录树本身就是知识路由
这一层的总规则写在 docs/AGENTS.md。它最重要的设计不是某种 Markdown 格式,而是 one home per fact:一个事实只有一个权威归属,其余地方链接过去。
下表是这套分工在任务执行时的样子。
| Agent 需要回答的问题 | 权威位置 | 不应放在这里的内容 |
|---|---|---|
| 每次会话都要遵守的红线 | 根或子目录 AGENTS.md |
完整教程、历史故事 |
| 组件如何共同装配、扩展点在哪里 | architecture.md |
精确类型、单包细节 |
| 一个子系统的类型、语义、Cordis API | subsystems/ |
跨系统流程叙述 |
| 怎样完成一次已知任务 | cookbook/ |
架构取舍和事故原因 |
| 为什么选择这条路径、放弃了什么 | .agents/notes/ |
已完成的施工计划 |
| 哪些事实可从源码机械导出 | catalog、graph、API 等生成参考 | 手工维护的第二份清单 |
| 什么事故值得被长期记住 | postmortem/ |
正向方案设计 |
这张表解决的是 Agent 上下文的一个根问题:同一事实散落在 README、Wiki、Prompt、代码注释和设计稿中时,模型即使"读过文档"也不知道该信哪一份。Harness 的做法不是提醒 Agent 多同步几份副本,而是尽量取消副本,建立唯一 owner,再让链接和门禁保证路径可达。
2.2 文档也被当作可验证的源码资产
在普通项目里,文档最常见的失败是"代码更新了,表格或示例没更新"。DeepSeek Harness 没有只靠 Review 解决这个问题。
tool-catalog.md从真实 Tool Plugin 读取模型可见的名称、描述和 JSON Schema。config-catalog.md、persistence-catalog.md、module-graph.md等由源码或运行时信息生成。- 子系统页中的
ts type-equiv与ts public-api片段会由verify-type-equiv检查是否仍与源码等价。 website/docs.ts只负责把 canonical Markdown 投影到网站路由和导航;网站生成树不是第二份内容源。
所以,Agent 修改一个公开类型、Tool Schema、配置字段或站点页面时,并非"最好顺便更新文档",而是需要更新该事实的唯一 owner,并让 doc-sync 验证它没有漂移。
这也是本文把 docs/ 放在实现之前的原因:它不是最后的说明书,而是实现的输入和验收对象。
三、决策记忆资产:Agent Note 如何保存长期理由
现在假设任务不只是局部修复,而是改变了行为、架构、跨模块契约、测试策略或工具流程。到这一步,Agent 不应只留下代码差异,而要判断是否需要在 .agents/notes/ 中保存一份能够跨会话复用的决策记录。
notes/README.md 的硬规则是:所有非平凡变更在同一个 PR 中新增或更新至少一个 Agent Note。非平凡不等于"改动行数多",而是指它改变了行为、架构、跨文件/跨包契约、流程、测试策略、磁盘/Wire/配置格式,或是未来维护者可能重新讨论的决定。
3.1 四种生命周期让决策记忆可以演化
Agent Note 的状态直接编码在目录路径中,而不是只写在正文里:
proposed/保存正在评审、尚未完全实现的方案;implemented/保存已经落地的决策,并且必须随着实际代码、路径和配置变化保持更新;rejected/保存已经否决、但其理由仍能阻止未来重复尝试的方案;archived/保存已经完成历史使命、但需要作为历史证据保留的冻结记录。
这四种状态解决的是不同的维护问题:proposed/ 防止未完成的设计被误认为现状,implemented/ 让决策与当前实现保持一致,rejected/ 防止团队重复讨论已经否决的方向,archived/ 则把不再指导当前工作的记录从活跃知识中分离出来。尤其是 archived/,其中的文件是冻结快照,不能再作为当前行为的权威来源。
3.2 Agent Note 不是工作日志,而是可演化的决策记录
它的路径编码了两个维度:
text
.agents/notes/{lifecycle}/{class}/yyyy-mm-dd-topic-title.md
proposed、implemented、rejected 是活跃状态;archived/ 是一棵独立的冻结历史树。feature、architecture、process、testing、bug-fix、simplification 则说明这是哪一类决定。
不同状态对应不同文档语态。提案拥有 Problem / Proposal / Alternatives considered / Acceptance criteria / Risks;已实现记录则改写为 Problem / Decision / Alternatives considered / Consequences。这要求 Agent 在合并时把"将要做什么"变成"现在实际是什么",而不是把施工清单永久留在仓库里。
其中最有价值的约束是 Alternatives considered 必须存在。它不是为了展示作者思考过,而是为了让未来 Agent 能知道:某个看起来很合理的方案曾经被讨论过,并因何失败。没有它,下一次会话很容易重新发明旧方案。
3.3 两个案例:为什么"删除"和"门禁"都要写成决策
仓库中 quality-gates 的核心判断是:Coding Agent 对可执行 Gate 的遵守程度,远高于对纯文字要求的遵守程度。这个决定最终落在 strict TypeScript、coverage、lint、重复检测、hygiene、Hook 和产物 smoke 上。它把"请遵守规范"转换成"违反时命令必须返回非零"。
另一份 remove-sdk-project-toolchain 记录了大规模删除。它没有把问题写成"代码太多",而是先证明四个包、两个命令产品、模板、配置协调和文档没有真实消费者;随后完整移除支持图,同时保留仍有消费者的 Runtime SDK。这个案例表明,simplification 并不是"让模型多删代码",而是一种同样需要消费者证据、替代方案和重新引入条件的架构决策。
Agent Note 因此连接了两件事:它让 Review 能同时检查"为什么这样设计"和"代码是否实现这个设计";也让下一次任务能在当前代码之外找到被压缩过的组织记忆。
四、操作协议资产:Skill 如何固化高风险流程
到目前为止,Agent 已经拥有了规则、当前知识和决策记忆,但它仍可能在执行动作时犯错:如何选择最小测试集、如何处理重写历史的推送、怎样判断一个简化候选没有消费者、怎样归档已经失去价值的决定?这些不是产品事实,也不适合塞进根规则。
.agents/skills/ 的职责正是这一层。每个 SKILL.md 都以类似下面的 frontmatter 开始:
yaml
---
name: dsh-pre-push-checks
description: Use before pushing, force-pushing, marking ready for review,
or claiming checks pass ...
---
这里的 description 是触发条件,不是介绍文案。一个成熟 Skill 通常包含五种信息:何时使用、哪些资料是权威来源、如何解析上下文、遇到条件分支时怎样决策、完成后提供什么验证和报告。它的目的不是替 Agent 思考,而是把最易错的判断条件固定下来。
4.1 dsh-pre-push-checks:把"跑测试"改为"选择会失败的证据"
这个 Skill 的开头就否定了一种常见习惯:不存在一个每次本地都必须执行的全仓库检查集合。它要求先确认 checkout、分支和真实 PR base,再用 change-scope 取得完整变更范围;随后按风险选择最窄、却能因回归而失败的证据:
| 变化的表面 | 应选择的证据 |
|---|---|
| Package 或脚本行为 | owning Vitest 文件或聚焦测试 |
| 文档、Agent Note、目录或文档链接注释 | pnpm run doc-sync |
| 模型、编辑器、CLI、终端可见输出 | 对应 runnable example 的 keyless snapshot |
| exports、bin、worker、构建配置或发布路径 | build、hygiene、built-artifact smoke |
| 真实 Provider 或 Agent 行为 | 有凭据时的目标 E2E |
它还明确禁止为了"让检查变绿"而使用 --passWithNoTests、降低 coverage 阈值,或把 --coverage.include 缩窄到不再覆盖受影响文件。对重写历史,则要求记录远端 OID 并使用 --force-with-lease,禁止裸 --force。
这种写法比"push 前运行全部测试"更适合 Agent 驱动交付:一方面避免每个微小改动都承受完整回归的等待时间;另一方面把"我已经验证"改成可以复查的、与变更表面对应的证据选择。
4.2 其余 Skill 不是附属工具,而是流程中的专职角色
仓库的 Skill 可以理解为一组专门的操作协议,而不是一个巨型自动化 Agent:
dsh-code-review处理静态 Gate 无法判断的所有权、取消、清理、权限位置和真实装配问题。dsh-find-simplifications要求先搜索生产消费者、动态加载、配置、测试、文档和既有 Note,再提出删除候选。这是一个非常实用、值得重点学习的skill。把"删除什么"从直觉判断变成基于消费者证据的工程决策,也与仓库累计删除的73万行内容所体现出的Vibe Coding简化文化相呼应。dsh-archive-agent-notes用未来决策价值,而不是年份或字数,判断一条已实现决定应继续活跃还是冻结。dsh-doc-standards先判断文档的 tree position、细节层级与 Tutorial/Reference 类型,再讨论措辞。dsh-prose-standard与dsh-trim-cot-leakage把会话中的推理、PR 过程和控制流叙述剥离掉,只保留当前契约与耐久理由。dsh-merging-stacked-prs把多层 PR 合并中的远端状态、顺序、Review、CI 和 mergeability 检查写成独立协议。
这里还有一个容易被忽略的设计:CLAUDE.md 链接到 AGENTS.md,Claude Code 的技能目录也复用 .agents/skills;部分 Skill 再用 agents/openai.yaml 表达 Codex 侧元数据。长期资产是仓库规则和工作流,而不是绑定某一个 Agent 产品的私有提示词。
五、执行证据资产:Hooks、Gates 与 CI 如何验证结果
到此为止,我们仍只有文本:AGENTS.md、文档、Note 和 Skill 都可以被 Agent 误读、遗漏或选择性遵守。DeepSeek Harness 的关键动作是再加一层:把可机械判断的承诺变成独立进程可观察、可返回失败的 Gate。
5.1 Hook 负责低延迟反馈,CI 负责系统性证据
lefthook.yml 的责任很克制:pre-commit 处理 staged lint、空白、翻译配对、归档 Note 和 Vendor manifest;pre-push 运行增量 typecheck。它故意不在每次 commit 都跑完整测试、coverage、snapshot、build 和文档同步。
这个边界很重要。Hook 是即时且便宜的反馈工具;Agent 根据当前 diff 选择相关检查;CI 再提供全量 coverage、平台矩阵、构建产物和有密钥 E2E 等系统证据。若把它们混在一起,Agent 要么被慢反馈拖垮,要么会想方设法规避检查。
5.2 run-gates.ts 把质量检查组织成依赖图,而不是一条长 Shell 命令
scripts/run-gates.ts 定义了 ci-static、ci-coverage、ci-snapshot、ci-artifacts、ci-consumers、doc-sync 等聚合模式。每个 Gate 有自己的 id、命令、依赖、环境变量和 allowFailure 属性;调度器校验依赖图,在资源上限内并行运行独立 Gate,并让 Artifact Consumer 等待 Build。
这比 lint && test && build && ... 的差异不只是性能。依赖图会保留每项检查的身份、输出和失败原因;它让 CI 墙钟时间接近最长依赖链,也让 Agent 和 Reviewer 能分辨"哪项证据失败了",而不是面对一段被前面命令截断的 Shell 输出。
5.3 证据必须来自被修改系统,而不是来自 Agent 的自我报告
docs/testing.md 把 Unit、per-file coverage、真实 Loader 组合、built-artifact smoke、keyless snapshot、浏览器 snapshot、真实 API E2E 和 runtime invariant 分成不同层。它们证明的对象不同:覆盖率只证明受测代码被执行,真实组合证明 cordis.yml 和 Loader 能装配,Snapshot 固化模型/用户可见输出,产物 smoke 证明发布后的 lib、bin 或 Worker 仍可运行。
可以把这套思想压缩成一句话:
Verify the world, not the self-report.
Agent 说"文件已创建""配置已生效""订单已退款""UI 已更新"都只是意图描述。真正的证据应重新读取文件系统、数据库、Session Log、子进程、HTTP API、浏览器 DOM 或已构建产物。这个原则对 Web Coding 尤其重要:页面截图、mock 回调和开发服务器控制台,都不能自动等价于真实用户路径的结果。
六、五类资产如何协作成一条交付流水线
看完这套工程设计后,下面这张表总结五类资产在流水线中的职责。它不是新的分类游戏,而是解释为什么这些资产不能互相替代。
| 资产 | 在任务中的作用 | 仓库载体 | 失败时会发生什么 |
|---|---|---|---|
| 规则 | 给出不变量、责任边界和下一跳 | AGENTS.md |
Agent 在错误位置实现,或擅自改变兼容/安全边界 |
| 当前知识 | 回答系统现状、类型、接口和 owner | docs/、README、生成参考 |
Agent 凭局部代码猜系统关系,文档与源码漂移 |
| 操作协议 | 为高风险动作提供触发条件和决策分支 | .agents/skills/ |
测试选择、Review、Git 历史和清理动作退化成个人习惯 |
| 决策记忆 | 保存理由、替代方案和重新讨论的上下文 | .agents/notes/ |
未来 Agent 重复旧争论,删除或重构失去原因 |
| 执行证据 | 从外部证明变更真实成立 | Hook、tests、snapshots、gates、CI | "已完成"只剩开发者或 Agent 的口头声明 |
五种资产并不是一条固定的串行流程,而是在一次任务中按需协作:规则缩小搜索空间;文档提供当前事实;Skill 约束高风险动作;Agent Note 保存长期决策;Gate 则独立验证结果。
七、从需求到验收:业务团队如何实现完整的工程流水线
DeepSeek Harness 公开的 SOP,重点解决的是"需求确定之后,如何让 Agent 可靠地完成交付",而不是完整的产品管理流程。它没有试图替团队回答用户是谁、为什么做这个产品、需求优先级如何排序等问题。
因此,业务团队要把这套经验扩展成完整生命周期,首先需要在五类 Agent 资产之前补上一个上游入口:需求定义资产。它负责说明为谁解决什么问题、范围是什么、做到什么程度算完成;五类 Agent 资产则负责把已经确定的需求转化为可实施、可验证、可合并的变更。
7.1 Issue 或 Product Doc 不是全部,而是需求入口
Issue 和 Product Doc 都可以承载需求,但职责不同。
- Product Doc 描述相对稳定的产品目标、用户角色、核心场景、范围、非目标和用户旅程,适合跨多个需求持续维护。
- Issue 描述一次具体的变更,应该包含问题背景、用户目标、实现范围、非目标、依赖关系和验收条件,适合直接驱动一次 Agent 任务或一个 PR。
可以把两者的关系理解为:Product Doc 说明"产品为什么存在、要解决什么问题",Issue 说明"这一次具体要交付什么"。Issue 可以链接到 Product Doc,但不应把完整产品背景重复复制到每一个 Issue 中。
验收条件也需要分成两层:Issue 或 Product Doc 写清楚"什么结果才算完成",测试、Snapshot、E2E 和 Gate 负责证明"这个结果确实成立"。因此,仅仅在 Issue 中写"用户可以正常使用"还不够,验收条件必须能够对应到某种可观察证据。
7.2 推荐的业务团队目录
在 DeepSeek Harness 的目录结构之上,业务团队可以增加一个产品与需求层,形成下面的最小完整结构:
text
project/
├── AGENTS.md 全局规则与任务入口
├── docs/
│ ├── product/ 产品目标与用户旅程
│ │ ├── goals.md 整体产品目标、范围与非目标
│ │ ├── user-journeys.md 核心用户场景
│ │ └── acceptance.md 跨需求的产品验收原则
│ ├── architecture.md 整体架构地图与模块边界
│ ├── subsystems/ 模块当前事实、接口与限制
│ ├── cookbook/ 已知开发任务的操作方法
│ ├── testing.md 测试分层与证据规则
│ └── postmortem/ 事故与失败经验
├── .agents/
│ ├── notes/
│ │ ├── proposed/ 尚未落地的设计方案
│ │ ├── implemented/ 已落地的技术决策
│ │ ├── rejected/ 被否决但仍有提醒价值的方案
│ │ └── archived/ 已冻结的历史决策
│ └── skills/ 高风险任务执行协议
├── tests/ 可执行验收证据
└── scripts/ Gate、生成器与质量检查
这里的 docs/product/ 是业务团队需要补充的产品层,不代表 DeepSeek Harness 仓库本身已经提供了完整的产品管理目录。Issue 则通常存在于 GitHub、Linear、Jira 等协作系统中,不一定需要复制到仓库;仓库只需要保存能够长期复用的产品事实和技术事实。
7.3 一个需求从提出到验收的文档链
一项需求可以沿着下面的链路推进:
text
Product Doc / Issue
用户目标、问题背景、范围、非目标、验收条件
↓
proposed Agent Note
架构方案、技术路线、替代方案、风险与验证计划
↓
AGENTS.md + docs/architecture.md + 目录规则
全局不变量、模块所有权、实现位置与禁止项
↓
代码 + docs/subsystems/ + Package README
实际实现、模块当前行为、接口与配置事实
↓
implemented Agent Note
最终决策、取舍、后果与重新讨论条件
↓
Tests / Snapshot / E2E / Gate / CI
可执行的验收证据
↓
Review / PR / Merge
人和 Agent 对需求、设计、实现与证据的共同确认
这条链中,每一层都应该有自己的唯一职责:需求文档不承担详细技术设计,架构文档不承担一次 PR 的施工计划,Agent Note 不承担用户手册,测试也不承担完整的产品背景。
7.4 整体设计和模块设计分别放在哪里
整体架构设计应该放在 docs/architecture.md,它回答系统由哪些部分组成、模块如何协作、新能力应该接入哪里,以及哪些边界不能被破坏。
模块的当前设计和技术事实应该放在 docs/subsystems/<module>.md 或对应 Package README 中,包括模块职责、接口、输入输出、生命周期、配置、依赖关系、用户可见行为和已知限制。
某个需求尚未实施时,架构方案、技术路线、替代方案和风险应该放入 .agents/notes/proposed/architecture/;需求实施后,将实际落地的决策整理到 .agents/notes/implemented/architecture/。Agent Note 记录的是"为什么选择这条路,以及放弃了什么",而不是把整个模块文档再复制一遍。
7.5 从提出到合并的生命周期
一个完整的需求生命周期可以分成六个阶段:
- 定义需求:在 Product Doc 或 Issue 中明确用户目标、问题、范围、非目标和验收条件。
- 确定设计:读取规则和当前架构文档;如果存在非平凡设计,创建 proposed Agent Note,记录方案、替代方案和风险。
- 执行实现:Agent 按目录规则和相关 Skill 修改代码,同时更新受影响的模块文档和生成参考。
- 记录决策:需求落地后,把 proposed Note 改写为 implemented Note,记录实际决策、后果和验证结果。
- 验证验收:根据需求表面的风险选择 focused test、Snapshot、E2E、build、doc-sync 或其他 Gate;验收证据必须来自被修改的系统。
- Review 与合并:Review 同时检查需求是否满足、设计是否兑现、文档是否同步、证据是否充分,最后再合并 PR。
这个模型的重点不是要求每个小改动都创建完整文档,而是让文档和证据的粒度与变更风险匹配:纯机械修改可以直接验证;改变用户行为、架构、数据格式或流程的需求,则必须留下可供未来复用的决策记录。
7.6 业务团队的最小落地顺序
团队不需要一开始就复制 DeepSeek Harness 的全部目录和 Skill。更稳妥的落地顺序是:
- 先建立根
AGENTS.md、docs/architecture.md和一套 Issue 验收条件模板。 - 再为最重要的领域补充
docs/subsystems/,让 Agent 能找到模块 owner 和当前事实。 - 为关键用户旅程建立最小的测试或 E2E Gate,把"完成"转化为可失败的检查。
- 当团队反复遇到同一种高风险任务时,再把处理过程沉淀为 Skill。
- 当某项设计会被未来重新讨论时,再创建 Agent Note,并在实现后转为 implemented 状态。
DeepSeek Harness 真正值得学习的,不是某个 Prompt 或某个 Agent 工具,而是它如何把工程经验写成规则,把高风险操作固化为协议,再把关键承诺转化为能够自动失败的质量门禁。补上 Product Doc 和 Issue 这一层之后,这套方法就从"需求确定后的 Agent 交付系统"扩展成了从用户目标、设计决策到最终验收的完整工程模型。