LLM 提取失败了怎么办?别只盯着 Retry

杭漂码农 专家 11小时前 更新于 2026年7月25日 191 浏览 0 点赞 约 2 分钟

把验证失败当成一个简单的 Exception 抛掉,是很多大模型工程实践里的误区。在 LLM 提取流水线里,格式错误的发票、OCR 识别崩了的布局、或者违反 Schema 的响应,本质上都是系统“尚未建立信任”的数据。如果你的处理逻辑只有“重试”或“丢弃”,结果要么是浪费钱重复失败,要么是悄悄丢失数据。

真正能上生产环境的方案是建立死信队列(Dead-Letter Queue, DLQ)。

验证逻辑应该是路由的起点

不管是用 Constrained Decoding 还是后验验证,总会有数据掉队。一个健壮的验证边界不应该只返回 truefalse,而应该输出一个可执行的路由决策。

一个合格的验证结果得包含:

  • 使用的 Schema 和模型版本
  • 哪个字段失败了,具体原因是什么
  • 是格式损坏、内容缺失还是语义错误
  • 提取时的置信度信号
  • 判定这次失败是否可以通过重试解决

高置信度的数据直接走通,可恢复的传输故障走有限次数的重试,而模糊或无效的数据必须进入 DLQ 等待人工审查。

死信记录需要的是“证据链”

很多人的 DLQ 只是简单地把原始输入扔进去,这在排查时简直是灾难,因为你得在海量日志里去拼凑当时发生了什么。

我建议死信记录应该采用“信封”模式,包含以下元数据:

{
  "record_id": "unique_id_123",
  "idempotency_key": "key_abc",
  "source_ref": "path/to/immutable/doc",
  "payload": {
    "raw_response": "...", 
    "extracted_data": "..."
  },
  "context": {
    "model_version": "claude-3-5-sonnet",
    "prompt_version": "v2.1",
    "schema_version": "1.0.4"
  },
  "error": {
    "code": "SEMANTIC_INVALID",
    "detail": "Date cannot be in the future",
    "confidence_score": 0.65
  },
  "trace_id": "trace_xyz_789",
  "attempt_count": 3
}
这样在几天后回溯时,工程师能一眼看出:系统看到了什么 → 输出了什么 → 被哪个规则拦截了 → 现在是否可以安全重放。

别盲目重试,先给失败分类

不是所有失败都值得再次调用模型。我会把失败分为四类来处理:

  • 瞬时基础设施故障: 超时、限流。这种用指数退避(Exponential Backoff)重试即可。
  • 确定性契约失败: 同样的输入永远违反同样的 Schema。不改 Prompt 或模型,重试就是纯烧钱。
  • 源数据模糊: 文档本身没信息。直接路由给人工审核,别让模型在那儿瞎猜。
  • 版本漂移: 新文档格式导致原有的假设失效。这类数据需要隔离,用于更新 Schema 或微调 Prompt。
AI大模型LLMopensource

全部回复 (3)

咖啡续命折腾党 中级 11小时前
其实加个简单的格式校验逻辑,能过滤掉不少低级错误。
0 回复
杭漂码农 专家 11小时前
那如果死信队列积压太快,除了手动看,有啥高效的批量修复办法?
0 回复
架构师老刘 中级 11小时前
以前死磕Prompt想让它一次成功,结果心态崩了,后来才发现得得有个兜底方案。
0 回复

发表回复

支持 Markdown 格式