先写代码,再反推“正确“ —— 在遗留Java迁移中发现AI生成代码品质控制框架
AI帮我写了代码,跑通了,然后我遇到了真正的问题
在将一个JDK8遗留系统升级到JDK17的过程中,我需要一个工具来自动替换jdeprscan扫出的数百处包装类构造器调用:
new Boolean(flag) → Boolean.valueOf(flag) new Integer(value) → Integer.valueOf(value)
括号嵌套、字符串内的括号、注释内的括号——简单的正则替换搞不定。我和AI对话设计方案,实现了括号平衡的状态机,用Python写了18个测试用例全部通过,移植到PowerShell 5.1,在实际环境中跑通了。
工具完成了。问题出现在下一步。
"我想让公司内部的AI也能生成同样的工具。"
我的环境中,与社内AI的交互只能通过邮件——发送规格书,接收生成的代码。没有实时对话,没有在线调试。我需要写一份文档,让另一个AI"重做"我手里已经验证通过的东西。
一开始我觉得很简单——写份设计文档发过去就好了。但很快我发现:
"写出能运行的代码"和"解释清楚为什么这段代码是对的",是完全不同的两种能力。
代码在跑,测试在过。但当我试图把"它为什么是对的"描述到另一个AI也能重现的程度时,我发现自己对这个"正确性"的理解远没有自己以为的那么清晰。
一段预期之外的旅程从这里开始了。
转折:"从代码倒推正确性"
在某个时刻,我说了这样一句话:
"我们应该先把代码写完并测试通过,再从那个版本的代码反向生成提示词规格书。"
这看起来只是调整了工作顺序。但回头看,这句话改变了整个项目的性质。
代码不再是目的。代码变成了提取"什么叫正确"的素材。
面对已经通过测试的代码,我开始反问自己:
-
这段代码是正确的,因为它满足了哪些条件?
-
这段代码会坏掉,是在哪些条件被打破的时候?
-
要让另一个AI重现这段代码的行为,最少需要传达什么?
回答这些问题的过程中,AI生成代码品质控制的5个设计决策逐渐浮出水面。
以下逐一展开。
品质控制 1:规模校准 — 判断问题到底有多大
发生了什么
这个项目最初有一份与其他AI对话产生的详细设计:4个阶段、5种CSV文件、独立的编号体系、分层的日志设计。
我做的第一件事是大幅缩减这个设计:
-
5种CSV合并为1个TSV
-
4个阶段简化为2个模式(scan / execute)
-
砍掉EvidenceDetail.txt(编辑器里直接跳转就好)
为什么这是品质控制
过度设计本身就是品质风险。 文件越多,需要维护的一致性越多。阶段越多,Bug藏身之处越多。机制越复杂,测试越难覆盖。
品质控制的第一步,是在写代码之前判断"为这个问题投入多少设计重量是合理的"。
框架层面的教训
AI会随着你的追问不断精细化设计,但它不会说"够了,该停了"。规模判断只能由人来做。
品质控制 2:外部参照 — 独立验证解法方向
发生了什么
在动手写代码之前,我先问了一个问题:"这个问题有没有人已经解决过了?"
找到了Comby,一个Apache-2.0的结构化代码搜索替换工具。它用一行命令就能做到我们要做的事:
comby 'new Boolean(:[args])' 'Boolean.valueOf(:[args])' .java
实际环境装不了Comby,但从它的源码中借鉴了两个核心设计:语言定义数据化(把注释和字符串的语法规则声明为数据结构)、不做完整的语法解析(只理解括号平衡和字符串/注释边界就够了)。
为什么这是品质控制
问AI"这个方案对不对",AI会说"对,很合理"。AI没有否定自己提案的动机。
Comby作为一个独立的、被社区验证过的参照系,确认了"括号平衡状态机"这个方向是业界已验证的方法。
框架层面的教训
不要信任AI的"您的方案是正确的"。解法的妥当性,要用AI以外的信息源来验证。
品质控制 3:行为锚定 — 用测试用例固定"正确"的定义
发生了什么
在写状态机实现之前,先定义了18个测试用例:
Case 03: 'new Boolean(")")' → 最后位置(字符串内括号被忽略)
Case 05: "new Boolean(flag // )\n)" → 最后位置(行注释内括号被忽略)
Case 10: 'new Boolean(flag' → -1(未闭合括号)
Case 18: 'new Boolean(x // comment)' → -1(行注释吞掉了右括号)
先用Python写代码让18个测试全部通过,再移植到PowerShell。
为什么这是品质控制
用自然语言写"请考虑括号平衡",不同的AI会有不同的理解。但 输入 → 期望输出 的对子没有解释空间。
测试用例是规格书中约束力最强的元素。 算法描述可以有歧义,测试用例不能。
这也是为什么后来的PromptSpec中,测试用例被放在算法描述之前。社内AI会把它当作"必须通过的目标",优先级高于自然语言指示。
框架层面的教训
"正确"不要用自然语言定义,用输入-输出对来定义。这是唯一在不同AI模型之间不会产生理解偏差的约束。
品质控制 4:地雷记录 — 把运行时发现的约束反馈到规格书中
发生了什么
本地测试全部通过的PowerShell脚本,在实际环境中接连碰壁。
问题1:.ps1文件乱码导致解析错误
PowerShell 5.1按系统默认编码(中文Windows是GB2312)读取脚本文件。UTF-8保存的文件中的日文注释乱码,导致语法解析失败。 → 解决:保存为UTF-8 with BOM。
问题2:Where-Object结果没有.Count属性
Set-StrictMode下,Where-Object返回单个对象时不是数组,没有.Count属性,直接报错。 → 解决:用@()包裹,强制转为数组。
问题3:TSV的跨行文本
new Integer(\n getValue()\n) 的OriginalText包含换行符,写入TSV后行错位,Phase 2无法正确读回。 → 解决:对OriginalText和ReplacementText做转义(\n → \\n)。
为什么这是品质控制
这些问题不可能通过事前告知AI来预防。用PowerShell 7知识生成的代码,在PowerShell 5.1的中文Windows上一定会崩。
关键不是"踩了坑",而是踩了之后怎么处理。三个问题全部写入PromptSpec的[MUST]区域,变成社内AI生成代码时的硬约束。
框架层面的教训
坑要踩了才能记录。记录下来的坑,就是下一个AI的
[MUST]约束。这个反馈循环是品质逐步提升的机制。
品质控制 5:变更隔离 — 显式锁定增量修改的影响范围
发生了什么
工具初版完成后,出现了新需求:"能不能识别出注释和字符串中的误报?"
我没有简单地对社内AI说"加一个判断功能"。而是写了一份结构化的增量规格书(ContextSpec.md):
要改的(3个函数):
-
Get-NonCodeRanges(新增) -
Find-HitsInFile(添加Context列) -
Export-PlanTsv/Import-PlanTsv(读写Context列)
不能动的(显式声明):
-
Find-MatchingParen -
Invoke-Scan -
Invoke-Execute -
Phase 2 执行逻辑整体
回归条件:
-
原有的18个括号平衡测试用例必须继续通过
为什么这是品质控制
AI倾向于追求"全局最优"。在添加新功能时,它可能会"顺手"优化现有代码,而这种优化可能破坏已有行为。
"这个函数不许改"和"这个函数请改成这样"是同等重要的指示。
框架层面的教训
对AI的变更指示,必须同时包含"改什么"和"不改什么"。显式声明不变的范围和回归条件,是防止增量修改失控的关键。
框架全景
将5个品质控制手段重新整理:
| 品质控制手段 | 回答的问题 | 时机 |
|---|---|---|
| 规模校准 | 为这个问题应该投入多少设计? | 设计之初 |
| 外部参照 | 解法方向是否妥当? | 实现之前 |
| 行为锚定 | "正确"具体指什么? | 与实现同步 |
| 地雷记录 | 哪些约束是事先不知道的? | 执行之后 |
| 变更隔离 | 修改会不会破坏已有的正确性? | 变更之前 |
值得注意的是,这5个手段在时间轴上分布在不同的位置。有的在设计开始时起作用,有的和实现同步,有的在执行后才浮现,有的在变更时才需要。品质不是在某一个工序中保证的,而是在整个开发生命周期中通过多个控制点的协作来实现的。
而最反直觉的一点是:这个框架是反向发现的。
我并不是设计好品质控制框架再去开发。而是在写代码、跑测试、踩坑、修复、写规格书的过程中,这5个控制点自然浮现了出来。先有正确答案,再从正确答案中倒推约束——这种"反向性"本身,就是这个框架的核心思想。
更广阔的视角
这个框架可能不仅适用于代码生成。
核心问题不是"让AI做什么",而是"如何定义正确性,如何围住正确性"。AI本质上倾向于依据上下文推断意图并自作主张,而不是严格遵循约束。当推断出错时,输出就变得不可预测。
用测试用例锚定行为。用禁止事项限制自由度。从验证过的成果物反向提取约束。变更时显式锁定影响范围。
这些是不依赖AI的善意或能力,而是通过结构化手段保证AI输出"正确"的方法。
而这些手段的精度,在你已经拥有一个正确答案之后,才能达到最高。
代码仓库
工具本体和规格书已在GitHub公开:
-
WrapperCtorReplace.ps1— 工具本体 -
PromptSpec.md— 从验证済みコード反向生成的提示词规格书 -
ContextSpec.md— 增量修改用规格书(变更隔离的实例) -
tool_full_test.py— Python等价逻辑验证测试
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)