规范 JSON 模型
I’m happy to translate the article for you, but I need the full text of the post (the content that follows the source line). Could you please paste the article’s body here? Once I have the content, I’ll provide a Simplified Chinese translation while preserving the original formatting, markdown, and any code blocks or URLs.
目的
Canonical JSON模型定义了由 FACET‑compliant 系统产生的 AI 执行状态的稳定、确定性表示。其目标是确保:
- 相同的输入产生字节级别完全相同的 JSON
- 输出可比较、可缓存、可差异化、可重放
- 提供商特定的格式不会将非确定性泄漏到下游系统
Canonical JSON 是确定性编译与概率模型执行之间的边界工件。
为什么确定性 JSON 很重要
现代 LLM 堆栈存在隐藏的非确定性:
| 非确定性来源 | 影响 |
|---|---|
| JSON 对象中字段顺序重排 | 缓存不可靠 |
| 可选字段出现/消失 | 重放不可能 |
| 供应商特定的消息布局 | 回归测试毫无意义 |
| 流式与非流式结构漂移 | 审计和合规脆弱 |
| 运行时应用的隐式默认值 | – |
这些影响导致:
- 缓存不可靠
- 重放不可能
- 回归测试毫无意义
- 审计和合规脆弱
规范 JSON 通过强制 单一规范化结构 消除这些失败模式。
规范 JSON 文档
规范 JSON 文档是满足 所有 以下条件的 JSON 对象:
- 确定性的字段顺序
- 所有可选字段的显式存在或缺失
- 数值和字符串的稳定编码
- 与提供者无关的结构
- 完全来源于已类型化的执行状态
FACET 将规范 JSON 视为 编译产物,而非序列化便利。
顶层顺序(规范性)
meta
system
tools
examples
history
user
assistant
output
所有符合规范的实现 必须 保持此顺序。
嵌套对象遵循:
- 词法键排序(UTF‑8,码点顺序)
- 由执行顺序或显式键派生的稳定列表顺序
规范 JSON 禁止 隐式默认值和结构歧义。
核心规则
| Rule | Requirement |
|---|---|
| Optional Fields | 在模式中定义但在运行时值中缺失的字段必须渲染为 null。省略已知字段被禁止。 |
| Empty Lists | 渲染为 []。 |
| Empty Objects | 渲染为 {}。 |
| Booleans | 始终显式(true / false)。 |
| Integers | 渲染时不带前导零。 |
| Floats | 标准十进制形式(除非必要,否则不使用指数)。 |
| Strings | UTF‑8,NFC 规范化。 |
| Escaping | 遵循 JSON 标准;不使用其他编码。 |
| Disallowed values | 不允许使用 NaN、Infinity、与地区相关的数字格式。 |
Rationale – 显式的 null 确保 JSON 键集 在无论数据内容如何都保持不变,从而实现 O(1) 的形状验证,并在不同语言的默认序列化行为(例如 JavaScript 与 Rust)之间提供稳定的哈希。
Production Pipeline
Input: [.facet] → [AST] → [R‑DAG] → [Token Box]
│
Core: [[ CANONICAL JSON IR ]] ─┤
│
Views: ┌──────────────┼───────────────┐
▼ ▼ ▼
[OpenAI] [Anthropic] [Gemini]
│ │ │
Output: └──────────────┼───────────────┘
▼
[ API Call ]
- Canonical JSON 是唯一的真实来源。
- Provider payloads(OpenAI、Anthropic、Gemini 等)是 Canonical JSON 的 派生视图,而非真实来源。
FACET 强制执行以下规则:
所有 provider payload 都是 短暂的。Canonical JSON 是 永久的。
后果
- 切换 provider 不会使历史失效。
- 即使供应商 API 发生变化,已存储的执行仍可重放。
- 审计和合规报告免受 provider 架构漂移的影响。
- provider 适配器中的错误不会破坏核心执行记录。
在实践中:
- Canonical JSON 被 存储、哈希、差异比较 和 缓存。
- Provider payload 在 即时生成 后即被丢弃。
因此,在执行层面上结构性地不可能出现 vendor lock‑in。如果某个 provider:
- 拒绝 payload
- 强制未文档化的约束
- 更改流式语义
这些失败都被隔离在 适配器层;Canonical JSON 仍然保持有效、稳定且可复用。
Source: …
@test / 快照测试
Canonical JSON 为 AI 系统提供了真正的快照测试,因为它具备:
- 字节对字节的确定性
- 与提供者无关
- 结构上完全显式
典型测试流程
- 在 Pure Mode(纯模式)下运行完整的执行管道。
- 生成 Canonical JSON。
- 对 JSON 进行哈希并/或存储为 快照。
- 以后运行时与该快照进行比较。
@test "payment flow"
vars:
amount: 100
currency: "USD"
assert:
- canonical_json_hash == "b3e2…"
保证
- 逻辑变更会立即显现。
- 提供者漂移不会使测试失效。
- 回归问题会在部署前被捕获。
对于企业系统,这能够实现:
- 确定性的 CI 流水线
- 可审计的执行日志
- 可复现的事件分析
- 具备加密保证的长期缓存
如果以下全部成立:
- 相同的 FACET 文档
- 相同的输入
- 相同的执行模式(Pure)
- 相同的 lens 注册表
则:- Canonical JSON 必须完全相同
Hash(canonical_json)必须相同- 下游行为 必须可复现
这构成了以下功能的基础:
- 记忆化(memoization)
- 快照测试
- 确定性代理(deterministic agents)
比较:临时 JSON 与规范 JSON
| 属性 | 临时 JSON | 规范 JSON |
|---|---|---|
| 字段顺序 | 不稳定 | 确定性 |
| 可选字段 | 隐式 | 显式(null) |
| 提供者泄漏 | 高 | 无 |
| 差异友好 | 否 | 是 |
| 缓存安全 | 否 | 是 |
规范 JSON 将 AI 行为转化为可版本化、可测试的制品——而非瞬时的模型输出。
可重玩性
| 可重玩 | 否 |
| 是 |
JSON is not a data format.
semantic boundary.
Canonical JSON turns that boundary into something that can be reasoned about, tested, and trusted.
FACET Canonical JSON plays the same role in AI systems that LLVM IR plays in compilers.
编译器栈
FACET Stack
| 层 | 描述 |
|---|---|
| Source Code | .facet 文档 |
| AST | 已类型化的 FACET AST |
| LLVM IR | 规范 JSON |
| Target Backend | 提供者适配器(OpenAI / Anthropic / Gemini) |
| Machine Code | 提供者负载 |
与 LLVM IR 共享的关键属性
- 提供者无关的表示
- 确定且稳定的结构
- 可差异化且可检查
- 用于优化、缓存和重放的安全目标
正如 LLVM 允许一个程序在不更改源代码的情况下针对 x86、ARM 或 WebAssembly,FACET 也允许一个代理架构在不更改执行语义的情况下针对多个 LLM 提供商。
这就是 规范 JSON 被视为 中间表示 而非序列化细节的原因。一旦存在此层,提供者负载就成为可替换的实现细节。
规范的 Canonical JSON 模型
本文档定义了 FACET v2.0 及以后版本的规范 Canonical JSON 模型。
所有符合规范的实现 必须 在生成规范执行输出时遵循这些规则。