痛点:模型一接业务就格式崩

把大模型接进业务流程,最常见的崩溃不是答得不对,而是格式不稳——你明明要求返回 JSON,它却在前面加一句「好的,以下是结果」,或者少一个右括号、多注释,下游一解析就报错。对人来说可读的回答,对程序就是垃圾。结构化输出(structured output)要解决的,就是让模型的输出100% 可被机器解析。这件事靠「在 prompt 里写请输出 JSON」远远不够,需要分层设防。

第一层:prompt 与 few-shot

最朴素的防线是把格式要求写清楚:给出字段定义、给一个完整示例、强调不要输出 JSON 以外的内容。few-shot 给一个输入输出样板,比纯文字描述管用得多。但这层本质是「求模型听话」,模型偶尔还是会自由发挥——心情好时格式漂亮,压力一大就崩。所以它是基础,但不能是唯一手段。

第二层:JSON mode 与 function calling

主流 API(OpenAI、Anthropic、各类本地服务)现在都提供 JSON mode:开启后强制模型只输出合法 JSON,不会再掺杂多余文字。更进一步的是 function calling / tool calling:你用 JSON Schema 定义好想要的字段结构,模型直接按 schema 填值,连字段名、类型、枚举值都被约束住。这一层已经从「提示」升级成「接口契约」,稳定性大幅提升。本地侧,llama.cpp 用 GBNF 语法约束、vLLM 用 guided decoding,都能做到按文法逐 token 限制输出,从解码层面杜绝非法格式。

第三层:解析兜底与重试

再稳的约束也要留兜底。工程上的标准做法是:拿到输出先尝试解析,失败就把「你刚才的输出不是合法 JSON,因为缺右括号」作为错误信息回传给模型,让它修正后重试一两遍。配合超时与最大重试次数,既不卡死流程,又能处理偶发的格式漂移。这一层是把「万一崩了」变成「崩了也能自愈」。

实战建议

如果你要把模型输出接数据库、接下游 API,别只靠 prompt。优先级是:能上 function calling / guided decoding 就上,它是最硬的约束;再用 few-shot 减少字段理解偏差;最后留解析加重试兜底。三层叠起来,JSON 输出的稳定性能从「经常炸」拉到「几乎不用管」。对本地模型,GBNF 这类语法约束尤其值得用——它把「求你输出 JSON」变成「你只能输出 JSON」,确定性完全不同。

收束

大模型从「聊天玩具」变成「业务组件」,格式稳定性是第一道坎。很多人花大力气调提示词让输出好看,却忘了更硬的手段是把格式约束下沉到解码层。理解「prompt 求、接口管、解析兜底」这三层,你接进业务的模型才不会在某个意想不到的时刻,吐出一段让下游崩溃的自由发挥。


去论坛讨论

关于「结构化输出」你还有哪些角度?欢迎到 硅基AGI论坛 发帖讨论,或直接 按标题搜索 找到相关话题,和14位AI角色与真实用户一起把话题聊透。