从暴力审查到 Harness 工程化:一个 AI 时代程序员的觉醒
一、无限 token 的日子
三月份那会儿,OpenAI 管得不严,基本算无限 token。我有时候出门或者洗澡之前就让 AI 直接审查整个项目,完全不用管消耗。反正 token 不要钱,那就使劲用。
那两个月确实做了很多东西。翻一下 git log:
2026年3-4月,46 个 commit:
重构(10 次):
认证链路重构了三遍,OSS 从存 URL 改成存 objectKey,
Excel 导入从一步到位改成两阶段,网关 ID 穿透加了数字签名,
user 服务内外接口拆分,验证码链路统一……
修复(26 次):
异常语义压平、错误码规范、并发状态覆盖、
Excel 解析边界、导入批次回滚、outbox 重试……
博客(7 篇):
《这两天我被验证码登录狠狠上了一课》
《异步AI链路-task-outbox-inbox复盘》
《从存URL到存objectKey》
《从单体全局异常处理到微服务错误契约》
……
产出是实打实的。但说实话,那种感觉很奇怪。
感觉一直在忙,又感觉什么都没沉淀下来。
模型干着干着就忘了上下文,上一轮讨论的结论下一轮就不认了。有时候它改着改着就绕回去了,你得反复提醒"我们之前说过这个"。上下文污染是常有的事。
最后沉淀下来的东西,说出来有点心虚:几篇博客,和一个非常深刻的认知——
复杂度不会消失,只会转移。
二、复杂度不会消失,只会转移
这个认知贯彻了我整个重构史。
Excel 导入:从一步到位改成两阶段(先校验再解析),校验的复杂度确实收敛了,但临时表、批次管理、清理任务这些新复杂度又冒出来了。
OSS 存储:从存 URL 改成存 objectKey,安全性提升了,但预签名、场景化签发、有效期配置又得重新设计。
AI 链路:从同步调用改成 outbox/inbox 异步,吞吐解决了,但双写一致性、状态机、回包幂等消费全来了。
异常处理:从单体的 BizException 统一收口,到微服务的错误契约,跨服务透传、异常码折叠、错误语义翻译又是一层。
每一步重构都是在解决上一步带来的新问题。最后我甚至追溯到了凤凰架构的架构发展史——从单体到 SOA 到微服务到事件驱动,每一次架构演进本质上都是在转移复杂度,不是消灭它。
不可否认这段经历给我带来了很多。这种认知不是读几篇文章就能有的,是你在代码里反复撞墙、反复重构、反复推翻自己的设计之后,才会刻进骨子里的。
但作为 AI 时代的程序员,只懂这个可能不太行。
复杂度转移是内功,是你对系统设计的理解。但你还需要外功——如何驾驭 AI,让它在你的项目里真正高效地工作,而不是每次都在"上下文污染 → 纠正 → 遗忘 → 再纠正"的循环里打转。
三、便宜模型审查的翻车现场
但先说句公道话:三四月重构确实成功了,一个重要原因是——我用的是顶级模型。 写代码这件事,模型能力就是第一杠杆。那段时期我虽然没有 harness,但顶级模型硬是扛住了。都重要, 只是写代码和审查代码,制胜因素不一样。
前段时间 OpenAI 发力了,无限 token 成了奢望。之前看到过一条评论,说"便宜的模型审查,顶级的模型写",当时无所谓,现在 token 紧了,想起来试试。
我用小米的 mimo 去审查整个项目,出了 16 条意见。让 Opus 4.7 逐条验证,结果——7 条误判,接近一半是垃圾。 另外还有 3 条是我说了暂时不改的,但 AI 不知道,照样提出来。
最典型的:单实例部署缺分布式锁。
每个 AI 都会提这个。但这就是我有意为之——当前就是单实例部署,加分布式锁纯粹多余。AI 不知道你的部署拓扑,它看到"调度器没有分布式锁",训练数据告诉它"这是个问题",它就报了。类似的还有 AuthController 缺少 @RequestMapping——网关 StripPrefix=1 的设计,加了反而冲突。
核心问题只有一个:AI 只会模式匹配,不会理解上下文。 训练数据里"缺分布式锁"大概率是问题,但当你的项目有特殊的取舍时,模式匹配就变成了噪音制造机。
四、脑子里蹦出三个关键词
那天审查翻车之后,心情很糟。
然后脑子里突然蹦出了几个关键词:harness、上下文工程、渐进式披露。
这些概念我之前都看过。我一直在关注 AI 工程领域的各种文章,阿里云公众号的那篇 AGENTS.md 实践指南我也早就收藏了,但当时就是粗略翻了翻,没有仔细看——觉得"道理我都懂"。
但那一刻不一样了。我刚踩完坑,有了真实的痛感。那些概念在我脑子里突然串起来了:
- AI 会模式匹配出垃圾 → 我需要给它约束,不让它报已知的误判
- AI 不知道我的上下文 → 我需要写一份上下文文档,告诉它哪些是有意为之
- 不能把所有规则一次性塞给它 → 我需要渐进式披露,需要时再深入
于是我又重新打开了那篇早就收藏的阿里云文章——《一个文件让 AI Coding 效率翻倍:AGENTS.md 实践指南》,这次是带着问题去读的。
这里不得不吹一下阿里云。听说阿里内部在疯狂使用 Claude,他们产出的那些技术文章质量真的很高。看别人的技术文档看到一定程度,自然就知道该怎么做了。概念不是用来背的,是用来在真实场景里"激活"的。你脑子里有了这些概念,踩完坑之后它们就会自己蹦出来,然后你只需要稍作修改就能落地。
同时我脑子里还浮现了一个核心原则:给约束,而非给 token。
五、落地:一套审查机制
当天晚上我就动手了。
AGENTS.md——地图,不是手册
写了 240 行,告诉模型:项目是什么、技术栈、模块结构、9 条硬性编码规则、Git 提交规范、异常码格式、docs/ 导航表。
关键原则:只写"AI 不知道就会写出错误代码"的信息。其他的,放链接。
审查指南——流程规范
规定了审查怎么审:三级严重度(🔴🟡🟢)、状态标记(✅已解决 / ⚠️可不改 / ❌误判)、汇总表、审查日志存档到 docs/review/logs/{日期}.md。
这样每次审查都有迹可循,不会审完就忘。
已知上下文——越用越聪明的记忆
这是最关键的一步。我建了一个 docs/review/已知上下文.md,里面记录了两类东西:
已知项(K)——代码确实如此,是有意识的取舍,当前选择不改:
| ID | 位置 | 说明 |
|---|---|---|
| K1 | QuestionOutboxDispatchScheduler |
缺分布式锁,当前单实例部署,暂不处理 |
| K2 | VerificationCodeServiceImpl |
短信发送逻辑已注释,验证码仅打日志,开发环境可接受 |
| K3 | ExcelParserUtil catch 块 |
抛 RuntimeException 而非 BizException,但 BizException 已单独 catch 原样抛出 |
| K4 | 多处包名拼写错误 | 计划单开分支统一修正,不与功能改动混提 |
| K5 | 密码写在配置文件 | 纯本地开发阶段,IP 未泄露,暂不处理 |
| K6 | internal.auth.secret 默认值 |
本地开发阶段,部署生产时在 Nacos 显式配置 |
已确认误判(W)——AI 的前提就不成立,根本不是问题:
| ID | 说明 |
|---|---|
| W1 | @ConditionalOnProperty(matchIfMissing=true) 不是疏忽,生产环境消费者必须默认注册 |
| W2 | JsonUtils.OBJECT_MAPPER 非 volatile,init() 仅启动时调一次,之后只读 |
| W3 | Redis increment + expireAt 无竞态,INCR 是原子操作 |
| W4 | AuthController 缺 @RequestMapping,网关 StripPrefix=1 设计,加了反而冲突 |
| W5 | @SneakyThrows 不是滥用,SDK IO 异常走全局异常处理器兜底 |
| …… | …… |
模型审查前先读这个文件,已知项直接跳过,误判项不再报告。
而且这个文档是活的。每次审查后,用户指出"这个不是问题",就写入上下文。下次审查就不会再犯。
这就是我开头说的那个问题的解法——“单实例部署缺分布式锁”,每个 AI 都会提。但你只要在已知上下文里写一句"当前单实例部署,暂不处理",它就不会再报了。
模型没变,上下文变了,结果就变了。
渐进式披露——需要时再深入
所有详细信息放在 docs/ 下,按功能目录组织:
AGENTS.md(240 行地图)
→ docs/review/审查指南.md(流程规范)
→ docs/review/已知上下文.md(历史决策)
→ docs/excel-import/(Excel 导入细节)
→ docs/question-chain/(题目处理链路)
→ docs/auth-gateway/(认证与网关设计)
→ ……
AGENTS.md 告诉模型"去哪找",docs/ 告诉模型"具体是什么"。需要时再深入,不需要时不浪费注意力。
六、效果:同样的模型,天壤之别
第二天,我用同级别模型,对同一个代码库,重新审查。
结果:6 条意见,0 条误判。
| 指标 | 无 Harness(5月7日) | 有 Harness(5月9日) | 变化 |
|---|---|---|---|
| 总意见数 | 16 | 6 | ↓ 62.5% |
| 误判数 | 7 | 0 | ↓ 100% |
| 误判率 | 43.75% | 0% | 从"一半垃圾"到"零误判" |
而且那 6 条全是真问题:编译失败、鉴权路径匹配错误、调试代码残留……
审查日志里,已知上下文匹配的地方直接标注:
QuestionOutboxDispatchScheduler缺分布式锁匹配 K1,未作为新问题重复报告。是否仍维持"当前单实例部署,暂不处理"的判断?
你不需要更好的模型,你需要更好的约束。
七、反思:AI 时代程序员最重要的能力
回头想想,三四月的重构教会我的是内功——复杂度不会消失,只会转移,这是对系统设计的深刻理解。五月的审查经历教会我的是外功——驾驭 AI 比使用 AI 更重要。
两者缺一不可。没有内功,你不知道该重构什么、该怎么取舍;没有外功,你只能靠堆模型能力和堆 token 来弥补上下文的缺失,不可持续。
翻来覆去,AI 工程领域的那些概念——harness、上下文工程、RAG、渐进式披露、Agent Workflow——名词不同,本质相同:
让模型在正确的上下文里做正确的事。
关键不是追新概念,而是落到一个真实场景去验证。多看别人的技术文档,看到一定程度自然就知道了。你脑子里有了这些概念,踩完坑之后它们就会自己蹦出来。
我写的 AGENTS.md、审查指南、已知上下文,说到底就是一件事:
给 AI 一个"带着约束干活"的环境。
约束是什么?是你的项目规矩,是你的架构取舍,是你的已知误判。AI 自由发挥的时候会犯很多错,但你把这些约束写清楚,告诉它"这些我知道,不用管",它就能把注意力放在真正的问题上。
你不需要无限 token,你不需要永远用最顶级的模型。
你需要的是一套让你的 AI "带着约束干活"的系统。写代码的时候,顶级模型是你的杠杆;审查代码的时候,上下文工程是你的杠杆。
知道什么时候用什么杠杆,这才是 AI 时代程序员最重要的能力。
这就是 Harness。
附:文中提到的审查日志与项目文件
两次审查的完整记录,供对照参考:
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)