构建印地语扫描件RAG助手:OCR与混合检索实战

印地语扫描件RAG实战:OCR质量、混合检索与工程细节决定成败。
本文分享为SVSU大学构建印地语/英语扫描通知RAG助手的经验。核心教训是OCR质量决定一切:需按页面检测语言、逐单元格重建表格、标记低置信度词。存储每个段落的页码和边界框,使答案可精准引用并高亮原文。向量检索无法处理代码、日期等精确查询,需混合检索(向量+关键词匹配+交叉编码器重排序),其中重排序改进最大。答案由语言模型基于段落生成,再由第二模型校验。审批工作流、角色权限、自动过期等工程细节对产品可用性至关重要。
构建印地语扫描件RAG助手:OCR与混合检索实战
大多数RAG演示从一堆英文PDF开始,但真实世界的文档往往更棘手。最近,开发者Abhishek分享了他为SVSU大学构建知识助手的经验——起点是一堆印地语和英语的扫描版通知文件,这些文件被复印、倾斜扫描,满是带线的表格,而大学工作人员需要从中快速找到答案。他的实践揭示了一个常被忽视的事实:在RAG系统中,检索和模型固然重要,但OCR质量决定了一切,而向量检索远不足以应对代码、日期等精确查询。

OCR质量决定一切
Abhishek在前几周把精力集中在检索和模型上,但很快发现,如果OCR输出的文本是破碎或错误的,后续所有环节都无法做好。他总结了三个改变全局的关键点:
- 按页面检测文字种类:在运行Tesseract之前先判断页面语言,并选用合适的语言模型。有些页面混合了印地语和英语,他的做法是两种都跑一遍,取置信度更高的结果。
- 逐单元格重建表格:通知文件里大多是表格,比如费用表、校历、代码列表。原始OCR输出会把表格变成一团乱麻。通过检测表格线并逐个单元格读取,"课程代码302"才能和"费用₹1,200"正确对应,而不是散落在三行里。
- 标记低置信度词汇:让审核者看到不确定的词,而不是静默猜测。
这条流水线在后台运行:工作人员上传扫描件,然后继续做自己的事。
Tesseract 是一个开源的 OCR 引擎,支持 100 多种语言,包括印地语(语言代码 hin)和英语(eng)。在混合语言文档中,通常需要分别用不同语言模型运行并比对结果。Tesseract 输出的每个词都附带置信度分数,可用于标记低置信度词汇供人工复核。此外,Tesseract 的表格识别能力有限,常把表格结构解析为线性文本,因此需要额外的表格线检测与单元格重构步骤。
pgvector 是 PostgreSQL 的扩展,为向量类型(如 vector(768))提供存储、索引(IVFFlat、HNSW)和相似度搜索操作符。它允许在同一个数据库中同时存储结构化数据(页码、边界框)和向量嵌入,简化了 RAG 系统的架构。查询时,<=> 操作符计算余弦距离,结合过滤条件可实现混合检索。
交叉编码器重排序 是一种两阶段检索的常用技术:先由向量检索或关键词匹配召回候选段落,再用交叉编码器(如 cross-encoder/ms-marco-MiniLM-L-6-v2)对每个「查询-段落」对进行精细打分。与双编码器不同,交叉编码器同时看到查询和段落,能捕捉更细粒度的相关性,但计算成本高,只适合对少量候选进行重排。
存储每个段落的精确位置
每个段落、每个表格行都被嵌入并存储到PostgreSQL中,使用pgvector扩展。同时,系统还保存了页码和来源的边界框。这看起来增加了工作量,但收益明显:答案可以引用"通知42,第3页第7行",点击引用会打开扫描件,并滚动、高亮到确切位置。对于需要根据答案采取行动的人来说,引用本身就是产品。
向量检索的盲区与混合检索
语义搜索在处理"关于滞纳金的政策是什么?"这类问题时表现良好,但面对"代码EX-2024-17说了什么?"就完全失效。通知文件里充满了代码、日期和精确金额,而这些恰恰是用户真正搜索的内容。他的解决方案是改进检索流程:
- 将问题重写为查询和印地语查询(用户说Hinglish,文档可能是两种语言之一)。
- 运行向量搜索找到相似段落。
- 对代码、日期和稀有词进行匹配。
- 合并结果,并用交叉编码器模型重新排序。
Abhishek表示,重排序器是整个项目中改进最大的一环。
基于段落回答,然后校验答案
语言模型拿到检索到的段落后,被要求仅依据这些段落回答,并附上编号引用。随后,一个更快的模型会对照源文档校验答案,标记出任何没有依据的声明。这类错误虽然罕见,但正是会破坏信任的那一类。
答案以流式方式呈现,边写边显示,这让整个体验感觉很快,即使检索需要一秒钟。
枯燥的部分才是产品
真正让这个助手可用的,是一系列看似无聊的工程细节:
- 草稿到激活的审批工作流:文档在审核前不能被使用。
- 角色和文档级可见性:有些通知只针对教职工。
- 自动过期:带结束日期的通知自动退役。
- 两步验证和锁定:这是大学数据,安全很重要。
- 自动答案质量测试:一组已知答案的问题在每次推送时于CI中运行,如果检索退化,部署就会失败。
CI/CD通过GitHub Actions运行到AWS服务器,使用Docker和Caddy。没有花哨的东西,这正是关键。
一个API,两个客户端
Web应用用Next.js构建,Android应用用Flutter。它们共享API和同一套账户。移动应用可以拍摄纸质信件、显示应用内更新通知。Widget测试在CI中于手机视口打开每个屏幕。由于API已经稳固,第二个应用的建设时间只是Web应用的一小部分。
如果重来,他会怎么做
Abhishek给出了三条经验:
- 从OCR评估集开始,而不是聊天UI。
- 让分块与文档结构(行、节)绑定,从第一天就如此,而不是固定窗口。
- 尽早为审批工作流预留时间,因为它对数据模型的影响比AI更大。
这个案例表明,构建面向真实文档的RAG助手,功夫往往在模型之外——OCR、结构化存储、混合检索和工程细节,才是让系统可信的关键。
相关推荐

Medicare 花5万治心梗,花100防心梗:医疗体系的错位
Medicare 为一次心梗治疗支付约5万美元,却不愿花100美元预防。本文解读 MedPage Today 观点文章及 Hacker News 热议,分析医疗支付体系为何偏向治疗而非预防,以及激励错配的深层原因。

英伟达或为Nscale西弗吉尼亚AI数据中心贷款联署担保
英伟达正考虑为Nscale在西弗吉尼亚州的AI数据中心贷款提供联署担保。本文分析芯片厂商介入数据中心融资的信号意义、风险分担逻辑及项目不确定性。

Claude Code v2.1.316 更新解析:企业级网关与多项稳定性修复
Claude Code v2.1.316 发布:新增企业网关池化组预算、分层策略模式、子智能体 effort 控制,修复 Shell、网络与会话恢复等数十项问题,并弃用 Opus 4.8 fast 模式。