AI 生成的逻辑如何安全进入应用?用 Stof 把数据与可执行行为放在同一文档
让模型生成 JSON、SQL 或代码片段并不难,难的是把这些结果接进真实应用:数据格式要解析,规则要校验,逻辑要执行,还要避免不可信输入获得宿主程序的全部能力。Formata 的 Stof 尝试从数据格式这一层解决问题:它把函数、验证与行为放进数据所属的文档中,并通过 Rust 实现、带 WASM 运行时的执行环境承载逻辑。
这不是“让模型生成的代码自动变安全”的魔法。它提供的是一个受限的运行边界和可组合的数据表达方式;宿主仍需审查输入、决定暴露哪些能力,并对业务操作做授权。
从 JSON 文档到携带逻辑的文档
Stof 将自己描述为 JSON 的超集:现有数据可以继续使用,需要时再加入逻辑。其文档示例展示了把 name 字段与 hello() 函数放在同一段内容中,再由 TypeScript 调用。
npm i @formata/stof
import { stofAsync } from '@formata/stof';
const doc = await stofAsync`
name: 'World'
fn hello() -> str { 'Hello, ' + self.name + '!' }
`;
console.log(await doc.call('hello'));
这里的 stofAsync、doc.call() 和 @formata/stof 均来自项目文档示例。文档还展示了将 JSON、YAML、TOML 等内容解析到同一个文档模型,再通过 doc.get() 读取值。这样做的价值在于:校验规则、计算值和数据不必散落在多个配置文件与应用层适配器中。
为什么它与 Agent 工具集成有关
AI Agent 常常需要根据运行时上下文决定某项操作,或者接收外部生成的工具定义。传统方式通常是由应用预先编译好所有分支;能力变化时,需要更新代码并重新部署。Stof 文档介绍了运行时解析新 Stof 内容、扩展文档能力的模式,并用宿主桥接函数展示如何显式提供外部能力:
import { stofAsync } from '@formata/stof';
const doc = await stofAsync`
fn loaded() -> str {
const stof = await Ext.fetch();
parse(stof, self);
self.say_hello()
}
`;
doc.lib('Ext', 'fetch', async () => {
return `fn say_hello() -> str { 'Hello, world!' }`;
});
console.log(await doc.call('loaded'));
这个例子的重要点不只是“逻辑可以动态加载”,还包括能力由宿主通过 doc.lib() 提供。生产系统应把桥接接口设计成最小权限集合:例如只允许查询某个租户范围内的数据,而不是把数据库连接、文件系统或任意网络请求直接交给文档逻辑。对写操作,还应在宿主边界进行参数校验、授权和审计;运行时隔离不能代替业务访问控制。
适合什么场景,不适合什么场景
Stof 值得评估的场景,是应用需要交换携带行为的文档、可演进的策略,或希望把配置与校验逻辑放在同一份数据中。官方文档还以 Limitr 的定价策略为例,展示 Stof 文档如何承载额度、验证与策略表达。
它并不意味着所有配置都应改成可执行文档。若规则固定、简单且由应用团队维护,普通 JSON 加静态校验往往更易理解。若考虑执行来自用户或模型的动态逻辑,必须先界定可调用函数、资源上限、超时、错误处理和版本兼容策略;并在部署前验证当前库版本的实际沙箱保证及其默认配置。不要仅凭“WASM”或“安全运行时”的描述推断其具备网络隔离、内存限制或完整的安全策略,这些细节需以对应版本的正式文档为准。
上手时的检查清单
- 从只读计算开始,把文档逻辑限制在纯数据与确定性转换。
- 逐个添加宿主桥接函数,并为每个函数定义允许的输入、输出与权限边界。
- 对动态载入内容做来源校验、版本固定和失败回退,避免静默执行未知版本。
- 用错误输入与越权请求做测试;把授权放在宿主侧,不依赖模型遵守提示。
- 先在隔离的测试环境评估资源限制和执行时限,再决定是否用于生产路径。
目前项目文档说明可从 TypeScript/JavaScript、Python 与 Rust 使用,TypeScript 包为 @formata/stof,官方文档 README 示例以 stofAsync 初始化文档。npm registry 返回该包的最新版本为 0.10.6,许可证字段为 Apache-2.0。采用前应以项目正式文档和具体发布版本核对 API 与安全边界。
Stof 的核心思路,是让数据与属于它的行为靠近,并将执行交给受限运行时。对 Agent 系统而言,这提供了一种值得探索的架构选项:不是把模型输出直接当作宿主代码执行,而是把动态逻辑放进可解析、可验证、由宿主谨慎开放能力的文档边界中。