一个不太性感的真问题

先说个场景。一个工程师想做一次爆炸冲击的力学仿真,他脑子里的物理图像很清楚:什么材料、什么边界、多大网格、要看哪些量。但从"想清楚"到"跑出结果",中间横着一道墙——他得把这套意图翻译成某个求解器能吃的算例脚本。

这道翻译墙有多高?以我们做的 CDEM(连续-非连续耦合方法)为例:一个中等复杂度的算例,从建模、写脚本到调通,通常要 1–2 名中级工程人员花上数日;开发一个新功能往往是月级,还得是有经验的人。工程师卡住的地方从来不是物理,而是实现细节:API 签名对不对、网格生成了没、材料组号有没有错、边界条件漏没漏、求解步怎么设、输出路径写哪。

更糟的是,这套细节换个求解器就得重来。OpenFOAM 的写法和 CDEM 的写法完全是两回事,专家的经验很难跨软件迁移。所以这不是某一个软件的易用性问题,而是"自然语言意图 → 可执行仿真"这条链路,在整个力学仿真领域普遍缺一段可靠、可复现的自动化。

大模型来了,第一反应当然是:那就让它直接写脚本啊?

我们试了。结论是:能写,但你不敢信。

我们做了个诚实的实验

与其吹能力,不如摆数据。我们在同一个自研技能底座 cdem_v6 上,固定同一批 10 个 CDEM 案例(S 类),只改变"用什么模型 + 什么代理工具链",跑了 6 组系统性测试。判定标准很硬:目录/审阅表明确标记"能不能直接运行",不靠感觉。

结果如下:

测试 工具链 + 模型 可运行 通过率
测试1 codex + gpt5.5(xhigh) 5/10 50%
测试2 codex + glm5.2(max) 4/10 40%
测试3 opencode + glm5.2(max) 7/10 70%
测试4 opencode + gpt5.5(xhigh) 2/10 20%
测试5 claude code + opus 4.8 7/10 70%
测试6 claude code + opus 4.6 6/10 60%

盯着这张表看几眼,有几个反直觉的地方:

第一,同一个模型,换工具链能差出一倍。 测试2 和测试3 都是 glm5.2(max),一个 40%、一个 70%。测试1 和测试4 都是 gpt5.5(xhigh),一个 50%、一个 20%。技能底座一样、模型一样,只是代理怎么组织上下文、怎么把技能喂进去、跑完有没有拿报错回灌——差异就这么大。"用了什么模型"根本不足以解释结果。

第二,有两个案例六组全军覆没。 A3-008-S 和 A3-010-S,不管换哪个模型、哪个工具链,10 次里 0 次跑通。这反而是最有价值的信号——如果只是某个模型偶尔写错,不会所有组合都倒在同一个地方。它指向的是我们技能库本身的盲区:可能是缺关键接口范例,可能是缺可直接复用的参考模板,可能是失败点集中在网格/边界/输出这些高危步骤上。

第三,"能运行"和"结果对"根本是两件事。 有些被标记为"不能运行"的目录里,居然存在 Result 目录和 .msh 网格文件——说明它跑到了中间阶段才挂,或者跑完了但没达到验收标准。反过来也有只生成了代码、什么产物都没有却被算作通过的。所以我们后来把状态硬拆成四级:代码生成成功 / 程序可启动 / 结果文件生成 / 人工验收通过,不再用单一目录后缀糊弄自己。

数据逼出来的一个判断

把这些坑连起来看,一个方向浮出来了:让大模型直接生成求解器代码,缺的是一层可检查的中间表示。

现在的路径是黑箱:自然语言进去,求解器脚本出来。脚本错了,你甚至说不清是"模型没理解用户要什么物理问题",还是"物理问题理解对了、但翻译成 CDEM 代码时错了"。这两类错误的修法完全不同,混在一起就没法系统改进。

我们的解法是引入一层通用力学计算语言(UCL,Universal mechanics Computing Language),把这条链路拆成两段:

工程师自然语言需求      
         ↓  意图解析 + 领域知识检索 + 物理约束检查
