博客 • AI / Structured Output
Claude Fable 5.1 JSON 輸出能力怎麼樣?AI Structured Output 與 API 開發實測方向
Claude Fable 5.1 在 2026-09-01 上线,API 模型名是claude-fable-5-1。文档里同时出现output_config.format和工具上的strict: true——都承诺「结构化 JSON」,但保证范围并不相同。
Claude Fable 5.1把 Structured Output 做成了 Messages API 的正式能力:你在请求里附带 JSON Schema,模型在生成最终回答时被约束,使输出 conform 到字段、类型和必填项。对 API 开发来说,问题不再是「会不会吐 JSON」,而是「这份契约在 Claude、OpenAI、Gemini 上分别保证到哪一层」。Structured Output 不再是 beta 头。
本文将说明:
- Fable 5.1 在产品线里的定位:什么时候值得用
- JSON outputs 与 Strict tool use 各自保证什么
- output_config.format 的可复制请求
- forced tool use 被禁用后,Agent 该怎么写
- 一套跨厂商 API 实测清单:测什么、怎么打分
先记住这一点:Fable 5.1 的 JSON 能力已經夠做生產契約,但「API 層 conform」不等於「業務層正確」。forced tool 會直接 400;minimum / minLength 這類約束也不會進解碼器。下面按規格 → 能力邊界 → 廠商對比 → 實測清單拆開。
Claude Fable 5.1 是什么
Claude Fable 5.1 是 Anthropic 面向长程 Agent、多步研究和文档/表格工作的旗舰推理模型。Claude API、Amazon Bedrock、Google Cloud、Microsoft Foundry 上的模型 ID 都是claude-fable-5-1。知识截止日期 2026-06,上下文 1M,同步输出上限 128K。
官方建议大多数工作负载先用 Claude Opus 5;只有当 Opus 5 在更高 effort 下评测仍不够,或任务本身是长时 Agent / 复杂推理时,再上 Fable 5.1。价格也说明了定位:输入/输出 $10 / $50 per MTok,是 Opus 5 的两倍。
| 规格 | Claude Fable 5.1 | Claude Opus 5 | Claude Sonnet 5 |
|---|---|---|---|
| 上下文 / 最大输出 | 1M / 128K | 1M / 128K | 1M / 128K |
| 价格($/MTok) | $10 / $50 | $5 / $25 | $2 / $10 |
| Thinking | Adaptive,始终开启 | Adaptive | Adaptive |
| 默认 effort | high | high | high |
官方文档:Claude Fable 5.1、Structured outputs。
JSON / Structured Output 能力边界
Fable 5.1 支持两条互补路径,可以单独用,也可以写在同一次请求里:
- JSON outputs:最终回答走
output_config.format,返回值是符合 schema 的 JSON 文本块。适合抽字段、生成报表、给下游 API 喂结构化数据。 - Strict tool use:工具定义里加
strict: true,保证工具名和 arguments 通过 schema 校验。适合 Agent 调外部系统。
和「只在 prompt 里写请返回 JSON」相比,能力差在解码阶段:schema 会约束 token,而不是生成后再祈祷能 json.loads。
| 能力 | Fable 5.1 表现 | 对 API 开发的含义 |
|---|---|---|
| 合法 JSON | JSON outputs 路径下可视为保证 | 少写正则补洞和二次 LLM 解析 |
| 字段 / 类型 / 必填 | 按你提交的 schema conform | 可以把输出直接喂校验器和业务代码 |
| 数值 / 长度约束 | 不支持,提交会 400 | minimum、minLength 必须放业务层 |
| 强制调用某个工具 | tool_choice any/tool 直接 400 | 改用 auto + strict,或改走 JSON outputs |
结构化输出的通用原理见2026 AI Structured Output 完整解析。本文只补 Claude 这一侧的差异和怎么测。
output_config.format 怎么用
2026 年官方已把 beta 参数output_format迁到output_config.format。新代码不要再带 structured-outputs-2025-11-13 头。Python SDK 1.0+ 在 messages.create() 里传旧字段会 TypeError。
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-fable-5-1",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Extract ticket fields from: billing failed for acct-9921, user wants a refund.",
}
],
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account", "other"],
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high"],
},
"account_id": {"type": "string"},
"summary": {"type": "string"},
},
"required": ["category", "priority", "account_id", "summary"],
"additionalProperties": False,
},
}
},
)
print(next(block.text for block in response.content if block.type == "text"))
对象必须写additionalProperties: false;required建议列出全部 property。少一个,请求可能被拒,或多出来的字段不会出现在输出里。
如果用 Pydantic,SDK 的client.messages.parse()仍接受 output_format 作为便利参数,内部会转成 output_config.format,并自动补 additionalProperties: false、去掉不支持的 constraint。
Strict tool use:不要再用 forced tool
Fable 5.1 的 Thinking 始终开启。强制工具调用会跳过思考,模型把推理写进 arguments,质量下降。所以tool_choice: {"type": "any"}和{"type": "tool"}会返回 400 invalid_request_error。要 schema-valid 的工具参数,保持 auto,并打开 strict。
{
"model": "claude-fable-5-1",
"max_tokens": 1024,
"tool_choice": { "type": "auto" },
"tools": [
{
"name": "create_ticket",
"description": "Create a support ticket from extracted fields.",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account", "other"]
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high"]
},
"summary": { "type": "string" }
},
"required": ["category", "priority", "summary"],
"additionalProperties": false
}
}
],
"messages": [
{ "role": "user", "content": "Use create_ticket for this refund request." }
]
}
想让模型一定调工具,把触发条件写进 prompt,例如「用 create_ticket 处理这条退款」。Agent 栈里 schema 还出现在 MCP inputSchema / outputSchema,见AI Agent 與 JSON Schema 完整解析。
和 OpenAI / Gemini 对比
同一份业务 schema,三家 API 的挂载位置不同。做多模型路由时,先抽象 schema,再写三套薄适配层。
| 项 | Claude Fable 5.1 | OpenAI | Gemini |
|---|---|---|---|
| 请求字段 | output_config.format |
response_format.json_schema |
responseSchema |
| 类型声明 | json_schema |
json_schema + strict |
application/json |
| 额外字段 | 必须 additionalProperties: false | Strict 模式同样强制 | 建议加上,不强制同一套报错 |
| 工具契约 | tools[].strict + input_schema | tools[].parameters / strict | function calling + responseSchema |
OpenAI 兼容面(如DeepSeek V4-Pro)通常跟 OpenAI 字段走;不要假设 Claude 的 output_config 能原样贴过去。
API 開發實測方向
评估「JSON 输出能力怎么样」,不要只看一次 happy path。用同一份 schema、同一组用例,分别打 Claude / OpenAI / Gemini,记录四项通过率。
-
1
冻结一份跨厂商 schema
只用三家都支持的子集:object、string、integer、enum、required、additionalProperties: false。先不要写 minimum 或递归 $ref,否则测的是厂商限制,不是模型能力。
-
2
准备 4~8 条真实文本
覆盖枚举边界、缺字段文本、多意图、超长描述。每条用例预先写好期望 category / priority,不要事后改标签。
-
3
打四项符合率
必填齐全、无多余 key、enum 落在集合内、类型全是声明类型。四项都过才算一次成功。单独统计 json.loads 失败率——Structured Output 路径上这项应接近 0。
-
4
单独测 breaking change
对 Fable 5.1 发一条 tool_choice: any,确认 400。再发一条带 minimum / minLength 的 schema,确认 400。这两条是回归用例,升级模型时先跑。
-
5
看延迟和 token,不只看正确率
Fable 5.1 默认 high effort,Thinking 始终开启,同样 schema 往往比 Sonnet 5 / Gemini Flash 更慢、更贵。把 P50 延迟和 output tokens 记进表格,决定哪条链路走 Fable、哪条走便宜模型。
CASES = [
"billing failed for acct-9921, user wants a refund",
"cannot login after password reset, error 403",
"please upgrade our workspace to Enterprise",
"the app crashes when opening a 12MB JSON file",
]
EXPECTED_KEYS = {"category", "priority", "account_id", "summary"}
def score(payload: dict) -> dict:
keys = set(payload)
return {
"has_required": EXPECTED_KEYS <= keys,
"no_extra": keys <= EXPECTED_KEYS,
"enum_ok": payload.get("category") in {"billing", "technical", "account", "other"},
"types_ok": all(isinstance(payload.get(k), str) for k in EXPECTED_KEYS),
}
把三次调用的原始 JSON 贴进 JSONNote Diff,比看日志更容易发现字段漂移。符合率掉到 95% 以下,先查 schema 是否混进了不支持的关键字,再查 prompt 是否和 enum 打架。
Schema 限制:官方不支持什么
JSON outputs 和 Strict tool use 共用同一套 JSON Schema 子集。用不支持的特性会直接 400,而不是「尽量遵守」。
| 类别 | 支持 | 不支持 |
|---|---|---|
| 基础 / 数值 | type / properties / required / enum / const | minimum / maximum / multipleOf |
| 字符串 format | date-time / email / uri / uuid | minLength / maxLength |
| 数组 | minItems = 0 或 1 | 更大的 minItems / maxItems |
| $ref | 本地 $ref / $def | 外部 $ref、递归 schema |
Python / TypeScript SDK 会自动剥掉不支持的 constraint,并写进 description。不要依赖这层静默改写——评测和线上应提交同一份已裁剪的 schema。
校验工作流:API 到业务层
推荐三层:API 选 JSON outputs 或 Strict tool → 业务层 json.loads + JSON Schema validate → 监控层记录违规率。Fable 5.1 不能替代后两层:空 content、截断、枚举大小写仍可能出现。
import json
from jsonschema import validate, ValidationError
SCHEMA = {
"type": "object",
"properties": {
"category": {"type": "string", "enum": ["billing", "technical", "account", "other"]},
"priority": {"type": "string", "enum": ["low", "medium", "high"]},
"account_id": {"type": "string"},
"summary": {"type": "string"},
},
"required": ["category", "priority", "account_id", "summary"],
"additionalProperties": False,
}
def parse_llm_json(raw: str) -> dict:
try:
data = json.loads(raw)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON: {e}") from e
try:
validate(instance=data, schema=SCHEMA)
except ValidationError as e:
raise ValueError(f"Schema mismatch: {e.message}") from e
return data
这份 SCHEMA 同时用于请求和校验。开发时把模型原文和 schema 贴进 JSONNote,比在终端里 print 快得多。
用 JSONNote 调试模型 JSON
跨厂商实测最耗时的是对比三次输出。JSONNote 在浏览器本地运行,Key 和样本都不上传:
-
1
校验 schema 与输出
把 Fable / OpenAI / Gemini 返回的 JSON 和同一份 schema 贴进JSON Schema,立刻看到缺字段、类型错、多余 key。
-
2
格式化原始响应
用JSON 格式化确认是不是合法 JSON,排除日志转义造成的假错误。
-
3
对比三次调用
用JSON Diff看字段名和枚举是否漂移,作为回归基线。
常見問題
Claude Fable 5.1 的 JSON 輸出可靠嗎?
在 output_config.format 路径上,语法合法和字段 conform 可以当作 API 保证。不可靠的是业务语义、数值范围、字符串长度——这些官方明确不进解码器。
還能用 tool_choice: any 嗎?
不能。Fable 5.1 / Mythos 5.1 对 any 和 tool 返回 400。改 auto + strict,或把最终结构放到 output_config.format;需要调用时在 prompt 里写清工具名。
和 OpenAI、Gemini 怎麼選?
要长程 Agent 和复杂抽取,Fable 5.1 的 schema 约束够用,但贵、慢。常规 CRUD 结构化输出优先 Sonnet 5 或 Gemini;多模型路由时 schema 用公共子集。
開了 Structured Output 還要手動校驗嗎?
要。API 约束不能替代 try/except + validate。空响应、网络截断、enum 大小写都可能漏过解码器。
舊的 output_format 還能用嗎?
REST 仍接受一段时间,但 Python SDK 1.0+ 的 messages.create() 会 TypeError。新代码一律写 output_config.format;parse() 助手可以继续用 output_format 这个便利名。
總結
Claude Fable 5.1 的 JSON 输出能力可以概括成三句:
Structured Output 已 GA;forced tool 被关掉;不支持的 schema 关键字会 400。
API 开发不要只 demo 一次 happy path。冻结公共 schema、跑符合率、把 breaking change 写成回归,再用 JSONNote 本地对比三次输出——这比再写一段「请返回 JSON」的 prompt 更接近生产。