ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Agent如何将合同发票等非结构化数据转化为结构化结果

Agent如何将合同发票等非结构化数据转化为结构化结果

只要碰过合同流转、发票归档、长文档检索这类活儿,一定会对“非结构化数据”又爱又恨。以前处理一份发票扫描件,得先转图片、再开OCR软件、手工核字段,光是“判断这张发票到底有没有被改过”就能耗掉一个下午;合同到了续签节点,法务捧着一堆版本逐字对比,眼睛都快看花。最近一年多,“Agent”这个概念被反复提起,很多人跑来问我:Agent到底最擅长处理哪类数据?合同、发票、文档这些全场景里,哪个工具表现最好?

我的回答可能会让一部分人失望:不存在一个封神型号,也没有一款工具能包打天下。但过去半年我系统地测过不少方案,从开源框架到订阅式智能平台都梳理过一遍,可以负责任地说,现在已经有一套非常成熟的组合打法,“解析模型 + 语义理解 + 工具调用 + 校验闭环”的Agent架构,在每个细分子场景里都能打败传统规则引擎和纯提示词工程。这篇文章就把我实际的选型思路、落地流程以及踩坑细节完整写出来,当作一份可以直接抄作业的笔记。

1. 为什么Agent成了处理合同、发票、文档的首选

1.1 非结构化数据的真正痛点:不是“识别”而是“理解”

先梳理一个容易混淆的概念。合同、发票、文档这类数据,最大的麻烦不是“看不清”,而是“读不懂”。扫描件里的文字,OCR技术五年前就能做到九成以上准确率,可问题是识别出来的文字只是一串字符,它没有结构、没有语义、没有上下文。

举个典型的例子:一份采购合同里写着“甲方于乙方交付标的物后15日内支付货款,但若乙方未提供全额发票则支付期限顺延”。这句话在传统OCR里就是一行普通文字,计算机根本不知道“15日”到底是付款期限还是交货期限,也不知道“乙方”和“甲方”谁是谁。再比如发票上同时出现“金额”“税额”“价税合计”三个数字,如果提取时只看字符不看位置关系,很容易把税额当成价税合计塞进数据库。

这正是“非结构化”的本质:信息存在于排版、位置、语义和上下文之中。传统工具擅长处理“长得规规矩矩”的字段,但现实中的合同没有固定模板,发票有折叠、有印章遮挡、有手写备注,长文档里还可能混着图表和批注。一旦离开模板范围,规则引擎就失灵了。

1.2 传统方案的死穴:规则、模板和无法泛化的模型

过去几年,处理这类数据的主流方案有三条路线,各有各的硬伤。

第一类是纯规则模板。金融、ERP厂商都做过这类能力,给某个银行的流水单做定制模板,字段坐标、字体、边框位置全是死的。做的时候精度特别高,但换一家供应商、换一个版本、加一个合并单元格,模板就当场报废。一个稍微大点的企业,可能要用几百套模板才能勉强覆盖日常文档,维护成本高到离谱。

第二类是传统光学字符识别加正则。这种方案最大的问题是脆弱。扫描件清晰度稍微差一点,印章压住了文字,表格线断掉了,错字一多后面的正则匹配就全乱套。更麻烦的是,很多字段不是靠正则就能提取的,比如“争议解决方式”,一段话里可能有三种表述,正则写多了反而误伤。

第三类是纯粹的通用大模型提示词调用。把整页文字一股脑扔给大模型,让它抽取字段。看起来聪明,实际在生产环境里飘忽不定。模型偶尔会编造不存在的条款,偶尔会把页码数字当成金额,而且没有校验机制,错了就是错了。

这三条路线本质上都缺了两个字:闭环。它们只负责“从文档到结果”的单向转换,结果对不对没人管。

1.3 Agent介入后的分工逻辑

Agent的介入,改变了处理链路的基本范式。过去是一把“更快更准的扫描枪”,Agent更像一个“有判断力的文档专员”。它不只是做识别,而是围绕目标拆解步骤:先做版面分析,再做字段抽取,再调用规则工具校验,校验不通过还能回到原文档里定位问题重新提取,最后把低置信度样本交给人工复核。

