新一代提示词工程 · 知识全景图面向有工程基础、提示词工程尚未系统化的工程师
显示设置

校验与修复回路

Validation and Repair Loop

PE-S-05内容已写满G01确定性输出第 10 层

确定性输出校验重试

一句话结论

修复回路的价值不在于多试几次,而在于把「坏结构」从异常降级为可计数、可收敛的常规分支。

本页结构(可跳转)

G 生成 按提示与结构契约出结果 V 校验 结构校验 + 业务规则 写成与模型无关的纯函数 G->V P 通过 交付下游 V->P 通过 R 失败:把具体错误回喂 给出位置与期望值 (不是笼统的「格式错误」) V->R 失败 N 限次闭环 ≠ 异常分支 重试上限必须显式写死 超限样本必须落盘可查 并区分首次通过率与最终通过率 V->N R->G 限次重生成
回路图:生成 → 校验 → 把具体错误回喂 → 重生成的限次闭环,以及超限样本的处置。 (本站自制)

01为什么需要它

模型给出坏结构不是偶发故障,而是当前生成方式下的固有概率:字段类型写错、枚举值越界、必填项留空、引用不存在的 id。

适用边界

修复回路的成本模型划定了它的适用范围:每次重试都要重跑一次生成,因此它只适用于单次生成成本可控、且失败可被校验器表达的场景。若一次生成代价极高,例如长上下文的大模型整段重跑,事后修复会成倍放大成本,此时应优先在生成期约束(约束解码或 API 侧严格 schema),把结构层面的失败直接消除;若失败根因是指令歧义或资料缺失,错误回灌只会重复同一次失败,应回到提示词或检索侧解决。合规与安全类要求也不适合放进这条回路,它们需要确定性判定而不是概率重试。

02机制说明

一条可用的修复回路由四个部件构成。

03何时该用 / 何时不该用

按场景对照:先看条件,再看该怎么做。
类别场景 / 条件(总结)具体做法(细节)
该用输出要进入下游系统且失败可被机器判定时为解析与校验失败建显式回路,并把失败样本计数留档。
该用校验规则稳定且与模型无关时把校验器写成纯函数,错误信息带字段路径与期望值,便于换模型复用。
不该用单次生成代价极高的场景长上下文整段重跑时,应优先用约束解码或严格 schema 在生成期消除结构失败。
不该用把重试当万能药失败根因在指令歧义或资料缺失时,应先修提示词或检索,而不是加大重试次数。

04实验台

  1. filepython

    查看代码
    import json, jsonschema
    
    MAX_TRIES = 3
    
    def validate(raw, schema):
        try:
            obj = json.loads(raw)
        except json.JSONDecodeError as e:
            return None, f"JSON 非法:第 {e.lineno} 行第 {e.colno} 列,{e.msg}"
        errs = [f"{'/'.join(map(str, p.absolute_path)) or '<root>'}:{p.message}"
                for p in jsonschema.Draft202012Validator(schema).iter_errors(obj)]
        return (obj, "") if not errs else (None, "\n".join(errs))
    
    def repair_loop(call_model, prompt, schema, max_tries=MAX_TRIES):
        errs = ""
        for attempt in range(1, max_tries + 1):
            ask = prompt if not errs else (
                f"{prompt}\n\n上次输出被校验器拒绝,错误如下:\n{errs}\n"
                "请只修正这些问题后重新输出完整 JSON。")
            obj, errs = validate(call_model(ask), schema)
            if obj is not None:
                return obj, attempt          # attempt = 重试次数 + 1
        raise RuntimeError(f"修复回路触顶:{max_tries} 次仍未通过;最后一次错误:{errs}")

    预期观察:首次即通过时返回 attempt=1;把某个字段的值改成字符串后,errs 应给出该字段的路径与期望类型,而不是笼统的「格式错误」;连续失败达到上限时抛出异常并计数,不得无限重试。

  2. filemarkdown

    查看代码
    回路指标记录表(每次请求一行)
    列:请求 id / 首次是否通过 / 重试次数 / 最后一次错误类型(结构 / 语义)/ 最终是否通过
    派生指标:首次通过率 = 首次通过数 ÷ 请求数;修复成功率 = 重试后通过数 ÷ 首次失败数;平均重试次数 = 重试次数总和 ÷ 请求数
    纪律:触顶样本逐条留档并归类到具体错误类型,不得只统计最终通过率。

    预期观察:能区分首次通过率与最终通过率,并据此判断瓶颈在提示词与 schema 侧还是在回路效率侧;触顶样本可被归因到具体错误类型。

05证据

主张外部工具链把「输出是否合法」做成了声明式断言:promptfoo 的确定性评测项里直接含 is-json 这类结构断言,且断言可用 not- 取反,使校验步骤能在评测与 CI 里机械执行。

分级official

来源S-0077 https://www.promptfoo.dev/docs/configuration/expected-outputs/

原文

展开原文关键句
Deterministic eval metrics: equals / contains / icontains / regex / is-json / javascript / python / webhook ... Every test type can be negated by prepending `not-`

主张结构正确性可以在生成期由约束解码保证(XGrammar 自述约束解码可保证 100% 结构正确,且已是多数推理引擎的默认结构化生成后端),说明结构层面的失败并非只能靠事后修复。

分级official

来源S-0093 https://pypi.org/pypi/xgrammar/0.1.33/json

原文

展开原文关键句
It leverages constrained decoding to ensure 100% structural correctness ... It is the default structured generation backend for most LLM inference engines

主张「生成→反馈→再生成」这条自我修正路线已被主流教程目录收为独立技术条目(Reflexion),说明在生态里它是被承认的标准做法而非异常处理。

分级community

来源S-0066 https://www.promptingguide.ai/

原文

展开原文关键句
Prompting Techniques → Zero-shot / Few-shot / CoT / Meta Prompting / Self-Consistency / Prompt Chaining / ToT / RAG / ... / ReAct / Reflexion / Multimodal CoT / Graph Prompting

06术语

术语校验与修复回路 Validation and Repair Loop

界定对模型输出做结构或语义校验,失败则把校验错误回灌给模型重试,直至通过或达到重试上限;工程上必须显式设定重试上限,并区分首次通过率与最终通过率。

相关节点—

术语结构化输出 Structured Output

界定以 JSON Schema 等模式约束模型输出结构的机制;API 侧的严格模式通常要求全部字段必填且禁止额外属性,因此它能消除结构失败,但不判断字段取值是否正确。

相关节点—

术语三档严格度 Three Tiers of Strictness

界定按约束强度区分的三档做法:自然语言格式要求、模式提示(仅提示结构)、约束解码或 API 级 schema 保证;档位越高,留给修复回路的结构失败越少,回路主要面向语义失败。

相关节点—

07失效模式

08在本站知识结构中的位置

所属分组
G01确定性输出
依赖深度
第 10 层(同层节点彼此无先后约束)
前置PE-S-04→PE-S-05 本节点→后继无(终点)

在 交互全景图 中定位本节点。