AI补全到工程化交付:SDD+Harness构建可控AI开发流水线
从AI 自动补全到AI 工程化交付中间隔着一条巨大的管理鸿沟。过去半年我一直在折腾 SDDSpecification-Driven Development规范驱动开发 Harness 这套组合目的只有一个把失控的、碎片化的 AI 辅助编码变成一条可规划、可执行、可验收、可回退的工程流水线。这篇文章不是科普AI 有多强而是分享我怎么搭一套可控化 AI 辅助开发体系以及这条路上踩过的坑、绕过的弯。先说结论Harness 和普通 IDE 里的 AI 插件有本质区别——它不是帮你生成更多代码而是约束 AI 在给定范围内正确地产出。SDD 则负责把模糊的人类需求翻译成机器可执行的规格链。两者加起来才勉强算得上驾驭工程 AI而不是被 AI 牵着走。1. 从AI 辅助到AI 工程的那道坎我为什么转向 SDD Harness1.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 编程改坏了只能整文件 revertAI 自己也不会记得更早的版本。有了轨迹之后我可以定位到某一次错误的生成动作精准回退那一步的 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 把本地验证接入 HarnessAI 生成的代码能否并入主干不能看它说能跑得看验证脚本的真实输出。我习惯在 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 代码不可控而头疼强烈建议从这个组合入手试试别指望靠换一个更强的模型解决问题——模型的智商不是瓶颈流程是否可控才是。