UCL:方程 / 本构材料 / 几何 / 初边值条件 / 耦合关系 / 精度要求        
         ↓  针对具体求解器的翻译器
CDEM / OpenFOAM / … 的可执行算例     
         ↓  运行 → 收敛检查 → 守恒/量纲校验 → 结果反馈与修正

UCL 是一份形式化的"物理定解问题描述"。它带来三个直接好处:

  1. 错误可定位。 意图理解错,错在 UCL 上;翻译错,错在 UCL→代码那一步。两段可以分别验证、分别改进。
  2. 可跨求解器。 同一份 UCL 理论上能生成多个后端。物理问题描述一次,CDEM 和 OpenFOAM 都能翻。专家经验第一次有机会沉淀在一个软件无关的层上。
  3. 能主动挑刺。 UCL 有语法、有语义、有约束检查器,就能在生成代码之前发现"这个需求缺了边界条件"“这两个物性互相矛盾”“这个问题根本不可定解”,直接拒答或反问,而不是硬写一个跑不通的脚本。

需要说清楚的是:CDEM 只是我们第一个跑通的验证例子,不是全部。项目本身是面向多求解器的,OpenFOAM 等是规划中的后端。初赛阶段我们先用 CDEM 这个边界清楚、有工业基础的切片把最小闭环做扎实,再论证向其他后端迁移。

怎么证明 UCL 不是花架子

一个中间语言最容易被质疑的一点是:这跟直接写个 Prompt 模板有啥区别? 所以验证计划必须能证伪自己。我们的设计是这样:

对照组。 同题、同求解器版本、同预算下,拉四条基线一起比:

  • 直接 LLM 生成(无 UCL、无 RAG,相当于"无干预平凡解")
  • LLM + 手册 RAG + 代码代理
  • 固定模板生成
  • 人工专家

比什么。 一次生成可运行率、四级验收通过率、物理矛盾检出率、跑通所需的修复轮数与人工工时。

什么算赢。 相对最好的那条自动基线,完整正确率至少提升 20 个百分点,且这个提升在整批案例上可重复,不是靠一两个案例撑出来的。

什么算输。 优势不显著;或者更危险的——错误结果被误判成正确(假阳性);或者人工澄清成本压根没降;或者 UCL 覆盖不了目标任务。输了就收缩语法或任务边界,把失败样本抽象成"失败模式 → 修正策略 → 可运行模板"回灌技能库,再重跑。

还要考它跨后端。 CDEM 切片跑通后,追加一个 UCL → OpenFOAM 的迁移试跑。如果 UCL 过拟合了 CDEM、换个后端就崩,那这层中间语言的核心卖点就不成立——这是我们特意留的一道证伪关。

那 6 组测试里的失败样本,现在成了最好的燃料。测试1 中所有"不能运行"的案例都伴随一个人工修正过的 改.js,我们要做的不是把它当结果文件存起来,而是反向抽象:原始脚本错在哪、修正版改了哪些接口/参数/边界、这些改动能不能写成通用规则、该不该进 API 核对清单。踩过的坑,不该踩第二次。

一点方法论上的收尾

做这个项目最大的体会,不是"大模型能写仿真代码"这种结论,而是几条被数据反复教育出来的纪律:

  • 别信单一指标,尤其别信"能跑"。 把状态拆到能追溯,你才知道系统到底在哪一步失效。
  • 共同失败比偶发失败金贵。 所有配置都倒在同一个案例上,那是系统在给你指路。
  • 诚实地报告 20% 那一组。 藏起最差的结果,你就永远不知道工具链的上下文注入有多重要。

力学仿真的自动化不会因为模型更大就自动解决。真正缺的是一层能被检查、能被追溯、能跨求解器复用的中间表示,以及一套敢于证伪自己的验证闭环。我们还在早期,UCL 的形式化、跨后端迁移、验证器都在做。但至少现在,我们是拿着一张诚实的数据表在往前走,而不是一句"AI 能行"。

更多推荐