ARTICLE DETAIL

建站实战干货

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

基于SDD与Harness构建可控化AI辅助开发体系

2026/10/3 11:09:00 拓冰建站 浏览量
基于SDD与Harness构建可控化AI辅助开发体系 从第一次把一个带规范模板的AI助手接入团队日常开发到现在我最大的感受是AI写代码这件事真正难的不是让模型听懂人话而是让它稳定地、不出格地、按团队约定好的方式产出成果。很多人觉得AI辅助开发就是装个插件、把需求敲进去、坐等代码生成但实际做过一个中型项目就会明白没有规范约束和驾驭机制的AI更多时候像一个有时靠谱有时离谱的实习生。这也就是我这篇文章想聊的核心用SDD规范驱动开发加Harness工程驾驭框架的思路构建一套可控化的AI辅助开发体系。这篇文章不是纯理论科普而是把我自己从零搭这套体系的全过程、踩过的坑、最后沉淀下来的方案一起分享出来。适合正在带团队做AI辅助开发落地的技术负责人、对SDD和Harness相关工程实践感兴趣的开发者以及那些已经被AI生成代码坑过、想找到控制方法的同学。1. 项目起底为什么AI辅助开发需要规范和驾驭1.1 AI写代码的真正痛点不是不够聪明而是不可控先聊一个很现实的场景。我们团队去年试点AI辅助开发初期效果确实惊艳——把一个后端接口的CRUD需求丢给AI几十秒就能生成完整代码连单元测试都带出来了。但问题也随之而来同一个需求换个提示词问一遍生成结果可能完全不一样昨天还能正常工作的功能代码今天用另一套表述去生成逻辑就变了更危险的是AI有时候会自我发挥在代码里引入我们工程体系里根本不存在的封装、依赖或者设计模式。这些问题表面上看是提示词写得不够好但根子上是缺少两个东西一个是规范也就是AI生成代码之前必须遵守的约束规则另一个是驾驭机制也就是一个能在AI工作流程中插入规则、拦截错误、强制校验的控制层。前者对应SDD后者对应Harness。SDDSpecification-Driven Development不是一个新概念传统软件工程里早有类似思想但在AI辅助开发场景下它的含义被刷新了不只针对人的开发流程更是给AI设定的行为边界。Harness这个词原本在工程领域指测试夹具或控制装置放到AI工程里它变成了一个承载规则、技能、工作流的运行时框架——就像给AI套上方向盘和刹车让它沿着既定的路径输出而不是野马一样乱跑。1.2 SDD让规范成为AI的行为边界SDD的核心思想是在让AI产出任何代码之前先给它一份足够明确的规范文档。这份规范不是简单说代码风格要统一这种空话而是要具体到可以校验的程度。我拿一个实际例子来说明。我们团队接了个需求要做一个用户积分查询的接口。如果完全不写规范直接丢给AI大概率会得到五花八门的实现有人喜欢返回RESTful风格有人喜欢返回统一的Result包装还有人会自作主张加个Redis缓存。但如果先写好一份SDD文档里面明确指定了接口路径、请求参数格式、响应包装类、异常处理方式、甚至方法命名前缀AI生成出来的代码就会稳定得多。在这套体系里SDD文档其实起到了三重作用第一重是约束作用把AI的选择空间压缩到团队认可的范围内第二重是校验基准后续的代码审查和自动化测试都拿规范当尺子第三重是沟通桥梁人和AI之间对什么叫正确的产出有一份共同语言——对人在提示词里说不清的边界问题规范里都能写清楚。1.3 Harness把散装AI能力装进工程框架如果说SDD是内容层的约束那Harness就是机制层的控制。我第一次接触Harness这个概念是在研究AI工程化落地时当时有个词叫harness anything意思是你可以把任何AI能力装进一个统一管理的框架里配上技能包、规则模板、工作流插件让AI按固定的流程干活。打个比方AI模型本身就像一台发动机动力很猛但方向不听使唤Harness则是连接发动机和车轮之间的传动、转向、刹车系统。它不做重活但决定了动力怎么传递、什么时候该收油、遇到障碍怎么反应。在开发场景里Harness负责管理AI能调用哪些工具、读取哪些文件、按什么顺序执行任务、在什么情况下必须停下来问人。我见过不少团队跳过这层直接上AI结果就像没装转向系统的车跑起来是快但没人敢真正开上项目主线。所以Harness在我的体系里从来不是一个可选增强项而是落地前置条件。2. 核心设计拆解规范层与驾驭层的协同机制2.1 规范层的设计从说人话到说机器听得懂的话构建这套体系的第一步是设计规范层。这里我踩过一个大坑最开始我把SDD文档写成了一篇散文语义很清晰但AI执行起来效果很差。因为AI对模糊的自然语言表述没有稳定的解析能力——尽量用现有的公共组件这句话人在理解时没什么歧义模型却可能判断不了哪些算现有组件。后来我把规范分成了三种类型效果立刻不一样了事实性规范明确的、非黑即白的技术约束。比如统一使用Golang 1.22版本接口响应必须包装在Result对象里数据库操作必须走dao层。这类规范AI几乎不会理解错可以放心交给它执行。偏好性规范相对主观但可以通过例子来锚定的约束。比如缓存策略优先使用本地Cache而非Redis日志中必须包含traceId。我会在规范里配上正反两个例子让AI照样子学。流程性规范规定AI在生成代码前必须完成哪些前置动作。比如先读取项目根目录下的CONTRIBUTING.md再扫描指定模块的已有接口定义最后才开始写代码。实际经验告诉我事实性规范和流程性规范的价值最大它们能直接消灭掉70%以上的乱生成问题。偏好性规范需要结合场景反复校准我通常会在Harness里设计一个规范反馈机制当AI生成的代码不符合偏好性规范时系统自动给它一次补充修正的机会并把修正结果记入日志方便后续调整规范文档。还有一点要强调规范一定要可校验不能只停留在写了的状态。我在后面会详细介绍配合的校验工具链这里先提一个思路——给每份规范文档配一个checklistAI每完成一步就自我检查一次而Human Reviewer只看checklist的通过情况不用再逐行审代码。2.2 驾驭层的实现Skill、工作流与规则的组合Harness层的实现我建议从三个维度入手Skill技能包、Workflow工作流、Rule规则引擎。这仨是有层级的组合关系不理解清楚就容易做成四不像。Skill可以理解为给AI预设的专业能力模块类似于给一个通用员工配了对应的作业指导书。每个Skill里包含一组提示词、上下文资料、以及它可以调用的工具列表。比如我做一个后端接口开发的Skill里面就打包了SDD规范模板、项目已有的接口示例、dao层代码的代码风格片段、以及自动调起单元测试的命令。AI接单后会优先加载这个Skill而不是靠默认能力瞎猜。Workflow则负责串联多个Skill和多个AI动作形成一次完整的任务流。举个例子一个标准的新功能开发Workflow长这样解析需求文档 → 扫描现有代码结构 → 识别受影响模块 → 生成设计建议 → 人机评审 → 生成代码 → 运行静态检查 → 生成单元测试 → 输出变更说明。每一步都有一个独立的Skill在背后支撑Workflow只负责编排顺序和设置进入下一步的触发条件。Rule引擎是最硬的约束层。它和Skill不同不受AI模型听不听话的影响每次调用AI之前Harness都会主动检查当前状态是否符合规则——比如没有通过静态检查的代码不能进入生成测试阶段改动文件数量超过10个必须强制要求人类介入审查这类。规则引擎不需要AI判断它是代码层面的硬约束相当于给整个AI工作流加了一把物理锁。这三者的关系我用一个比喻帮助团队理解Skill是工具箱里的专用工具Workflow是工件的操作顺序Rule是安全带和防护罩——你动作再快该防护的时候必须防护。2.3 协同逻辑规范前置、驾驭贯穿、反馈闭环把SDD和Harness拼在一起形成完整体系关键在于三个协同动作。规范前置是指所有AI任务开始之前Harness必须先把相关SDD文档灌进上下文。这个动作不能省。有一次我图省事让AI直接根据一段口语化需求去改代码结果它把整个模块的命名风格都重构了一遍差点把代码库搞乱。从那以后我把加载规范写进了Workflow的第一步像强制执行一样谁也不许跳过。驾驭贯穿是指Harness在全过程中持续起作用而不仅仅是启动时加载一次规范。当AI生成了一版代码Harness会在后台自动做静态检查、格式校验、规范关键词匹配如果发现异常会在AI完成当前步骤之前就给出修正反馈。这种边写边查的实时驾驭模式比事后让人在Code Review里挑毛病要高效得多。反馈闭环是指每一次人机协作的结果都要反向沉淀到SDD和Harness配置中。比如某次AI生成的代码在测试阶段暴露了一个边界条件没处理我会把这类问题写进新的规范条目再把它对应到Rule引擎的一个检查规则里。这样下次遇到相似任务AI就不会再踩同一个坑。这个闭环是体系价值持续放大的关键没有闭环的话整个体系运行越久反而越僵化。3. 实操落地从零构建一套可控化AI辅助开发体系3.1 环境准备与工具选型理论说完了进入实操部分。先说明一下我不打算绑定某个特定商业产品而是介绍一套可自建的技术栈思路。我自己用的是开源方案这样团队可控性最强。基础环境方面我需要这几样东西一个可本地部署的代码生成模型服务支持通过API调用这样Harness才能把规范注入到模型的上下文里。我这里是基于开源模型在内部服务器上起了一个服务主要考虑数据安全代码不能出内网。Harness框架负责承接SDD规范、管理Skill和Workflow。我用的版本有命令行端和桌面端命令行端适合集成进CI流程桌面端适合开发者本地调试Skill和Workflow。插件系统用于扩展静态检查、格式校验、测试执行等外部工具。插件机制遵循统一接口规范装的时候要注意各插件之间的依赖关系。一个代码仓库用来存SDD规范文档、Skill配置、Workflow定义、规则引擎的策略文件。这里强烈建议把规范和配置都用Git管理起来后续一切的变更都可以审计和回滚。选型思路我给三个建议第一模型服务要能支持动态调整上下文长度因为SDD文档往往不短第二Harness要选支持规则优先级配置的实际运行中总有冲突情况需要程序化裁决第三插件系统要有沙箱机制外部工具崩了不能直接拖垮整个AI任务。3.2 规范模板的编写一份可直接抄的SDD文档骨架规范文档是这套体系的灵魂所以我把模板的结构完整放出来大家可以按项目实际调整。下面是我沉淀下来的一份通用SDD文档骨架# SDD: [模块/功能名称] ## 1. 目标与范围 - 本次开发要解决什么问题 - 明确不在范围内的需求防止AI自我发挥 ## 2. 技术基线 - 语言与版本 - 框架版本 - 允许引入的新依赖列白名单 - 禁止引入的依赖列黑名单 ## 3. 接口与数据结构 - 接口路径、方法、请求/响应结构用代码块写示例 - 数据结构定义字段、类型、约束、默认值 - 错误码与错误处理规范 ## 4. 业务规则 - 权限要求 - 字段校验规则 - 状态流转规则 - 边界条件尤其要写出什么情况下不允许做什么 ## 5. 代码风格约定 - 命名规范 - 分层规范controller/service/dao - 事务与异常处理方式 - 日志与监控埋点要求 ## 6. 测试要求 - 必须覆盖的分支列表 - 测试数据准备要求 - 命名与断言风格 ## 7. 验收清单Checklist - [ ] 接口路径与文档一致 - [ ] 响应结构符合统一包装 - [ ] 边界条件已处理 - ...这份骨架里我特别想强调两个容易忽略的点。第一个是边界条件。AI生成代码时特别容易忽略异常路径。如果你不说清楚当用户不存在时返回什么错误码当积分余额不足时走什么分支模型大概率只写happy path。所以我在业务规则里专门加了一条每段逻辑必须列出不少于3个失败场景及预期行为。这个约束加进去后生成代码的质量明显上了一个台阶。第二个是验收清单。这份清单要在编写任务下发时就让AI看到并且要求它每完成一个checklist项就主动标注已确认。这里有个小技巧我会在清单末尾加一行我不确定的地方……让AI在遇到规范没有覆盖的情况时必须显式提问而不是自作决定。实测下来AI列出的不确定项比我想象的更有价值许多规范盲区都是这么暴露出来的。3.3 Harness技能与工作流插件的配置规范文档准备好了接下来就是把它装配进Harness。这一步要做的核心事情是创建一个后端开发Skill把SDD模板、项目代码片段、常用命令都打包进去然后配置一个标准的开发Workflow。Skill目录里我通常这样做组织skills/ backend-dev/ spec/ sdd-template.md project-conventions.md examples/ controller-sample.go service-sample.go tools/ static-check.sh run-test.shspec目录放规范文档examples目录放已经验证过的优质代码样例AI生成代码时会自动参考这些样例的风格tools目录放那些需要调用的外部脚本。每个Skill我还会写一个skill.yaml在里面声明这个Skill的触发条件、适用范围和依赖的插件列表。Workflow的配置则关注两步之间的承接和校验。我的需求到代码Workflow定义大概是workflow: name: feature-dev steps: - name: load-spec skill: spec-loader params: spec_path: specs/{ticket_id}/sdd.md - name: scan-repo skill: repo-scanner params: scope: affected_modules - name: gen-code skill: backend-dev params: target_file: ./internal/service/{module} - name: static-check plugin: golangci-lint critical: true - name: unit-test plugin: go-test critical: true - name: report skill: change-reporter这个配置文件里有个关键参数叫critical。当某一步的校验插件执行失败时如果设了critical: true整个Workflow会停下来等待人处理如果设成falseAI可以自己尝试修正后继续。我的建议是生成代码之后的静态检查和单元测试务必设为critical。这一步拦住的错误越多后面人审查的时间就越少。插件配置这里也有个坑很多插件默认跑在外层容器里读取不到内网仓库的认证信息。解决方法是给每个插件单独配一个运行上下文把仓库地址和认证方式注入进去而不是靠系统默认配置。这块配置写清楚了后面能省下大量排查问题的时间。3.4 内网部署一次私有化落地的完整记录在完全隔离的内网环境里部署这套AI辅助开发体系是我觉得整个实操中最需要对细节较真的一步。因为很多开源组件默认要联网拉取模型、插件和数据到了内网第一件事就是把所有外部依赖都提前进行本地化。我的部署步骤大致如下模型本地化先把代码生成模型的权重文件、分词器、配置文件拷到内网服务器用离线模式启动模型服务。这里要注意模型服务启动参数里的离线模式必须显式开启不然它会在初始化阶段尝试请求外部资源导致启动卡死。依赖包仓库内网化建立内网的软件包镜像源把Harness框架、插件系统以及所有需要的基础依赖统一放到一个内网源里。安装时全部指向内网地址不碰外网。Skill文件入库把SDD模板、示例代码、工具脚本全部提交到内网Git仓库。因为内网的开发主机访问不了外网所以Skill的分发全部走Git拉取相当于给整个团队共享同一份规范基线。流程打通把Harness配置成CI流水线的一环每次开发者触发任务时从内网Git拉取最新规范与Skill执行完整个Workflow后把产出物和报告自动提交回代码库。部署过程中最有价值的一次记录我们内网服务器配置不高一次性跑大模型的上下文窗口又很大出现过几次OOM。后来我把Workflow进一步拆细每个步骤跑完后主动释放上下文只在当前步骤保留必要的信息。这个优化非常有效直接把内网环境的稳定性拉到了可用水平。所以我要提醒一句不要盯着大模型参数猛堆工程上的节制和优化往往比硬件堆料更值得先做。4. 常见问题与排查技巧实录4.1 Skill加载失败与插件不生效这是整套体系里出现频率最高的问题。我遇到的最典型一种情况是Harness启动时直接报failed to load plugins后面跟着一串 boot 信息看起来某个插件入口没有激活。排查下来大部分原因是插件配置里的入口路径写错了或者是插件之间的依赖顺序不对。我自己的排查路径分为三步一看插件的启动日志确认它是否真正进入了初始化流程二查依赖确认插件要求的运行环境变量是否齐全三做隔离测试——把插件单独从整体环境中拆出来看它能否独立工作。还有一种隐蔽情况是配置文件编码问题某些插件对UTF-8之外的编码极度敏感文件里多了个BOM头就会静默跳过这类问题在Linux环境和Windows之间传送文件时尤其容易遇到。4.2 文件权限与系统调用异常这个问题集中出现在Skill要读取项目文件或执行脚本的时候。典型报错是类似setnamedsecurityinfow failed的权限问题以及AI工作流要访问的文件不在授权范围里。我一开始以为是操作系统权限没配好后来发现Harness对Skill配置里声明的可读文件路径有严格的白名单机制凡是没在skill声明文件里列出的路径框架会直接拦截访问。所以解决方案反而是先回skill配置文件把要访问的目录、文件模式、以及脚本的执行权限全部写清楚。比如在skill.yaml里加一行配置明确允许读取specs/{ticket_id}/**下的所有Markdown允许执行tools/*.sh其他操作一律拒绝。这样安全性和稳定性同时提升误操作的概率也大幅下降。顺带一提Windows环境上装这套体系时脚本换行符和编码问题会频繁出现统一转成LF并配好UTF-8无BOM格式能省掉很多无意义的调试。4.3 规范漂移AI开始自由发挥规范漂移是指AI在运行一段时间后逐渐脱离规范约束、开始自己发明约定的现象。这个问题特别隐蔽因为它不是一次性地尿跑题而是在多次迭代中悄无声息累积的。比如规范里写了统一使用context传递traceId但某次AI在生成新接口时遇到一个老代码片段照着老代码的样子直接塞了个全局字段进去。单次看误差不大但累积起来代码库就慢慢变成两种风格混用的混沌状态。针对规范漂移我采用三层防御第一层是Workflow里每次代码生成前强制拉取SDD文档最新版本不给AI任何一次凭记忆的机会第二层是Rule引擎里加风格嗅探检查用自定义脚本扫描生成代码里的关键特征词一旦发现与规范冲突的命名或结构强制中断第三层是把检查结果同步到一个趋势看板我每周看一次——哪类问题反复出现就说明对应的规范表述还不够明确需要在下一次SDD修订里补强表述。4.4 团队协作规则冲突与版本管理当多个人在同一个Harness服务上提交不同需求的Skill和Workflow时规则冲突几乎是必然的。最典型的是一个人改了全局Rule的一个参数结果别人跑任务时他依赖的通关条件变了整个流被卡住。解决这个问题的思路我参考了基础设施代码化的经验所有规则、Skill、Workflow都放进同一个Git仓库用分支管理变更任何修改都必须过一遍合并请求审查通过才能合入主干运行流水线时Harness从主干拉取最新配置保证一切生产环境的行为都可追溯、可回滚。与此同时我会为每个Workflow维护一个OWNERS文件标明哪个团队对这套流程有决策权。具体执行时跨团队的规则变更发起一个评审会话等到所有相关方确认后才合入。这套机制从制度上避免了别人改了规则导致我的AI任务突然失败的问题算是踩了很多坑之后总结出来的治本之策。5. 实战心得与后续扩展5.1 从个人效率工具到团队工程基建整套体系跑顺之后我觉得最有成就感的不是AI帮我写了多少行代码而是它从一个个人效率工具真正长成了团队工程基建的一部分。最初的时候每个开发者自己配自己的Harness规范也各有各的理解现在规范统一收口到Git仓库Skill和Workflow有专人维护新成员入职后拉一份仓库整个AI辅助开发环境就齐活了。团队层面还有一个额外的收获因为每份SDD文档、每个生成任务都有完整的日志和报告我们在复盘时多了大量的客观数据。这周AI在接口生成的通过率是多少、边界条件漏了多少个、哪类规范被违反的频率最高——这些事情过去靠体感判断现在有数据说话。这个能力反过来又推动规范迭代让SDD本身越来越接近团队的真实工程标准。5.2 一些踩坑之后留下的真实建议最后分享几条我时不时会拿出来翻看的经验都是踩坑换来的。第一规范先于工具。不要一上来就折腾Harness的各种花哨插件先花一天时间把手头的SDD文档写扎实。工具是放大器方向错了放大的是乱象。第二驾驭机制要克制。规则和检查项不是越多越好每一条规则都有维护成本和误伤风险。我一般只保留那些真实拦住过问题的规则把那些理论上能拦住问题、但从来没触发过的规则定期清理掉保持整个框架的轻盈。第三人机分工定得越早越好。在我的体系里AI负责按规范生成和自检人负责定义规范和处理中断事项。不要让AI去决策那些规范之外的事情也不要把繁琐的机械校验全丢给人做。这个分工一旦明确效率和质量才会同时往上走。这套体系后续我还在继续扩展比如把规范覆盖率分析做到更细致、把反馈闭环和自动化测试更深度地打通。每次迭代的过程中我越来越觉得AI辅助开发的本质不是让模型替人思考而是把人和模型的优势以工程化的方式组合起来。SDD提供明确的目标和边界Harness提供流程和约束剩下的就是把每一次成功和失败都沉淀回体系本身让它越用越顺手。