0Pricing
AI Prompt Engineering · 课时

修复与验证循环

修复格式错误的输出。

修复与验证循环 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。

修复循环为何存在

即使有模式,输出仍可能失败:令牌上限导致 JSON 被截断、模型臆造出额外字段、需要数字的地方出现字符串,或者违反业务规则。修复循环会检测失败,并将错误反馈给模型进行纠正。

它是一张安全网,能将 98% 的成功率提升到 99.9%。

验证—修复循环

典型循环是:生成、验证;如果无效,则带着具体错误重新提示,直到达到限定的尝试次数。

def generate_valid(prompt, schema, max_tries=3):
    msgs = [{'role': 'user', 'content': prompt}]
    for _ in range(max_tries):
        out = call_model(msgs)
        ok, err = validate(out, schema)
        if ok:
            return out
        msgs.append({'role': 'assistant', 'content': out})
        msgs.append({'role': 'user',
                     'content': 'Invalid. Fix this error and resend JSON only: ' + err})
    raise ValueError('repair budget exhausted')

具体错误胜过笼统错误

修复质量取决于反馈的精确程度。“无效的 JSON”帮助不大;而“评分字段必须是 1 到 5 之间的整数,但得到的是 7”几乎总能让模型在一轮内修正。

请将验证器的准确错误消息(路径加原因)反馈给模型。

def validate(obj, schema):
    v = jsonschema.Draft202012Validator(schema)
    errs = sorted(v.iter_errors(obj), key=lambda e: e.path)
    if not errs:
        return True, None
    msg = '; '.join(f"{list(e.path)}: {e.message}" for e in errs)
    return False, msg

分层验证

验证分为多个层级;请先进行成本最低的 check:

  • 语法层面——能否解析为 JSON?
  • 结构层面——是否符合模式?
  • 语义层面——取值是否满足业务规则和跨字段不变量?

即使折扣和小计都是有效数字,折扣也不能超过小计;这就是语义 check。

def semantic_ok(o):
    return o['discount'] <= o['subtotal'] and o['total'] == o['subtotal'] - o['discount']

确定性预修复

在消耗一次模型调用之前,请先尝试针对常见缺陷的廉价确定性修复:

  • 使用 strip 移除 Markdown 代码围栏。
  • 从周围说明文字中提取最外层 JSON 对象。
  • 移除末尾逗号。

只有确定性清理失败后,才升级为模型修复。

def extract_json(text):
    text = text.strip().removeprefix('json').strip()
    start, end = text.find('{'), text.rfind('}')
    if start != -1 and end != -1:
        return text[start:end + 1]
    return text

处理截断

如果 finish_reason == 'length',说明 JSON 已被截断;修复这个残片没有意义。相反,请提高 max_tokens、减少请求的数据量,或采用流式传输并请求继续生成。请区分截断和格式错误,因为两者需要相反的处理方式。

if resp.choices[0].finish_reason == 'length':
    # do NOT feed truncated JSON back; regenerate with more room
    return retry_with(max_tokens=resp_max * 2)

限制循环范围

无界修复会带来成本和延迟风险,陷入停滞的模型甚至可能无限循环。请始终限制尝试次数,添加每个请求的预算,并定义回退方案(平稳降级、排队等待人工审核,或返回安全默认值)。

try:
    data = generate_valid(prompt, schema, max_tries=3)
except ValueError:
    log_for_review(prompt)
    data = SAFE_DEFAULT

工具调用中的修复

对于函数调用,修复通道就是工具结果。返回结构化错误后,模型会在下一轮自行纠正,无需单独的循环。

msgs.append({'role': 'tool', 'tool_call_id': call.id,
  'content': json.dumps({'error': 'amount must be positive', 'got': args['amount']})})
# next model turn will re-issue the call with a corrected argument

幂等性与副作用

当修复循环包装的是一个操作(而不只是生成过程)时,请确保重试具有幂等性。使用幂等键,使重新发出的调用不会重复扣费或重复创建记录。请在提交副作用之前进行 validate,绝不要在之后验证。

观察修复率

修复率是一个领先的质量信号。修复率上升可能意味着提示词回归、模式过于严格或模型发生漂移。请使用 log 记录每次成功所需的尝试次数以及出现最多的错误路径,并在这些指标激增时发出警报。

metrics.histogram('llm.repair.attempts', tries)
metrics.increment('llm.repair.error', tags={'path': top_error_path})

将约束与修复结合

最强的流程会分层设置防御:使用受约束解码或严格模式模式来尽量减少失败,使用确定性清理处理廉价修复,再用有界的模型修复循环处理少量残留问题。单独依靠任何一层都不够。

快速检查

接口返回完成原因为长度,并且 JSON 已被截断。正确的处理方式是什么?

回顾

稳健的修复流程:

  • 按层级进行验证:语法、结构、语义。
  • 将精确到路径级别的错误反馈给模型。
  • 在支付模型调用成本之前,先尝试确定性清理。
  • 单独检测截断并重新生成。
  • 限制尝试次数,确保幂等性,并监控修复率。

您已完成结构化生成。下一门课程:防护栏与输出验证。

常见问题解答

「修复与验证循环」课时是免费的吗?

是的 — 「修复与验证循环」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「修复与验证循环」这节课中我会学到什么?

修复格式错误的输出。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「修复与验证循环」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 结构化输出的意义
  2. 提示中的 JSON Schema
  3. 工具与函数模式
  4. 修复与验证循环
← 返回 AI Prompt Engineering