ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SDD+Harness:打造可控化 AI 辅助开发体系,让代码不再失控

2026/10/3 11:09:00 拓冰建站 浏览量
SDD+Harness:打造可控化 AI 辅助开发体系,让代码不再失控 “AI 写代码一时爽代码失控火葬场。”这句话是我这两年做 AI 辅助开发落地时最真实的感受。团队里每个人都想让 AI 多干点活可一旦让模型放开手脚它能在不知不觉中把你不想要的东西也写进项目里自作主张的依赖、模棱两可的命名、脱离业务规则的边角逻辑。你会发现真正难的不是让 AI 会写代码而是让 AI 在一个可控的边界里写代码。也正因此最近我一直在琢磨一个组合SDD 规范驱动 Harness 驾驭工程 AI用来搭建一套真正的可控化 AI 辅助开发体系。这套体系解决的是“AI 辅助开发如何从‘玩具’走向‘生产力’”的问题。单纯让 AI 写代码、做代码补全、生成测试用例这些能力大家早就玩顺了但一旦进入真实项目你会发现 AI 经常在给你“埋雷”。而 SDD 的思路是先定义好一个不可妥协的规范契约再让 AI 在规范框架内执行Harness 则负责把 AI 的能力封装成可编排、可复用、可观测的工程组件——它不替代模型而是给模型套上“缰绳”。这套组合特别适合正在做 AI 工程化落地、想把 AI 嵌入到团队交付链路里的开发者和架构师。1. 为什么“可控化”是 AI 辅助开发的生死线1.1 AI 辅助开发的失控焦虑过去这半年我见过太多团队在引入 AI 编程工具之后经历“先兴奋、后崩溃”的过程。第一个星期大家觉得 AI 无所不能什么函数都能帮你写什么测试都能帮你补第二个星期开始发现代码开始出现莫名奇妙的重复逻辑、不存在的 API 调用、以及从某个开源项目里“缝合”过来的历史包袱等到了第三四个星期Code Review 已经无法看下去了因为 AI 生成的代码占到了全量变更的 70%而 Review 的时间反而翻了倍。问题的根源并不在于模型能力不行恰恰相反模型能力越强失控的破坏性就越大。一个没有约束条件的 Agent在拿到“帮我优化一下订单模块”这种模糊指令时它不会说“我不确定你的优化标准”而是会直接动手改掉你以为绝对不会动的核心封装顺带重构了数据库索引。等你发现时几千行 diff 已经躺在分支里了。这种失控感是所有从“AI 写代码 Demo”迈向“AI 辅助开发落地”的团队都会撞上的墙。另一个被很多人忽略的失控点是“不可复现性”。同一条指令昨天跑和今天跑结果可能完全不一样。这在大模型时代是常态但在软件开发这个靠确定性吃饭的领域里是大忌。你没法保证 AI 每一次生成的代码都遵守同样的质量基线除非在 prompt 之外还有一套程序化的校验机制兜底。1.2 SDD 规范驱动不是需求文档而是验收契约SDD全称 Specification-Driven Development中文我们可以叫它“规范驱动开发”。它和传统意义上的“需求文档”有本质区别。需求文档是写给人类看的语气自由、目标宽泛哪怕写得不够精确人也能靠上下文脑补出意图。但 SDD 里的规范Spec是写给“模型 机器”双方看的契约它要求每一个输入、输出、边界条件、性能指标、禁止事项都被明确写死。我举个生活中的例子帮大家理解你要装修房子跟施工队说“我要一个温馨的客厅”施工队可以自由发挥结果大概率是你想骂人。但如果你把图纸画好、材料定好、灯位标高标好、验收标准写清楚施工队只能按照图纸干效果再差也有底线。SDD 就是把“温馨”翻译成“客厅东南角 3 米处设置 2700K 色温洗墙灯、沙发背景墙乳胶漆色号为 XXX、完工后照度不低于 300lx”这样的硬指标。在 AI 辅助开发的语境里SDD 的规范文件通常包括目标描述、输入数据格式、输出产物格式、依赖约束、编码风格约束、异常处理要求、验收测试用例以及“禁止事项”清单。这些内容不是用来“启发”模型的而是用来“锁定”模型行为边界的。我在实际项目中把规范文件放在项目根目录的spec/文件夹里每次让 AI 干活之前必须先把对应的规范文件丢给它再让它写代码——效果立竿见影。1.3 Harness 在体系中的位置调度、插件与技能包有了一纸规范还需要一个能严格遵守规范的“执行者”。大模型本身只是一个会说话的脑子它没法自己打开文件、跑测试、调用内部系统接口。Harness 解决的就是这个问题它是一个工程化的 AI 执行框架负责把模型连接到真实世界的工具链上。用驾驶来类比模型是发动机Harness 是方向盘、仪表盘和传动系统。Harness 不改变发动机的排量但决定了这辆车以什么路线行驶、在什么条件下刹车、怎么把动力传输到轮子上。它能加载插件来扩展模型的能力边界——比如文件读写插件、命令行执行插件、局域网服务调用插件它能定义 skill技能包让模型在特定场景下遵守一套标准作业程序它还能编排工作流把多个步骤串成一条自动化的流水线。这里要澄清一下 Harness 和普通 Agent 的区别。普通的 AI Agent 更像是一个“实习生”你给个目标它自己摸索路径过程不可见、不可控而 Harness 里的工作流更像是一台“自动售货机”每一步动作、每一次工具调用、每一个判断节点都是提前定义好的模型的角色只是在每个节点上执行“自然语言计算”。你可以随时看到它正在做什么、在哪一步停了、为什么停。这个区别在工程落地时极其关键因为它意味着诊断、回滚、审计成为可能。对比项普通 AgentHarness 工作流执行路径模型自主规划预定义流程驱动可控性弱靠 prompt 约束强靠配置约束可观测性难以追踪中间步骤执行日志完整可复用性每次重新推理固化规范模板适配场景探索、研究、原型生产级重复任务2. SDD 规范驱动的核心环节与实战写法2.1 三段式开发闭环写规范、生成、校验回环SDD 不是让你放弃和 AI 对话而是让你把对话收敛到一个闭环里。我在团队里推广的标准流程是三步首先把需求翻译成规范文档然后基于规范生成代码或配置最后用自动化测试和静态检查做校验校验不通过就回到第一步修订规范或让 AI 根据报错信息迭代。这个闭环跑通后AI 生成的内容不再是“一次性运气”而是可持续维护的资产。这个闭环中最容易被人忽视的是第三层“校验回环”。很多团队用完 prompt 拿到代码就算完事这恰恰是失控的开端。AI 生成代码后我们必须用 lint 工具、单元测试、端到端测试去验证规范中的每一条约束是否被满足。更强一点的团队会把规范中的验收指标写成脚本化的断言比如“查询接口 P95 延迟必须低于 200ms”“所有对外 API 必须包含 rate limit 注解”然后把这一类断言接到 CI 里。我这里要强调一个观念转变SDD 里的规范实际上是在把“人给 AI 提要求”这件事从“对话式”升级成“配置式”。对话是临时性的文档和断言是持久性的。同一个 AI 工具今天用可能给你生成 A 风格的代码明天用可能生成 B 风格但只要规范文档和校验脚本还躺在仓库里任何风格都必须过同一道关卡。2.2 规范文档的关键要素有哪些很多同学第一次写规范时容易走两个极端要么写得像一篇作文通篇废话要么只给一句话管不住 AI。我自己打磨过很多版后认为一份能真正约束 AI 的规范至少要有下面这些要素目标与范围这个任务要交付什么明确“不做什么”往往比“做什么”更重要。输入与输出数据从哪来、格式长什么样、产出去哪给出示例片段。约束条件必须遵守的框架版本、命名规范、目录结构、依赖白名单。验收标准可量化的指标比如测试覆盖率、响应时间、日志格式要求。禁止事项明确写出 AI 不许动哪些文件、不许引入哪些库、不许修改哪些配置。示例产物给一个符合要求的样例模型会疯狂模仿样例格式。把禁止事项写清楚是我从血泪里学到的。最开始我写规范只写“应该”怎么做AI 经常自作主张去改无关文件后来我把禁止事项放在规范靠前的位置比如“禁止修改src/main/resources/application.yml”“禁止删除migrations/下任何历史脚本”失控比例明显下降。因为模型对“不要做什么”的遵循其实比对“应该做什么”的遵循更精准。2.3 一份可落地的规范文件示例下面我直接放一份我在内部项目里用过的规范模板大家根据自己的场景改一改就能用# 规范库存报表生成任务Spec 1.0 - 目标根据 /data/inventory/raw.csv 生成日报表 /data/inventory/report.md - 输入格式CSV字段顺序为 sku_id, warehouse_code, quantity, updated_at - 输出格式Markdown 表格表头为 SKU ID、仓库代码、当前库存、更新时间 - 聚合规则同 sku_id 在多个仓库的记录汇总为一行数量求和 - 数据清洗quantity 为空白或非数字的行直接丢弃并在文件末尾追加统计信息 - 性能约束脚本必须在 5 秒内完成处理不得使用外部 API - 质量校验执行 pytest test_inventory_report.py 必须全部通过 - 禁止事项 - 禁止修改 /data/inventory/raw.csv - 禁止引入 pandas 以外的任何数据处理依赖 - 禁止删除输入文件中未在报告中出现的字段 - 示例产物 | SKU ID | 仓库代码 | 当前库存 | 更新时间 | |--------|----------|----------|----------| | A1001 | WH-01 | 231 | 2025-01-15 10:00 |这份规范丢给任何支持文件读写的大模型配合 Harness 的插件它都能严格按要求产出报表。你可能会觉得“写规范比写代码还费劲”但别忘了这份规范是可以复用的。下个月报表需求改成按周汇总你只需要改聚合规则和输出文件名AI 立刻又能在新约束下干活比重新调一次 prompt 稳定得多。2.4 为什么 SDD 能压制 Agent 的“自由发挥”倾向底层逻辑其实很简单大模型在做生成时遵循的是一个“最大化概率”的原则遇到模糊不清的地方它会去补全它认为最合理的细节。如果你不告诉它金额字段必须保留两位小数它可能输出 3 位如果你不告诉它不能碰历史迁移脚本它可能为了“保持风格一致”把旧脚本也顺手改了。这不是模型蠢而是人的指令没给够信息量。SDD 从两个层面解决这个问题。第一层它把隐性知识显性化团队里那些只可意会不可言传的约定比如“幂等接口必须校验 requestId”“错误信息必须包含 traceId”统统写进规范文档模型第一次就能看到。第二层它把自由度压缩到可以校验的区间哪怕模型真的在某处自由发挥校验回环也会立刻把它揪出来而不是等代码合并后由人肉背锅。所以我会说SDD 不只是给 AI 看的文档更是给整个工程团队看的“安全护栏”。3. Harness 安装与工程化配置实操3.1 安装前的环境准备要说 Harness 的安装踩坑我先给还没用过的朋友们提个醒在那之前先把基础环境理清楚能省两个小时。Harness 通常依赖 Node.js 运行时我建议直接使用 Node.js 18 以上的长期支持版本老版本在插件加载时容易出现兼容问题。其次是模型服务的准备。Harness 本身不内置大模型它需要对接一个可调用的模型服务。本地开发时你可以对接 OpenAI 兼容的本地推理服务或者云端 API企业内网环境则建议提前把模型权重部署好通过内网地址暴露成标准接口。跑通之前的判断标准很简单打开内网机器的终端直接 curl 一下模型服务的地址如果能在几秒内得到回复Harness 后续就稳了。还需要注意的是网络与下载渠道。插件市场里的插件需要从离线包或者镜像仓库获取我踩过的坑是在某些有网络隔离要求的环境里直接敲安装命令结果等了半天日志显示卡在下载阶段。正确的做法是提前在有网环境下把安装包和所需插件包下载好拷到内网机器上再执行本地安装。3.2 Windows、Linux 与内网服务器的安装步骤我分别说下常见场景的操作要点。开发机上如果只是体验最简单的是用全局包管理工具安装 Harness 的命令行入口npm install -g harness harness --version这里我给的是通用命令形式不同发行渠道的包名可能带有后缀或组织前缀以你所用版本的官方文档为准。装好后执行版本命令能打印版本号说明安装成功。Windows 用户需要注意如果是在 PowerShell 里执行全局命令遇到权限报错多半是脚本执行策略限制用管理员身份打开终端再执行一次即可。Linux 服务器上安装时我建议加上用户级目录配置避免污染系统环境。设置一个专门的工作目录以后所有的 harness 配置、插件、skill 数据都存在这里mkdir -p ~/harness-workspace cd ~/harness-workspace npm install -g harness export HARNESS_HOME~/harness-workspace真正要落地到内网时麻烦主要在“离线”两个字。我的做法是在有网的一台机器上执行harness plugin download --all把插件离线包和核心二进制打包成一个harness-offline-bundle.tar.gz再拷贝进内网。内网机器上解压后设置离线模式环境变量并指向本地仓库tar -xzf harness-offline-bundle.tar.gz -C ~/harness-workspace export HARNESS_OFFLINE1 export HARNESS_PLUGIN_SOURCElocal设置完成后启动 Harness它会优先从本地仓库加载插件不再试图访问外部网络。这一步做完内网部署的基础就通了。有同学问“装到 D 盘行不行”Windows 下当然可以但要注意一个细节配置目录和插件目录如果带有中文或空格路径某些插件脚本在解析路径时可能出错我建议安装路径一律用纯英文无空格。3.3 插件系统给 AI 接上“手”和“眼”没有插件的 Harness就像一个只有大脑没有四肢的人它能想但做不了。插件系统的价值在于把模型能力与真实工具链打通。最常用的几个插件类型包括文件系统插件读写项目文件、命令执行插件跑 shell 命令、pytest、eslint、HTTP 请求插件调用内部 API、浏览器自动化插件操作页面这也是 RPA 场景的基础。插件管理的命令行通常长这样harness plugin list harness plugin install fs-toolbox harness plugin install command-runner harness plugin uninstall browser-automation我强烈建议不要一股脑装一堆插件。插件越多加载越慢prompt 上下文被插件说明占掉的空间越大模型反而会“选择困难”。我个人的标准是一个任务只装必要的 3 到 5 个插件。比如做代码生成就装文件读写、命令行、代码搜索这 3 个做 RPA 采集就装 HTTP 请求、浏览器自动化、数据清洗这 3 个。剩下的一律按需再装。3.4 Skill 机制把领域知识封装成可复用的技能包如果说插件是给 AI 的工具skill 就是给 AI 的“操作手册 考试大纲”。一个 skill 通常由三部分构成一份说明文档写清楚在什么场景下启用、任务怎么拆解、质量标准是什么、一组参考示例给模型看“规范产出长什么样”、以及一些脚本或模板资源。我自己在工程里维护 skill 的标准目录结构如下skills/ inventory-report/ SKILL.md examples/ report-sample.md scripts/ validate.sh templates/ spec-template.md部署 skill 很简单把它放进 Harness 的skills目录重启后就会自动加载。内网部署和本地部署逻辑一致只要把整个skills文件夹一起拷进内网环境即可。不过这里有个坑有些 skill 会在首次加载时尝试从网络拉取依赖在内网环境会失败。对策是写 skill 时就把运行所需的资源文件放到 skill 自己的目录下脚本里用相对路径引用。Harness 和具体的 Agent 框架还有一个重要差异在 Agent 模式里模型自己决定“我该调用什么工具、按什么顺序调用”而在 skill 模式下skill 文档本身就是一套标准作业程序模型更多是照着执行。所以 skill 写得好不好直接决定执行质量。我写 SKILL.md 时会刻意遵循“场景 — 步骤 — 校验 — 异常处理”四段式把每个环节该调用的插件名也写进去这样模型在流程走到某一步时不会犹豫。4. 完整案例从规范到 Harness 工作流落地4.1 场景选择企业内部库存日报生成理论讲再多不如跑一个完整案例。我选了一个我们内部已稳定运行两个月的场景库存日报生成。业务方每天上午需要一份 Markdown 格式的库存日报表数据来源是仓库系统导出的一份 CSV。这个任务重复、琐碎、格式要求严格非常适合做成 SDD Harness 的标准流水线而且它还带了一点 RPA 的影子——如果数据不是通过导出 CSV而是需要去内部系统页面点击下载那就要用到浏览器自动化插件。这个场景的核心难点有三个一是输入数据经常会多出末行合计、空行和损坏编码二是业务方对报表的格式变化零容忍少一列、多一列都会引起投诉三是执行环境必须稳定不能依赖某个同事每天早上手动跑。这些痛点刚好是 SDD 和 Harness 擅长处理的。4.2 第一步编写 SDD 规范我直接贴出当时定义的规范文件关键部分# 规范每日库存报表生成Spec 2.0 - 数据源/data/inventory/daily_export.csv - 输出路径/data/inventory/report_YYYY-MM-DD.md - 表头要求SKU ID、仓库代码、当前库存、更新时间 - 汇总规则按 SKU ID 仓库代码分组同一组的多行记录取更新时间最新的一行 - 异常处理 - sku_id 为空或缺失 - 丢弃并计入 error_count - quantity 无法解析为数字 - 置为 0 并计入 error_count - 质量门禁 - 报告末尾必须包含 采集时间, 数据行数, 错误行数 - 报告不得出现空表 - 禁止事项 - 禁止修改原始 CSV 数据 - 禁止使用非白名单依赖只允许 csv 标准库和 strftime 类格式化函数这份规范写完后我没有急着让 AI 干活而是先把它交给团队同学做一次“猜提示词演习”如果一个人只有这份规范、没有任何其他上下文能不能准确说出现在要生成一份什么样的报表能说出来说明规范信息足够。说不出来说明规范还有缺口需要补。这个演习是我推荐的验证技巧比直接审查 markdown 文档有效得多。4.3 第二步定义 Harness Skill 与插件封装规范写好后接下来要把它变成 Harness 能执行的技能。我先安装了两个插件文件系统读写插件和命令行执行插件。然后写了一个inventory-reportskillSKILL.md 内容要点如下# SKILL: inventory-report ## 启用场景 当用户请求生成每日库存日报时启用。输入参数为日期格式 YYYY-MM-DD。 ## 执行步骤 1. 调用 file-reader 插件读取 /data/inventory/daily_export.csv 2. 调用 command-runner 插件执行 python scripts/normalizer.py 3. 校验生成报告的完整性 - 检查表头是否符合 spec 2.0 - 检查末尾是否包含统计信息 4. 输出报告路径给用户 ## 参考规范 规范文件位置/spec/inventory_report_spec.md 在生成报告前必须重新读取该规范确保理解最新约束。 ## 异常处理 - 输入文件不存在终止任务并提示“未找到昨日导出文件” - 报告校验失败重新执行步骤 2最多重试一次把这份 SKILL.md 连同normalizer.py脚本和示例输出文件放入skills/inventory-report/重启 Harness这个技能就被自动注册了。之后执行任务时只需要对 Harness 说一句“生成 2025-01-15 的库存日报”它就会严格走上面的流程而不是自己发明一套新做法。4.4 第三步运行工作流并校验结果实际运行时我会用 Harness 提供的命令行模式直接触发任务harness run skill:inventory-report --date 2025-01-15运行日志会显示每一步插件的调用情况。由于输出路径固定我还要加一层保险在 CI 里放一个断言脚本检查生成的 Markdown 文件是否包含规范要求的表头和统计信息。这样即便 Harness 在夜间运行第二天业务方打开报表前门禁已经替我们把过关了。有一次凌晨执行时HVAC 系统出现瞬时故障导致服务器重启任务日志里显示模型在第三步“校验报告完整性”后自动重试了一次最终成功生成报表。这就是可观测性和自动重试机制的价值。如果换成裸调 Agent模型可能会在重启后从此忘掉任务又或者生成一个缺了统计信息的半成品。5. 常见问题与排查技巧实录5.1 failed to load plugins 的三种诱因很多新手一开始就栽在“插件加载失败”这个槛上。我归纳了三种最常见的诱因。第一种是插件目录权限不对Harness 插件需要写入缓存文件夹如果目录权限不足就会加载失败第二种是插件与主程序版本不匹配比如主程序已经升级到新协议而插件还是旧版本第三种是内网环境下插件依赖缺失安装插件时有依赖包没有进入离线包运行时自然加载不了。排查方法是分步骤看日志。先harness plugin list看插件列表里有没有正常标记再手动调用一次插件看报错信息最后检查插件目录里的 manifest 文件确认依赖版本。不要一上来就重装重装往往治标不治本。5.2 web boot: 1 entry did not activate 的错误指向报错信息里带着web boot意味着问题出在 Harness 的桌面端或 Web 界面入口而不是命令行核心。我遇到过几次现象是桌面端启动后白屏或提示入口未激活。绝大多数情况是插件市场入口的静态资源加载失败或者是本地 Web 服务端口被占用。我建议先回退到命令行模式把harness serve --headless启动的服务停掉再启动桌面端。如果还是不行看日志中 web 入口模块在等什么资源把离线包里的 web 静态资源重新解压一遍。曾经有个同事的机器上装了安全软件把 Harness 的 Web 服务拦了导致入口始终激活不了加白名单后就正常了。5.3 Skill 读取文件失败Windows 权限问题 setnamedsecurityinfowWindows 环境下跑 Skill 时如果脚本读取文件报setnamedsecurityinfow failed (win32)这不是 Harness 本身坏了而是操作系统文件 ACL 层返回了失败。常见原因是文件被其他进程占用、文件上设置了拒绝读的 ACE、或者杀毒软件实时扫描拦截了句柄操作。我的处理顺序是先确认文件没有被 Excel 或编辑器等进程独占打开然后用系统管理员权限启动 Harness最后如果问题依旧存在到文件属性的安全标签页里加一条当前用户的完全控制权限。注意改了 ACL 以后需要重启 Harness 会话才能生效。有些自动化执行策略会要求机器在凌晨锁屏状态运行任务Windows 锁屏状态下某些权限相关的 API 会异常这种情况可以把任务注册为系统服务而不是依赖桌面会话。5.4 安装失败与卸载清理的实操建议不少同学反馈“Harness 无法安装”多半是历史版本的残留配置、全局目录权限、或者包管理器缓存冲突。我建议先清理 npm 的全局缓存再确认配置目录存在再重新执行安装。npm cache clean --force rm -rf ~/.harness npm install -g harness这里要特别提醒一点不要为了卸载而手动删除乱七八糟的文件否则下次安装必出问题。标准卸载流程是先用harness plugin list把所有插件禁掉再停掉所有相关进程最后删除配置目录。我见过有人绕过卸载直接删安装目录导致路径配置写死在用户级配置文件里新版本装完还在用旧配置最后各种诡异报错。5.5 内网环境的限制与实践建议内网部署最大的敌人是“下意识觉得离线等于安全”。离线确实能缓解供应链安全问题但也会带来模型版本锁定、skill 更新滞后等运维负担。我建议在内网建立一条“外网镜像同步 — 补丁包导入 — 定期版本验证”的流程至少每两个月同步一次否则模型和插件落后太多SDD 规范的编写也会变得别扭。另外一个细节内网环境里如果有多个团队共用同一个 Harness 集群一定要把 skill 和插件的版本发到集中配置中心管理避免某个人在本地改了一个 skill其他人运行时行为不一致。可控化 AI 辅助开发体系说到底就是让 AI 的每一次输出都能被追踪、被重复、被审计。而内网环境恰恰是最容易暴露这类管理短板的地方值得多花一点心思。我个人在实际操作中的体会是SDD 规范和 Harness 这类工程框架本质上是在帮我们转换心态——不再指望 AI“聪明到能猜对我们想要什么”而是逼我们把需求想清楚、写明白、可度量。这个过程一开始会有点笨拙甚至会让你怀疑“写规范比写代码还慢”但一旦跑通一两个真实场景把规范模板和 skill 沉淀下来后续的效率提升是指数级的。工具会快速迭代今天叫 Harness明天可能有别的框架但“先定义验收标准再让 AI 在约束里创造”这个原则我相信在未来很多年内都会是工程 AI 的底层逻辑。