这套流程之所以管用,是因为Agent天然支持工具调用和多轮推理。处理发票时,它可以调一个金额计算工具验证“单价×数量=总价”;处理合同时,它可以调一个日期解析模块,把“2024年5月1日前”和“2024.05.01”统一成标准格式,再判断付款时间是否早于生效时间;遇到印章遮挡导致某个字段识别不全,它不会硬猜,而是直接定位原图区域做二次识别。

所以那些指望“找一个工具把文档全搞定”的思路,其实是把Agent看窄了。真正值得比较的,不是某个模型本身,而是整个Agent链路在不同场景下的组合表现。

2. 工具选型思路:评估Agent处理非结构化数据的5个核心维度

2.1 解析能力:文字抽取只是第一步

评估一个Agent方案,第一件事不是看它有多聪明的对话能力,而是看它的解析底座够不够扎实。

我自己的测试习惯是:准备一组混合文档,里面包含打印清晰的PDF、手机拍摄的照片、灰度传真件、带水印扫描件、表格嵌套复杂的长报告。先看三个基础指标:

  • 印刷体字符识别准确率。这一项现在主流方案差别不大,都能做到95%以上,真正拉开差距的是下面两项。
  • 手写体与印章处理。发票上常有手写备注,合同签署页有手写签名,印章覆盖区域里的文字是否还能提取出来,很多工具在这里直接败下阵。
  • 版面还原能力。表格里跨行跨列的单元格,拆开后顺序怎么排;两栏排版的长文档,先读左栏还是右栏;页眉页脚是否被当作正文。这个能力直接决定后续语义理解的输入质量。

我踩过的坑里最明显的一个:某文档智能方案对普通合同文本识别很准,但遇到带复杂表头的验收报告,表格内容全乱成一锅粥,原因是它在版面分析阶段把单元格顺序重排错了。解析能力不行,后面Agent再聪明也是白搭,因为输入本身就是脏的。

2.2 语义理解与结构化输出:能不能把“上下文”变成字段

第二个维度是看Agent把理解结果转化成一个稳定数据结构的水平。合同、发票处理的最终目标,不是让Agent“看懂”,而是要它输出一个符合下游系统要求的JSON或者数据库行。

评判标准很简单:给它一个明确字段清单,比如合同编号、签约主体名称、签约时间、含税总金额、付款周期、违约责任条款,它能准确找到这些字段吗?更深一层,它能不能处理模糊表达?比如合同里写“租期为两年,自乙方完成场地交接之日起算”,这里的“两年”是期限,“自乙方完成场地交接之日”是起算点,字段抽取时需要把它们拆开,且不能把“乙方完成场地交接之日”误当成签约日期。

这里推荐一个实用技巧:在Agent的提示词里内置示例样本,也叫结构化输出引导。出于篇幅考虑我放一段简化示意:

{ "contract_no": "HT-2024-001", "signing_date": "2024-03-15", "total_amount": { "value": 120000, "currency": "CNY", "tax_inclusive": true }, "terms": [ { "item": "payment_term", "content": "甲方应于发票收到后30日内付款", "start_event": "发票收到之日", "days": 30 } ] }

有了清晰的输出模板,Agent才不会随心所欲地发挥。看不出来的朋友们可以把这个schema当作一个“答题卡”,限定模型往格子里填答案,而不是让它写一篇小作文。

2.3 多轮修正与工具调用:遇到模糊信息怎么办

只看单轮抽取能力,所有大模型都差不多,真正的分水岭在于“一次没抽对怎么办”。

好的Agent会做三件事。第一,定义一个可观测的中间状态,在抽取的每个字段旁边附带置信分数;第二,当置信分数低于阈值时,自动触发一轮修复动作,通常是把原文档位置信息调出来,用多模态模型重新观察该区域;第三,如果修复后仍不确定,就调用外部工具做交叉验证,比如查历史合同库、匹配企业工商信息、计算税率是否自洽。

我做过一个发票处理流,里面有一步是调用计算工具验证“不含税金额乘以税率是否等于税额”,误差超过0.01元就判定为需要人工复核。这一步在传统方案里根本做不到,因为传统方案没有“知道自己在算什么”的全局意识。Agent可以把计算规则当成工具接进来,这才是它和普通识别程序本质上的区别。

2.4 安全性、成本与私有化部署

处理合同、发票时,数据安全是不能回避的问题。合同里包含商业机密,发票里包含纳税人信息和交易流水,如果企业有合规要求,数据绝对不能传到第三方公有云。

