先说结论:OpenAI 在 2026 年 10 月 19 日发布的《Advancing coding in low-resource programming languages》里公布,GPT-6.1 Sol 在它自己的 COBOL 迁移评测上,低推理强度准确率 86.6%,上一代 GPT-5.6 Sol 同设置只有 5.4%;调到更高推理强度能到 97.9%。这些都是 OpenAI 自己测的数。
我们自己也跑了一遍:用 Codex 接本站的 gpt-6.1-sol,把一个带定点金额计算和缺失记录处理的小 COBOL 程序迁到 Python。低推理强度 113 秒、高推理强度 221 秒,两次的迁移结果都和 GnuCOBOL 编译运行原程序的输出逐字节一致,各自生成的测试全部通过。
对维护银行、金融和传统企业老系统的程序员来说,这意味着 AI 迁移老代码已经能干活了,但前提是:先拿原程序跑出真实输出当基准,再让 AI 迁,再用测试逐字节对比。
两个评测怎么读
OpenAI 这次做了两个评测,测的是两种不同的能力:
- COBOL 迁移评测:把现有 COBOL 程序迁到 C++、Java、Kotlin、Python 或 Rust。用隐藏测试检查,要求可观察输出逐字节一致,所有测试都过才算这次迁移成功。测的是「保住老程序的行为」。
- MultiLangBench:让模型用指定语言从零写一个兼容 SQLite 的数据库引擎,覆盖 20 种语言,用 SQLite 改编来的测试检查通过率。测的是「在冷门语言里写新代码」。OpenAI 已把测试集放到 GitHub 上。
| 评测 | 对比 | 旧模型 | 新模型 |
|---|---|---|---|
| COBOL 迁移(低推理强度) | GPT-5.6 Sol → GPT-6.1 Sol | 5.4% | 86.6% |
| COBOL 迁移(更高推理强度) | GPT-6.1 Sol | — | 97.9% |
| MultiLangBench 20 种语言平均(最高推理强度) | GPT-5.6 Sol → GPT-6 Astra | 26.8% | 87.4% |
| MultiLangBench:COBOL | GPT-5.6 Sol → GPT-6 Astra | 10.9% | 72.1% |
| MultiLangBench:Fortran | GPT-5.6 Sol → GPT-6 Astra | 21.4% | 83.5% |
| MultiLangBench:Visual Basic | GPT-5.6 Sol → GPT-6 Astra | 27.5% | 89.4% |
数据来源:OpenAI 官方文章 https://openai.com/index/low-resource-programming-languages/ ,均为 OpenAI 自己的评测结果。COBOL 在 MultiLangBench 里仍是最难的一门语言。
OpenAI 在文中也专门提醒:COBOL 的定点运算默认会丢掉多余的小数位,除非显式写了 ROUNDED;如果重写时改成了四舍五入,程序照样能跑、不报错,但金额会不一样。上生产前仍然需要专家复核,并按系统的业务规则和依赖做测试。
实操:用 Codex + gpt-6.1-sol 迁移一个 COBOL 程序
① 创建 API Key
在本站注册登录后,进控制台创建一个 API Key,复制下来备用。
② 配好 Codex
Codex 的安装方法见 Codex 接入配置教程。装好后编辑全局配置文件 ~/.codex/config.toml:
model_provider = "aicodewith"
model = "gpt-6.1-sol"
model_reasoning_effort = "low"
[model_providers.aicodewith]
name = "aicodewith"
base_url = "https://api.aicodewith.ai/chatgpt/v1"
wire_api = "responses"
experimental_bearer_token = "sk-你的Key"
把 sk-你的Key 换成上一步复制的 Key。model_reasoning_effort 就是推理强度,low 和 high 都可以写;也可以不改文件,在命令行用 -c model_reasoning_effort=high 临时切换。更多配置项见 config.toml 配置详解。
我们实测时先直接调用了一次接口,返回的模型 id 是gpt-6.1-sol,Codex 运行日志里显示的也是model: gpt-6.1-sol。
③ 准备 COBOL 示例,先跑出原程序的基准输出
示例程序读两个文件:accounts.dat 是账户和利率,txns.dat 是交易金额。每笔交易按利率算利息(COMPUTE 没写 ROUNDED,所以会截断),找不到账户的交易记一次缺失并跳过,最后输出合计。
IDENTIFICATION DIVISION.
PROGRAM-ID. INTEREST.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ACCT-FILE ASSIGN TO "accounts.dat"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT TXN-FILE ASSIGN TO "txns.dat"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD ACCT-FILE.
01 ACCT-REC.
05 A-ID PIC X(4).
05 A-RATE PIC 9V9999.
FD TXN-FILE.
01 TXN-REC.
05 T-ID PIC X(4).
05 T-AMT PIC 9(7)V99.
WORKING-STORAGE SECTION.
01 WS-EOF PIC X VALUE "N".
01 WS-N PIC 99 VALUE 0.
01 WS-I PIC 99.
01 WS-FOUND PIC X.
01 WS-TABLE.
05 WS-ENT OCCURS 20 TIMES.
10 WS-ID PIC X(4).
10 WS-RATE PIC 9V9999.
01 WS-INT PIC 9(7)V99.
01 WS-TOTAL PIC 9(9)V99 VALUE 0.
01 WS-MISS PIC 99 VALUE 0.
01 D-AMT PIC Z,ZZZ,ZZ9.99.
01 D-INT PIC Z,ZZZ,ZZ9.99.
01 D-TOT PIC ZZZ,ZZZ,ZZ9.99.
PROCEDURE DIVISION.
OPEN INPUT ACCT-FILE
PERFORM UNTIL WS-EOF = "Y"
READ ACCT-FILE
AT END MOVE "Y" TO WS-EOF
NOT AT END
ADD 1 TO WS-N
MOVE A-ID TO WS-ID(WS-N)
MOVE A-RATE TO WS-RATE(WS-N)
END-READ
END-PERFORM
CLOSE ACCT-FILE
MOVE "N" TO WS-EOF
OPEN INPUT TXN-FILE
PERFORM UNTIL WS-EOF = "Y"
READ TXN-FILE
AT END MOVE "Y" TO WS-EOF
NOT AT END PERFORM PROCESS-TXN
END-READ
END-PERFORM
CLOSE TXN-FILE
MOVE WS-TOTAL TO D-TOT
DISPLAY "TOTAL INTEREST " D-TOT
DISPLAY "MISSING ACCTS " WS-MISS
STOP RUN.
PROCESS-TXN.
MOVE "N" TO WS-FOUND
PERFORM VARYING WS-I FROM 1 BY 1
UNTIL WS-I > WS-N OR WS-FOUND = "Y"
IF WS-ID(WS-I) = T-ID
MOVE "Y" TO WS-FOUND
COMPUTE WS-INT = T-AMT * WS-RATE(WS-I)
ADD WS-INT TO WS-TOTAL
MOVE T-AMT TO D-AMT
MOVE WS-INT TO D-INT
DISPLAY T-ID " " D-AMT " INT " D-INT
END-IF
END-PERFORM
IF WS-FOUND = "N"
ADD 1 TO WS-MISS
DISPLAY T-ID " MISSING ACCOUNT - SKIPPED"
END-IF.
两个数据文件内容如下,注意第三笔交易的账户 A009 并不存在:
accounts.dat
A0010035
A0020125
A0030399
txns.dat
A001000123456
A002000099999
A009000050000
A003001234567
A001000000099
基准输出一定要用真编译器跑出来,不能让 AI「推算」。在 Debian/Ubuntu 上装 GnuCOBOL,编译运行:
sudo apt-get install -y gnucobol
cobc -x INTEREST.cbl
./INTEREST > expected_output.txt
我们用 GnuCOBOL 3.2.0 跑出来的真实输出:
A001 1,234.56 INT 43.20
A002 999.99 INT 124.99
A009 MISSING ACCOUNT - SKIPPED
A003 12,345.67 INT 4,925.92
A001 0.99 INT 0.03
TOTAL INTEREST 5,094.14
MISSING ACCTS 01
看前两行就知道截断有多关键:1,234.56 × 0.035 = 43.2096,COBOL 给的是 43.20,四舍五入会是 43.21;999.99 × 0.125 = 124.99875,COBOL 给的是 124.99,四舍五入会是 125.00。
④ 让 Codex 迁到 Python,并生成逐字节比对测试
在放这几个文件的目录里(建议先 git init 提交一次,方便回看改动),运行:
codex exec "把 INTEREST.cbl 迁移成 Python 3(interest.py),要求输出和原 COBOL 程序逐字节一致(包括定点运算截断、金额格式、缺失账户处理)。expected_output.txt 是用 GnuCOBOL 编译运行原程序得到的真实输出。再写一个 test_parity.py:运行 interest.py,把 stdout 和 expected_output.txt 逐字节比较,并额外构造几条会暴露“四舍五入 vs 截断”差异的测试数据,用 cobc 编译原程序跑出期望值做对比。最后运行测试并报告结果。"
想迁到 Java,把提示词里的 Python 3 和文件名换掉即可,比对测试的思路一样。日常怎么跟 Codex 交互,可以看 Codex 怎么用。
低推理强度那次生成的核心计算是这样的,它用整数「分」来算,并用整除实现截断,注释里也写明了原因:
amount = number(record[4:13])
# No ROUNDED clause: discard fractional cents before adding to total.
# Assignment to unsigned PIC fields also discards excess high digits.
interest = (amount * rates[account] // 10_000) % 1_000_000_000
total = (total + interest) % 100_000_000_000
生成的测试里专门挑了会让截断和四舍五入结果不同的边界值(比如乘出来是 0.5 分、1.5 分、0.9999 分),每组都现场用 cobc 编译原程序算期望值,而不是自己写死答案。
⑤ 低、高两档各跑一次
同一份提示词、同一份文件,分别用 -c model_reasoning_effort=low 和 -c model_reasoning_effort=high 各跑一次。结果:
| 推理强度 | 耗时 | 生成的测试 | 和原程序逐字节一致 |
|---|---|---|---|
| low | 113 秒 | 6 项,全部通过 | 是 |
| high | 221 秒 | 11 项,全部通过 | 是 |
跑完后我们又自己在终端里把 python3 interest.py 的输出和 expected_output.txt 用 cmp 对了一遍,两次都完全一致。
两档的区别主要在测试覆盖:high 档额外测了 Windows 换行、末行无换行、超长行被切成多条记录等文件格式边界,并另做了 5,000 笔随机交易对比。这么小的程序 low 档已经够用;程序越大、边界情况越多,越值得开 high。
必看的坑
截断和四舍五入
COBOL 的 COMPUTE 不写 ROUNDED 就截断,而 Python 的 round()、Java 的 BigDecimal.setScale(2, RoundingMode.HALF_UP) 都是舍入。这种差异不会报错,只会让某些账的最后一分钱对不上。提示词里要写明「保留截断」,测试里要放专门暴露这个差异的数据。
缺失记录
老程序里「找不到就跳过并计数」「找不到就用默认值」这类规则往往就是业务规则本身,迁移时最容易被「顺手改进」成抛异常。示例里我们特意放了一笔不存在账户的交易。
先给老系统补测试,再迁
没有基准就没法判断迁得对不对。先用真编译器把原程序在各种输入下的输出跑出来存好,再动手迁。让 Codex 给老代码补测试的做法,可以参考 用 Codex 修真实 Bug 并跑测试;迁移前顺手清掉没用的段落,可以看 用 Codex 清理死代码。
语法能跑不等于行为一致
新代码能编译、能运行,只说明语法对了。字段宽度、溢出时丢高位、金额显示格式这些细节,只有逐字节对比输出才能发现。OpenAI 的评测也是按「所有测试逐字节通过才算成功」来算的。
怎么选模型:gpt-6.1-sol 还是 gpt-6-astra
- 迁移现有 COBOL 代码、要求行为不变:用 gpt-6.1-sol。OpenAI 的 COBOL 迁移评测就是用它报的成绩。
- 用 COBOL、Fortran、VB 等冷门语言写较大的新功能:可以试 gpt-6-astra。MultiLangBench 的成绩是它在最高推理强度下拿的。
想看 gpt-6.1-sol 和 Claude 的对比,见 GPT-6.1 Sol 和 Claude Opus 5.5 对比。
常见报错
- 提示 401 Unauthorized:Key 填错或没生效,见 Codex 401 Unauthorized 怎么解决。
- 提示 429 Too Many Requests:请求太频繁或额度用完,见 Codex 429 报错处理。
- 提示 selected model is at capacity:模型暂时繁忙,见 Codex 提示模型满载怎么办。
常见问题
Codex 能直接迁移整个 COBOL 系统吗?
可以一个程序一个程序地迁,但每个程序都要先有用真编译器跑出的基准输出和比对测试。OpenAI 也明确说,用到生产系统前仍需专家复核,并按业务规则和依赖测试。
没装 COBOL 编译器,能让 AI 推算出原程序输出当基准吗?
不建议。基准的意义就是「真实行为」,AI 推算的输出本身可能就错在截断或格式上。GnuCOBOL 免费,一条命令就能装好。
推理强度选 low 还是 high?
小程序、逻辑简单,先用 low,速度快一倍左右;程序大、文件格式和边界情况多,用 high,它会自己补更多边界测试。我们这次两档都一次迁对。
能迁到 Java 吗?
可以。OpenAI 的评测覆盖 C++、Java、Kotlin、Python 和 Rust 五种目标语言。把提示词里的目标语言换掉,比对测试的做法不变。



