用校验闭环提高大模型输出可靠性
文章主张将模型生成纳入受控工程流程,让模型处理模糊输入,由确定性代码约束结果。以 JSON 提取为例,建议通过校验循环处理格式异常,而非仅靠加长提示词。
AI 深度解读
把 LLM 接进产品,难点不只是让它答对一次,而是让系统在它答错时也能继续工作。作者的核心主张是:模型负责理解模糊输入,确定性代码负责检查结果、约束行为,并在失败后组织纠错。
这篇短文值得读的地方,是把「继续改提示词」变成了一条具体的工程路径:生成、校验、反馈、重试。不过,作者把这套机制称为可靠组件,还需要补上边界。
模型负责理解,代码负责把关
作者反对一种常见工作流:随手写个提示词,把生成的函数复制进 pull request,然后期待测试通过。问题不在复制这个动作,而在于把模型输出直接当成了可信结果。
传统代码适合处理明确规则:输入是否合法、字段是否齐全、类型是否符合要求。模型则适合处理含糊的转换,例如从自然语言里提取结构化信息。
两者应该分工。
模型可以提出结果,是否接受结果要由程序决定。
拿数据提取来说,「返回 JSON」只描述了输出形式,却没有完整约束业务结构。能被 JSON 解析器读取,不代表对象一定包含 name 和 age,更不代表年龄符合业务要求。把这些检查交给代码,失败就有了明确的判定依据。
校验失败后,把具体错误交回模型
作者给出的做法是一个反馈循环:保留原始输入,调用模型生成结果;解析并校验,失败后把上次输出和具体错误一起加入上下文,再让模型修正。
下面的示例用于提取姓名和年龄,原样保留:
import json
from pydantic import BaseModel, ValidationError
class UserExtract(BaseModel):
name: str
age: int
def extract_with_retry(client, prompt, max_retries=3):
messages = [{"role": "user", "content": prompt}]
for _ in range(max_retries):
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
response_format={"type": "json_object"}
)
raw_content = response.choices[0].message.content
try:
data = json.loads(raw_content)
validated = UserExtract(**data)
return validated
except (json.JSONDecodeError, ValidationError) as e:
messages.append({"role": "assistant", "content": raw_content})
messages.append({"role": "user", "content": f"Fix this error: {e}"})
raise RuntimeError("Failed to generate valid schema after retries.")
关键看 validated = UserExtract(**data):response_format={"type": "json_object"} 之后,程序仍要检查字段结构。另一个细节是,按循环写法,max_retries=3 实际限制的是最多调用 3 次,包含首次调用。原文代码的循环体缩进不完整,直接运行前还需要修正。
这比反复强调「请严格遵守格式」多了一层可执行约束。模型收到的也不再是笼统的「你错了」,而是解析器或校验器给出的具体错误。
但循环有终点。尝试耗尽后,函数抛出 RuntimeError;调用方仍然要决定如何向用户解释失败,以及是否允许人工处理。
产品差异可能来自模型外面的代码
作者进一步提出:提示词工程正在消退,系统架构正在接替它。对依赖 AI 功能的 SaaS 来说,竞争优势更多来自模型周围的编排层,包括反馈循环、状态机和评估框架。
这里的「编排」,就是规定每一步怎么走:何时调用模型,拿什么检查输出,失败后是否重试,最终如何结束。
这个观点对日常 AI 编程也有启发。生成代码只是一步,检查结果、执行测试、根据失败信息修改,才构成完整流程。作者强调的不是某句提示词,而是让错误有机会被发现和纠正。
我的判断
我认同把约束写进程序,但「提示词工程正在消亡」说得过满。明确任务、提供必要上下文,仍然会影响第一次生成的质量;提示词和校验机制可以同时发挥作用。
更需要打问号的是可靠性。作者没有提供成功率、重试成本、延迟或对照实验,因此「变成可靠组件」是工程主张,不能当成已验证的效果。
通过结构校验,只能说明输出满足已声明的约束。
示例里的姓名可能提取错,年龄也可能是模型编的,只要类型符合要求,仍可能通过检查。此外,代码只处理 JSON 解析和 Pydantic 校验失败,没有展示 API 调用异常的处理。
相比继续加长提示词,校验循环的优势是验收条件清晰;相比单纯拒绝错误结果,它又提供了自动修复机会。代价则是更多调用和更长等待,是否划算,需要用实际任务评估。
能拿来做什么
- 在 Node 数据提取接口里,把 JSON 解析和字段校验设为两个明确步骤,只有通过检查的对象才能进入后续业务流程。
- 为自动纠错设置调用上限,并保留原始输入、失败输出和校验错误,让每次修正都有具体依据。
- 在日常 AI 编程中,把测试或类型检查的实际报错反馈给模型,同时继续检查业务逻辑是否正确。
- 用团队自己的典型输入和边界样例,对比单次生成与校验重试的成功率、调用次数和耗时,再决定是否采用。