所以在选型时,我会明确问三件事:支持私有化部署吗?模型的输入输出是否有日志留存?敏感字段能否做本地脱敏?

成本方面,我通常用“单页文档处理成本”和“人工复核成本”两个口径来算。完整方案的实际花费有三块:解析底座的调用费、大模型语义理解的Token费、人工兜底的人力费。很多方案看起来单次调用很便宜,但准确率只有80%,意味着两成文档要人肉重看,那点省钱瞬间被人工成本吃掉。

2.5 不同场景下的推荐梯队

聊完维度,给一个按场景划分的选型梯度,用我自己的经验排序。

场景类型优先看中的能力推荐方案形态选型倾向
合同审查与条款抽取长上下文理解、条款关联私有化部署的语义型Agent,搭配RAG索引重语义型
发票批量核验录入字段精度、规则校验高精度解析引擎 + 规则校验工具组成的Agent工作流重解析型
复杂长文档归档检索版面还原、结构重建文档解析器 + 表格还原 + 问答Agent的组合综合型
知识问答型文档平台语义检索、来源引用检索增强生成型Agent,内置多轮纠偏问答型

你只要明确自己每天处理的主要是非结构化数据里的哪一种,选型方向就基本清晰:要精度选重解析,要理解选重语义,两者都要就选能编排混合链路的方案。我的体会是,别指望单一模型同时干好所有事,组合优于单点。

3. 实操全过程:从上传合同/发票到输出结构化数据的完整落地方案

3.1 第一步:文档预处理与版式识别

很多人拿到文档就直接扔给大模型,这是大忌。真实世界的文档太脏,尤其是扫描件和照片件。我惯常的做法是先建一条预处理管线。

  • 图像质量检查:判断是不是扫描件、清晰度够不够,DPI低于300的扫描件先做增强处理。
  • 倾斜矫正与去噪:手机拍出来的发票,边角透视畸变严重,不做矫正直接识别会导致字体变形。
  • 版面分析:把文档切分成标题、正文、表格、印章区、页眉、页脚等区块,并保留区块之间的阅读顺序。
  • 印章区域识别:标注出印章覆盖区域,方便后续特殊处理。

这一小节的操作意图非常明确:把文档从“像素层”提升到“结构层”,后续所有语义工作都在结构层上展开。版面分析环节,我建议优先选支持复杂表格还原的解析器,不要让大模型直接看连续长文本,因为纯文本会丢失坐标与位置关系,字段对不上时就很难回溯。

3.2 第二步:定义Agent任务与输出Schema

任务定义不是写一句“帮我提取合同字段”就完事,要做的事更多:

  • 确定要输出的字段清单,规定每个字段的类型,枚举型和自由文本型分开。
  • 给每个字段写下清晰的提取指引,注意说清楚“什么情况下不输出”和“什么情况下输出空”。
  • 准备少量示例样本,通常5到10个就够,放进提示词里作为few-shot引导。

我见过不少项目死在“输出Schema一步到位”上。第一版就把所有字段都定义得又细又严格,结果模型被迫在信息不足的时候强行猜测,空值率反而飙升。正确的做法是先定义一套宽Schema,允许模型标注“字段不存在”而不是硬填;跑一段时间积累真实样本后,再收紧成精确的窄Schema。

这里有个实际技巧:在Schema设计里增加一个数组字段,专门放“原文定位”,每个抽取字段都带上它在原文档中的页码、页内坐标或者段落ID。如果解析引擎已经给了区块ID,Agent在输出时直接引用区块ID,效果比坐标更直观。

3.3 第三步:设计召回、抽取、校验的Agent工作流

完成Schema定义之后,要规划Agent的内核执行逻辑。单纯让模型“答一次”远远不够,我通常会把流程设计成以下几个环节:

  1. 预检索:如果文档集合很大,先按文件名、日期、业务线做粗筛,不让Agent处理无关文档。
  2. 上下文装配:把版面分析后的区块按阅读顺序组装成上下文,必要时把表格区块转为Markdown格式,增强表格语义。
  3. 抽取调用:Agent读取文档结构,按Schema要求输出候选字段。
  4. 规则校验:调用可执行工具逐字段校验。比如日期字段必须是合法日期,金额字段必须能转数字,发票税率必须与发票类型匹配。
  5. 错误处理:校验不通过时,Agent根据错误类型重新观察源区,最多尝试两轮;若仍无法解决,进入人工复核队列,并附上失败原因说明。

