Mistral 用 AI 编程代理将一家欧洲能源企业约4万行 Fortran 77 代码迁移到 C++,但重点在于通过数值一致性验证、模块化工作流和人工评审来确保结果可信。团队并未完全放手让代理自主改写,而是将代理用于理解、文档化和分步实现,保留人工在关键判断点的闸门。
Mistral AI于2026年9月9日公布的一篇官方案例文章显示,其应用团队曾帮助一家欧洲能源企业,将一套用于储层模拟的4万行Fortran 77代码迁移到C++。这不是一次逐行改写:由于原系统缺少测试套件和集中式文档,项目团队需要先理解代码和其中的物理逻辑,再把它重构为更容易维护的现代系统。
这起案例的重点并不只是迁移规模,而是Mistral对AI编程代理工作边界的描述。团队最终没有让代理完全自主地重写整个代码库,而是围绕数值一致性、文档、任务拆分和人工评审建立了一套受控流程。
从旧语言到现代系统,不是语法替换
Fortran 77于1977年标准化。Mistral指出,这类代码通常带有明显的时代痕迹:缺少模块、命名空间和结构化类型,程序状态可能保存在COMMON块中,由多个过程共享;变量还可能根据变量名首字母隐式确定类型,拼写错误因此不一定会立即触发编译错误。
把这样的代码转换为C++,表面上可以从语法入手,但真正的迁移往往涉及架构重构。原有的全局数组可能需要重新组织为具有明确边界的对象,调用关系和数据流也可能需要重新设计。Mistral给出的示例中,C++版本把分散的全局状态整理为一个GasProperties参数,并将网格循环移到调用方,而不是保留Fortran代码的逐行对应关系。
这种做法提高了可读性和可维护性,却也使验证更困难。若目标只是生成一份看起来像C++的代码,逐行比较还能提供某种参照;但当系统的结构和数据流都发生变化时,团队必须证明新的实现仍然产生相同的物理结果。
团队先搭建“数值一致性”验证框架
在让代理开始迁移之前,Mistral团队先建立了一个用于比较两个代码库的验证框架。旧Fortran程序被增加了导出状态的子程序,用来生成运行过程中的状态快照;C++一侧则使用测试框架读取这些检查点,对迁移模块的关键中间结果和最终输出进行比较。
这些检查点并不只覆盖最终答案。客户的储层工程师还标记了若干关键中间状态,团队据此检查迁移后的模块是否在计算过程中保持一致。Mistral称,这使数值一致性成为一种相对容易检查、也更有说服力的完成标准。
例如,旧程序可以在某次运行中输出RHOG变量的值,再把同一数值作为C++模块的参考检查点。这样的测试不能证明整个系统没有任何问题,但能够把“大规模迁移是否正确”拆解成一组可重复的局部判断。
这也与科学软件现代化中的普遍难题相呼应。AIFlux此前在科学计算进入代理式AI时代、但验证成为瓶颈的报道中提到,代码生成成本下降之后,确认结果是否符合科学目标,往往成为更昂贵的环节。
代理先帮助理解和记录旧代码
该项目的另一个障碍是知识分散。相关说明存在于旧PDF、源代码注释和代码本身的隐含行为中,而不是一套集中维护的开发文档里。
Mistral团队先通过自定义解析器生成整个程序的调用者—被调用者树。由于Fortran这类过程式程序可以较清晰地表示为调用关系树,团队随后使用Vibe CLI启动一百多个代理,为树中的节点补充文档。
这些代理从调用树的叶节点开始,逐步向上梳理代码。它们可以通过文档库读取相关PDF,并使用Mistral OCR处理材料;完成后,代理会向原代码库提交拉取请求。另一个循环运行的审查代理负责检查新提交的拉取请求,并在需要时安排修改任务。
这部分工作说明,代理在遗留系统中的价值并不局限于“写新代码”。在原作者已经离开、文档又不完整的情况下,建立可供人和后续代理使用的上下文,可能是迁移工作的前置条件。
三种工作方式之后,团队选择了中间路线
Mistral描述了三次不同的尝试。
第一次尝试给予代理较高自主权:每个Fortran子程序由一个代理独立迁移,持续运行一周。结果可以工作,但并不能称为现代化。原来的COMMON块被一对一地变成全局结构体,基于GOTO的控制流也基本保留,最终更像是“换成C++语法的Fortran”。
第二次尝试采用结构化的多代理分工,让规划、编码、测试和代码质量审查分别承担不同角色。Mistral表示,这一方案明显改善了代码质量,但复杂度最终仍会使代理陷入循环:它们遇到错误后尝试几次修复,随后停滞,却没有人介入解锁。
最终,团队选择了介于两者之间的方式:由人类工程师运行由编码、测试和审查代理组成的工作流,按模块推进迁移。这样既保留了结构化流程的质量,也保留了人工在代理卡住时介入的能力。
这种“代理负责执行、人类负责关键判断”的模式,也出现在其他大型代码迁移案例中。AIFlux此前对企业Java迁移基准ScarfBench的报道指出,代码能够编译,并不等于能够部署,更不等于行为与原系统一致。对遗留代码来说,运行时环境、配置、依赖和隐藏的业务规则都可能成为迁移失败的来源。
按模块推进,仍保留人工评审闸门
在验证框架和文档基础完成后,Mistral与客户的储层工程师共同根据调用树识别相对独立的模块。团队将这些模块定义为规模可控的子树,经验上单个模块少于约1万行Fortran。
每个模块先生成目标C++架构,再由储层工程师评审。架构获批后,团队将其拆分为任务队列,并为每项任务运行“规划—实现—测试—重复”的子工作流。代理生成的拉取请求仍需由人类审查,直到修改完成并合并。
Mistral称,第一轮工作覆盖了约4万行代码,而完整代码库规模约为30万行。项目之所以具备较好的起点,是因为这套Fortran代码库相对自包含,并且可以运行。对于没有可运行基线、依赖外部系统,或把关键物理知识写在无人维护的经验中的项目,迁移难度可能更高。
需要注意的是,上述规模、流程和结果均来自Mistral的厂商案例披露。公开材料没有提供独立第三方对迁移后系统的完整复现或性能评估,因此“4万行已迁移”应理解为项目阶段性范围,而不是对所有遗留科学代码迁移成功率的普遍证明。
AI降低了搬运成本,却没有消除责任
Mistral从这次项目中总结了三个原则:先建立数值一致性的验证框架,再编写迁移代码;在依赖代理之前先整理文档;在大规模项目中,结构化工作流和人工评审闸门优于完全自主运行或完全依赖手工操作。
这三点共同指向一个变化:AI代理可能降低代码理解、文档补全和重复重写的成本,但不会自动解决“什么才算正确”这个问题。对于储层模拟这样的物理系统,正确性不只意味着编译通过,还意味着中间状态、最终输出和领域知识仍然彼此一致。
因此,这起案例更适合被看作一种工程组织方式的展示,而不是AI可以无人监督完成遗留系统迁移的证明。代理可以并行处理大量局部任务,也可以协助人类从旧代码中恢复结构和知识;但架构选择、验收标准、异常处理以及最终合并,仍然需要能够理解领域风险的人承担责任。
当旧代码越来越容易被“翻译”时,真正稀缺的能力可能变成了建立可靠基线、设计可重复的验证,以及在自动化流程失效时知道何时暂停。对于复杂科学软件而言,现代化的终点不是得到一份新语言代码,而是得到一个能够被理解、被测试、被维护,并且仍然可信的系统。
来源:Mistral官方案例:Modernizing complex legacy code with AI agents。