在科学计算、气象、能源、航空航天、精算和工程仿真里,Fortran 仍然承担着大量经过验证的数值核心。
这些代码往往不是"语法问题",而是模型、库、性能剖面、回归用例和验证历史的组合。把它移植到 Python,不是重构,而是重新实现和重新验证。

PRAXO-CORE 的 Fortran SDK 提供第三条路:不移植模型,而是在 Fortran 进程里放一个受治理的 Agent 循环。
这不是"用 Fortran 写新应用",也不是"Python 已经过时"。它是一个更窄的工程声明:让 Agent 下沉到模型真正运行的地方。
一、核心结论
Fortran SDK 是原生 Fortran 2008 实现,不是桥接,也不是 Python 包装。
当前公开验证:
- 62 条规范向量,11 组;
- 原生回归测试;
- API 声明快照
0.2.0; - 远程
fortran-conformanceCI; - 源码 tag
fortran/v0.2.0; - Core 源码 MIT;GNU Fortran 及其运行时是单独许可的外部工具链依赖。
两个明确的 partial 面:
- 异步 stream 支持 :
praxo_stream提供 part record 和六个 contract kind 字符串,不是异步运行时; - 有界 JSON Schema 子集:覆盖向量定义的行为,但不是完整 JSON Schema。
其余声明范围内通过。不要把它说成"完整 Go parity"。
二、为什么不是 Python 移植,也不是 Python 包装
默认方案有两种:
- 把 Fortran 模型移植到 Python;
- Fortran 暴露一个 API,Python 服务拥有 Agent 循环。
第一种是重新实现和重新验证。对经过多年验证的数值模型,这个成本经常被低估。
第二种经常是正确工程选择:隔离新运行时,避免碰脆弱的仿真代码。但治理边界会跟着 Agent 走:策略、工具授权、检查点、审计事件、人工审批都要跨进程重新建立。
原生 Agent 循环是第三条路:循环就在模型所在的进程里。
三、模块拆解
Fortran SDK 的 API 由一组 Fortran module 组成:
| Module | Surface |
|---|---|
praxo_types |
messages、calls、requests、responses、usage、sessions、events、decisions、results、errors |
praxo_interfaces |
model、tool、policy、event sink 抽象接口;tool registry |
praxo_agent |
agent options 和有界 Agent 循环 |
praxo_context |
token 估算和上下文压缩 |
praxo_runtime |
recording、filter、multi event sink;内存 store |
praxo_unicode, praxo_json |
原生 UTF-8、JSON 解析、编码、遍历、相等性 |
praxo_checkpoint |
注册类型的 JSON 信封 |
praxo_toolcall |
JSON、XML 风格、点号标签、纯文本工具调用;markup 移除 |
praxo_schema, praxo_pattern |
契约 schema 校验和有界 ASCII 模式 |
praxo_policy |
词法路径授权 |
praxo_plugin |
严格 manifest 解析和校验 |
praxo_middleware |
每次 run 的限制、工具选择、fallback、structured-output repair、PII 脱敏 |
praxo_stream |
stream-kind 常量和 part record |
核心调用很小:
options%provider => provider
options%tools => tools
options%events => sink
call run_agent(options, state, 'hello', 'caller-generated-run-id', result, error)
if (error%failed()) print *, error%code
调用约定:
- callback target 必须在 run 期间保持存活;
multi_sink%add和filter_sink%target持有指针,target 必须比 sink 活得久;- registry 持有每个注册 tool 的多态副本;用户自定义 tool 里的指针组件仍由调用方管理生命周期;
- 每次 run 有本地历史,不修改输入 session 或 options;
- 跨线程共享可变 model、registry、store 或 sink 需要调用方自己同步;
- 调用方提供唯一 run ID,结果和事件会保留它;
- step limit 为零或负数时选择 8 步;
- token limit 非正数时关闭 usage budget;
- model/tool 失败会传播;被拒绝的策略在调用前失败;
- 上下文压缩在每次模型调用前检查;
- 负 usage 和计数器溢出会 fail closed。
四、边界:256KB 和两个 partial
Fortran SDK 的 JSON 边界:
- 输入最大 262,144 字节;
- 最多 4096 个 value node;
- 最多 64 层嵌套容器;
- 非法 UTF-8、孤立代理项、畸形数字、尾随数据会被拒绝;
- 重复对象键保留,查找和相等性使用最后一个值;
- 小数相等性避免二进制浮点舍入(指数在 signed 64-bit 范围内);更大指数字面量按词法比较;
- 数值 schema 边界使用有限
real64; - JSON 工具返回本地
JSON_INVALID/JSON_CAPACITY状态,不新增 wire 错误码。
模式匹配:
- 支持 ASCII 字面量、点、字符类/范围、锚点、
*、+、?,以及基本转义类; - 不是完整 RE2;分组、交替、计数重复、Unicode 模式匹配和不支持的转义会返回
SCHEMA_PATTERN_UNSUPPORTED; - 模式工作是有界的,不支持的 pattern 不会静默接受数据。
其他限制:
- 路径策略是词法规范化,不是操作系统级隔离;不解析符号链接、reparse point、文件系统大小写规则或竞态;UNC 和 drive-relative 路径会被拒绝;
- 插件解析只校验声明,不执行插件、不验证签名;
- stream 只提供 part record 和六个 kind 字符串,不是异步 Agent stream;
- memory search 使用 ASCII 大小写折叠和规范 UTC 时间戳词法排序;
- 上下文估算会先规范化有效 JSON 参数文本,再估算字节长度;
- multimodal message block 和 parity 清单之外的 optional Go hook 未实现;
- PII 脱敏覆盖邮箱、SSN、信用卡、电话模式,不是完整合规。
五、治理与可复现性
研究机构或受监管的模型所有者,不需要一个会聊 Fortran 的 Agent。他们需要的是:Agent 能参与流程,同时不绕过流程周围的控件。
这意味着:
- 策略钩子能看到最终工具参数;
- 工具授权是显式的,中间件修改之后还要再检查;
- 检查点支持恢复;
- 事件是结构化的,能用于审计和遥测;
- 人类审批发生在正确边界;
- 框架清楚说明自己不负责什么。
如果循环就在 Fortran 进程里,策略决策丢失的地方更少。模型、工具和审批边界可以靠得更近。
但这不自动等于可复现或安全。它只是减少了一种边界穿越。其余仍然是工程和验证。
六、我们不宣称什么
- 不宣称完整 Go parity;
- 不宣称异步 stream;
- 不宣称完整 JSON Schema;
- 不宣称 provider adapter;
- 不宣称包注册表发布;
- 不宣称操作系统级沙箱;
- 不宣称通用 PII 合规;
- 不宣称插件执行或签名验证;
- 不宣称 MPI、OpenMP、GPU、netCDF、HDF5 或领域库集成;
- 不宣称生产可用或安全认证;
- 不宣称"Python 已经过时";
- 不宣称 sidecar 总是错的。
七、如何验证
python language/fortran/run-tests.py
需要 GNU Fortran 和 Python 3.10+。FC 或 --compiler 可以指定编译器路径。Python 只用于构建和测试;编译后的 Core 消费者不需要 Python。
然后:
- 读
spec/languages.md的 Fortran 行; - 读
language/fortran/README.md的 Scope and Limits; - 读
spec/parity/fortran.md的两个 partial 面; - 检查 256KB/4096/64 限制是否适合你的场景;
- 测试路径处理、策略顺序、取消、回调失败等安全行为;
- 再决定原生循环、桥接还是 sidecar。
仓库:https://github.com/axisvela/praxo-core Fortran 文档:https://axisvela.github.io/praxo-core/languages/fortran/ Fortran 源码:https://github.com/axisvela/praxo-core/tree/main/language/fortran 语言矩阵:https://github.com/axisvela/praxo-core/blob/main/spec/languages.md
八、结语
Fortran 不需要变成 Python,才能用 Agent。
它需要的是一个能在原进程里受治理地运行、边界清楚、可以验证的 Agent 循环。
62 条向量、256KB 边界、两个 partial 面、模式化 PII 脱敏、词法路径策略------这些限制不是缺点清单,而是可信度的一部分。
对不愿冒险移植验证模型、但又需要 Agent 能力的团队,这是一条值得评估的第三条路。