返回 AI 资讯
把老项目交给 AI 重写:逐个函数改写加新旧对照的那套提示词打法
提示词案例2026-10-08风险:低

把老项目交给 AI 重写:逐个函数改写加新旧对照的那套提示词打法

近期一批逆向重建项目跑通了一套可复制的流程:不让 AI 一次重写整个项目,而是每个函数走完描述、契约、改写、对照检查四步。本文给出每一步的提示词写法、上千个函数怎么组织、以及哪些地方必须人工把关。

朋友接手了一个十二年前的订单系统,C# 写的,二十多万行,原作者早走了,文档只有一份三页的部署说明。他的任务是把它迁到新的技术栈上。

开评估会的时候,有人说"让 AI 重写一遍"。技术负责人当场否决:二十万行代码,AI 重写出来的东西你敢上线吗?出了问题算谁的?

这个否决是对的,但理由不对。问题不在于能不能让 AI 重写,而在于你怎么组织这次重写。最近一批项目给出了一个可复制的做法:不让它一次重写整个项目,而是逐个函数改写,并且每个函数都要求新旧对照检查。

先把"重写"这件事拆成能提示的四层

观察近期那些成功的逆向重建项目,会发现它们都不是一步完成的,而是分了层级:

第一层是描述。 不让 AI 改任何东西,只让它说清楚眼前这段代码是干什么的、输入输出是什么、依赖了哪些外部状态。

第二层是改写。 在这个函数边界内,用目标语言重新实现,要求保持行为一致。

第三层是对照检查。 拿新旧两份实现,逐个分支比较,列出差异,判断哪些是可接受的(比如浮点精度、调用约定),哪些是真正的逻辑错误。

第四层是组装和验证。 把通过检查的函数组装起来,跑集成测试。

绝大多数失败案例都栽在跳过第三层。AI 说"已完成",你就信了,然后 bug 在生产环境才暴露。

提示词第一层:只描述,不改

第一层的关键是把"理解"和"改写"彻底分开。提示词可以这样写:

  • 给定以下函数源码,只做三件事:说明它的功能、列出全部入参与返回值、列出它读写的所有外部状态(全局变量、文件、数据库、网络)
  • 不要改写、不要优化、不要提建议
  • 如果有任何一处行为你无法确定,明确标注"不确定",不要猜测

最后一句是整个提示词里最重要的。允许它说"我不知道",是防止它编造的第一道防线。没有这句话,模型会用最合理的猜测填满所有空白,而那些猜测在二十万行代码里是找不出来的。

这一层的产出应该是一份结构化描述,一个函数一份。别嫌慢,这层做得扎实,后面两层的返工率会低一个数量级。

提示词第二层:改写,但先定契约

第二层开始前,先把契约写出来。所谓契约就是:

  • 这个函数被调用的所有地方,以及调用方期望的行为
  • 边界条件:空输入、超长输入、异常输入分别怎么处理
  • 副作用:会不会写日志、会不会发消息、会不会改全局状态

然后提示词这样组织:

  • 这是函数 X 的描述和它的调用契约
  • 请用目标语言重新实现,必须满足契约中的每一条
  • 不允许改变任何可观测行为,包括异常类型、错误码、日志内容
  • 如果契约中有任何一条在目标语言里无法实现,停下来说明原因,不要自行取舍

"停下来说明原因"这一句是第二层的核心。历史上最惨的那次事故,是模型发现某个行为在目标语言里不好实现,就悄悄换了一种实现方式,编译通过、单测通过,上线三个月后在一个边缘场景下数据写错了。

提示词第三层:新旧对照,别信"已完成"

第三层是这套打法里区别于普通"让 AI 重写"的地方。做法是:

  • 这里有两份实现,A 是原始版本,B 是你改写的版本
  • 逐个分支比较 A 和 B 的行为,列出每一处差异
  • 对每处差异给出判断:行为等价 / 行为不等价 / 无法确定
  • 只输出差异列表,不要输出修改后的代码
  • 你没有把握的地方必须写"无法确定",不允许用"应该没问题"之类的表述

