welclaiAI·TREND·DIGEST
应用案例

用 LLM 做数据抽取:把杂乱文本变成表格

把非结构化文本变成干净的行与列,正是 LLM 安静发光之处——前提是你定义好 schema、校验每个字段、并为杂乱的输入做好打算。

use-cases2026-05-08 10:46 KST·主编·7 分钟

大量有用的信息活在没有任何电子表格能读懂的文本里:邮件、发票、简历、客服工单、合同、笔记。梦想是把这一切都倒进干净的行与列,而这正是语言模型真正能交付成果的任务之一。与自由形式的生成不同,抽取有一个正确答案——那个值要么在文本里、要么不在——这让它比大多数 AI 用例既更有用、也更可核查。本文是一篇关于如何把它做好、以及它在哪里出错的概念性演练。

从 schema 出发,而非从文本

最常见的错误,是让模型"把重要的信息提取出来"。那个指令没有正确答案,于是你得到一些不一致的字段,它们从一份文档到下一份变着形状,永远无法被加载进表格。要改为先精确地定义目标 schema:你想要的确切字段、每个字段的类型(文本、数字、日期、类别、布尔),以及每个字段的含义。"发票总额作为数字,币种作为三字母代码,到期日作为 YYYY-MM-DD"是模型能稳定命中的目标。"那些钱的东西"则不是。schema 就是规格说明;下游的一切都取决于先把它弄明确。

把"缺失"当成一等公民的值

真实的文档是不完整的。一个你预期的字段常常会缺失,而这是最重要的一件要处理的事,因为一个被压着要填某字段的模型,会编造一个貌似合理的值,而不是把它留空。一个编造的发票号看起来和真的一模一样,却比一个空单元格危险得多,因为没有任何东西把它标记为错。所以要明确地定义"不存在"长什么样——一个 null、一个空字符串、一个特定的标记——并指示模型在值确实不在文本里时就用它。"如果字段不存在则返回 null;不要猜"是任何抽取提示词里最有价值的句子之一。

请求结构化输出并约束它

要求以结构化格式给出数据——通常是符合你 schema 的 JSON——而非你之后还得去解析的散文。大多数当前的模型和服务工具都支持符合你所提供 schema 的受约束或结构化输出,其机制在 Hugging Face 文档之类的资源里有详尽记载。把字段名按你想要的样子精确给出,为每个字段指定类型和允许的值,对分类字段给出选项的封闭列表,好让模型从你的分类法里挑选,而不是发明标签。约束越紧,输出越一致,而一致性就是全部要点——你在构建必须对得齐的行。

演示,而非只是讲述

当你在指令里包含几个完整演练过的示例时,抽取质量会跃升:一段有代表性的输入片段,以及你想从中得到的确切结构化输出。示例能传达散文难以传达的边界情形——如何格式化一个不完整的日期、当你预期一个值却出现两个时怎么处理、对一个存在但含糊的字段该怎么办。挑那些覆盖了别扭情形、而不只是干净情形的示例,因为干净的情形从来不是问题。少数几个精心挑选的示例,往往比几段规则更有价值,而把它们加上去几乎不花你什么。

抽取之后校验每一个字段

绝不要凭信任就相信抽取出的数据——在它一回来就校验它,用普通代码而非另一个模型。检查类型是否匹配:一个日期字段能解析为日期、一个数字字段是数值、一个类别是允许值之一。检查范围和格式:一个数量不为负、一个邮箱含有"@"、一个代码匹配它预期的模式。在你能的地方交叉核对内部一致性:那些行项目加起来等于陈述的总额吗。校验是你既抓住模型错误、也抓住真正畸形输入的地方,而它把无声的坏数据变成一个可见、可路由的异常。任何校验失败的东西,都该被标记给人,而不是加载进表格。

为失败的情形规划好路径

即便一个强健的流水线,也不会把一切都抽取正确,而假装不是这样,正是坏数据毒化数据库的方式。提前决定当抽取或校验失败时会发生什么:把低置信度或无效的记录路由到一个人工复核队列,而不是丢弃它们或盲目接受它们。这个"人在回路"的兜底,正是一个你能信任的系统、与一个随时间悄悄腐蚀你数据的系统之间的差别所在。它也恰恰是 NIST AI 风险管理框架之类的框架所鼓励的那种对后果有意识的控制——当一个错误有下游成本时,让一个人留在回路里。复核队列不是失败的标志;它是那个让你能自信地自动化掉简单的九成的安全阀。

拿一个有标注的样本来衡量

在你规模化地信任一个流水线之前,衡量它。手工标注一个有代表性的文档样本及其正确抽取,然后跑流水线、逐字段比对。逐字段的准确率告诉你哪些字段可靠、哪些需要打磨——而答案几乎总是不均匀的,干净的字段近乎完美,杂乱的字段则苦苦挣扎。这让你能做一个知情的决定:把可靠的字段自动化,把不可靠的路由到复核。每当你改变 schema、提示词、示例或模型时都重新跑一遍衡量,因为这些里的每一个,都可能悄悄劣化那些过去能用的字段。抽取是少数几个基准真值具体可得的 AI 任务之一,所以没有不去衡量的借口。

在怪罪模型之前先留意输入

抽取麻烦里出人意料的一大部分,和模型毫无关系,而完全在于文本是怎么到达的。文档到你手上时,可能是干净的数字文本、扫描的图像、把布局弄得一团糟的导出,或者那种视觉结构承载着原始文本会丢失的含义的格式。当一张表被压扁成一行连贯不断的文字、或一份扫描被转成带着字符错误的文本时,模型是在从垃圾里抽取,而无论你的 schema 多好,它都会产出垃圾。在你调提示词之前,先看看模型实际上被给了什么——流水线所见的那个输入,而非你屏幕上所见的那个。最高杠杆的修复往往在上游:更好的转换、保留的结构,或把图像当成图像处理,而不是硬把它们塞进一个会摧毁那个恰恰承载着答案的布局的文本通道。

也值得早早地去想成本和规模,因为抽取常常是一项高体量的活。把每一份文档都跑过最强、最贵的模型,很少是必要的;许多字段很简单,一个更小、更便宜的模型就能可靠地处理它们,而把更难的字段或更难的文档升级到一个更强的。能批处理的就批处理,并像衡量准确率那样衡量每文档成本。一个准确、却在你真实体量下不经济的流水线,实际上是无法部署的——而发现这一点的时机,是在设计期间,而不是在你已经把它对准了一百万条记录之后。

总结

把杂乱的文本变成表格,是你能用语言模型做的最可靠、最可核查、最安静有价值的事情之一——前提是你把它当成工程、而非魔法。先定义 schema,让缺失变得明确以便模型从不编造一个值,请求受约束的结构化输出,用示例来教,在代码里校验每一个字段,把失败路由给人,并拿有标注的数据来衡量。略过校验和复核队列,你得到的是一台快速生成貌似合理、却错误的行的机器。把它们建进去,你就能从那些没有任何电子表格读得懂的文本里得到干净的数据。

#data-extraction#structured-output#validation#tutorial