当前位置: 首页 > news >正文

长文本审核踩坑实录:从OCR乱码到RAG精召回的实战经验

长文本审核踩坑实录:从OCR乱码到RAG精召回的实战经验

当法务专家一眼看穿大模型的"一本正经胡说八道",那种落差比跑20公里还难受

写在前面

在合同智能审核这条路上,我踩过的坑连起来能绕办公室三圈。文档结构复杂、语义偏法律条款化、普通OCR识别后空位错乱、格式崩塌——这些问题堆在一起,再强大的大模型也难免产生幻觉。经过长期重复造轮子的折腾,我想把这套"血泪经验"分享给正在做同类项目的同行,希望能帮大家少走几段弯路。


一、知识库体系与大模型选型:格式清理比模型选择更重要

1.1 技术栈选型

我们的知识库基座采用以下组合:

  • 向量库:pgvector
  • 重排模型:rerank 系列
  • 文本向量化模型:BGE-M3

1.2 最大的坑:语义分片割裂上下文

起初,我们直接对法律文件进行上传切片,依赖纯语义分片。结果发现:上下段落被强行分开,文本块支离破碎,完整条款被割裂成多个碎片,检索和审核效果大打折扣。

客户要求的是精确结果,而纯语义分片远远达不到。

1.3 解决方案:基于格式标记的结构化清洗

最终我们选择了"笨但有效"的办法——按照指定格式标记统一清理法律法规文件

标记含义
#一级目录
##二级目录
###三级目录
####.三级目录下的条款内容

虽然前期需要投入人力进行格式整理,但整理完成后,向量化切片得到的文本块完整且语义连贯,检索准确率明显提升。

经验总结:不要迷信纯自动化的语义分片,对法律这种强结构化文本,预先做格式标准化处理,性价比远超后期反复调参。


二、合同文本处理:Mammoth.js 拯救格式错乱

2.1 普通OCR的痛点

标准合同文本通常有固定模板,但模板中的空位和横线填写内容才是审核重点,常规条款只需知识库风险验证即可。

问题来了:用POI流转OCR提取文本后,提交给大模型的内容格式完全崩塌——文本堆砌在一起,空格、下划线、填写位置全部丢失。大模型面对一堆"乱码",自然无法给出准确的审核结论。

2.2 破局方案:Mammoth.js 转HTML

经过多轮对比,我们最终采用Mammoth.js.docx文件直接转换为 HTML。这样做的好处立竿见影:

  • 合同格式完整保留
  • 空位和填写区域清晰可辨
  • 提交给大模型的上下文结构完好

审核出来的结果自然更全面、更准确

2.3 核心代码片段

VUE前端(存储与读取HTML格式合同):

