内容提要
本文介绍如何确保语言模型输出可靠的结构化数据。核心方法包括:用工具调用和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,根据实际失败逐步添加层。