
1. 为什么 AI 编码越顺手项目反而越不可控先说一个我自己踩过的真实场景。前年我带着团队全面接入 AI 辅助开发人人都说写得快结果一个迭代下来代码里出现了三种风格的错误处理方式、两套互相冲突的接口命名还有一个 AI 自己发明的理论上应该存在但实际没人实现的工具函数。代码评审从看逻辑对不对变成了找 AI 到底偷偷改了什么。那一刻我意识到AI 编码真正的问题不是能力不足而是不可控。这个痛点不是个例。很多人觉得只要提示词写得够细AI 就能按规矩办事但实际用下来会发现提示词的作用范围非常有限。你写了一段长长的 PromptAI 确实在开始那几百行里遵守了但上下文窗口被撑大之后它为了完成某个局部任务会把前面的约束忘得一干二净。这不是模型笨而是当前对话式助手的工作方式决定了它天生缺少稳定执行规范的机制。所以我想做的事不是再换一个更聪明的模型而是搭一套可控化的 AI 辅助开发体系用规范驱动SDD把约束前置用 Harness 这类工程化工具把模型驾驭起来。这套体系我们内部跑了三个多月核心结论其实是下面这句话——别指望 AI 自觉要给它一个没法不自觉的环境。这篇文章我会把整套思路拆开讲SDD 规范驱动到底在驱动什么Harness 和普通 Agent 有什么区别怎么从安装、写 Skill、配插件到内网部署一步步落地以及我实际踩过的一些坑。适合正在用 Claude Code、DeepSeek、CodeBuddy 等工具写代码但觉得越用越心虚的开发者也适合想把 AI 编码纳入团队流程的技术负责人。1.1 我遇到的三个失控现场第一个现场是改一处伤一片。需求迭代时 AI 为了满足新的返回值格式直接把公共库里已经被三个模块引用的函数签名给改了编译能过但运行时全部传错参数。第二个现场是自造接口。AI 在生成新功能时引用了一个并不存在的getUserStatusV2()方法理由是这个项目里应该有类似方法。第三个现场最隐蔽——规范漂移。团队明明约定错误码统一用{ code: number, message: string }但 AI 在一段长对话的后期开始返回{ errCode: E001 }因为某次历史代码里出现过这种写法。这些场景的共同点是什么不是 AI 不够强而是我们给了它足够的自由度。对话式助手默认把完成任务当作最高优先级在你没有明确设置边界的时候它倾向于创造性地完成任务而这个创造性对软件工程来说往往是灾难。1.2 提示词工程为什么解决不了系统性问题市面上大量教程在讲提示词工程什么角色设定、思维链、Few-shot 示例确实能提升单次生成质量。可一旦代码量上去了项目结构复杂了你就会发现提示词工程处理不了三个问题。第一上下文会被稀释。一个 50 万行代码的仓库AI 能看到的只是被塞进窗口的那几万个 token它没有项目全景图。第二规范无法自动执行。你可以在 Prompt 里写请遵循目录结构的规范但 AI 不会每次开工前主动去读规范文件。第三没有强制校验环。AI 输出完代码后没有任何机制去检查它是否违反了规则错误被默默合并进了主分支。要解决这三个问题就必须把规范从提示词里抽出来变成独立存在的、可被 AI 加载和执行的资产。这就是 SDD 规范驱动在 AI 时代的真正含义。2. SDD 规范驱动先给 AI 画好施工图再让它动工SDD 全称 Specification-Driven Development规范驱动开发。它不是什么新概念传统的软件工程里就有规格说明、接口契约这些说法。但在 AI 辅助开发的语境下SDD 的含义变得非常具体在让 AI 动手写代码之前先把需求规格、接口契约、编码规范、验收标准全部定义清楚并且让 AI 在生成代码时必须围绕这些定义展开而不是让它自由发挥。你可以把它理解成给 AI 一份施工图。施工图上标好了哪里是承重墙、哪里是门窗、用几号钢筋AI 是施工队按图施工就行。没有施工图的施工队干出来的活儿能不能住人全看运气。2.1 SDD 和 TDD、BDD 的区别在哪里很多人会把 SDD 和测试驱动开发TDD、行为驱动开发BDD搞混。简单区分一下。TDD 的核心是先写测试再写实现它用测试用例来约束代码行为。问题是测试告诉 AI 的是结果要长什么样但没告诉它过程中不许干什么。BDD 的核心是用自然语言描述业务行为再由行为描述生成测试和实现它更像需求文档的延伸。SDD 的层次更高。它约束的是整个开发合约接口签名、数据模型、目录结构、命名风格、错误处理约定、性能边界、安全要求。测试用例只是规范集里的一个小部分。在 AI 编码场景下SDD 最大的好处是它把产品希望你做什么和工程上允许你怎么做分成两个层次而后者正是 AI 最容易失控的地方。2.2 一套可落地的规范集长什么样结合我们团队的实际做法目前沉淀了一套分层的规范资产放在仓库根目录的specs/文件夹下规范类型文件示例作用对象接口契约api-contract.md所有对外 API 的请求/响应结构、错误码约定数据模型>- 若函数超过 80 行必须拆分 - 拆分后每个函数只做一件事 - 禁止定义超过 3 层的嵌套回调。这些规则不是给人看的是给 AI 的硬约束。人看这种规则会觉得啰嗦但 AI 每次读完这些规则后生成的代码风格一致性明显提升。把规范写得像机器的命令行参数一样明确这是 SDD 在 AI 时代落地的基本功。2.3 规范怎么真正喂给 AI三种注入方式规范文件放在仓库里只是第一步怎么让 AI 在每次编码时都带上这些规则才是关键。我用过三种方式效果不同。第一种是会话前缀注入。每次启动编码会话时用一段固定开头把关键规范文件内容粘贴给 AI。这种方式最简单但会占用大量上下文 token而且聊天到中后期容易被稀释。第二种是Skill 加载。把规范包装成一个 SkillAI 在开始任务前主动调用 Skill 来加载规范。它比会话前缀注入好的地方在于按需加载但需要 AI 有主动调用 Skill 的自觉性。第三种是Harness 层面的强制注入。在使用 Harness 这类工具时可以在配置里声明当前工作区的强制规则文件列表。Harness 会在每次请求构造上下文时自动把规则文件的内容放到系统消息的最前面并且固定在那个位置——AI 就算在长对话后期也会不断看到这些规则。这也是我后来选型 Harness 的核心理由之一。3. Harness 与 Agent 的区别一套骨架怎样驾驭任意模型关于 Harness社区里一个最常见的问题是Harness 是不是又一个 Agent它和 Claude Code、DeepSeek 的 CLI 工具有什么关系我的理解是这样Agent 是可以自主行动的人工智能体它的特点是能拆解任务、调用工具、循环执行而 Harness 是承载和控制 AI 的外围工程骨架。如果你把 AI 模型比作发动机那 Agent 是装了发动机的整车Harness 则是生产主线上的智能机械臂——它负责把发动机装进不同的车身、校准参数、监控状态并且保证不出安全事故。3.1 马具、缰绳和驾驭的本意Harness这个词本身就有马具、缆索的意思也有驾驭、利用的含义。我特别喜欢这个隐喻。一匹好马大模型跑得快但如果没有马具和缰绳骑马的人没法控制方向不敢让它放开跑。Harness 就是那套马具它不替代马的力量而是让你能安全地驾驭这股力量。所以 Harness 和 Agent 的根本区别在于控制逻辑的位置。Agent 把控制逻辑放在模型内部模型自己规划、自己决策是否调用工具而 Harness 把控制逻辑放在模型外部由一套工程代码来约束模型的行为边界、输入输出格式、可用工具集合。外部控制的优势是可审计、可回滚、可配置。你能看到每一次 AI 调用发生了什么、改了哪些文件、消耗了多少 token而这些 Agent 自己往往不会给你交代。3.2 Harness 的核心能力清单我实际用下来觉得一套合格的 Harness 类工具至少要有下面这几块能力缺了就会回到混乱状态。一是规则注入链。能在每次请求时稳定地把规范文件加载到上下文中顺序、优先级固定。这是整个可控化体系的基石没有它 SDD 就落不了地。二是技能仓库Skill。把常见的编码动作固化下来比如按规范生成新模块审查本次变更是否违反规范为指定接口补充测试AI 可以通过名称调用这些 Skill而不需要在对话里反复描述。三是插件系统。Harness 本身是骨架真正干活的是插件。插件可以扩展 AI 的工具能力比如读取 Git 变更、编译检查、执行测试、调用内部文档系统。四是审计与日志。每一次 AI 操作都有完整记录包括输入、输出、文件变更、耗时。这个能力平时感觉不到存在但一旦出了问题它是唯一能让你还原现场的东西。五是模型适配层。同一个 Harness 配置可以切换不同的模型后端从 DeepSeek API 到本地部署的 Qwen 模型再到 Claude 都能跑不需要把规则体系重新写一遍。3.3 Harness 与点击式 IDE 内助手的区别现在很多 IDE 也有内置的 AI 助手比如 CodeBuddy 这类用起来也很方便。但 IDE 内助手默认是安安静静改代码的模式对个人开发者很友好对团队协作来说却有个问题规则散落在各个开发者的 IDE 配置里无法统一管理。Harness 则更像一个控制台。它不太关心你在哪个 IDE 里编码它关心的是任务从进入到产出的全链路是否合规。你可以把 Harness 当作一个服务层接到 CI/CD 里、接到代码评审流程里、甚至接到 RPA 机器人上让 AI 能力变成整个研发管线的一部分而不仅仅是某个开发者窗口里的聊天机器人。4. 从零搭一套 Harness 工作区安装、模型接入与 Skill 编写讲完理念说点能直接落地的。下面是我实际搭建一套 Harness 工作区的步骤和思路里面的目录结构、配置逻辑是基于社区里常见的实践整理的不同发行版的 Harness 在细节上会略有差异但大的路径是一致的。4.1 安装与环境准备含装 D 盘的技巧Harness 这类工具一般是命令行程序。安装方式各家略有不同有基于 Node 生态的也有基于 Python 生态的。我们这边选的是 Node 体系的版本原因只有一个团队前端人多Node 环境已经是标配不用额外维护一套运行时。安装的第一步是确认本机环境。Windows 上最容易翻车的是权限问题我建议不要让安装目录落在 C 盘的 Program Files 下。Windows 对这些目录有额外的安全限制插件私服、配置文件写入、Skill 目录创建都容易触发权限异常。直接装到 D 盘比如创建一个D:\tools\harness目录后面省很多事。如果你用 Linux包括 Kali 这类环境就按常规方式全局安装基本不会有坑。安装完成后先做一次基础配置初始化。命令通常是harness init或类似的入口。初始化过程会生成一个配置目录里面有几个核心文件$HOME/.harness/ ├── config.yaml # 全局配置模型端点、密钥、日志级别 ├── plugins/ # 插件目录每个插件一个子目录 ├── skills/ # 技能目录每个 Skill 一个子目录 └── workspace.yaml # 工作区配置决定哪些仓库启用哪些规则config.yaml里最核心的是模型接入配置。我用的是 DeepSeek所以会配置 API Base 和密钥。如果你用的是本地部署的模型这里就可以改成内网地址。社区里也有人用 Qwen3-27B 这类量级部署到公司内网跑效果在自主完成为主的小任务上完全可用。模型的选择不用焦虑Harness 的价值恰恰在于模型可以随便换骨架不用动。4.2 第一个 Skill:从需求描述到验收清单光有 Harness 本身还不够真正让 AI 守规矩的是往技能仓库里放 Skill。我建议第一个 Skill 不要写太复杂就做一个从需求文本生成验收清单的小技能。每个 Skill 通常是一个文件夹里面包含一个说明文件和一个执行代码文件。大致结构如下skills/ └── generate-acceptance-checklist/ ├── SKILL.md # Skill 的说明告诉 AI 什么时候该调用 └── run.js # 实际的执行逻辑SKILL.md的内容决定了 AI 是否会在合适的时机调用它。这份文件用自然语言写清楚触发条件和执行步骤就行# Skill: Generate Acceptance Checklist 当用户提出一个新的功能需求时调用此 Skill。 步骤 1. 从用户的描述中提取功能点 2. 阅读 specs/acceptance-checklist.md 中的格式规范 3. 将功能点映射为可勾选的验收条目 4. 将结果写入 docs/acceptance/需求名称.md 文件。你可能会问AI 凭什么在提出需求时主动调用这个 Skill答案是 Harness 会在每次构造上下文时把 Skill 的目录清单和简要说明提供给模型。模型看到当用户提出新功能需求时调用此 Skill并且能通过工具调用机制自动执行就会形成条件反射式的行为。这不是魔法是上下文设计——你反复让 AI 看到这个规则它的行为就会趋于稳定。4.3 插件体系给 AI 接上 Git 和编译能力Skill 解决的是行为流程问题插件解决的是工具能力问题。最常用的插件集中在几个方向Git 变更查看插件、编译检查插件、测试运行插件、代码搜索插件。我推荐先装一个 Git 变更查看插件。这个插件的作用是让 AI 在生成代码前能先看到git diff和git status知道当前工作区有没有别人正在改的文件、有哪些文件处于冲突状态。别小看这个能力它能让 AI 减少盲改的概率。我们曾经遇到过 AI 直接覆盖了同事尚未提交的改动就是因为可怜的 AI 根本没意识到那个文件已经被改过了。配置插件时要注意一点插件并不是越多越好。每加一个插件AI 在决策时面对的选项就多一个在一些边缘场景下它可能选错工具。我用下来的原则是默认最小集按需扩展基础就装 Git 变更、编译检查、测试运行三件套后面确实有需要再加。4.4 工作区的规则绑定最后一步是把规范文件绑定到具体仓库。workspace.yaml里通常这样声明workspaces: - repo: backend-api rules: - specs/api-contract.md - specs/coding-rules.md - specs/change-boundary.md skills: - generate-acceptance-checklist plugins: - git-diff - compile-check这套声明非常直观这个仓库启用哪些规范、哪些技能、哪些插件。绑定之后任何人用 Harness 在这个仓库里干活AI 都会自动带上这些约束。规范文件改一处全团队生效。不再需要挨个给别人发新版本的提示词模板。5. 真机踩坑插件加载失败、Win 权限问题与内网部署工具思路讲得再顺落地时一定会有坑。下面的问题我都在真实环境里遇到过排查过程写出来大家可以按这个思路复现遇到同样的报错就知道怎么处理。5.1 failed to load plugins 与 web boot: 1 entry did not activate 排查链路这个报错是 Harness 在启动时加载插件失败具体提示类似failed to load plugins ... web boot: 1 entry did not activate。第一次遇到时确实懵了一下这个词组的意思是插件声明了入口文件但在 Web 启动阶段没有被成功激活。排查第一件事是将报错信息里的插件名找出来。Harness 的日志会告诉你哪个插件出了问题一般格式是plugin: xxx。找到后先尝试禁用这个插件看 Harness 是否能正常启动。能启动说明问题就在这个插件上。第二件事是检查插件目录的结构。常见原因有两个一是插件缺少入口文件比如声明文件写的是entry: src/index.js但实际目录下没有这个文件二是入口文件本身抛了异常比如某个依赖缺失或者本应导出的activate函数没有被正确导出。我遇到的是后者——插件入口写成了module.exports { active: fn }而 Harness 期望的是activate拼写不一致直接导致 entry 没有 active。第三件事是检查版本兼容。Harness 版本升级后旧的插件可能还在用已经被废弃的 API。社区里这种情况很常见解决办法是把插件升级到对应版本或者暂时不启用不兼容的插件等后续适配。这条报错的排查要诀是不要对着完整报错瞎猜先定位到具体的插件再逐个击破。5.2 Windows 下 Skill 读取文件的权限问题另一个高频坑是 Skill 在读取文件时抛出一个诡异错误setnamedsecurityinfow failed (win32)。这个错误在 Windows 上经常出现原因是代码试图设置某个文件或目录的安全描述符但被系统拒绝。我遇到的触发场景是这样的一个 Skill 需要读取D:\project\docs\specs\api-contract.md但它在此之前先尝试对路径上的某个目录执行了设置安全属性的操作。Skilling 目录如果落在某些受保护目录下比如 OneDrive 同步目录或者文件被别的进程锁定就会触发这个问题。排查过程分四步。第一步把 Skill 的访问目标移到不受系统保护的路径下比如D:\harness-data\skills\projects不放在用户名目录下减少安全策略干预。第二步检查文件是否被 OneDrive、杀毒软件实时扫描锁定。第三步确认当前运行用户对目标目录有没有完全控制权限必要时把目录放在用户直接创建的文件夹下而不是系统默认的文档目录。第四步如果还是不行在 Harness 配置里关闭对文件安全描述的自动同步选项这类配置通常会有一个开关来控制是否调用setnamedsecurityinfo。5.3 内网服务器部署没有外网时怎么同步模型和 Skill团队落地时必须面对内网部署。我们先将 Harness 本体、Skill 仓库、插件全部放到内网 Git 服务器上然后写了一个同步脚本定时将外网更新拉取到内网镜像仓库。这里关键是模型也要私有化或走内网网关。如果模型走外网 API内网开发环境会有合规和数据安全压力。我们的做法是用内网 GPU 服务器跑一个量级合适的开源模型通过 OpenAI 兼容的接口暴露给 Harness。Harness 端配置一个内网 Base URL 就行其余逻辑不变。实测下来写单元测试、补注释、做代码审查这类任务小模型已经能完成得很好涉及复杂重构和多文件协调的任务效果会差一些但可以通过把任务拆细来弥补。Skill 同步到内网服务器也有个容易忽略的点Skill 内部不要直接写绝对路径。你本机可能是D:\tools\harness\skills内网服务器可能是/opt/harness/skills如果代码里硬编码了路径同步过去必然报错。推荐用 Harness 提供的环境变量或相对路径占位符来引用目录这样同一份 Skill 才能在多个环境之间复用。6. 让 Harness 进入研发流程规则入库、RPA 联动与变更审计个人能用起来和团队能跑起来完全是两个难度等级。这一章讲的是把 Harness 从我自己的工具变成研发流程的一部分。6.1 规则集和 Skill 全部纳入 Git 管理规范文件和 Skill 代码是研发资产不能只存在于某个人的.harness目录里。我们把这些资产统一放在一个独立的ai-ops仓库里和业务代码、基础设施配置一样做版本管理。这样做的好处是显而易见的。每次修改规范都相当于一次代码变更有 Diff、有 Review、有记录。某个规范文件被改动了可以通过 Git 历史看到谁改的、为什么改、影响了哪些 Skill。跑 CI 的时候仓库的变化还会触发校验比如检查 Skill 目录结构和SKILL.md的格式是否合法避免有人提交了一个无法加载的 Rule 文件到主分支。提交规范变更也有一条铁律如果某个规范要废掉先保证没有 Skill 还在引用它再删除文件。否则 AI 会读到一份已经失效的规范而相关 Skill 还按旧规矩干活一起冲突就乱套。6.2 与 RPA 联动让 AI 处理更完整的流程热词里有harness RPA 落地实现这个方向我们确实试过。RPARobotic Process Automation机器人流程自动化擅长处理重复的、固定流程的任务而 Harness 擅长让 AI 在复杂规则下生成内容。两者联动可以做出非常实用的效果。举一个实际的例子。我们有一个需求工单流转的场景RPA 从工单系统里抓取需求文本经过解析和分类后将消息发送到 Harness 的触发入口Harness 按需求类型调用对应的 Skill完成初步的代码方案设计并把输出写回工单系统的备注字段里。整个过程人只需要在最后做一次确认。这套东西跑通之后大量动辄要翻需求文档、找规范、写方案的时间被压缩掉了。落地时要注意一个细节RPA 与 Harness 的接口层要设计成消息队列模式而不是同步调用模式。AI 生成方案可能要几秒甚至几十秒RPA 如果一直在等待会把流程卡死。用队列解耦之后RPA 只管发任务Harness 完成后回调即可。6.3 变更审计让每一次 AI 改动都留痕可控化体系里最容易被忽视但其实最重要的一环是变更审计。我们在 Harness 的审计日志基础上加了两个环节。第一个是变更语义归类。每次 AI 完成一次操作插件会自动识别这次操作属于新增文件修改文件删除文件还是批量重命名并和 Git 记录做交叉比对。如果某次操作跨了多个模块审计系统会打一个高风险标记推给评审人。第二个是自动化的规范体检。AI 完成变更后会调用一个规范体检插件对本次变更做几件事检查新增代码是否违反了coding-rules.md中的长度、命名和嵌套约束检查是否修改了change-boundary.md里禁止 AI 触碰的文件清单检查 API 文件是否和api-contract.md里的契约保持一致。体检结果会作为评论贴到 Merge Request 里。有了这一环很多规范问题在人工评审之前就被拦住了。我们团队里AI 改完代码直接合入主分支的担忧逐渐变成了AI 改完代码先过体检再看余下部分的习惯。7. 用一个季度的实测聊聊这套体系的边界和收益最后说点掏心窝的话。这套 SDD Harness 的体系我们跑了三个多月收益和边界都逐渐清晰。收益最明显的是代码风格一致性。规范文件注入之后AI 写出来的代码在命名、结构、错误处理上的一致性非常高几乎不需要人工纠正。其次是可控感。有了 Skill 和插件的约束AI 不再随意触碰不该碰的文件也不再凭空发明接口。审计日志让我能还原每一次 AI 行为这对团队信任的建立太关键了。边界也如实说一下。首先是运行时成本。每次请求都要携带规范文件token 消耗比裸用对话式 AI 要高一些但换来的是稳定性我觉得很值。其次是规则维护成本。规范文件要跟着项目演化持续更新它不是一次写完就一劳永逸的。最后是模型能力的天花板。Harness 能约束 AI 的行为但不能让一个模型变得更强。复杂架构设计、跨模块的大重构目前还是要靠人主导AI 更适合在明确边界内做执行类工作。根据我自己的经验如果你要开始搭建这套体系最划算的投入是先把规范文件写进仓库哪怕暂时不引入 Harness光是让 AI 在每次编码时能看到清晰的规则文件你就能感受到区别。等规范稳定了再逐步加入 Skill、插件、审计把人管 AI变成体系管 AI。说到底AI 辅助开发的未来不是更聪明的模型而是更严密的工程体系。希望能给你们一些启发。