
最近这段时间,Harness这个词突然火了起来,铺天盖地的营销文章让人看得眼花缭乱,不少研发同学难免会慌:这又是什么新风口,我是不是又落后了?其实大可不必焦虑,Harness从来不是什么凭空出现的"黑科技",它更像是我们研发人早就一直在做的工程实践,只是现在被正式定义、系统梳理,有了一个统一的名字而已。
很多人提到Harness,第一反应就是"用AI多写点代码",但这其实是对它最大的误解。真正的Harness,核心不是解放AI的生产力,而是把AI装进一套可控、可审计、可复用的工程流程里,让AI从"一个不受控的高效助手",变成"能稳定融入生产研发的工程能力"。
对于我们日常开发的Java Spring Boot业务项目来说,尤其是那些有一定历史包袱、需求以增量改造为主的系统,最可怕的从来不是AI写不出代码,而是AI在没有边界的情况下乱改代码,不懂项目里的历史隐性约定,把需求拆解、代码实现、评审验证混为一谈,改完代码却不明确风险,甚至触碰SQL、配置这类高风险区域而没有任何阻拦。
基于一次真实的Java Spring Boot项目实践,我整理出了这套Harness最佳实践,从核心原则、适用场景、仓库组织,到具体实践、流程复盘、落地顺序,全方位拆解如何把Harness思想落地到实际项目中。需要说明的是,Harness思想本身和编程语言无关,弄懂了这套逻辑,不管是Python、Go还是其他语言,都能灵活复用。
一、先抓核心:Harness落地的4条关键原则
如果把Harness的所有实践浓缩成最关键的几条原则,我总结为4点,这也是我们整个项目落地的核心指导思想,记牢这4点,就不会偏离Harness的本质。
第一,OpenSpec管变更生命周期。用/opsx:propose -> /opsx:apply -> /opsx:verify -> /opsx:archive这一套流程,管住"需求从提出到归档"的全过程,让每一次变更都有迹可循、有章可依。
第二,AGENTS.md只当地图,不当百科全书。AGENTS.md的核心作用是告诉AI"先看什么、按什么流程做",相当于一个入口导航;而真正的项目知识,比如架构设计、业务规则、隐性约定,应该统一放在docs/目录下,避免AGENTS.md变得臃肿失控。
第三,Claude的硬约束靠permissions + hooks。把规则写在提示词里,只是"软约束",AI难免会有判断失误的时候;真正能拦住危险动作的,是权限配置和钩子函数,这才是Harness的"硬护栏"。
第四,团队专用动作放到skills和subagents。比如代码评审摘要生成、Spring分层架构检查、SQL风险审查这些高频动作,应该沉淀成可重复调用的能力,而不是每次靠人临时提醒AI,这样才能提升流程的复用性和一致性。
如果再压缩成一句话,就是:需求先工件化,知识先显性化,执行先加护栏,评审与验证必须分离。这十六个字,贯穿了我们整个Harness落地的全过程。
二、明确边界:这套Harness方案适合哪些项目
不是所有项目都适合照搬这套Harness配置,它有自己的适用场景,找对场景才能发挥它的最大价值,避免画蛇添足。
这套Harness最适合的,是这类Java Spring Boot项目:有一定的历史包袱,不是全新的从0到1项目;需求以增量改造为主,比如迭代新功能、修复老bug、优化现有逻辑,而不是整体重写;前后端之间存在一些口头约定或隐性契约,这些约定没有写进文档,新人或AI很难快速掌握;团队希望把AI编码变成团队的"流程能力",而不是某个人的个人技巧;需要把"需求、实现、评审、校验"这几个环节明确拆开,避免混在一起导致风险失控。
反之,如果你的项目是一个很小的demo仓库、一次性脚本仓库,或者是纯实验性质的项目,甚至是全新的从0到1项目,就没必要照搬这套配置。这类项目更注重灵活性,约束太多反而会降低效率,可以考虑和Superpowers、ecc、omc等框架搭配使用,根据项目实际情况调整约束强度。
这里要强调一点,Harness的核心是"可控",但不是"僵化"。我们的目标是在约束和效率之间找到平衡,而不是为了约束而约束。
三、基础铺垫:适合Harness的仓库组织方式
要落地Harness,首先要搭建一个合理的仓库结构,让每个目录、每个文件都有明确的职责,避免混乱。一个适合Java Spring Boot项目的Harness仓库结构,建议如下(按目录层级依次说明,重点标注核心文件和目录的作用):
plain
repo/
├─ AGENTS.md # 🌟 通用OpenSpec规则,AI的导航地图
├─ CLAUDE.md # 🌟 Claude系统提示词,定义AI的基础行为
├─ REVIEW.md # 🌟 只读评审代理提示词,规范评审标准
├─ docs/ # 📚 项目知识库目录,存放所有项目知识
│ ├─ architecture/ # │ ├─ 🔥 整体架构知识
│ │ └─ index.md # │ │ └─ 项目架构总览,让AI快速了解系统整体设计
│ │ └─ implicit-contracts.md # │ │ └─ 隐性业务约定/项目坑点,核心中的核心
│ ├─ product/ # │ ├─ 🔥 产品知识
│ │ └─ index.md # │ │ └─ 产品规则,明确业务逻辑边界
│ ├─ standards/ # │ ├─ 🔥 相关规范
│ │ ├─ testing.md # │ │ ├─ 测试规范,明确测试要求和标准
│ │ └─ database.md # │ │ └─ 数据库与SQL规范,规避数据层风险
├─ openspec/ # 📚 OpenSpec执行目录,管理变更生命周期
│ ├─ changes/ # │ ├─ 变更目录,存放当前和历史变更
│ │ ├─ <changes名> # │ ├─ 当前正在执行的change,每个change对应一个需求
│ │ │ ├─ specs/ # │ │ │ ├─ 该change的工作原理说明
│ │ │ ├─ proposal.md # │ │ │ ├─ 需求实现提案,拆解需求边界
│ │ │ ├─ design.md # │ │ │ ├─ 具体执行方案,明确技术实现细节
│ │ │ └─ task.md # │ │ │ └─ 执行步骤节点,拆解具体工作内容
│ │ └─ archive/ # │ │ └─ 归档文件,存放已完成的change
│ └─ specs/ # │ └─ 当前系统工作原理说明,让AI了解系统现状
├─ .claude/ # 📚 Claude项目级配置目录,核心约束层
│ ├─ settings.local.json.example # │ ├─ 🔥 项目级权限设置,定义AI可操作范围
│ ├─ skills/ # │ ├─ 🔥 项目级Skills,团队专用能力沉淀
│ │ ├─ prepare-review/ # │ │ ├─ review前变更审计,生成评审摘要
│ │ │ └─ SKILL.md # │ │ │ └─ 该skill的具体执行逻辑
│ │ ├─ spring-architecture-review/ # │ │ ├─ Springboot分层架构检查,避免分层混乱
│ │ │ └─ SKILL.md # │ │ │ └─ 架构检查的具体规则
│ │ └─ sql-risk-review/ # │ │ └─ SQL、Mapper、批量更新等风险检查
│ │ └─ SKILL.md # │ │ └─ SQL风险检查的具体规则
│ ├─ agents/ # │ ├─ 🔥 子代理,承担专项审查职责
│ │ └─ reviewer.md # │ │ └─ 只读评审代理,做独立代码审查
│ └─ hooks/ # │ └─ 🔥 Hook,硬护栏的核心实现
│ ├─ guard_write.py # │ ├─ 文件写入保护,拦截高风险路径写入
│ ├─ ensure_change_context.py # │ ├─ 上下文变更保护,检查change是否存在
│ └─ run_checks.sh # │ └─ 编译检查,自动执行编译、测试等
├─ src/ # 📚 项目源代码目录,和常规Spring Boot项目一致
│ ├─ main/
│ │ ├─ java/
│ │ └─ resources/
│ └─ test/
│ ├─ java/
│ └─ resources/
├─ pom.xml # 📚 Maven配置文件
└─ .gitignore # 📚 Git忽略文件
这套结构的核心不是"文件多",而是"职责分层清晰",每个目录和文件都有明确的定位,不会出现职责交叉或遗漏。简单来说,各核心目录的职责可以总结为:
openspec/:管理"这次改什么",负责把需求变成change工件,驱动变更生命周期;
docs/:管理"这个项目本来是怎么工作的",存放所有项目知识、规则和隐性约定;
AGENTS.md / CLAUDE.md / REVIEW.md:管理"AI进入仓库后应该怎么做",是AI的基础行为规范;
.claude/settings.json + hooks:管理"哪些事不能做、哪些检查必须跑",是Harness的硬护栏;
skills / agents:管理"团队专用的审查动作",沉淀可复用的团队经验和能力。
搭建好这个仓库结构,就为Harness的落地做好了基础铺垫,后续的所有实践都将围绕这个结构展开。
四、核心实践:7个关键落地技巧(附实战细节)
仓库结构搭好之后,就进入了核心实践环节。这7个最佳实践,是我们从真实项目中总结出来的经验,每一个都解决了实际落地中的痛点,也是确保Harness能稳定发挥作用的关键。
实践一:AGENTS.md只做导航,不做知识库
这是整个Harness落地过程中最容易踩坑的一点,很多团队一开始会本能地把所有规则、知识都塞进AGENTS.md,觉得这样AI能一次性看到所有内容,效率更高。但实际上,这样做很快就会导致AGENTS.md臃肿不堪,后续维护困难,而且AI在读取时也会抓不住重点,反而降低效率。
正确的做法是:AGENTS.md只负责告诉AI"去哪里看、按什么流程做",相当于一个入口导航,而真正的知识、规则、隐性约定,全部放进docs/目录下对应的文件中。
具体来说,AGENTS.md至少应该包含这几部分内容:仓库采用的工作流是什么,AI进入仓库后必须先读哪些文件,没有change是否允许开始开发,哪些目录是受保护的,主要的命令入口是什么(比如/opsx:propose、/opsx:apply等)。
这里有一个判断标准:如果你的AGENTS.md变得越来越长,通常不是因为规则变多了,而是因为你没有把知识正确拆分到docs目录下。这时候就需要及时整理,把属于项目知识的内容迁移到docs/,让AGENTS.md始终保持简洁,只做导航作用。
实践二:把"隐性约定"单独文档化,避免踩坑
对于有历史包袱的Java Spring Boot项目来说,最危险的往往不是那些写在文档里的显式规则,而是那些"大家都知道,但没人写下来"的隐性约定。比如在我们这次实践中,就遇到了两个典型的隐性约定:status = null 和 status = 0 在历史语义上并不等价,前端在单元详情接口中,依赖contentResponse字段做回显。
这些隐性约定如果只存在于口头沟通中,AI基本不可能稳定推断出来,很容易在编码时出错,导致"本地能跑、联调出错"的问题。所以,最佳实践是:把所有容易导致联调失败的口头约定,单独沉淀到docs/architecture/implicit-contracts.md文件中。
而且要做到两件事:一是在OpenSpec的design.md阶段,就显式检查这些隐性约定,确保设计方案符合约定;二是在reviewer和verify阶段,把这些约定作为对齐依据,避免实现时偏离约定。
这一步做得好不好,几乎直接决定了AI产出代码的可落地程度。很多团队用AI编码时经常出现"代码能跑但不符合业务逻辑"的问题,核心原因就是没有把隐性约定显性化,AI不懂项目的历史包袱和业务潜规则。
实践三:OpenSpec只管"变更生命周期",不代替全部治理
很多人对OpenSpec的定位有误解,觉得它可以包揽所有的项目治理工作,但实际上,OpenSpec的定位非常明确:它只负责把需求变成change工件,并驱动change的生命周期,不负责代替其他的治理工作。
在Java Spring Boot项目中,我们推荐使用下面这条主流程来管理change的生命周期:/opsx:propose -> /opsx:apply -> /opsx:verify -> /opsx:archive。这四个步骤的职责的必须严格区分,不能混为一谈。
第一步,/opsx:propose:把需求拆成一个change,产出proposal.md、design.md、tasks.md三个核心文件。这里有一个非常重要的实战经验:第一版proposal往往不靠谱,不要急着执行。它更像第一轮工作草案,而不是最终方案。如果proposal拆错了,宁可废弃当前change,重新生成新的change,也不要硬着头皮继续做,否则后续会出现更多问题,返工成本更高。
第二步,/opsx:apply:根据已经确认过的design.md和tasks.md实施代码改动。这一步的重点不是"让AI尽量多写代码",而是"只做tasks.md范围内的事",不允许AI自行扩展需求,每完成一个里程碑,就自动跑一次检查,确保代码没有偏离设计方案。
第三步,/opsx:verify:核对"实现有没有和OpenSpec工件对上"。这里要特别注意,verify的作用非常重要,但也非常有限:它不是代码评审,也不是架构评审,只负责检查实现与change工件(proposal.md、design.md、tasks.md)是否一致,不负责检查代码质量、架构合理性等内容。
第四步,/opsx:archive:把当前change归档,保持openspec/changes/目录下的进行中上下文干净,方便后续进入下一个change。很多团队会忽略这一步,导致openspec/changes/目录下堆满了已完成的change,后续查找和管理非常麻烦。
实践四:把"实现、评审、验证"彻底拆开,各司其职
这是Harness和普通AI编码方式最大的区别之一,也是确保AI编码可控的核心。在真实的项目开发中,下面这几件事绝对不能混在一起:需求拆解、代码实现、OpenSpec对齐校验、架构审查、SQL风险审查、面向PR的人工阅读摘要。
最佳实践是把它们拆成不同的职责,让每个环节只专注于自己的核心任务:
-
/opsx:verify:只负责检查"实现有没有和OpenSpec对上",确保代码实现没有偏离需求拆解和设计方案; -
/prepare-review:只负责整理"这次到底改了什么",生成PR前的评审摘要,方便人工快速了解变更内容,提高评审效率; -
/spring-architecture-review:只负责检查Spring分层架构有没有乱,比如Controller里写业务逻辑、Service职责混乱等问题; -
/sql-risk-review:只负责检查SQL、Mapper、批量更新、索引和扫描范围等数据层风险,比如批量更新没有where限制、索引缺失等问题; -
reviewer子代理:只负责做一轮独立、只读、偏代码审查视角的检查,重点关注代码质量、逻辑合理性等。
这样拆开的好处有两个:一是每种审查都有明确的目标,不会互相覆盖又互相遗漏,比如不会出现"检查了架构却忽略了SQL风险"的情况;二是出问题时更容易定位,到底是proposal有问题、实现有问题,还是架构/SQL有风险,不用在一堆混乱的流程中找原因。
实践五:真正的硬护栏,必须落在permissions + hooks
很多团队喜欢把规则写进提示词,然后默认AI会严格遵守,但在实际工程实践中,这种做法并不可靠。AI难免会有判断失误的时候,一旦提示词中的规则没有被遵守,就可能触碰高风险区域,导致线上事故。
最佳实践是:能通过权限系统和hook强制拦住的,就不要只靠提示词约束。提示词是"软约束",权限和hook才是"硬护栏",两者结合才能确保风险可控。
比如下面这些目录,在Java Spring Boot项目中属于高风险区域,一旦被误改,很可能导致线上故障:
src/main/resources/application*.yml、src/main/resources/bootstrap*.yml(配置文件,直接影响系统运行);
src/main/resources/db/、sql/(数据库脚本,误改可能导致数据丢失或错乱);
deploy/、infra/(部署相关文件,误改可能导致部署失败);
secrets/(密钥文件,泄露会导致安全风险)。
对于这些路径,我们建议直接在permissions.deny中禁止修改,同时在guard_write.py里再做一层路径校验,双重防护,确保即使AI判断失误,也无法修改这些高风险目录下的文件。
同理,对于Bash执行命令,也应该分层控制。像mvn test、mvn -q -DskipTests compile、mvn -DskipTests package、git status、git diff这类安全命令,可以放入permissions.allow中,允许AI执行;但像git push、kubectl、terraform、helm、rm -rf以及任何生产部署相关的命令,都应该默认禁止,避免AI误操作导致严重后果。
实践六:Hooks不只做拦截,还要做自动检查
在Claude Code场景下,hooks最有价值的地方,不只是阻止危险动作,还包括自动补上执行后校验,让"检查会不会跑"不再依赖模型自觉,而变成流程自动发生,减少人工干预。
我们在实践中,给hooks配置了三个核心功能,覆盖了"写入前、命令前、写入后"三个关键节点:
-
写入前校验:通过guard_write.py拦截受保护路径写入,一旦AI试图修改高风险目录下的文件,直接拦截并提示,不允许继续操作;
-
命令前检查上下文:通过ensure_change_context.py检查当前是否存在OpenSpec change,如果没有change,对高风险Bash动作直接提示确认,而不是默认放行,避免AI在没有需求拆解的情况下乱执行命令;
-
写入后自动跑检查:通过run_checks.sh在代码变更后自动执行编译检查、单元测试、打包检查,确保代码能正常编译、测试通过,避免出现"代码能写但无法运行"的问题。同时,对于文档类变更(比如修改docs/目录下的文件),可以跳过重检查,避免无谓的资源消耗。
这套设计的关键点是:把"被动检查"变成"主动触发",不管AI有没有意识到需要检查,流程都会自动执行,确保每一次变更都经过必要的校验,降低风险。
实践七:Skill和Subagent只做团队专用能力
很多团队会把所有能力都硬塞进主提示词里,导致主提示词越来越长,维护困难,而且不同团队的需求不一样,很多能力并不通用,强行塞进主提示词会造成冗余。
最佳实践是:把团队专用的能力,沉淀到.claude/skills/和.claude/agents/目录下,比如生成PR前的review摘要、检查Spring Boot分层架构、检查SQL风险、做一轮只读视角的reviewer审计等,这些能力都是团队在日常开发中高频使用的,而且具有团队特殊性,适合单独沉淀。
这样做有三个好处:一是可复用,以后每个change都可以重复调用这些能力,不用每次都重新写提示词;二是可组合,不同类型的需求可以只调用需要的能力,比如不需要SQL变更的需求,就可以不调用sql-risk-review这个skill,提高效率;三是可演进,团队后续可以持续补充自己的审查能力,比如新增"接口参数校验""异常处理规范检查"等skill,而不必频繁修改系统提示词,降低维护成本。
简单来说,主流程负责通用约束,skills/agents负责团队私有经验,两者分工明确,才能让Harness既规范又灵活。
五、标准工作流:从初始化到归档的完整流程
结合我们的实战经验,整理出了一套适合Java Spring Boot项目的Harness标准工作流,共7个步骤,从仓库初始化到change归档,形成完整闭环,团队可以直接复用,也可以根据自身项目情况微调。
第0步:初始化仓库(基础准备)
先通过openspec init --tools claude生成OpenSpec对应的基础目录结构,然后再补齐以下核心文件和目录,确保仓库结构符合Harness的要求:AGENTS.md、CLAUDE.md、REVIEW.md、docs/目录(重点补齐implicit-contracts.md)、.claude/settings.json、.claude/hooks/、.claude/skills/、.claude/agents/。
这一阶段的目标不是"立刻开始写代码",而是先把change生命周期、项目知识入口、权限和hook的承载位置搭好。如果这个骨架没立起来,后面的流程就很容易重新滑回"想到哪改到哪"的无序状态。
第1步:创建change(需求工件化)
执行/opsx:propose命令,让需求先变成change工件,生成proposal.md、design.md、tasks.md三个核心文件。这一步的核心是"需求拆解",把模糊的需求变成清晰、可执行的方案,避免后续开发偏离需求。
第2步:人工审proposal/design/tasks(关键把关)
这一步绝对不能省,是控制风险的关键。人工重点检查三个方面:一是需求边界是不是对的,有没有遗漏或多余的内容;二是是否遗漏了项目中的隐性约定,确保设计方案符合项目历史包袱;三是是否把多个问题错误混成一个change,避免change过大、边界不清;四是tasks.md是否足够可执行,每个任务节点都要明确、具体,让AI知道该做什么。
第3步:必要时废弃change重来(及时止损)
如果proposal拆错了,或者design方案不符合需求,不要勉强修补。直接废弃当前change,重新生成新的change,往往更省成本。我们在实战中就遇到过多次第一版proposal不符合需求的情况,及时废弃重来,避免了后续更大的返工。
第4步:执行/opsx:apply(代码落地)
基于已确认的proposal.md、design.md和tasks.md,执行/opsx:apply命令,让AI实施代码变更。这一步要注意,AI只能做tasks.md范围内的事,不允许自行扩展需求,每完成一个任务节点,就自动跑一次检查,确保代码符合设计方案。
第5步:跑专项审查(风险排查)
代码落地后,依次执行专项审查,不建议一次性打包调用,分开执行更清晰、更可控:
-
/prepare-review:生成PR前的评审摘要,整理本次变更的核心内容,方便人工评审; -
/spring-architecture-review:进行Spring分层架构审计,检查分层是否混乱,比如Controller写业务逻辑、Service职责过重等问题; -
/sql-risk-review:进行数据层和SQL风险审计,检查SQL语句是否有风险、Mapper配置是否合理、批量更新是否有where限制等; -
@"reviewer (agent)":让reviewer子代理做一轮独立、只读的代码审查,重点关注代码质量、逻辑合理性等。
第6步:执行/opsx:verify(对齐校验)
专项审查完成后,执行/opsx:verify命令,确认代码实现是否和OpenSpec change工件(proposal.md、design.md、tasks.md)对齐,确保没有偏离需求和设计方案。如果发现不一致,及时修改代码,重新执行verify,直到对齐为止。
第7步:归档(闭环收尾)
所有检查都通过后,执行/opsx:archive命令,对当前change进行归档,将其移动到openspec/changes/archive/目录下,保持进行中change目录的干净。到了这一步,这个change才算从"提出需求"走到了"完成闭环"。
六、实战复盘:一次真实change的完整执行过程
前面讲的都是方法论,下面把我们这次Harness落地中的真实执行过程保留下来,方便大家更直观地理解:一条change在项目里到底是怎么从初始化、拆解、修正、执行、审查一路跑完的。这些细节比单纯的方法论更有参考价值,因为它能让你看到实际落地中会遇到的问题和解决方式。
1. 初始化仓库:先搭骨架,再填内容
首先通过openspec init --tools claude生成OpenSpec对应的基础目录结构,然后我们开始补齐AGENTS.md、CLAUDE.md、REVIEW.md这三个核心文件,明确AI的导航规则和行为规范。接着,我们重点完善了docs/目录,尤其是docs/architecture/implicit-contracts.md,把项目中所有的隐性约定都整理进去,比如前面提到的status字段语义、前端依赖的contentResponse字段等。最后,我们配置了.claude/settings.json、hooks、skills和agents,搭建好硬护栏和团队专用能力。
这一阶段我们花了大概1天时间,没有急于写代码,而是先把仓库骨架搭好。事实证明,这一步的投入是值得的,后续的所有流程都能顺畅推进,没有出现因为结构混乱导致的效率低下问题。
2. 第一轮propose:快速成形,及时推翻
需求进入后,我们先执行/opsx:propose,让AI拆解对应change。很快,proposal.md、design.md、tasks.md等相关文件就生成了,但我们仔细审查后发现,第一版拆解并不符合真实需求------AI误解了部分业务逻辑,把两个不同的需求混在了一个change里,而且没有考虑到项目中的隐性约定。
这时候我们没有勉强继续,而是直接废弃了这个change。这也是Harness很重要的一条经验:proposal不是生成出来就要执行,第一版不对,就应该及时推翻,避免后续返工。
3. 第二轮propose:重新拆解,持续细化
第一版废弃之后,我们重新执行/opsx:propose,生成新的change。但第一次生成后仍然不满足需求,AI还是没有完全理解业务边界。于是我们开始持续补充上下文,把项目的业务逻辑、隐性约定、需求边界一一告诉AI,让它修正理解偏差。
随后,AI生成了新的proposal.md,我们再次审查,发现还是有部分细节遗漏,于是继续补充业务信息,让AI进一步修正。这一阶段反复调整了3次,才最终确定了符合需求的proposal。
这个过程非常能体现Harness的现实意义:AI可以很快把change搭出一个骨架,但proposal的质量,高度依赖你有没有把真实业务边界和上下文交代清楚。AI不是万能的,它需要明确的指引,才能产出符合需求的方案。
4. 进入design:自动生成是起点,人审是关键
在确认了proposal的边界和逻辑之后,我们让AI继续生成design.md,明确具体的技术实现细节。design.md生成后,我们开始人工审计,发现其中存在一些错误和遗漏,比如部分SQL语句的逻辑不符合数据库规范,Spring分层设计有问题,没有考虑到异常处理场景。
于是我们开始修正design.md,补充异常处理逻辑,调整SQL语句,优化Spring分层设计。这不是一次就结束的,而是多轮审计、持续修正,前后调整了2次,才最终确定了符合要求的design方案。
这里出现了一个非常典型的问题:由于proposal中已经把范围限定在adunit/save、adunit/update两个接口,AI始终无法稳定判定到素材相关的逻辑,无论我们怎么补充上下文,AI都容易偏离范围。
最后的处理方式是:当前change先只处理adunit/save、adunit/update范围内的逻辑,素材相关的逻辑后续再单独开一个change。这样一来,change的边界变得清晰,AI也能准确理解需求,后续的执行过程也顺利了很多。
这一段过程,正好印证了一条非常重要的最佳实践:当模型始终无法稳定理解某块逻辑时,优先怀疑的往往不是模型能力,而是change边界定义得不够清楚。这时候,拆分change比强行让AI理解更高效。
5. verify、apply和专项审查:分开执行,各司其职
在任务边界清晰、design方案确认之后,我们先让子代理@"reviewer (agent)"通过/opsx:verify做了一轮验证,确认design方案符合OpenSpec约定,没有偏离需求。随后,我们正式执行/opsx:apply,让AI开始落地代码。
代码落地之后,我们没有把所有审查动作一次性打包调用,而是依次跑专项审查:
首先执行/prepare-review,生成PR前的评审摘要,整理出本次变更的核心内容、修改的文件、新增的功能,方便后续人工评审;
然后执行/spring-architecture-review,进行Spring分层架构审计,发现AI在Controller里写了少量业务逻辑,我们及时修正,把业务逻辑迁移到Service层;
接着执行/sql-risk-review,进行数据层和SQL风险审计,发现一个批量更新语句没有where限制,这是典型的事故隐患,我们立即补充where条件,避免后续出现数据错乱问题;
之后,让@"reviewer (agent)"再做一轮只读审计,重点检查代码质量和逻辑合理性,发现部分异常处理不完整,我们补充了异常捕获和返回逻辑;
最后,我们再执行一次/opsx:verify,检查代码实现是否仍然和OpenSpec工件一致,确保所有修改都没有偏离需求和设计方案。
这一步最值得强调的是:verify、review、架构审查、SQL审查不是一回事,它们有各自的职责,分开编排更清晰、更可控,也更方便定位到底是哪一个环节出了问题。如果把所有动作混在一起,一旦出现问题,很难快速找到原因,会浪费大量时间。
6. 最后归档:完成闭环
所有审查都通过,代码也已经提交测试,确认没有问题后,我们执行/opsx:archive命令,对当前change进行归档,将其移动到openspec/changes/archive/目录下。到这一步,这个change才算真正完成,从需求提出到代码落地、审查归档,形成了完整的闭环。
7. 实战过程的核心感悟
把这段过程保留下来,比只讲方法论更有价值,因为它更直观地说明了几件事:
第一,第一版proposal往往只是草案,不能盲目执行,人工审查必不可少,而且要敢于废弃错误的change,及时止损;
第二,design阶段的人审,通常比apply后返工便宜得多,在design阶段发现并修正问题,能节省大量的后续返工成本;
第三,/opsx:verify不是万能审查,它必须和review、架构审查、SQL审查分开,各司其职,才能全面覆盖风险;
第四,当某块逻辑始终解释不清时,宁可拆change,也不要把所有问题硬塞进一个change,清晰的边界是高效执行的前提。
换句话说,Harness的价值不只是"让AI参与开发",而是让整个开发过程变成可拆解、可回退、可审计、可复用、可沉淀的流程,这才是它能真正融入生产研发的核心原因。
七、重点关注:Java Spring Boot项目最值得加护栏的5个地方
并不是所有限制都无脑加越多越好,约束太多会降低效率,约束太少会增加风险。我们始终认为,在限制中保持简洁,AI才能更好地工作。结合Java Spring Boot项目的特点,下面这些坑最值得优先考虑加护栏,也是我们在实战中遇到的高频问题。
1. Controller写业务逻辑
这是Java Spring Boot项目中最常见的"脏问题",很多开发人员(包括AI)都会习惯性地在Controller里写业务逻辑,导致分层混乱、代码复用性差、维护困难。所以,我们需要在CLAUDE.md、REVIEW.md、reviewer子代理、spring-architecture-review这个skill中同时卡住,明确规定Controller只能负责接收请求、返回响应,不能包含任何业务逻辑,业务逻辑必须放在Service层。
2. 直接改SQL/配置/数据库脚本
这类改动往往"本地能跑,线上出事",比如修改配置文件导致系统启动失败,修改SQL脚本导致数据丢失,修改数据库脚本导致表结构异常。所以,我们应该通过permissions.deny、guard_write.py、database.md、sql-risk-review这个skill多层保护,禁止AI直接修改这些高风险文件,如需修改,必须经过人工审批,重新生成change,按流程执行。
3. Service过胖,职责混乱
这类问题很容易在AI连续补代码时越滚越大,一个Service负责多个不相关的业务逻辑,导致代码臃肿、逻辑混乱、难以维护。我们需要靠reviewer子代理和spring-architecture-review这个skill持续盯住,一旦发现Service职责混乱,及时拆分Service,明确每个Service的核心职责。
4. 测试只跑happy path
这是很多项目的通病,AI在写测试用例时,也容易只考虑正常场景,忽略异常场景、边界场景,导致测试覆盖率不足,潜在bug无法被发现。所以,我们至少要在testing.md和review摘要里明确:本次变更跑了哪些测试,哪些场景没有测,为什么当前可以接受,避免测试流于形式。
5. 批量更新没有where限制
这类问题不是bug,而是事故预告。一旦批量更新没有where限制,会导致全表数据被修改,造成严重的数据错乱,甚至无法恢复。所以,在数据库规范(database.md)和SQL风险审查(sql-risk-review)里,必须把它作为显式检查项,一旦发现,直接拦截,不允许执行。
八、实战补充:3条千金难买的落地经验
除了前面讲的结构设计和最佳实践,这次Harness落地还有3条很重要的经验,这些经验不是来自理论,而是来自实际操作中的踩坑和总结,对后续团队落地Harness非常有帮助。
1. 第一版proposal通常只是草案,人工审查不能省
AI很容易先产出一个"结构看起来合理、业务边界其实不对"的proposal,尤其是对于有历史包袱、业务逻辑复杂的项目,AI很难一次性理解所有细节。因此,proposal阶段的人工审查,绝对不能省,而且要仔细审查,重点关注需求边界、隐性约定、change拆分是否合理,避免后续出现更大的问题。
2. design阶段修正,比apply后返工便宜得多
一旦进入apply阶段,错误就开始变成代码、测试和联调成本,此时再修正错误,需要修改代码、重新测试、重新联调,耗时耗力。而在design阶段,错误还只是"方案上的问题",修正起来只需要调整设计方案,成本低、效率高。所以,最值得花时间的地方,其实是design阶段,多花一点时间审查和修正design方案,能节省大量的后续返工成本。
3. change边界不清时,宁可拆成多个change
如果模型始终无法稳定理解某块逻辑,通常不是因为它"再多想一轮就会懂",而是因为当前change边界定义得不够好,包含了太多不相关的内容,导致AI无法抓住重点。这时候,最佳实践不是继续硬压AI理解,而是把复杂问题拆开,先让change边界变清晰,一个change只负责一个明确的需求,这样AI能更准确地理解需求,执行效率也会更高。
九、团队落地:推荐的3阶段实施顺序
如果团队想逐步引入这套Harness,不建议一次性全部落地,那样成本太高,也容易出现混乱。我们建议按下面3个阶段落地,循序渐进,逐步完善,让团队有一个适应的过程。
第一阶段:最小可用版(1-2周)
先上最核心的几个组件,把"变更工件化"和"隐性约定显性化"跑通:
-
OpenSpec:搭建openspec/目录,使用
/opsx:propose -> /opsx:apply -> /opsx:verify -> /opsx:archive流程管理change; -
AGENTS.md:编写AI导航地图,明确AI的基础流程和入口;
-
CLAUDE.md:编写Claude系统提示词,规范AI的基础行为;
-
docs/architecture/implicit-contracts.md:整理项目中的隐性约定,让AI了解项目历史包袱;
-
reviewer子代理:实现基础的只读评审能力,辅助人工审查。
这个阶段的目标是:让每一次需求变更都能变成change工件,有明确的拆解和记录,AI能了解项目的隐性约定,避免出现"联调出错"的问题。
第二阶段:补硬护栏(2-3周)
在第一阶段的基础上,增加硬护栏,让高风险动作可控:
-
permissions:配置权限,禁止AI修改高风险目录和文件;
-
guard_write.py:实现文件写入保护,拦截高风险路径写入;
-
ensure_change_context.py:实现上下文变更保护,检查change是否存在;
-
自动检查:配置run_checks.sh,实现代码变更后自动执行编译、测试、打包检查。
这个阶段的目标是:通过权限和hook,强制拦住危险动作,让AI的操作始终在安全范围内,减少人工干预的成本。
第三阶段:补团队专用能力(持续迭代)
最后,补充团队专用的skills和agents,让流程真正变成可复用的工程能力:
-
prepare-review:实现PR前评审摘要生成能力;
-
spring-architecture-review:实现Spring分层架构检查能力;
-
sql-risk-review:实现SQL风险审查能力;
-
其他团队私有skills/agents:根据团队需求,新增接口参数校验、异常处理规范检查等能力。
这个阶段的目标是:沉淀团队的私有经验,让Harness更贴合团队的实际需求,进一步提高开发效率和代码质量,减少人工审查的工作量。
十、附录:可直接复用的Harness检查清单
为了方便团队落地和自查,我们整理了一份可直接复用的检查清单,涵盖仓库层、流程层、风险层三个维度,对照这份清单,就能快速判断你的Harness是否具备了在真实项目里稳定运行的基础。
仓库层检查清单
⬜ 是否有docs/architecture/implicit-contracts.md
⬜ 是否有openspec/changes/目录
⬜ 是否有.claude/settings.json
⬜ 是否有hooks、skills、agents目录
流程层检查清单
⬜ 没有change时,不允许直接开始开发
⬜ proposal/design/tasks是否经人工审计
⬜ apply后是否自动跑检查
⬜ verify是否独立执行
⬜ change完成后是否archive
风险层检查清单
⬜ 高风险目录是否已deny
⬜ SQL/Mapper是否有专项风险检查
⬜ 测试缺口是否被显式说明
⬜ Spring分层是否有独立审查
⬜ 隐性约定是否在docs中显性记录
如果这些项大部分都能满足,说明你的Harness基本已经具备了在真实项目里稳定运行的基础。如果有遗漏,可以对照清单逐步完善。另外,我们这次实践的相关配置文件也已经打包好了,大家可以用于参考,公众号后台回复「20260401」即可获取。
最后:别被新词吓到,Harness的本质是工程实践的沉淀
说实话,最近Harness这个词一出来,营销号铺天盖地的宣传,导致很多人都会有点慌,觉得这又是一个新的风口,自己如果不跟上,就会被淘汰。但其实,Harness真的没那么吓人。
因为我们以前做项目的时候,也一直在做差不多的事。我们会定开发规则,会加权限限制,会做代码审查,会留回退方案;会告诉工具什么能做,什么不能做;什么可以自动跑,什么一定要人来拍板。这些事,我们以前就在做,只是那时候没有一个很统一的名字,把它们都组织到一起。
所以我想说,别被新词吓到。Harness不是突然从天上掉下来的东西,它更像是我们早就懂、早就在做的一些工程经验,现在终于被定义出了名字,被系统梳理成了一套可复用的流程。
只是到了AI coding时代,这件事反而更重要了。因为AI很像一个特别能干的小帮手,做事快,写东西也快,但它快不代表它每次都对,它能做很多事也不代表它知道哪条线不能碰。所以我们要给它规则,给它边界,给它检查,也给它刹车。这其实就是Harness思想最有价值的地方:不是让AI随便冲,而是让它在可控的路上跑,让AI真正成为提升团队效率的工具,而不是增加风险的隐患。