1. Fortran 77 迁移 parity harness 对不齐?先把 Vibe CLI 多智能体入口统一到 TaoToken
Fortran 77 迁移到 C++ 的 parity harness 对不齐时,TaoToken 先统一 Vibe CLI 多智能体入口:去官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_parity_intro 取 YOUR_API_KEY,Base URL 设 https://taotoken.net/api。
最近有工程团队复盘过一类很典型的遗留数值代码迁移:欧洲能源运营商的 Fortran 77 油藏模拟器要迁到 C++,首批冲刺只覆盖整个代码库的一部分,但验证方式非常明确——先搭数值对齐 parity harness,再用 Vibe CLI 拉起多个智能体生成调用树、文档和迁移代码,最后落到人工操作的 coder、tester、reviewer 结构化工作流。这个思路听起来很顺,真正落地时却经常卡在一个很“工程化”的地方:coder 智能体、tester 智能体、reviewer 智能体各自从不同环境启动,Key 分散、Base URL 不一致、模型名混用,导致日志里的 Token 消耗对不上,parity harness 报错时也说不清是数值迁移问题,还是多智能体调用链问题。
所以本文不从“如何让智能体写更多代码”切入,而是从“如何让多智能体迁移遗留数值代码时,入口、Key、Base URL、日志、parity 记录全部可核对”切入。核心动作只有两个:启动 Vibe CLI 前,先到 TaoToken 官网拿 YOUR_API_KEY;然后把客户端 Base URL 统一设为 https://taotoken.net/api。后面再展开 Vibe CLI 环境变量或配置文件片段、按 coder/tester/reviewer 分组启动多智能体的命令,以及每个模块迁移后的 parity harness 对照记录。
2. 迁移前先固定 parity harness:没有基线就不要启动 coder 智能体
Fortran 77 油藏模拟器这类代码,最危险的地方不是语法旧,而是数值行为隐藏得很深。数组下标从 1 开始、隐式类型、COMMON 块、GOTO、格式化 I/O、编译器浮点优化、REAL 精度、随机种子、单位换算,这些都可能让 C++ 版本“看起来能跑”,但和原版输出对不上。所以正确顺序是:先固定 parity harness,再让 coder 智能体动代码。
建议目录结构如下,重点是 legacy、cpp、harness、cases、records 分离。coder 只能改 cpp 下目标模块,tester 只能运行 harness,reviewer 只能读 diff 和 records。
fortran77-to-cpp/ legacy/ sim77.f modules/ cpp/ sim.cpp modules/ harness/ run_case.sh compare.py cases/ case_001.dat case_002.dat baseline/ case_001.out case_002.out records/ module_parity.csv logs/ env/ modules.txt基线阶段不要接任何生产库,也不要把智能体直连 Oracle 或油藏生产数据。用脱敏样本、合成输入和本地文件跑通。先编译 Fortran 77 原版,生成 baseline:
mkdir -p baseline cpp_output records logs f77 -O0 -o legacy/sim77 legacy/sim77.f ./legacy/sim77 --input cases/case_001.dat --output baseline/case_001.out ./legacy/sim77 --input cases/case_002.dat --output baseline/case_002.out然后给 C++ 版本留出同样的入口。注意,如果原版程序使用固定格式文件、列式输出或二进制输出,harness 层要先把格式解析清楚,否则后面 reviewer 智能体看到的“数值不一致”可能只是 I/O 格式差异。
一个最小 Python 对比脚本可以这样写。它不做复杂数值分析,只负责把 baseline 和候选输出逐值比较,输出 JSON,方便 tester 智能体、reviewer 智能体和人工一起核对。
#!/usr/bin/env python3 import sys import json def load_values(path): values = [] with open(path, "r", encoding="utf-8", errors="ignore") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue for token in line.replace(",", " ").split(): try: values.append(float(token)) except ValueError: continue return values def main(): if len(sys.argv) < 3: print("usage: compare.py baseline.out candidate.out --atol 1e-9 --rtol 1e-7") sys.exit(64) baseline_path = sys.argv[1] candidate_path = sys.argv[2] atol = 1e-9 rtol = 1e-7 if "--atol" in sys.argv: atol = float(sys.argv[sys.argv.index("--atol") + 1]) if "--rtol" in sys.argv: rtol = float(sys.argv[sys.argv.index("--rtol") + 1]) a = load_values(baseline_path) b = load_values(candidate_path) if len(a) != len(b): print(json.dumps({ "status": "length_mismatch", "baseline_count": len(a), "candidate_count": len(b) }, ensure_ascii=False)) sys.exit(2) if not a: print(json.dumps({"status": "empty", "count": 0}, ensure_ascii=False)) sys.exit(0) max_abs = max(abs(x - y) for x, y in zip(a, b)) max_rel = max(abs(x - y) / max(abs(x), 1e-300) for x, y in zip(a, b)) ok = all(abs(x - y) <= atol + rtol * abs(x) for x, y in zip(a, b)) print(json.dumps({ "status": "pass" if ok else "fail", "max_abs": max_abs, "max_rel": max_rel, "atol": atol, "rtol": rtol, "count": len(a) }, ensure_ascii=False)) sys.exit(0 if ok else 1) if __name__ == "__main__": main()跑单个用例:
./cpp/sim --input cases/case_001.dat --output cpp_output/case_001.out python harness/compare.py baseline/case_001.out cpp_output/case_001.out --atol 1e-9 --rtol 1e-7如果这一步还没稳定,就不要急着把 coder 智能体并发开到很高。parity harness 是后面所有多智能体协作的验收标准,它不稳,Token 消耗越多,返工越贵。
3. Vibe CLI 接 TaoToken:Base URL、Key 与配置文件的最小改法
多智能体迁移时,最怕每个角色读不同的环境变量。建议统一先到 TaoToken 官网创建 Key:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=vibe_cli_key 。拿到 YOUR_API_KEY 后,所有客户端都指向同一个 Base URL:https://taotoken.net/api 。
Vibe CLI 的配置字段名可能随版本变化,下面给的是最小映射思路:无论它读 Vibe 自己的变量、OpenAI 兼容变量,还是 Mistral 兼容变量,核心都是 base_url 和 api_key 两项。实际字段名以你本地版本为准。
# Vibe CLI 环境变量示例 export VIBE_API_BASE="https://taotoken.net/api" export VIBE_API_KEY="YOUR_API_KEY" # 如果当前 Vibe CLI 版本读取 OpenAI 兼容变量 export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="YOUR_API_KEY" # 如果当前 Vibe CLI 版本读取 Mistral 兼容变量 export MISTRAL_API_BASE="https://taotoken.net/api" export MISTRAL_API_KEY="YOUR_API_KEY"配置文件示意如下。注意注释只是说明,实际合并到你已有的 Vibe CLI 配置里,不要凭空新增不存在的插件或 API。
# 示意:把 provider 的 base_url 指向 TaoToken # 字段名请以你的 Vibe CLI 版本为准 [provider] name = "taotoken" base_url = "https://taotoken.net/api" api_key_env = "VIBE_API_KEY" model = "your-vibe-model"团队里往往不只用 Vibe CLI。Claude Code 和 Codex 也可能被拿来做迁移辅助。这里必须分清:Claude Code 用 settings.json 和 ANTHROPIC_;Codex 用 config.toml,不要把 ANTHROPIC_套到 Codex 上。
Claude Code 的 settings.json 可以这样配置:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "YOUR_API_KEY" } }Codex 的 config.toml 可以这样配置:
model = "your-codex-model" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY"然后给 Codex 单独设置 Key:
export TAOTOKEN_API_KEY="YOUR_API_KEY"如果你用 CC Switch 管理多套客户端,建议把“三件套”固定下来:Claude Code 的 settings.json、Codex 的 config.toml、Vibe CLI 的 env 文件。三者都指向同一个 Base URL,Key 都用 TaoToken 控制台创建的 Key。只有需要按 coder、tester、reviewer 分账时,才在 TaoToken 控制台创建多个 Key,分别填入不同 env 文件;不要混用不同供应商的 Base URL,否则日志里根本查不清 Token 来自哪个角色。
4. 按 coder / tester / reviewer 分组启动多智能体:并发、队列与 Token 归因
多智能体迁移最容易失控的地方,是角色边界不清。建议一开始就写死:
- coder 智能体:只读 legacy 目标模块,只写 cpp 目标模块,不能改 harness,不能改 cases。
- tester 智能体:只运行 harness/run_case.sh,只写 cpp_output 和 records 下的测试结果,不能改 C++ 代码。
- reviewer 智能体:只读 git diff、baseline、cpp_output、compare.py 输出,不能写代码,只能输出审查意见和风险点。
准备三个 env 文件,Base URL 完全一致。如果暂时不想拆 Key,三个文件都可以先用 YOUR_API_KEY。
# env/coder.env VIBE_API_BASE=https://taotoken.net/api VIBE_API_KEY=YOUR_API_KEY VIBE_ROLE=coder VIBE_MAX_RETRY=3 # env/tester.env VIBE_API_BASE=https://taotoken.net/api VIBE_API_KEY=YOUR_API_KEY VIBE_ROLE=tester VIBE_MAX_RETRY=3 # env/reviewer.env VIBE_API_BASE=https://taotoken.net/api VIBE_API_KEY=YOUR_API_KEY VIBE_ROLE=reviewer VIBE_MAX_RETRY=3模块列表单独放文件,避免命令行里手写模块名导致 coder 改错范围。
well_pressure relative_permeability well_index material_balance time_stepping下面命令里的vibe请替换成你本地实际可执行文件或入口。重点是分组、并发和日志。先让 coder 并发跑,但不要多个 coder 同时改同一个模块。
# 加载统一 Base URL 和 Key export VIBE_API_BASE="https://taotoken.net/api" export VIBE_API_KEY="YOUR_API_KEY" # coder:并发 4,按模块逐个生成 C++ 迁移版本 xargs -a modules.txt -I{} -P 4 bash -lc ' module="$1" set -a . env/coder.env set +a vibe run --role coder --module "$module" --workdir "$PWD" \ > "logs/coder_${module}.log" 2>&1 ' _ {}coder 跑完后,不要立刻 review 全部模块。先让 tester 按模块跑 parity harness。tester 的并发可以低一些,避免大量数值输出和 Token 调用同时冲击日志。
# tester:并发 2,只跑模块相关用例并输出 JSON/CSV xargs -a modules.txt -I{} -P 2 bash -lc ' module="$1" set -a . env/tester.env set +a ./harness/run_case.sh "$module" \ > "logs/tester_${module}.log" 2>&1 ' _ {}reviewer 建议串行或并发 1。它要读 diff 和测试结果,并发太高会让审查意见互相覆盖,也不利于 Token 归因。
# reviewer:串行,只读审查 while IFS= read -r module; do set -a . env/reviewer.env set +a vibe run --role reviewer --module "$module" --read-only \ > "logs/reviewer_${module}.log" 2>&1 done < modules.txt如果 Vibe CLI 支持任务队列,最好把模块迁移做成状态机:pending -> coder_running -> tester_running -> reviewer_running -> passed 或 blocked。状态机不需要复杂,一个 CSV 或 SQLite 本地表就够。关键是让每个模块的 Token 消耗和 parity 结果能关联到同一个 module id。
Token 归因建议从两个地方看:一是 Vibe CLI 日志里是否有 usage 字段;二是 TaoToken 控制台里按 Key、时间窗口和调用量聚合。若一个 Key 给三个角色共用,就只能看总消耗;若想按角色拆分,就在 TaoToken 控制台给 coder、tester、reviewer 分别建 Key,但 Base URL 始终是 https://taotoken.net/api。
5. 每个模块迁移后的 parity harness 对照记录:数值对齐与 Token 消耗一起记
parity harness 的输出不能只看一个 pass。建议每个模块迁移后都写一条对照记录,字段至少包括数值结果和 Token 消耗。这样当 reviewer 说“这个模块风险高”时,你能马上看到它是不是同时伴随着 tester 重试多、reviewer Token 高、max_abs 接近容差边界。
推荐表格字段如下:
| 模块 | legacy 版本 | cpp 版本 | 用例 | max_abs | max_rel | 容差 | 结论 | coder_tokens | tester_tokens | reviewer_tokens | 总 tokens | 备注 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| well_pressure | f77-abc | cpp-123 | case_001 | 1.2e-12 | 3.4e-10 | 1e-9 / 1e-7 | pass | 待填 | 待填 | 待填 | 待填 | 无 |
| time_stepping | f77-abc | cpp-124 | case_002 | 4.8e-8 | 2.1e-6 | 1e-9 / 1e-7 | fail | 待填 | 待填 | 待填 | 待填 | 检查浮点累加顺序 |
跑对照记录时可以这样组织:
module="well_pressure" case_id="case_001" ./cpp/sim --input "cases/${case_id}.dat" \ --output "cpp_output/${module}_${case_id}.out" python harness/compare.py \ "baseline/${case_id}.out" \ "cpp_output/${module}_${case_id}.out" \ --atol 1e-9 --rtol 1e-7 \ > "records/${module}_${case_id}.json"然后把 JSON 里的 status、max_abs、max_rel 填进记录表。Token 消耗可以从日志里聚合。不要假设 Vibe CLI 一定有某个固定 JSON 字段,先 grep 你实际日志里的 usage、tokens、input_tokens、output_tokens 等关键字。
grep -RhoE '"(total_tokens|input_tokens|output_tokens|tokens)"[[:space:]]*:[[:space:]]*[0-9]+' logs/ \ | sort | uniq -c如果日志只有自然语言,也可以人工按模块记录。关键是同一模块的 coder、tester、reviewer 消耗放在同一行。这样后面排查“为什么这个模块迁移成本高”时,不会只剩一句“模型不太行”。
parity 对不齐时,建议按下面顺序排查:
- 先看输入用例是否一致。baseline 和 cpp_output 必须来自同一份 cases 文件。
- 再看输出解析是否一致。Fortran 固定格式输出和 C++ 浮点输出可能在列数、精度、科学计数法上不同。
- 检查数组下标。Fortran 默认从 1 开始,C++ 从 0 开始,循环边界和存储顺序最容易错。
- 检查隐式类型。Fortran 77 里 I-N 开头变量默认 integer,其他默认 real,迁移时如果显式类型写错,数值会缓慢漂移。
- 检查 COMMON 块和全局状态。多个模块共享状态时,初始化顺序变化会直接改变结果。
- 检查 GOTO 转换。GOTO 改成循环、函数或状态机后,边界条件可能变化。
- 检查浮点精度和编译器选项。REAL 与 double、-O0 与 -O2、快速数学优化都可能造成差异。
- 检查随机数和时间步。随机种子、迭代顺序、并行归约顺序不稳定时,max_abs 会随机波动。
- 检查单位换算。油藏模拟器里压力、体积、渗透率单位一旦混用,parity 会大面积失败。
只有确认 parity 失败不是 harness 问题后,才让 coder 重跑目标模块。reviewer 这时只读 diff 和测试结果,不直接改代码。tester 也只重跑用例,不参与修复。
6. 多智能体 Token 爆量时的排障顺序:先看 Base URL,再看并发,最后看 parity
多智能体迁移遗留数值代码时,Token 爆量通常不是单一原因。排障顺序建议从接入层开始,而不是一上来就怀疑模型能力。
第一,看 Base URL。所有客户端必须指向 https://taotoken.net/api。如果 Vibe CLI 读的是 OPENAI_BASE_URL,Codex 读的是 config.toml 里的 base_url,Claude Code 读的是 ANTHROPIC_BASE_URL,三者路径不一致,就会出现有的请求走 TaoToken,有的请求走旧供应商。检查环境变量时不要把 Key 打全。
env | grep -E 'VIBE|OPENAI|MISTRAL|TAOTOKEN|ANTHROPIC' \ | sed -E 's/(API_KEY=).*/\1***/'第二,看 Key。401 或 403 通常不是模型问题,而是 Key 没创建、没复制完整、没权限或已被替换。需要新建或检查 Key 时,回到 TaoToken 官网:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=token_troubleshooting 。
第三,看 404 和路径。Base URL 写错是常见问题,尤其是把https://taotoken.net/api写成其他路径,或者在末尾多拼了/v1。先按产品事实统一为 https://taotoken.net/api。
第四,看 429 和并发。coder 并发 8、tester 并发 8、reviewer 并发 4,很容易在短时间内把请求打满。建议 coder 从并发 2 到 4 起步,tester 并发 1 到 2,reviewer 串行。429 出现后不要只加重试次数,要先降并发,再加指数退避。
第五,看重试风暴。一个模块 parity 失败后,如果 coder 自动重试 10 次、tester 又跑 10 次、reviewer 再审查 10 次,Token 会成倍增长。建议在 Vibe CLI 外层加最大重试次数,并把失败模块移到 blocked,而不是无限重跑。
grep -RniE '401|403|404|429|timeout|rate limit' logs/ || true第六,看 parity 本身。如果 Base URL、Key、并发都正常,但 tester Token 仍然很高,通常是数值对不齐导致反复重跑。此时应该冻结 coder 自动修改,让 reviewer 输出差异清单,人工确认是浮点容差、数组下标、隐式类型还是 I/O 解析问题。parity 失败不是靠“再让智能体试一次”解决的,它需要可复现的对照记录。
7. 安全边界:多智能体不碰生产库,SQL/命令本地执行
迁移油藏模拟器这类代码时,数据敏感性比普通业务代码更高。无论 Vibe CLI 多智能体、Claude Code 还是 Codex,都不应该直连 Oracle 或生产库。不要让 MCP、Agent 工具或自定义脚本自动执行生产 SQL。所有 SQL、导出命令、对比命令都由读者在本地或隔离环境执行,智能体只处理脱敏后的文件、diff 和测试输出。
建议把禁止提交的文件写进 .gitignore:
.env env/*.env logs/ pids/ cpp_output/ records/*.local.csv *.key *.pemKey 只通过环境变量或本地未提交配置文件注入。不要把 YOUR_API_KEY 写进代码、README、Dockerfile 或 CI 日志。如果必须在 CI 中跑 parity harness,也只用脱敏样本,并把 Key 放在 CI secret 中。
reviewer 智能体的权限也要限制为只读。它可以读 git diff、records 和日志,但不能写 cpp 源文件,不能改 harness,不能执行数据库命令。tester 智能体只运行本地 harness,不能访问生产数据源。coder 智能体只修改目标模块,不能扩大文件范围。
8. 文末 CTA:把 Vibe CLI 多智能体迁到 TaoToken 的最小路径
如果你正在用 Vibe CLI 做 Fortran 77 到 C++ 的迁移,并且已经在 parity harness 上遇到对不齐、多智能体 Token 对不上、Base URL 或 Key 分散的问题,建议按下面路径走一遍:
- 先用模型对话验证你的迁移提示词、角色边界和输出格式是否稳定:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_chat
- 如果 coder、tester、reviewer 多智能体要长期并发跑模块迁移,查看 Coding Plan 是否适合你的 Token 消耗模式:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_coding_plan
- 到控制台创建或管理 API Key,把 Vibe CLI、Claude Code、Codex 的 Key 统一纳管:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_api_keys
- 如果团队同时使用 Claude Code 辅助迁移,按文档配置 settings.json 和 ANTHROPIC_*,不要和 Codex 的 config.toml 混用:https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_claude_code
最后再强调一次最小接入动作:启动 Vibe CLI 前,去 TaoToken 官网拿 YOUR_API_KEY,把客户端 Base URL 设为 https://taotoken.net/api。官网入口可以走这个带 UTM 的链接:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=fortran77_final_cta 。当入口、Key、Base URL 统一之后,coder/tester/reviewer 的 Token 消耗才能和每个模块的 parity harness 对照记录对齐;数值迁移是否正确,也才有可复查的证据链。