从"AI 自动补全"到"AI 工程化交付",中间隔着一条巨大的管理鸿沟。过去半年我一直在折腾 SDD(Specification-Driven Development,规范驱动开发)+ Harness 这套组合,目的只有一个:把失控的、碎片化的 AI 辅助编码,变成一条可规划、可执行、可验收、可回退的工程流水线。这篇文章不是科普"AI 有多强",而是分享我怎么搭一套可控化 AI 辅助开发体系,以及这条路上踩过的坑、绕过的弯。
先说结论:Harness 和普通 IDE 里的 AI 插件有本质区别——它不是帮你生成更多代码,而是约束 AI 在给定范围内正确地产出。SDD 则负责把"模糊的人类需求"翻译成"机器可执行的规格链"。两者加起来,才勉强算得上"驾驭工程 AI",而不是被 AI 牵着走。
1. 从"AI 辅助"到"AI 工程"的那道坎:我为什么转向 SDD + Harness
1.1 失控的典型症状
如果你已经用 AI 编程超过三个月,大概率遇到过这几个场景:
- AI 生成了一段能跑的代码,但和需求文档里写的业务逻辑完全不是一回事;
- 上下文一长,AI 开始"遗忘"你半小时前定下的约束,自作主张引入新的依赖;
- 代码能编译、单测能过,但代码风格、目录结构、接口命名和团队规范背道而驰;
- 更头疼的是,AI 在某个文件里"灵机一动"改了无关函数,而你压根没注意到这次改动。
这些症状的根因不是模型不够聪明,而是我们压根没给 AI 一个可被校验的边界。普通聊天的上下文窗口太脆弱,一次刷新、一次会话切换就丢光了状态。而 Harness 式的工作流,核心思路是把 AI 的生成过程变成有状态、可追踪、可回滚的工程动作。
1.2 提示词工程救不了长期项目
很多人第一反应是"我把提示词写好不就完了"。早期的我也这么干,后来发现提示词工程在一次性生成任务里很有效,但放到一个迭代周期长、多文件耦合、需要持续演进的项目里,它会迅速失效。
原因很直白:提示词本质是一次性的输入指令,它不携带项目级的历史决策记录,也无法感知工作区里其他文件的真实状态。AI 补全代码时,它看的是你的提示词和它自己训练出来的"常识",而不是你项目里此时此刻的真实约束。要让 AI 在长期项目里可控,必须把约束外置——外置到规格文件里、外置到工作区的状态文件里、外置到可执行的验证脚本里。这正是 SDD + Harness 组合存在的意义。
1.3 什么是 SDD 和 Harness 的正确分工
我个人的理解是:
- SDD 解决"做什么"的问题:把需求拆成有优先级的、可验收的规格条目;
- Harness 解决"怎么做"和"怎么管"的问题:负责调度模型、维护执行状态、提供回退机制、串起验证步骤。
打个生活化比方——SDD 是建筑施工图,Harness 是工程监理。图纸定义了墙要多厚、窗户开在哪,监理负责确保施工队按图纸干活,干错了能砸掉重来。没有图纸,监理再严格也不知道该管什么;没有监理,图纸画得再细也可能被施工队"自由发挥"。
2. 把"让 AI 写代码"变成"按规格造轮子":SDD 规范化拆解的核心做法
2.1 三级规格拆解:需求规格、任务规格、验收规格
我一上来就把整个项目拆成三级规格,分别放在独立目录里维护。这套结构是为了让 AI 在任意一个执行节点都能"只看眼前"而不迷失全局。
第一级是需求规格(RQ-SPEC),对应产品侧的原始诉求。它不需要写技术实现,只描述业务规则、用户场景、边界条件。比如"用户可以用邮箱和密码登录,连续错误 5 次锁定账号 30 分钟",这是原始需求。
第二级是任务规格(TK-SPEC),由我(或架构师角色)把需求翻译成可执行任务。任务规格必须包含:涉及的模块、需要的接口签名、依赖项、硬性约束、允许改动的文件列表、禁止触碰的文件列表。
第三级是验收规格(AC-SPEC),每条任务对应一组可执行的验证条件。比如"调用 /api/auth/login 时,参数缺失必须返回 422 + 错误码字段",这不仅仅是描述,后面会变成自动化测试。
2.2 从需求到任务规格的具体写法示例
拿登录模块举例。在任务规格里我会明确写:
任务编号: TK-102 关联需求: RQ-004 目标: 实现邮箱密码登录接口 改动范围: - src/modules/auth/ - src/utils/password.py 禁止改动: - src/database/migrations/ - config/production.yaml 接口约束: POST /api/auth/login 参数: { "email": string, "password": string } 成功响应: { "token": string, "expires_in": 3600 } 失败响应: { "error": "invalid_credentials" } 边界条件: - 邮箱不存在时返回 401,与密码错误时不区分提示 - 用户被锁定时返回 423 + "account_locked"这样一份任务规格,AI 在执行时就不需要"猜"业务意图了。它只需要像是照着填空题一样把行为补齐。就算它补得不够完美,我能基于规格逐条验收,而不是像以前那样靠肉眼 review 两三百行生成的代码。
2.3 规格评审环节不可跳过
有一个很容易被忽略的动作:给 AI 执行之前,规格本身必须先过一遍"评审"。我通常直接用一个小模型或者让另一个 AI 扮演评审角色,检查任务规格是否有歧义、是否覆盖边界条件、改动范围是否收窄。
这个环节极其重要。实测下来,一个存在二义性的规格会让 AI 产生大量无意义发挥。比如你写"完善登录逻辑",AI 可能去改密码重置流程;但如果你写"仅修改 TK-102 改动范围内文件的登录接口行为",它就安分得多。规格评审不花多少时间,但能省掉后面大量的返工成本。
3. Harness 具体怎么驾驭模型:工作区、上下文与执行回退的约束机制
3.1 Harness 不是 IDE 插件,而是运行环境
刚开始我看到 "DeepSeek Harness" 这类词时,以为它是一个普通插件。实际用过之后,我倾向于把它理解为一套"AI 执行沙箱 + 状态控制器"。它会为每次任务建立一个隔离的工作区,把规格文件、相关代码、既有测试全部挂载进去,然后才让 AI 开始生成代码。
这样一来,AI 看到的不是整个项目的庞杂文件树,而是本次任务真正需要感知的最小集合。上下文切片这个设计特别关键——它比"把所有代码塞进对话"更可控,也大幅降低了 AI 产生跨文件误操作的概率。
3.2 "Harness 和 Agent 的区别"到底在哪
搜索热度里不少人纠结 Harness 和 Agent 的区别。我用自己的话概括:
- Agent 是"AI 自主行动的能力单元",它有多步规划、能自己决定下一步做什么;
- Harness 是"约束 Agent 行为的运行框架",它规定 Agent 每一步能做什么、不能做什么、做完必须产出什么。
如果说 Agent 是"手脚",Harness 就是"缰绳和导航仪"。单独用 Agent,你看到的是它很能干,但不可预期;配上 Harness,你看到的是它能干且基本不跑偏。实际工程里,我不会让 AI 以纯 Agent 模式自由发挥,而是让它在这个 harness 定义的状态机里一格一格推进。
3.3 执行轨迹与回退机制的设计
在 Harness 工作流里,每次代码生成都会记录执行轨迹(trace)。这个轨迹包含:AI 读了哪些文件、改了哪些文件、生成时依据了哪条规格条目、执行了哪些验证命令。
这个设计给我的实际价值是"代码回退"不再是一刀切。以前用普通 AI 编程,改坏了只能整文件 revert,AI 自己也不会记得更早的版本。有了轨迹之后,我可以定位到某一次错误的生成动作,精准回退那一步的 diff,而不是丢掉整块的改动。这跟我手动用 git 配合有很大区别——git 告诉我改了什么,Harness 告诉我"为什么这么改、按什么理由改"。
4. 一条可落地的 SDD + Harness 开发流水线:从任务拆解到验收回退
4.1 理想流水线的六个环节
综合我自己的实践,一套标准流程大致是:
- 需求入库:产品侧的需求先落到 RQ-SPEC;
- 规格拆解:架构师/资深开发者把 RQ-SPEC 拆成 TK-SPEC;
- 任务派遣:Harness 按 TK-SPEC 调动模型,在工作区执行生成;
- 自动验收:执行 AC-SPEC 对应的单元测试、接口测试、lint 检查;
- 差异评审:人类审查关键 diff,结合 trace 判断是否放行;
- 合并回退:通过则合入主干,不通过则基于 trace 回退到最近可用状态。
不要小看"差异评审"这一环。它必须由人来做,而且只 review diff 和 trace,不用像以前那样通读全部生成代码。这既避免了人力过载,又保留了人的判断权。
4.2 把本地验证接入 Harness
AI 生成的代码能否并入主干,不能看"它说能跑",得看验证脚本的真实输出。我习惯在 Harness 的配置里把验证命令编排好:
# 在 Harness 工作区内执行验证 python -m pytest src/modules/auth/tests/ -q python -m mypy src/modules/auth/ python -m ruff check src/modules/auth/这些命令执行失败时,Harness 会把失败信息反馈给 AI,让 AI 继续修复,或者标记为"过度生成"并触发回退。实测下来,这个反馈闭环是保证质量最有效的一步,本质上就是给 AI 装了一个"验收仪表盘"。
4.3 内网部署与团队协作的注意点
如果你和我一样,有把整套体系部署在内网服务器的需求,那要注意几个点:
- 大模型权重要做防护。本地部署时,模型是通过内网 API 暴露的,harness 侧只要配置 base_url 指向内网地址即可;
- 工作区目录建议放在共享存储上,方便多人复用规格和执行轨迹;
- 权限上要区分"谁能提交规格、谁能修改 harness 配置、谁能放行合并",否则团队里人人都能改动约束,流水线就崩了。
4.4 用 Harness 串起 RPA 落地场景
顺带提一句,现在热词里也有"harness + rpa 落地实现"。我理解这个方向是把同样的规格驱动逻辑应用到 RPA 流程编排上——RPA 机器人执行的每一步也用规格文档约束,用 harness 去管理流程版本和触发条件。这样同事改 RPA 流程时,不用再靠 Excel 表格来回传,而是直接改一条规格记录,由 harness 负责更新与回退。思路和代码工程完全一致,只是执行体从"模型生成代码"换成了"机器人执行操作步骤"。
5. 多模型协作与本地化部署的现实取舍
5.1 不同任务用不同模型的策略
同一套 Harness 体系下,我不建议所有任务都用同一个最强模型。模型选择应该跟着任务难度走:
- 简单函数生成、正则、测试脚手架,用一个快速的小模型就够,成本低、延迟低;
- 跨模块重构、接口设计、复杂边界推导,用更强的模型;
- 规格评审、需求歧义检查,反而适合用一个"挑剔"的模型,专门挑刺。
这个思路对应了实践中常见的"多 AI 协作"场景。不是让多个 AI 同时写代码——那只会产出灾难——而是让它们各司其职,各自负责一个可验证的环节。
5.2 DeepSeek 系列模型在 Harness 中的适配
在我实际用的模型谱系里,DeepSeek 系列是性价比非常高的选择。比如用 deepseek 模型做 RQ-SPEC 拆分时,它可以给出比较全面的边界条件清单;而做代码执行任务时,只要给定清晰的约束和格式要求,它的产出质量也相当稳定。
如果你也想试,安装和接入流程并不复杂:把模型的 API 地址配置到 harness 的模型路由里,然后针对不同任务配置不同的 model 字段。这里有一个关键提醒——模型切换时,格式约束必须保持一致。比如要求输出 JSON 就都要求 JSON,否则 harness 的后续解析器很容易断掉。
5.3 提示词优化插件的实际作用
热搜里一直有"deepseek harness 提示词优化插件"这个词。我试过这类插件之后的理解是:它的工作是在把任务规格传给模型之前,先对指令做一次结构强化——比如把人工写的含糊描述改写成更严密的指令链。
真实的使用反馈:它对一次性任务是锦上添花,对长链路任务帮助不小。因为在长链路里,模型每执行一步,提示词的微小歧义都会被放大。建议你把提示词优化插件当作"输入端的保险丝",而不是替代规格拆分。规格拆分是设计问题,提示词优化只是表达问题,两者不在一个层面上。
6. 这半年踩过的坑:Harness 不是银弹,边界比能力更重要
6.1 上下文过载:让 AI 一口气处理整个模块
第一次实战时,我把一个大模块的所有规格、所有历史 trace 全部挂进一次任务,结果 AI 直接在中间崩了,输出了前后矛盾的结构。后来我学乖了:每次任务只挂载当前 TK-SPEC 所需的最少上下文。Harness 的切片机制本来就是干这个的,别自己贪心把它绕过去。
建议的做法是:如果一个需求涉及超过 5 个文件,就主动拆成两到三个任务,让 AI 分步执行,每步只动一小片。拆得越小,回退粒度越精确,找错越容易。
6.2 规格写得"太像需求描述",等于没写
我犯过的最典型的错误,是把 TK-SPEC 写成了产品需求说明书。比如"优化登录体验"这种描述放进任务规格,AI 当然自由发挥。正确的做法是规格里只保留可验证项和硬性边界,不给 AI 留解释空间。
有个自检方法很好用:拿任务规格去问一个初次接触项目的人,他是否能不看项目代码就说出"代码必须做什么、绝对不能做什么"。如果答案模棱两可,说明规格没写到位。
6.3 回退粒度与"AI 盲信"
Harness 提供了回退能力,但如果你只回退到上一版 git commit,很多无关改动仍然会被混进主干。我现在的习惯是要求 Harness 把每次 AI 生成产出一个独立 patch 文件,回退时只撤销那个 patch 涉及的 diff,不动其他任何文件。这样多个任务并发时,互不污染。
还有一点必须强调:别盲信 AI 的"自述"。AI 会告诉你"测试都过了",但我亲眼见过它虚构测试结果。因此 Harness 工作流里所有的验证结果必须来自真实命令输出,而不是来自模型描述。验证环节绝对不能省,这个底线守不住,后面的可控都是纸糊的。
6.4 人机协作的节奏:Harness 管效率,人管判断
用了一段时间之后,我最大的体会是:Harness 不是让人闲着,而是把人的精力从"盯过程"转移到"抓关键"。以前我是全程盯着 AI 输出,生怕它跑偏;现在我只关心三个时间点:规格评审时、关键 diff 审查时、验收失败时。
这种节奏下,我一个人可以同时推进三到四个模块的开发,质量反而比以前更高。原因很简单:失控的自由发挥被约束了,AI 生成代码的可预期性大幅提升。
最后再分享一个让我很受用的经验:SDD + Harness 这套体系,一开始落地时会觉得"写规格比写代码还麻烦",但坚持一两个迭代之后,你会发现自己团队的返工率明显下降,因为错误在更早的环节就被拦截了。如果你也因为 AI 代码不可控而头疼,强烈建议从这个组合入手试试,别指望靠"换一个更强的模型"解决问题——模型的智商不是瓶颈,流程是否可控才是。