做 RAG 时,很多人把注意力放在向量库和模型上,却忽略了最前面的文档解析。PDF 里的表格错位、公式断掉、页眉页脚混进正文,后面检索再强也救不回来。
Chandra OCR 适合处理这类硬文档:复杂表格、表单、手写、多语言、数学公式、版面结构。它能把文档转成 Markdown、HTML 或 JSON,并保留更详细的 layout 信息。
这类工具的价值不在于把字识别出来,而在于让文档进入 RAG 前,先变成可检查、可切分、可追责的结构。
最小安装和两种运行方式
如果你只是先跑通,可以安装基础包:
pip install chandra-ocr推荐的轻量路径是使用 vLLM 后端。先启动服务:
chandra_vllm另一个终端处理 PDF:
chandra input.pdf ./output如果你希望本地 HuggingFace 方式运行,可以安装扩展:
pip install chandra-ocr[hf]
chandra input.pdf ./output --method hf想先看交互界面:
pip install chandra-ocr[app]
chandra_app实际项目里,先用 app 看输出质量,再决定批处理参数,会更稳。
不要直接把 OCR 输出入库
最常见的错误,是把 OCR 结果直接切块、embedding、入库。这样做很快,但质量不可控。
更好的流程是:
PDF 或扫描件
-> Chandra OCR
-> Markdown / HTML / JSON
-> 版面清洗
-> 表格和正文分开处理
-> 切块
-> 元数据补齐
-> 向量库和全文索引OCR 只是第一步。真正决定 RAG 质量的,是后面的清洗和切块。
输出格式怎么选
Markdown 适合普通知识库,因为它可读、容易 diff、适合人类抽查。
HTML 适合保留版面、表格和层级,尤其你要做页面预览或证据定位。
JSON 适合需要程序处理 layout、段落、坐标、图片、表格的场景,比如合同审查、票据抽取、表单还原。
可以这样定:
普通手册问答:优先 Markdown
复杂表格检索:Markdown 加独立表格文件
需要证据定位:HTML 或 JSON
表单抽取:JSON
人工校验流程:Markdown 和原始页面截图一起存表格要单独对待
表格是文档 RAG 的重灾区。把表格当普通段落切掉,很容易丢列名和行关系。
建议把表格拆成两份内容。一份保持原表格,用于人类查看;另一份转成行级文本,用于检索。
表名:供应商付款记录
列:供应商、月份、金额、状态
行:供应商 A,2026-03,12500,已付款
行:供应商 B,2026-03,8700,待审批这样用户问“哪些供应商三月还没付款”时,检索能命中行级语义;回答时再把原表格作为证据展示。
给每个切块补元数据
OCR 文档入库必须带元数据。至少要有:
{
"doc_id": "contract_2026_001",
"page": 12,
"section": "付款条款",
"content_type": "table_row",
"source_file": "contract.pdf",
"ocr_engine": "chandra",
"review_status": "unchecked"
}注意,这段 JSON 只是示例,生产里不要把敏感文件名、客户名、合同号随便暴露给模型。内部存储可以完整,进入 prompt 前要脱敏。
建一个小型 OCR 验收集
不要等上线后才发现表格识别不稳。先准备 20 页代表性文档:扫描件、横向表格、手写备注、双栏排版、中文英文混排、公式页、盖章页。
每次更新 OCR 工具或参数,都跑一次验收:
文字准确率是否可接受
表格列是否错位
段落顺序是否正确
页眉页脚是否被清理
公式是否保留可读形式
图片和图注是否被标记
输出是否能稳定切块RAG 项目里,OCR 验收应该和模型评测一样重要。底层材料脏了,模型越强,回答越像一本正经胡说。
一个实际落地建议
先别追求全自动。复杂文档场景,建议把高风险页打上 review_status。低风险资料自动入库,高风险资料进入人工抽查。
比如合同、财报、医学报告、招投标文件,OCR 后至少抽查关键表格和金额页。工程上可以把抽查结果写回元数据,后续回答时优先引用已确认内容。
Chandra 这类 OCR 工具让文档智能的前处理更强,但它不是魔法。真正的精品文档 RAG,是把 OCR、清洗、切块、元数据、检索和人工复核都串起来。少哪一段,后面都容易翻车。
用人工抽查修正切块规则
OCR 输出之后,不要马上做大规模 embedding。先随机抽 20 个切块,人工看它们是否像可以独立回答问题的证据。
差的切块通常有这些特征:
只有页眉页脚
表格列名和数据分离
跨页段落被截断
图片说明和图片分开
同一段法规被切成两半
多个主题混在一块看到这些问题,先改切块规则,不要急着调模型。RAG 最贵的幻觉,经常来自最便宜的切块错误。
为复杂表格保留原始上下文
表格转成行级文本后,检索会更好,但回答时可能丢掉表格结构。建议同时保存 table_id。
{
"chunk_id": "table_03_row_12",
"table_id": "table_03",
"row_text": "供应商 B,三月,8700,待审批",
"page": 8
}当模型引用某一行时,前端可以把整张表格一起展示,读者能看到上下文。这比只给一句行文本可靠。
多语言文档要分语种策略
中文、英文、日文、德文混在一起,embedding 模型如果选错,检索会明显变差。可行做法是先检测每个切块主语言,再决定 embedding 模型或索引分区。模型支持是一回事,系统检索稳定是另一回事。