控制输出格式 | 提示词工程 | 做产品
控制输出格式
只要模型的输出要被程序接住,格式就必须稳定。而「在提示词里说清楚」这一招,可靠性大概是九成——听起来不错,放到线上就是每天几百次失败。
你会遇到的现象
-
要求只返回 JSON,它偏要在前面加一句「好的,这是您要的结果:」
-
解析代码写了一堆兼容逻辑,还是时不时崩
-
开了流式输出之后,前端拿到半截 JSON 没法处理
三层手段
第一层:在提示词里请求。
最基本的做法,写清楚要什么格式。有两个技巧能明显提高命中率:给一个格式样例(比描述格式有效得多,这是给例子那一招的应用),以及明确说「不要有任何解释文字,第一个字符必须是左花括号」。
但它终究是「请求」不是「保证」。模型本质上是在做概率延续,而「好的,这是您要的结果」这种开场白在语料里实在太常见了,总有概率冒出来。
第二层:用接口参数强制。
多数平台提供了 response_format 之类的参数,能在生成层面约束输出——生成的时候就只允许产出符合 JSON 语法的 token。这不是事后检查,是从根上不给它跑偏的机会。
更进一步的是提供 schema:不仅要求合法 JSON,还指定有哪些字段、什么类型。能用就一定要用,这是可靠性提升最大的一步。
但要清楚它保证的边界:**它保证语法合法,不保证内容正确。**字段是齐的,值可能是编的;类型是对的,数字可能是错的。格式约束管不了幻觉。
第三层:你自己校验。
这一层不能省,哪怕前两层都上了。解析失败怎么办、字段缺了怎么办、值明显不合理怎么办——这些分支必须写。
常见的兜底策略:重试一次(把错误信息带上,让它自己改)、降级(换个模型或退回简单模式)、拒绝(明确告诉用户这次没成功,而不是展示一堆乱码)。
还有个实践细节:**把「解析失败率」做成一个监控指标。**它悄悄上涨,通常意味着上游模型版本变了——尤其是你用了带 latest 的模型名的时候。
三层是叠加,不是三选一
① 在提示词里请求 给格式样例 +「第一个字符必须是左花括号,不要任何解释文字」
约九成 剩下那一成,放到线上就是每天几百次失败
② 用接口参数强制 response_format + schema:生成时就只允许产出合法的 token
语法必对 但只保证语法,不保证内容——字段齐了,值可能是编的
③ 你自己校验 解析失败 → 带着错误重试一次 · 降级 · 明确拒绝,别展示乱码 这一层不能省 哪怕前两层都上了
把「解析失败率」做成监控指标:它悄悄上涨,通常意味着上游模型版本变了。
第二层是可靠性提升最大的一步,能用就一定要用。但它守的是语法边界,越过这条线的内容正确性,仍然要靠第三层和后面的核验来兜。
格式本身要设计
光有约束还不够,格式设计得好不好,直接影响模型填得对不对。四条经验。
一、字段名要能自解释。category 比 c 好,confidence_0_to_1 比 score 好。模型是顺着字段名的语义在填值的,名字含糊,它就得猜你要什么。
**二、别嵌套太深。**三层以上的嵌套结构,填错的概率明显上升。能拍平就拍平。
**三、给枚举值划定范围。**要分类就把可选项全列出来——「category 只能是这五个值之一:…」。否则它会自己发明新类别,而且发明得很合理,让你一时看不出问题。
**四、留一个「不确定」的出口。**这条常被忘。如果所有字段都必填,遇到材料里没有的信息,它只能编一个。给一个 null 或者 "未提及" 的合法选项,等于给了它一条说实话的路——这是防幻觉最实在的做法之一。
和流式输出的冲突
这是产品设计上必须做的一个取舍,很多团队踩了才发现。
流式输出能大幅改善感知速度:用户看着字一个个冒出来,比盯着转圈舒服得多。但它和结构化格式天然冲突——**半截 JSON 是没法解析的。**你只能等它全部生成完,那流式就白开了。
三种处理方式,按场景选。
**一、给人看的就别要 JSON。**如果输出是直接展示给用户的一段文字,那就开流式、要纯文本或 Markdown,别为了「整齐」硬套结构。
**二、给程序读的就关流式。**数据抽取、分类打标这类,输出本来就是给代码用的,用户看不见中间过程,流式没有意义。关掉,用严格格式约束。
**三、两者都要,就拆成两段。**这是最常见的真实场景——既要展示一段自然的回答,又要拿到结构化的元数据。做法是:让它先流式输出给人看的正文,最后再输出一小段结构化数据,前端渲染正文,程序解析末尾那段。或者干脆分成两次调用,各管各的。
最后提醒一句,这个取舍要在设计阶段就定,别等前端做完了才发现格式对不上。「这段输出是给人看的还是给程序读的」——这个问题该在写提示词之前就问清楚。
常用调用参数 response_format 和 stream 这两个参数的完整说明。
给例子比讲道理管用 给一个格式样例,比描述格式有效得多。
幻觉产生的原因 格式约束保证不了内容真实,这两件事是分开的。
