资讯动态

《大模型输出护栏:格式、内容、降级三层设计》

发布时间:2026/10/8 11:22:20 来源:尧图企业网站定制
授权与合规声明本文为技术实践笔记示例均基于公开文档与自建环境中的实验不涉及任何未获授权的系统。文中结论仅代表个人实践小结与所涉厂商无利益关系。转载请注明出处。1. 为什么模型文本不能直接当作程序输入1.1 模型输出是自然语言不是数据把大模型的回复直接喂给后续代码是很多刚接入 LLM 的应用会踩的第一个坑。模型在训练目标上优化的是下一个 token 的概率分布它并不保证输出是一个能被json.loads解析的合法结构也不保证字段含义符合你的业务预期。换句话说模型吐出来的永远是一段文本而你的程序需要的是一份契约。两者之间的鸿沟就是护栏要补的地方。1.2 不验真就用的三类事故第一类是格式事故模型在 JSON 外面多聊了两句好的这是结果“或者把单引号当成双引号导致解析直接抛JSONDecodeError。第二类是内容事故字段类型对、结构对但值越界或自相矛盾比如开始时间晚于结束时间”。第三类是幻觉事故模型编造了一个并不存在的枚举值或对象下游按约定取值时拿到None。这三类事故的共同点是——它们都发生在模型已经生成完文本、但还没被消费的窗口里。1.3 本文护栏的边界只管模型文本需要先划清一条线本文讨论的护栏针对的是模型生成的文本尤其是你打算拿来驱动逻辑的那段输出。它不负责校验外部工具、API、数据库的返回那些属于工具调用链路的课题。把这两件事混在一起会让你的校验逻辑既臃肿又难维护。下表先给出三层护栏的总览。护栏层校验对象失败处置是否阻断主流程格式护栏能否解析为约定结构拒绝并重试是内容护栏字段值是否合法、合规拒绝或打回修正是降级层前两层都不可用时的兜底走规则路径 / 安全默认否替身2. 第一层格式护栏2.1 优先用结构化输出 / JSON Mode最省心的格式护栏是别让模型自由发挥。主流模型服务商都提供了结构化输出Structured Output或JSON Mode能力你声明一个 schema模型被约束只产出符合该 schema 的 JSON不能随意加字段、改类型。这相当于把格式校验的重心从事后解析提前到事前约束失败率显著下降。具体是否开启、开启到什么程度取决于你用的模型与 SDK 版本建议查阅对应官方文档确认。2.2 严格解析 失败重试即便开了 JSON Mode也不能假设永远成功。任何从模型拿到的文本第一步都应该是严格解析。解析失败的进入有限次数的重试retry每次重试都显式要求只返回 JSON不要任何解释文字。下面是一段最小可用的护栏代码注意它区分了解析失败和最终放弃两种状态。⚠️代码待验证importjsonimportredef_strip_code_fence(text:str)-str:# 去掉常见的 json ... 包裹mre.search(r(?:json)?\s*(.*?),text,re.DOTALL)returnm.group(1).strip()ifmelsetext.strip()defparse_model_json(raw:str,max_retry:int2):last_errNoneforattemptinrange(max_retry1):try:cleaned_strip_code_fence(raw)returnjson.loads(cleaned),Noneexceptjson.JSONDecodeErrorase:last_erre# 真实场景里这里应再次调用模型并重写 promptraw# 占位触发外层重试逻辑returnNone,fparse_failed_after_{max_retry}_retries:{last_err}2.3 给模型少自由的提示结构格式护栏的另一半在 prompt。一个有用的经验是把输出格式写得越具体解析失败越少。下面是个请求体的示例片段明确告诉模型输出契约减少它在 JSON 外啰嗦的概率。⚠️代码待验证{messages:[{role:system,content:你只输出 JSON字段为 {\label\: string, \score\: number}。不要任何解释。},{role:user,content:判断这条评论的情感}],response_format:{type:json_object}}格式策略适用场景额外成本自由文本 后处理解析模型不支持结构化输出重试次数多JSON Mode只需合法 JSON低Structured Output字段名/类型强约束最低失败率3. 第二层内容护栏3.1 用 JSON Schema 做字段级校验格式对了不代表内容对。内容护栏的第一件事是用一份 schema 约束字段的语义合法性。Python 里常用pydantic或jsonschema来做这件事pydantic适合把 JSON 直接映射成带类型的对象jsonschema则能直接吃一份 JSON Schema 文档做通用校验。下面用一个pydantic模型示范字段级约束。⚠️代码待验证frompydanticimportBaseModel,Field,ValidationErrorclassSentiment(BaseModel):label:strField(pattern^(positive|negative|neutral)$)score:floatField(ge0.0,le1.0)defvalidate_content(data:dict):try:returnSentiment(**data),NoneexceptValidationErrorase:returnNone,e.errors()3.2 业务规则与违禁内容检查schema 只能管形状管不了业务含义。比如结束时间必须晚于开始时间“推荐理由不能为空”“不能出现违禁词”这些要靠自定义规则。违禁内容检查建议做成可配置的词表 正则便于随合规要求更新而不是硬编码散落在各处。⚠️代码待验证BANNED[内部接口,root 密码]# 示例词表按业务补充defcheck_policy(obj:dict)-list[str]:issues[]reasonobj.get(reason,)ifnotreason.strip():issues.append(reason 为空)forwinBANNED:ifwinreason:issues.append(f命中违禁词:{w})returnissues3.3 校验失败的处置retag 还是 reject内容校验失败后要决定修还是扔。如果失败原因只是字段越界例如 score 超出 [0,1]可以尝试让模型基于原输出做最小修正retag这通常比整段重写更省 token。如果失败涉及语义自相矛盾或违禁内容则应直接 reject 并进入下一层降级。处置策略本身也应当可配置避免把能修和不能修混在一起。校验维度工具典型失败类型/范围pydantic / jsonschemascore 越界、字段缺失枚举约束pattern / enumlabel 出现未知值业务一致性自定义规则时间区间倒挂合规词表 正则命中违禁词4. 第三层降级4.1 规则兜底路径前两层都拦不住、或模型完全不可用时不能让主流程崩溃也不能把脏数据写进下游。降级的第一种形态是规则兜底用一套确定性的、不依赖模型的代码去产出尽量合理的结果。例如情感分类模型挂了就退回基于情感词典的简单打分摘要模型挂了就退回取前 N 句。⚠️代码待验证defrule_based_fallback(text:str)-dict:# 不依赖模型的最简兜底词典命中即 positivepos_hitssum(wintextforwin[好,赞,喜欢])neg_hitssum(wintextforwin[差,烂,讨厌])labelpositiveifpos_hitsneg_hitselseneutralreturn{label:label,score:0.5,fallback:True}4.2 安全默认值第二种形态是安全默认当连规则兜底都给不出有意义结果时返回一个明确标注fallbackTrue、且对下游明确可控、可被识别为兜底的结构。关键在于这个默认值必须可被下游识别为不可信而不是伪装成模型正常输出否则会把不确定性悄悄传下去。4.3 降级的可观测与开关降级发生后必须打点哪一层触发了降级、原因是什么、兜底结果是什么。没有可观测的降级等于静默失败。同时建议把降级做成一个开关——在模型服务抖动时快速切到规则路径在恢复后切回避免人工反复改代码。降级策略返回可信度适用规则兜底中受限场景可用模型不可用但规则可覆盖安全默认低明确不可信完全无可靠结果人工队列高待处理强一致业务5. 三层组合成一条 Pipeline5.1 顺序与短路三层不是并列的而是有顺序的先格式、再内容、最后降级。每层失败就短路到下一层但降级层失败连兜底都没有才真正向上抛错。这样的顺序保证能解析的先解析能校验的先校验实在不行再兜底避免一上来就走降级浪费模型能力。5.2 一个可复用的 Runner 骨架把三层串起来可以抽象成一个GuardRunner它接收原始模型文本依次执行 parse → validate → fallback并返回统一的结果结构含ok、data、source三个字段标记结果来自模型还是兜底。⚠️代码待验证defguard_run(raw:str,max_retry:int2):data,errparse_model_json(raw,max_retry)ifdataisNone:return{ok:False,source:fallback,**rule_based_fallback()}obj,verrvalidate_content(data)ifobjisNone:return{ok:False,source:fallback,**rule_based_fallback()}ifcheck_policy(obj.model_dump()):return{ok:False,source:fallback,**rule_based_fallback()}return{ok:True,source:model,data:obj.model_dump()}5.3 配置驱动的分层开关在真实项目里这三层最好由一份配置描述哪层开启、重试几次、降级走哪条路径。这样不同业务线能复用同一套 Runner只改配置不改代码。护栏本身也应支持灰度关闭便于在模型升级后重新评估哪层还能省。配套护栏 Runner 骨架我把上面这套GuardRunner抽成了可直接拷进项目的模块含解析、校验、降级三个可插拔函数。放在资料包里扫码即可获取Pipeline 阶段输入输出失败去向格式护栏原始文本字典 / 报错重试→降级内容护栏字典校验对象 / 报错降级降级层任意安全结果向上抛错6. 与工具返回校验不是一回事6.1 校验对象不同这是本文最想强调的一点模型输出护栏校验的是模型自己生成的文本工具返回校验校验的是外部系统API、数据库、命令行回传的数据。两者来源不同、信任假设不同。把模型的 JSON 和工具的 JSON 用同一套校验糊弄过去是工程上常见的偷懒也是 bug 温床。6.2 失败处置不同模型输出失败通常可以换种说法再问一次重试/降级都围绕模型工具返回失败则要排查的是网络、权限、接口契约重试策略完全不同且往往不能简单用规则兜底代替。两套校验应各自独立、各自可观测。6.3 何时需要两层都上当你的应用同时让模型产出结构化结果且调用外部工具时两层都要有。典型链路是模型决定调用哪个工具模型输出护栏管这一段→ 工具返回结果工具返回校验管这一段→ 模型再综合生成最终回复又回到模型输出护栏。不要因为某一层做得好就省略另一层。维度模型输出护栏工具返回校验校验对象模型生成文本外部系统返回信任假设不可信、会幻觉不可信、会超时/越界失败处置重试/降级/规则兜底重试/熔断/上游告警关注重点格式语义合规契约可用性边界7. 落地清单与度量7.1 上线前检查清单落地时建议先过一遍清单① 是否所有模型输出入口都走了格式护栏② 是否定义了最小够用的 JSON Schema③ 业务规则与违禁词是否可配置④ 降级路径是否一定返回fallback标记⑤ 降级是否被监控打点。这五条缺任何一条护栏都不算闭环。7.2 用哪些指标判断护栏够用判断护栏是否够用看三个比率即可解析成功率格式护栏生效后仍失败的比例、内容校验是否通过、降级触发率。三者随模型版本、prompt 调整会变化建议做成看板持续观察而不是上线一次就不管。具体阈值因业务而异本文不给出统一数字避免误导。7.3 常见误用常见误用有三种其一把模型输出当真理直接落库没有fallback标记其二只在成功分支写逻辑降级分支返回空对象导致下游KeyError其三把工具返回和模型输出用同一份 schema 校验导致一方变更连累另一方。这些都不是模型不够强的问题而是护栏设计缺位。配套落地检查清单我把第 7 章的清单和指标看板模板整理成了可勾选的清单文档对照着改你的项目就能补齐护栏闭环。放在资料包里扫码即可获取附表 A本文引用事实与出处对照表事实出处本文位置主流模型服务商提供结构化输出 / JSON Mode 能力各模型厂商官方文档建议按所用模型查阅2.1 节pydantic / jsonschema 可用于字段级校验pydantic、jsonschema 开源项目文档3.1 节模型输出失败可重试、可降级通用工程实践无单一权威出处2.2、4 节模型输出校验与工具返回校验应分离本文基于工程经验提出的结论6 节具体某模型版本的结构化输出开启方式无一手出处待验证2.1 节附表 B术语速查表术语含义输出护栏在消费模型文本前对其做格式/内容/降级校验的防护层格式护栏第一层确保模型输出能被解析为约定结构内容护栏第二层校验字段语义、业务规则与合规降级第三层前两层不可用时走规则兜底或安全默认结构化输出模型被约束只产出符合 schema 的 JSON 的能力JSON Schema描述 JSON 结构、类型、约束的声明式规范幻觉模型生成与事实或约定不符的内容fallback 标记降级结果中标识结果不可信、来自兜底的字段写在最后这篇用到的资料写这篇文章时我把模型输出怎么验真再用这条线从头到尾在自建环境里跑了一遍顺手也整理了几份配套的东西《输出护栏三层设计速查卡》把格式/内容/降级每一层的校验点和代码骨架压缩成一页方便对着改。《GuardRunner 可运行模块》文中那段 Runner 抽成的独立文件解析、校验、降级三个函数都可插拔。《落地检查清单与指标模板》第 7 章清单的勾选版加上降级触发率看板的字段建议。资料是我自己整理的放在下面这个码上扫码即可获取资料较多建议先看「全套 AGI 大模型学习路线」再挑一个实战项目跟练。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