这个工作流的黄金原则是:Agent本身不要直接写死规则,规则全部以工具的形式外置。原因很简单,Agent的强项是理解,工具的强项是精确计算。让Agent调用工具而不是让Agent做算术,准确率能提升一大截。

3.4 第四步:关键参数的调优与阈值设置

实操时最容易被忽略的是“参数如何定”。这里给组我反复测试后觉得稳妥的初始值,大家按自己场景微调:

  • 温度:合同、发票等事实抽取任务设为0.2以下。不要为了“创造性”调高温度,抽错一个金额的代价比回答生硬严重得多。
  • 置信度阈值:建议设为0.8。置信度低于0.8的字段,宁可进入人工复核,也不放行自动入库。
  • 最大重试次数:两轮足够。超过两轮还在同一个地方失败,大概率是文档本身缺损或Schema定义与文不对应,再重试只是浪费Token。
  • 文档分块重叠:长文档按语义切块时,相邻块之间保留10%左右的文本重叠,避免关键段落在切点被截断。
  • 批量并发数:根据解析引擎和模型服务的吞吐能力定,我习惯先压测一轮,看延迟曲线,找到性价比拐点。

设置置信度阈值时有一个数学上的理解方式:准确率和人工召回之间是此消彼长的关系。阈值调高,系统自动处理量变少,但出错率低;阈值调低,自动处理量变大,但错误字段漏进系统的概率增大。具体取多少,取决于下游系统的容错能力。财务系统入库后极难反向修正,所以金额字段的阈值我会直接拉到0.9。

3.5 第五步:批量回灌与异常样本迭代

最后一步不要跳过。任何Agent方案的第一版都不可能完美,真正决定长期效果的是后续迭代机制。

我在项目里做得最多的一件事就是建“坏样本集”。批处理跑完1000份文档后,把人工修正过的样本全部收集起来,按错误类型归成几类:字段漏抽取、字段抽错、格式不合法、源文定位失败、空白误报。然后定期把这些坏样本喂回模型进行微调,或者补充到few-shot提示词里。

这个迭代逻辑可以参考一个简单的衡量公式:每次迭代后,用固定测试集重新跑一遍,记录抽取准确率、空值率、人工复核率三个指标,只有三项全面改善才发布新版本配置。我的经验是,前三个迭代周期提升最快,人工复核率通常能从30%压到5%以内,后面进入平台期,就需要靠引入更多外部工具来做校验了。

4. 实战案例:一个合同审查Agent和一个发票核验Agent的搭建记录

4.1 合同审查Agent:条款抽取、风险提示与版本对比

合同场景的特点是长、复杂、条款关系强。一份采购合同可能二十多页,付款条款藏在第十五页,而关联的违约责任在第八页,需要Agent具备跨区域的关联能力。

我的搭建思路如下:先做版面分析和段落切分,按章节标题建立索引结构;再把整份合同按章节块交给Agent,Agent在理解每章内容的同时,把一个“条款关系图”逐步拼接起来。输出时,不仅提取签约主体、合同期限、总金额这类基本字段,还要生成风险提示项。

风险提示的设计是重头。我设置了几个固定检查项:

  • 收款账户信息是否齐全,开户行账号是否与签约主体名称对应。
  • 合同日期是否逻辑自洽,有没有“付款期限早于合同生效日期”的情况。
  • 金额大小写是否一致,数字格式是否被篡改。
  • 违约责任条款是否缺失,争议解决方式是否为空。

版本对比这个场景也值得一提。客户给的合同经常有多个版本,法务需要知道改了什么。传统做法是用文本diff工具,但效果很差,因为格式调整会导致大面积误报。我让Agent先对两个版本做章节级对齐,再逐个语义块比较,输出“仅措辞调整”“条款实质变化”“删除条款”“新增条款”四类结果,精确度比直接diff高出一个量级。

搭建完成后,法务团队的使用方式是:先让Agent快速过一遍合同并输出风险清单,法务只查看清单与原文定位,不用逐字重读。这个模式落地后,他们每份合同的平均审查时间从40分钟压到了15分钟以内。

4.2 发票核验Agent:从OCR到微指标校验的整链路

发票是另一个典型场景,它字段不算多,但对精度要求极其苛刻,一个小数点错位就是财务事故。