exportfunctionbuildContractHtmlKey(input){constid=String(input.contractId||input.documentId||'').trim()constfileName=String(input.fileName||'').trim()constfileUrl=String(input.fileUrl||'').trim()return[id,fileName,fileUrl].filter(Boolean).join('__')||`contract-${Date.now()}`}exportasyncfunctionsaveContractHtmlRecord(record){constkey=record.contractIdconstrecords=awaitreadContractHtmlLibrary()constnormalizedTextType=normalizeTextType(record.isUnifiedText||record.fields?.textType)constsavedRecord={...record,contractType:pickContractType(record),isUnifiedText:normalizedTextType,fields:{...(record.fields||{}),contractType:pickContractType(record),textType:normalizedTextType,isUnifiedText:normalizedTextType},updatedAt:Date.now()}records[key]=savedRecord// 同步存储至chrome.storage.local或localStorage}

Java后端(Word文档内容提取):

privatePdfOcrResultextractWordContent(StringfileUrl,StringfileName)throwsException{PdfOcrResultresult=newPdfOcrResult();Stringcontent;if(fileName.toLowerCase(Locale.ROOT).endsWith(".docx")){try(InputStreaminputStream=newURL(fileUrl).openStream();XWPFDocumentdocument=newXWPFDocument(inputStream);XWPFWordExtractorextractor=newXWPFWordExtractor(document)){content=extractor.getText();}}else{try(InputStreaminputStream=newURL(fileUrl).openStream();HWPFDocumentdocument=newHWPFDocument(inputStream);WordExtractorextractor=newWordExtractor(document)){content=extractor.getText();}}result.setContent(content);result.setCurrentPage(1);result.setTotalPages(1);result.setPdfUrl(fileUrl);result.setFileName(fileName);returnresult;}

三、RAG增强的至暗时刻:从"幻觉狂欢"到精准召回

3.1 多LLM并行抽取策略

我们将提交给大模型的合同文本,通过多个LLM并行处理,每个LLM只负责指定的几项审核任务。这样做的好处:

  • 任务解耦,降低单次处理的复杂度
  • 每个模型专注抽取特定内容,精度更高

审核过程中检测到不合规条款后,输出到融合节点LLM进行语义增强,使其成为可被知识库检索的内容。

3.2 召回策略的两难困境

在知识库检索环节,合同文本的语义整体偏"平仄",我们采取了广检索 + 精召回的策略。但问题随之而来:

策略问题
精确召回要么不输出,要么输出的内容幻觉极重
粗略召回内容不够精准,噪音太多

最让人崩溃的是:大模型输出的内容看似有理有据、引经据典,但拿到客户那边,法务专家一眼就看出全是胡编乱造。初次看到模型输出时的快感不亚于跑完5公里,而被客户当面拆穿时的落差,比跑20公里还难受。

3.3 终极解决方案:ES双验证机制

痛定思痛,我们回归"老路子"——引入Elasticsearch进行二次验证

大模型输出 → 提取关键字 → ES检索知识库 ↓ ┌──────┴──────┐ ↓ ↓ 检索到内容 检索不到 ↓ ↓ 直接输出 标记"需人工验证" ↓ ┌───────┴───────┐ ↓ ↓ 验证正确 验证错误 ↓ ↓ 标记为"已采纳" 标记为"已废弃" 后续可直接引用 后续ES检索直接过滤

这套机制上线后:

  • 精准度大幅提升,幻觉输出显著减少
  • 人工介入可控,只处理知识库未覆盖的边界案例
  • 持续迭代,已验证正确的内容会沉淀为知识库资产

四、总结:技术服务于效率,而非替代工作者

回顾整个历程,有几点核心体会:

  1. 格式处理是地基:无论是法律文件还是合同模板,投入精力做好结构化清洗,比换模型、调参数回报更高。

  2. 多阶段验证胜过单次大模型推理:用ES做"事实核查"层,是抑制幻觉最务实的手段。

  3. 人工介入不是失败,而是闭环:标记不确定项、人工验证、沉淀知识库——这是一条可持续优化的路径。

  4. 技术跟随业务变化:不管是RAG增强还是模型微调,终极目标都是提升工作者的效率,而不是解决工作者本身

AI辅助的终点,不是替代专业判断,而是让专业人士能更专注于真正需要人类智慧的那部分工作。


作者简介:多年企业服务SaaS后台开发经验,现专注于AI辅助合同智能审核领域。欢迎同行交流讨论。


本文首发于CSDN,转载请注明出处。

http://www.jsqmd.com/news/1077154/

相关文章:

  • 终极指南:发现689款免费macOS开源应用,让你的Mac更强大![特殊字符]
  • Video2X:AI视频增强神器,4K超分辨率与智能插帧全解析
  • MuleSoft驱动的企业级AI编排:LLM如何安全嵌入核心业务流
  • 5分钟掌握NewTab Redirect:彻底告别Chrome无聊新标签页!
  • synchronized 和 ReentrantLock 到底差在哪——从底层扒到应用场景
  • RHEL8-9 RPM 全参数详解
  • MySQL - extra->>“$.multiple“用法详解
  • 【系统优化】C盘空间清理终极指南:8种方法从原理到实操
  • GLM-5.1深度集成Coding Plan:AI编码从API调用到开发动作的范式升级
  • Java毕设项目: 基于 SpringBoot+Java 的社区数字化治理中智慧物业综合运维系统设计与实现(源码+文档,讲解、调试运行,定制等)
  • 如何为Windows系统上的LG Ultrafine显示器实现专业级亮度控制
  • 用 Codex 联动 Agnes 搭建 AI 视频流水线:从单镜到连贯短片
  • 快充充电器电压取电芯片可请求9V、12V、20V等
  • 文化IP联名服饰收益计算器,输入IP授权费,定价,销量,自动核算联名纯利润。
  • 抖音无水印下载终极指南:3分钟学会批量保存任何内容
  • CentOS 7 上升级 GCC版本
  • 如何在5分钟内完成系统镜像烧录:Balena Etcher终极指南
  • 塞尔达传说旷野之息存档编辑器:打造完美海拉鲁冒险的终极指南
  • 湛江中学无人机科创课程落地案例 一年斩获十五项省级科创奖拆解分析
  • 2026手机条码标签打印软件盘点:4款移动端工具适配多场景选型指南
  • 51-C20+实时时钟+校时+吃药检测+药品分类+药量显示+3次定时+声光提醒+OLED屏+(无线方式选择)-3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Wedecode:如何用3分钟破解微信小程序的黑盒困境?
  • 3步掌握LeetDown:A6/A7设备iOS降级终极指南
  • Spring Boot 异步任务线程池配置
  • OpenClaw 对接淘宝商品详情 API,搭建自动化竞品监控选品系统(完整实操教程)
  • 3步完成黑苹果配置:OpCore Simplify让OpenCore EFI创建变得简单快速
  • AI 机器人神经与基建核心
  • STM32-S82+RTC时钟+校时+剩余药量+语音提醒+吃药检测+药品分类+药量显示+3定时+TFT屏+(无线方式选择)-3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可
  • 社交平台推荐算法三阶段解析:召回、排序与重排
  • 糯玉米供应商哪家比较靠谱