如何从LLM中获取可靠的结构化数据

如何从LLM中获取可靠的结构化数据

💡 原文英文,约4000词,阅读约需15分钟。
📝

内容提要

本文介绍如何确保语言模型输出可靠的结构化数据。核心方法包括:用工具调用和JSON模式约束输出,先设计Schema而非提示词,区分语法、结构和语义错误,构建带本地修复和重试的循环,以及处理无法重试的失败。建议字段设为可空而非可选,并跟踪每次成功提取的尝试次数作为关键指标。

🔎

延伸解读

三类错误需区别对待

文章强调,模型输出错误可分为语法、结构和语义三类。语法错误如代码围栏或截断,可本地修复;结构错误如字段缺失或类型不符,需重试;语义错误如虚构日期,重试无效。混淆这三类错误是常见架构失误,应分别设计处理策略。

可空字段优于可选字段

作者建议将字段设为可空而非可选,以强制模型明确表示“无此信息”。可选字段允许模型静默省略,导致无法区分“文档未提及”与“模型遗漏”。可空字段将潜在幻觉转化为显式可检查的值,显著提升提取质量。

重试策略需区分失败类型

重试循环应区分速率限制错误与模式验证错误:前者需指数退避,后者应立即修复请求。同时,对于源文档缺失信息或存在歧义的情况,重试无法改善结果,应通过可空字段和人工审核处理,而非浪费令牌。

监控关键指标

文章强调跟踪每次成功提取的尝试次数(attempts per success)作为关键健康指标,并关注p95而非平均值。此外,记录验证错误路径分布和本地修复命中率,可提供比整体失败率更具操作性的洞察,帮助定位问题字段。

Q&A

如何确保语言模型输出可靠的结构化数据?

确保语言模型输出可靠的结构化数据需要综合使用多种方法:使用工具调用或JSON模式约束输出,先设计Schema而非依赖提示词,区分语法、结构和语义错误,构建带本地修复和重试的循环,并处理无法重试的失败。建议将字段设为可空而非可选,并跟踪每次成功提取的尝试次数作为关键指标。

为什么仅靠提示词要求模型返回JSON不够可靠?

因为语言模型是基于概率逐词生成的,提示词只是影响输出的因素之一,模型可能因训练数据、输入文档格式或上下文而偏离指令。实际中会出现Markdown代码围栏、日期格式错误、字段缺失、数组超长、截断等问题,这些失败类型不同,需要不同的处理方式。

约束语言模型输出的三种机制是什么?各有什么优缺点?

三种机制是:JSON模式、工具调用和约束解码。JSON模式保证输出是合法JSON,但不保证结构;工具调用通过强制模型调用特定函数来约束参数结构,支持广泛且约束较强;约束解码通过掩码采样使非法输出不可能,但可能迫使模型在信息不足时编造内容。

为什么建议先设计Schema而不是写更长的提示词?

因为Schema是主要工件,可以从中生成TypeScript类型、API的JSON Schema和运行时验证器,三者同步变化,避免漂移。而提示词是散文,无法强制执行,扩展性差。通过Schema可以精确约束字段格式、可空性等,提高提取质量。

在结构化数据提取中,为什么字段应该设为可空而不是可选?

可空字段强制模型明确决定是否提供值,null表示“文档中不存在”,而可选字段允许模型静默省略,无法区分“文档未提及”和“模型忘记”。可空字段将静默幻觉转化为显式可检查的值,提高数据可靠性。

如何构建一个不浪费token的重试循环?

重试循环应首先尝试本地修复(如去除Markdown围栏、提取JSON片段),然后发送修复请求而非全新尝试,包含原始提示、失败输出和具体验证错误。限制最大尝试次数(如3次),并区分速率限制错误(指数退避)和模式验证错误(立即修复)。

如何处理无法通过重试解决的失败?

对于源文档中不存在的信息、歧义和静默截断等失败,重试无法解决。应通过Schema设计(如可空字段)、置信度信号和人工审核步骤来处理,而不是盲目重试。对于截断,应检查停止原因并提高输出限制或拆分输入。

在结构化数据提取中,如何实现流式输出?

流式输出有两种方法:使用部分JSON解析器(如best-effort-json-parser)处理不完整JSON,或改变输出格式为每行一个对象,逐行解析和验证。后者更优,因为每个对象独立可解析,单个错误不会影响整体。

衡量结构化数据提取管道健康状况的关键指标是什么?

关键指标是每次成功提取所需的尝试次数(attempts per success),应记录并监控其p95值。此外,还应跟踪验证错误路径的分布和本地修复命中率,这些指标能快速反映质量回归。

在什么情况下不需要使用这些复杂的结构化数据提取技术?

当模型输出直接供人阅读(如聊天、摘要)、只提取一两个字段、或有人工审核时,不需要复杂机制。在探索阶段也应避免过早构建,先使用简单Schema和safeParse,根据实际失败逐步添加层。

🏷️

标签

➡️

继续阅读