主题
10.1 多模态 RAG 概述与场景分析
从纯文本到多模态:RAG 的下一个前沿
前面九章我们构建了一个功能完善的企业知识库问答系统,它能够处理 PDF、Word、Markdown 等各种格式的文本文档,通过向量检索 + LLM 合成的方式回答用户的自然语言问题。但如果你仔细观察真实世界中的知识形态,会发现一个有趣的事实:人类的知识远不止文本这一种形式。
产品手册里有电路图和接线图;培训材料里有操作截图和流程图;客服工单里附带了用户报错的屏幕截图;技术文档里有数学公式和代码片段;质检报告里有设备照片和检测曲线;设计规范里有 CAD 图纸和 3D 渲染图。这些非文本信息往往包含了文本无法替代的关键知识——一张接线图比一千字的文字描述更能说明问题,一段错误截图比描述"页面显示异常"更有助于排查。
这就是**多模态 RAG(Multi-modal RAG)**要解决的问题:让 AI 系统能够同时理解和检索文本、图像、表格、图表等多种模态的信息,并基于这些多模态上下文生成准确的回答。本章将作为第二个完整项目,带你从零构建一个支持图片、表格、图表等多种内容类型的智能问答系统。
什么是多模态 RAG
传统 RAG (单模态) vs 多模态 RAG 的对比:
传统 RAG:
┌──────────┐ ┌──────────────┐ ┌─────────┐
│ 用户问题 │ →→ │ 文本 Embedding│ →→ │ 文本检索 │ →→ LLM 回答
└──────────┘ └──────────────┘ └─────────┘
仅处理文本
多模态 RAG:
┌──────────┐ ┌──────────────────────────────┐ ┌─────────────┐
│ 用户问题 │ →→ │ 多模态理解 │ →→ │ 跨模态检索 │ →→ 回答
│ (可含图片) │ │ · 文本 Embedding │ │ · 文本↔图片 │
└──────────┘ │ · 图片特征提取 (CLIP/ViT) │ │ · 表格结构化 │
│ · 表格/图表解析 │ │ · 图表语义化 │
└──────────────────────────────┘ └─────────────┘多模态 RAG 与传统 RAG 的核心区别在于三个层面:
数据层面的扩展:不再只处理纯文本,而是能接受图片(照片、截图、扫描件)、表格(Excel/CSV/HTML table)、图表(折线图、饼图、流程图)、公式(LaTeX/MathML)等作为输入数据。每种模态都需要专门的解析和理解方式——你不能把一张 PNG 图片直接塞进文本 embedding 模型里。
检索层面的融合:当用户提问时,系统需要判断这个问题可能需要哪种模态的信息来回答。"这个接口的返回值是什么?"可能需要看 API 文档的表格;"这个错误长什么样?"需要看错误截图;"销售趋势如何?"需要看图表。更复杂的是,有些问题的答案横跨多种模态——比如"部署架构是怎样的?"可能需要同时参考架构图(图片)和配置说明(文本)。
生成层面的增强:LLM 在合成回答时,不仅要基于文本上下文,还要能"看到"图片内容。这需要使用支持视觉输入的多模态模型(如 GPT-4V、Claude 3、Gemini Pro Vision),或者将图片转换为文本描述后再输入给纯文本模型。
为什么现在做多模态 RAG 正当时
多模态 AI 并不是一个新概念——早在 2021 年 CLIP 模型发布时就已经有了图文对齐的能力。但直到最近,构建一个生产级的多模态 RAG 系统才变得真正可行。原因有三:
第一,多模态大模型的成熟。GPT-4V(GPT-4 with Vision)在 2023 年发布后,首次让一个模型同时具备了接近人类的视觉理解能力和强大的文本推理能力。它不仅能识别图片中的物体,还能理解图表趋势、阅读表格数据、解读手写笔记、分析 UI 截图。Claude 3.5 Sonnet 和 Gemini 1.5 Pro 在这方面也达到了类似水平。这意味着我们终于有了一个可靠的"大脑"来处理多模态信息。
第二,LlamaIndex 对多模态的原生支持。LlamaIndex 在较新的版本中引入了 MultiModalNode、ImageDocument、ImageRetriever 等专门的数据结构和组件,使得在框架内处理多模态数据变得像处理文本一样自然。你不需要自己从头搭建一套多模态管线——LlamaIndex 已经帮你铺好了路。
第三,成本的大幅下降。调用一次 GPT-4V 分析一张图片的成本大约在 0.01-0.03 美元之间(取决于图片大小),比两年前便宜了约 80%。对于企业级应用来说,这个成本已经完全可以接受——即使每天处理 1000 张图片,月成本也就几百美元。
典型应用场景
为了让我们要构建的项目更加具体,下面列出几个多模态 RAG 最有价值的应用场景:
场景一:智能技术文档助手
这是最直接也是需求最强烈的场景。想象一下一个软件开发团队的内部 wiki:
python
TECH_DOC_USE_CASE = {
"数据类型": {
"text": ["API 文档", "README", "设计文档", "代码注释"],
"image": [
"架构图 (系统架构/网络拓扑/数据流)",
"时序图 (API 调用时序/消息流转)",
"ER 图 (数据库关系)",
"UI 截图 (界面原型/实际效果)",
"报错截图 (常见错误及解决方案)",
],
"table": [
"参数对照表 (请求/响应字段定义)",
"状态码表 (HTTP Status / 业务错误码)",
"配置项表 (环境变量/功能开关)",
"版本对比表 (v1.0 vs v2.0 差异)",
],
"chart": [
"性能基准图 (QPS/延迟/吞吐量)",
"依赖关系图 (模块/服务依赖)",
"部署拓扑图 (K8s 集群布局)",
],
},
"典型查询": [
("用户认证的完整流程是什么?", "需要时序图 + 文本说明"),
("订单服务的数据库表结构?", "需要 ER 图 + 字段表"),
("v2.0 新增了哪些 API?", "需要版本对比表 + 变更日志"),
("这个 500 错误怎么解决?", "需要报错截图 + 排查步骤"),
("系统的性能瓶颈在哪?", "需要性能基准图 + 优化建议"),
],
}在这个场景中,如果只有文本 RAG,用户问"用户认证流程是什么",系统只能找到零散的文字描述拼凑出一个不完整的回答。但有了多模态能力,系统可以找到那张精心绘制的认证时序图,把它连同相关的文字说明一起交给 GPT-4V,生成的回答就会包含清晰的步骤描述和关键节点的解释。
场景二:产品/制造知识库
制造业企业的知识库中充满了图片和图表:
python
MANUFACTURING_USE_CASE = {
"数据示例": {
"装配图纸": "爆炸图/装配顺序图/零件清单",
"工艺卡片": "工序流程图/SOP 步骤图",
"质量标准": "外观检验标准(合格/不合格样品对比图)",
"设备手册": "控制面板照片/指示灯含义表/报警代码表",
"安全规范": "PPE 穿戴示意图/危险区域标识图/应急流程图",
},
"痛点": [
"新员工看着文字版 SOP 还是不知道怎么操作",
"老员工的经验都在脑子里('这个声音不对就是轴承坏了'),离职就没了",
"质检标准靠人眼比对,效率低且不一致",
"设备故障时翻厚厚的 PDF 手册找不到对应的图",
],
"多模态价值": [
"拍张设备照片就能问'这个按钮是干什么的?'",
"上传零件照片问'这个装在哪里?'自动定位到装配图",
"展示不良品照片问'这属于哪类缺陷?'自动匹配检验标准",
],
}场景三:医疗/科研文献助手
医学和科研领域是多模态 RAG 的天然战场——论文中充斥着实验结果图表、病理切片影像、分子结构式等:
python
MEDICAL_RESEARCH_USE_CASE = {
"数据类型": {
"CT/MRI/X光": "医学影像及其诊断报告",
"病理切片": "显微镜下的组织图像",
"实验图表": "生存曲线/剂量反应图/统计显著性图",
"分子结构": "化学分子式的 2D/3D 表示",
"流程图": "诊疗路径/实验方案/信号通路",
},
"能力要求": {
"精度": "极高 — 医疗容错率极低",
"可追溯": "必须标注每条回答的证据来源",
"隐私": "患者数据脱敏合规 (HIPAA/GDPR)",
"专业术语": "准确使用医学术语,不能通俗化过度",
},
}项目范围与边界
基于以上场景分析,我们的多模态 RAG 项目聚焦于以下范围:
项目范围界定
✅ 本项目覆盖:
├── 文本 (Text) — Markdown / 纯文本 / 富文本
├── 图片 (Image) — PNG/JPG/WebP(截图/照片/图表)
├── 表格 (Table) — HTML Table / Excel / CSV 解析为结构化数据
├── 图表 (Chart) — 折线图/柱状图/饼图的语义理解
└── 混合文档 — PDF 中包含图文表混合内容
❌ 本项目暂不覆盖:
├── 视频 (Video) — 需要视频帧提取 + 时序理解(可后续扩展)
├── 音频 (Audio) — 需要 ASR 转文字(可接入 Whisper)
├── 3D 模型 (3D) — CAD/点云(需要专用工具链)
├── 医学影像 (DICOM) — 需要专业预处理管道
└── 实时摄像头输入 — 需要流式处理架构技术选型与架构预览
多模态 RAG 系统技术栈
┌─────────────────────────────────────────────────────┐
│ Frontend │
│ Vue 3 + 图片上传/拖拽/预览/标注 │
├─────────────────────────────────────────────────────┤
│ API Layer (FastAPI) │
│ · 文件上传 (multipart/form-data) │
│ · 多模态问答端点 │
│ · 图片分析独立端点 │
├──────────────┬──────────────────────────────────────┤
│ │ Core Engine │
│ 文本管线 │ 多模态管线 │
│ ┌──────────┐ │ ┌─────────────────────────────┐ │
│ │ Text │ │ │ Image Understanding │ │
│ │ Embedding│ │ │ · GPT-4V 视觉理解 │ │
│ │ (OpenAI) │ │ │ · CLIP 图文对齐检索 │ │
│ └──────────┘ │ │ · OCR 文字提取 (Tesseract) │ │
│ │ │ │ │
│ │ │ Table Parsing │ │
│ │ │ · camelot/pdfplumber 表格提取 │ │
│ │ │ · 结构化 → Markdown 转换 │ │
│ │ │ │ │
│ │ │ Chart Understanding │ │
│ │ │ · Deplot 图表数据提取 │ │
│ │ │ · 趋势/数值/类别理解 │ │
│ │ └─────────────────────────────┘ │
├──────────────┴──────────────────────────────────────┤
│ Storage Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Qdrant │ │ Postgres │ │ MinIO/S3 │ │
│ │ (Vectors)│ │ (Metadata)│ │ (Images) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────┤
│ External Services │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ GPT-4o / GPT-4V│ │ OpenAI Embedding│ │
│ │ (多模态理解+生成)│ │ (文本+图片Embed) │ │
│ └────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────┘相比第9章的企业知识库系统,多模态 RAG 项目有几个关键的技术差异:
GPT-4V 替代/补充 GPT-4o 作为核心 LLM:GPT-4V(Vision)具备视觉理解能力,能够接收图片作为输入并理解其内容。在多模态场景下,它是不可或缺的组件。当然,如果你的预算有限或对延迟敏感,也可以用"CLIP 提取图片特征 → 将图片转为文本描述 → 用普通 GPT-4o 生成回答"的方式来降低成本。
图片存储的独立化:文本可以直接存入向量数据库(embedding 后的向量和原始文本都很小),但图片文件本身太大(通常几十 KB 到几 MB),不适合存在 Qdrant 或 PostgreSQL 里。所以需要一个对象存储服务(MinIO 或 AWS S3)来存放原始图片文件,而在数据库中只存储图片的 URL 或引用 ID。
新增图表理解模块:传统的 OCR 只能提取图片中的文字,但对于图表(chart)来说,文字只是标签——真正的信息隐藏在柱子的高度、折线的趋势、扇区的比例中。我们需要专门的工具(如 Google 的 Deplot 或微软的 Chart-to-Text 模型)来把这些视觉元素转化为结构化的数据描述。
核心挑战与应对策略
构建多模态 RAG 系统面临着一些独特的挑战,我们在开始编码之前先梳理清楚:
挑战一:跨模态语义对齐
文本和图片存在于完全不同的表征空间中。文本 "销售增长了 20%" 和一张显示上升趋势的柱状图表达的是同一个意思,但在计算机看来它们是完全不同的东西——一个是字符串序列,另一个是像素矩阵。如何让系统能够理解"这个问题可以用这张图来回答"?
策略:使用 CLIP(Contrive Language-Image Pre-training)模型做图文对齐。CLIP 通过海量图文配对数据训练,学会了将文本和图片映射到同一个共享的嵌入空间中。在这个空间里,语义相近的文本和图片的向量距离会很近。LlamaIndex 内置了对 CLIP 的支持,我们可以用 CLIPImageEmbedding 来生成图片的 embedding,然后用 VectorStoreIndex 同时索引文本节点和图片节点,实现统一的跨模态检索。
挑战二:图片理解的准确性
GPT-4V 虽然强大,但它并不是完美的。它在以下情况下容易出错:低分辨率图片、密集的文字(如密集的表格)、需要精确计数的场景("图中有几个红色标记点?")、以及需要空间推理的场景("A 组件在 B 组件的左边还是右边?")。而且每次调用 GPT-4V 分析图片都有一定的错误率和不确定性。
策略:(1)在图片送入 GPT-4V 之前先做预处理——调整分辨率、增强对比度、裁剪感兴趣区域;(2)对关键图片采用多次验证机制——用不同的 prompt 问同一张图片然后交叉校验;(3)保留图片原文(不做破坏性修改),允许人工审核和修正。
挑战三:成本控制
多模态处理的成本显著高于纯文本。每张图片的 GPT-4V 调用约 0.01-0.05 美元(取决于图片大小和 token 数),CLIP embedding 每张约 0.001 美元,OCR 处理每张约 0.0005 美元。如果一个知识库有 5000 张图片,仅建索引的成本就可能达到 50-250 美元。加上运行时的查询成本,一个月轻松上千美元。
策略:(1)分级处理——不是所有图片都需要高精度分析,缩略图和图标类图片可以用轻量级模型快速跳过;(2)缓存一切——图片的 embedding、OCR 结果、GPT-4V 的分析描述都可以缓存,避免重复计算;(3)智能路由——简单的问题只用文本检索就够了,只在确实需要图片信息时才触发多模态处理。
挑战四:检索粒度
文本可以被切分成 512 token 的 chunk,每个 chunk 都是一个独立的检索单元。但图片怎么办?一张 PDF 页面可能包含 3 张图、2 个表格和 5 段文字——如果把整页作为一个单元太粗粒度(检索到一大堆无关内容),如果把每个图片单独切出来又丢失了与周围文字的上下文关联。
策略:采用 "区域感知的多模态 Node" —— 在解析文档时,不仅提取文本 chunk,还为每个图片/表格/图表创建独立的 MultiModalNode,同时在 metadata 中记录它的位置信息(页码、坐标、前后文摘要)。检索时既可以选择单独匹配某个图片 Node,也可以选择包含该图片的更大上下文区域。