我搭建的发票Agent流程如下:

  1. 解析引擎识别发票版式,提取发票号码、开票日期、购买方、销售方、不含税金额、税额、价税合计、税率、校验码等字段。
  2. Agent对关键字段做内部校验:金额关系是否正确,税率是否在合理范围,购买方名称是否与内部供应商库匹配。
  3. 用计算工具验证金额关系:价税合计减去不含税金额是否等于税额,允许误差不超过0.01元。
  4. 对于印章遮挡区域,触发二次高清识别,只裁剪被遮挡的区域做局部识别,避免整页重跑。
  5. 低置信度发票自动进入人工复核队列,系统打印出“疑似问题字段 + 原图定位”给财务同事确认。

与传统做法相比,这套方案最显著的收益是“筛选复核”而不是“全量复核”。过去每张发票都要人工核对一遍,现在只有被Agent标记为低置信度或校验失败的那部分才需要人看。在一个月两万张发票的模拟测试里,人工复核量从百分之百降到了百分之八,而差错率并没有上升。

4.3 通用的文档问答Agent:让“查资料”真正变快

除了合同和发票,很多团队还需要一个处理各种杂七杂八文档的问答Agent。它不追求百分之百的字段级抽取,而是帮助人在海量文档里快速找到答案。

实现起来相对简单:文档解析后建立向量索引,用户提问时先检索相关片段,再让Agent基于检索片段生成回答。关键要求有两个,一是回答必须引用来源,包括页码和段落编号;二是如果检索不到相关内容,Agent必须明确说“没有找到”,绝不编造。

这个场景对上下文长度的要求比合同低,但检索质量直接影响答案质量。我用过一个技巧:把解析后的表格转成一行一行的“结构文本”,比如销售明细表格里的每一行,转成一个带行号和列名的自然语言句子,检索效果比纯Markdown表格好很多。原因是向量检索对语义密度更敏感,结构化句子的可匹配性比二维表格强。

5. 我在实际踩坑中总结的7条避坑清单

实操里走弯路是常态。为了让大家少交学费,把我经常踩的坑集中写一下,顺便给出排查思路。

常见问题可能原因排查与解决
抽取字段总是把税额当价税合计版面分析阶段字段区域切分错误检查解析引擎的区块坐标,修正表格行识别逻辑
合同日期逻辑混乱分块切断了条款间的从属关系按章节语义切块,保证条款与修饰句在同一个上下文
高置信度输出仍然出错置信度来自模型自说自话,没有经过校验层加权增加规则校验工具,置信度必须结合计算校验结果
Agent重试后仍在原地犯同样错误重试策略没有引入新信息第二轮重试时提供区块坐标和裁剪图,让模型“重新看一眼”
长文档处理Token消耗过大没有做版面区块裁剪,整页文本全量喂入只保留与目标字段有关的区块,页眉页脚与无关节一律过滤
人工复核变成“全文重看”Agent只输出最终结果,没有给出差异说明要求Agent生成差异摘要和字段定位,人工只看关键差异
Schema更新频繁,效果忽高忽低示例样本没有跟随Schema更新每次改Schema同步更新few-shot与回归测试集

再补充两条独家经验:

第一条,解析层的输出一定要保留“坐标回溯”能力。不管是文本区块还是表格单元格,每个元素都带上它在原文档中的页码、坐标、甚至像素框。这个数据结构刚开始看觉得冗余,但等到你要做定位、复核、裁剪、重识别时,它比任何高深的模型能力都更救命。

第二条,Agent的提示词里不要堆砌太多规则。太多规则会让模型顾此失彼,更容易出错。我建议把复杂规则做成外部代码工具,提示词里只写“调用工具做校验”,把“怎么校验”交给工具而不是模型。这个分离是Agent方案稳定性的核心。

我个人在实际操作中的体会是,处理合同、发票、文档,并不存在“选对一个大模型就万事大吉”的捷径,真正靠谱的是把解析、理解、校验、人工复核编排成一条温控良好的流程。Agent的价值并不在于替你做决定,而是把模糊、零散、乱序的非结构化数据,变成一条有来源、有置信度、可回查的结构化数据链。最后再建议一个扩展方向:把Agent的结构化结果再高亮映射回原稿,每个字段旁标注它在原文中的位置,这样审核人员只需要点开字段就能看到原始出处。信任感一旦建立起来,这套系统就不再是玩具,而是真正能每天顶班的数字员工。

返回列表