这里有个反直觉的点:要求它输出差异列表而不是新代码。让它输出代码,它会顺手把上一版的问题一起"修"掉,你就失去了对照。让它只做比较,它才会真的去看两份代码。

输出的差异列表应当人工过一遍。经验比例是:每 100 个函数里大概有 5 到 15 处"无法确定",这十几处就是你要重点看的地方,剩下 85 个可以快速通过。

怎么组织上千个函数

一个中型项目动辄几千个函数,靠人一条条喂提示词不现实。可行的工作流是这样:

先分桶。 按模块、按依赖层级分。叶子函数(不被别的函数依赖的)先做,被依赖多的后做。这样能保证做到某个函数时,它依赖的东西已经改完了。

编号和状态机。 每个函数一个编号,四个状态:未开始 / 描述完成 / 改写完成 / 检查通过。状态存在文件里,脚本读状态决定下一步做什么。

断点续跑。 这是必须的。几千个函数的任务一定会中断——上下文超限、API 报错、机器重启。状态存在磁盘上,重跑时从断点继续,不要从头来。

每个函数独立上下文。 不要让一个会话里处理几十个函数。上下文越长,模型越容易把前一个函数的假设带进后一个函数。一个函数一个干净的会话,慢但可靠。

迁移到你自己的老项目

这套打法不只适用于游戏逆向,也不只适用于换语言。下面这些场景都能用:

老系统迁移。 从 C# 到 Java、从 Python 2 到 Python 3、从 jQuery 到现代框架。契约层尤其重要——老系统的调用方往往依赖一些没写进文档的行为。

依赖库替换。 某个库停止维护,要把几千处调用换成另一个库。先描述清楚旧库的每一个用法,再逐个替换,最后对照检查。

技术债清理。 那些"能跑但没人敢动"的模块。用第一层先把它们描述出来,光是这一步就能让团队重新拥有这份代码的知识。

性能改造。 改写前先锁定行为契约,改造后逐分支对照,能保证优化没有改变语义。

法律与工程边界

这一段必须写,而且要写在前面。

逆向工程在不同法域下的合法性完全不同。基本共识是:你有权对自己合法拥有的软件做兼容性研究和修改,但你不能分发逆向得到的成果,也不能绕过技术保护措施。 具体到你所在的地区和具体用途,需要单独确认,不能套用别人的结论。

工程边界上也有几条硬线:

  • 不要在没有测试覆盖的模块上做批量改写。先补测试,再做迁移。
  • 不要让 AI 同时改写超过一个函数。批量改写等于放弃对照。
  • 不要在改写完之前删除原实现。新旧两份要并存到检查通过为止。
  • 不要跳过人工复核那十几处"无法确定"。那是这套流程里唯一真正需要人的地方。

一份可复制的检查清单

开工前:确认法律边界、确认测试覆盖、确认能回滚、把项目按依赖分层。

执行中:每个函数走完描述 → 契约 → 改写 → 对照四步,状态落盘,断点续跑,一个函数一个会话。

收尾时:全量跑集成测试,对"无法确定"的每一处做人工判定,保留原始实现直到测试全绿。

这套流程不会让重写变快很多,但它把"敢不敢上线"这个问题从玄学变成了清单。二十万行的老系统,按这个节奏做,一个三人小组大概能在两三个月内完成迁移,而且每一步都知道自己站在哪。

真正值钱的不是 AI 写的那些代码,是那份逐函数的差异列表——它第一次让团队看清楚,自己手上这套跑了十二年的系统,到底在干什么。

适合谁:维护老系统需要做技术栈迁移的工程团队、接手无文档遗留代码的开发者、正在做技术债清理的技术负责人

相关资讯