你有没有见过这样的场景:一位游客走进博物馆,对着一幅古画出神,然后转头问导览员:“这幅画里为什么有只仙鹤?它旁边那首诗讲的又是什么意思?” 一位好导览员不会背出整本馆藏目录,而是迅速找出与这幅画相关的文字说明、画家背景、同展厅的其他展品照片,把它们按照“先讲画、再讲字、最后补充史料”的顺序摆在你面前,娓娓道来——整个过程,就是多模态RAG(检索增强生成)的缩影。 传统RAG只让大语言模型“读书”,多模态RAG则让它“既读书又看图”。它先把图文文档切分成可以理解的碎片,把文字和图片映射到同一个“记忆空间”,当用户提问时,系统同时用语义和关键词两种方式找回最相关的图文块,再把它们注入模型生成带证据的回答。本文就用博物馆导览这套生活逻辑,带你一步步搭建自己的多模态RAG。
掌握多模态RAG,等于帮大模型装上“眼睛”和“档案馆”,这是企业知识问答、内容审核、智能客服等场景的高价值技能,也是大模型应用工程师的必备进阶能力。
可视化演示
演示多模态文档分块、跨模态索引构建与图文混合检索生成,理解检索增强在非文本知识源的应用。
本节配有交互动效(进入视口后自动加载,约 3KB)。
多模态分块 文本块 图像块 chunk 图文分块策略
多模态知识源与文档切分
博物馆策展的第一步,不是把展品堆进库房,而是先“盘点”:哪些是油画,哪些是雕塑,哪些是说明牌,再把一幅大画的画面按构图切分成几个视觉单元,同时把旁边的文字说明用夹子夹在画框旁。多模态RAG的第一步同样如此——处理多模态知识源。
真实的文档千奇百怪:PDF里有排版段落,PPT里有一页页图表,网页里嵌着产品图,还有扫描件里的表格。如果一股脑全部塞给模型,上下文瞬间爆炸,检索也找不到重点。所以要做文本块切分和图表信息抽取:文本按段落或语义切成 200~500 token 的小块;图片用检测模型抠出表格区、插图区;最后建立“图文配对”——一张架构图和它下方的说明文字归为一组,就像策展人把画和说明牌放在一起。
这一步决定了后续检索质量的下限。切分的核心原则是“语义完整 + 边界清晰”,而衡量两个块是否该放一起,可以看它们的嵌入向量有多“像”。
回到博物馆的比喻:切分做得好的策展人,能让观众一眼找到“画在哪、说明在哪、下一幅连接着什么”。多模态文档的切分与图文配对,就是为系统画好一幅精确的“展厅地图”。
- 点积计算先算两个向量各分量乘积再求和,数值越大表示同向程度越高。
- 向量范数对向量每个分量求平方和再开根号,得到向量的“长度”,用于消除文本长短带来的偏差。
- 相似度比值点积除以两个向量长度的乘积,结果落在 −1 到 1 之间,1 表示方向完全一致。
跨模态索引构建
不同展品的“长相”千差万别——油画是色彩与笔触,雕塑是体积与材质,说明牌是文字。游客问“有没有蓝白配色的瓷器?”导览员必须把一个抽象的“蓝白”概念翻译成能同时匹配图片和文字的统一编号,才能快速定位。在技术世界里,这个“统一编号系统”就是统一向量空间。
做法是训练一对双塔编码器:图像编码器把图片块变成向量,文本编码器把文本块变成向量,并通过对比学习让“描述一只猫的文字”和“一张猫的照片”在向量空间里靠得很近。训练时随机抽取一批图文对,匹配的正样本要互相靠近,不匹配的负样本要彼此推远,这就是经典的 InfoNCE 对比损失。
索引构建完成后,所有图文块都以向量形式写入向量数据库,同时附带来源页码、文档ID等元数据。这意味着导览员的“中央目录”建成了——无论观众从文字还是视觉角度提问,系统都能用同一种语言检索。
- 相似度计算用余弦相似度衡量第 i 条文本与第 j 张图片的匹配程度,越大表示越匹配。
- 温度缩放除以温度系数 τ,控制相似度分布的“尖锐程度”,τ 越小对比越强烈。
- Softmax 与负对数正确图片的指数占比越大,损失越接近 0;模型被迫在众多负样本中精准挑出正样本。
多模态上下文注入
导览员得到观众的问题后,不会搬来整个展厅,而是挑出最相关的三件展品,按“先说结论画、再摆细节图、最后附说明牌”的顺序放在台面上。这就是多模态上下文注入:把检索到的图文块组织成模型能直接消费的格式。
具体做法分为三步。检索结果组织:把命中列表按分数排序,过滤低分项;图文序列排列:将文本块与图像块交错拼接,图像块通常用视觉编码器转成视觉 token(多模态大模型)或转成文字描述(传统大模型);Prompt 拼接:在开头放系统指令和用户问题,中间插入 top-k 个图文块,并在每块末尾标注“〔来源:第3页图2〕”这样的引用标记。
为什么要拼接向量而非直接拼接原文?因为不同来源的长度、格式差异巨大,模型需要统一的“输入格式”。用拼接线性变换可以写成:
上下文注入就像导览员给答案“配菜”:菜(内容)要新鲜,顺序(加载格式)要讲究,盘边(引用)要注明出处。注入结构混乱,模型再强也答不好。
- 向量拼接符号 ⊕ 表示把三个向量沿维度方向首尾相接,组成一个大向量。
- 线性投影拼接结果乘上权重矩阵 W_o,将维度压缩到模型期望的输入维度。
- 加偏置最后加上偏置向量 b_o,允许模型学到一个不均匀的偏移,增强表达能力。
图文混合检索
观众问“上个月市场部那张数据表里,哪款产品增长率最高?”这类问题,光靠“长得像”的语义匹配不够,还要求精确命中“市场部、增长率、数据表”这些关键词。聪明的导览系统会同时用两套办法:稠密向量召回负责“神似”——语义相近的都能找到;稀疏关键词召回(如 BM25)负责“形似”——关键词精准匹配。最后把两路分数融合成最终排序。
融合之后往往还有一道“精排”:用一个轻量的交叉编码器(cross-encoder)对 top-20 候选逐对打分,把最合适的图文块提到最前面。就像导览员先由安保同事粗筛出可能相关的展品,再亲自逐一确认哪三件最贴题。
- 稠密分数查询向量与候选向量在统一空间中的余弦相似度,已归一化到 0~1。
- 稀疏分数基于关键词共现和词频的 BM25 分数,同样做 Min-Max 归一化处理。
- 加权求和λ 在 0 到 1 之间调节两路证据的信任度,得到最终排序分。
多模态生成增强机制
选好展品、排好顺序之后,最关键的一步来了:导览员开口回答。他必须“看着展品说话”——描述画中仙鹤时对照画面细节,引用诗句时对照说明牌,不能凭印象胡编。多模态大模型的生成环节同样如此,这是生成增强机制。
多模态大模型(如 GPT-4o、Qwen-VL)本身就具备跨模态能力:图像经过视觉编码器变成一个个视觉 token,与文本 token 一起进入 Transformer 的注意力层,让模型“看”着图片组织语言。同时,Prompt 中强制要求“仅依据给定材料回答,并标注〔来源〕”,从指令层面压制幻觉;推理后还可以做忠实度校验,检查答案中的每个关键论断是否在上下文中找得到依据。生成过程在数学上是一个自回归的条件概率连乘:
导览员的魅力来自“有据可查”,多模态RAG的回答价值同样来自“有图有真相”。生成机制做得稳,模型才不会在关键数据上“睁眼说瞎话”。
- 条件概率分解整句回答的概率,等于每个词在已知前文条件下的概率相乘。
- 引入上下文每个词的条件中同时带上用户问题 x 和检索图文集合 C,保证生成“不跑题”。
- 自回归生成模型在每一步只预测下一个词,再把预测结果拼进输入继续预测,循环至结束符。
应用落地与评估
当整套导览系统打磨成熟,博物馆就可以把它推广到所有展厅,甚至做成手机App:游客拍照提问,系统秒回图文并茂的答案,还能跳转到对应展品原页。这就是多模态RAG的应用落地。
目前最成熟的落地场景是企业文档问答:把合同扫描件、产品图纸、会议纪要、竞品海报全部导入系统,员工用自然语言提问,系统检索图文证据并生成带引用的回答;知识库管理则更进一步,自动为新文档打标、去重、更新索引。评估一套多模态RAG系统,不能只看答案顺不顺,还要看答案是否忠实于材料:
从展厅里的第一次导览,到全馆的智能问答体系,多模态RAG的价值落在每一个“被准确找到的图文证据”上。未来随着长上下文和多模态模型的进步,这套架构会变得更自然、更强大。
- 提取论断把生成答案拆成若干条原子论断,如“X产品增长率最高”。
- 逐一验证去检索到的图文上下文中寻找每条论断的证据,找到的归入支持集合。
- 计算比值支持论断数除以总论断数,越接近 1 说明回答越“有据可依”。
AI 应用场景
企业产品手册智能问答
阶段:文档解析 → 跨模态索引 → 图文混合检索 → 生成回答
解决的问题:传统售后客服面对上千页产品手册(含爆炸图、接线图、参数表)只能靠人工翻阅,效率低且容易漏看图片细节。多模态RAG 将手册图文一并索引,用户描述故障现象,系统自动检索“相关图纸 + 对应文字段落”,生成带图引用和操作步骤的维修建议。
具体案例:某工业设备厂商上线多模态RAG客服,用户提问“液压泵异响怎么排查”,系统返回 3 张相关剖面图、2 段故障分析文本,并生成“先看滤芯再查油路”的带编号排查步骤,一次性解决率提升 35%。
法律案件证据检索与答辩辅助
阶段:跨模态索引 → 混合检索 → 幻觉抑制 → 引用溯源
解决的问题:法律卷宗包含合同扫描件、现场照片、证人证言录音转写等异构材料。传统关键词搜索无法理解“照片里的签字笔迹”这类视觉信息。多模态RAG把图片取证与文字案情统一向量化,律师提问“对方是否在 3 月合同上补签了名字”,系统同时比对扫描件图像块和合同文本段落,输出带页码和图像裁剪框的证据链。
具体案例:某律所在尽调场景中,将 2000 份历史合同与签字页扫描图建立多模态索引,检索“违约赔偿条款”时,系统能同时呈现条款文本和对应签字页截图,合同审查时间从 3 天缩短到 2 小时。
Python 演示
# -*- coding: utf-8 -*-"""多模态RAG简化演示: 文本特征与图像描述特征 -> 统一向量空间 -> 混合检索 -> 生成"""import mathimport re class MultimodalRAG: def __init__(self, docs): self.docs = docs self.text_vectors = [] self.img_vectors = [] self.vocab = set() self.vocab_index = {} self._build_index() def _tokenize(self, text): return re.findall(r"[\w\u4e00-\u9fa5]+", text.lower()) def _build_index(self): for doc in self.docs: self.vocab.update(self._tokenize(doc["text"])) self.vocab.update(self._tokenize(doc["img_desc"])) self.vocab = sorted(self.vocab) self.vocab_index = {w: i for i, w in enumerate(self.vocab)} for doc in self.docs: self.text_vectors.append(self._sparse_vector(doc["text"])) self.img_vectors.append(self._sparse_vector(doc["img_desc"])) def _sparse_vector(self, text): vec = [0.0] * len(self.vocab) for w in self._tokenize(text): if w in self.vocab_index: vec[self.vocab_index[w]] += 1.0 norm = math.sqrt(sum(x * x for x in vec)) or 1.0 return [x / norm for x in vec] def _cosine(self, a, b): return sum(x * y for x, y in zip(a, b)) def retrieve(self, query, alpha=0.7, top_k=2): q_vec = self._sparse_vector(query) q_words = set(self._tokenize(query)) results = [] for i in range(len(self.docs)): text_sim = self._cosine(q_vec, self.text_vectors[i]) img_sim = self._cosine(q_vec, self.img_vectors[i]) dense = alpha * text_sim + (1 - alpha) * img_sim overlap = len(q_words & set(self._tokenize(self.docs[i]["text"]))) overlap = overlap / max(len(q_words), 1) fused = 0.8 * dense + 0.2 * overlap results.append((fused, i)) results.sort(key=lambda x: x[0], reverse=True) return results[:top_k] def generate(self, query, top_k=2): hits = self.retrieve(query, top_k=top_k) context = [] for score, idx in hits: doc = self.docs[idx] context.append("图片: %s | 文字: %s" % (doc["img_desc"], doc["text"])) ctx = "\n".join(context) return "【检索证据】\n%s\n【生成回答】根据资料,%s" % (ctx, query) def main(): docs = [ {"text": "多模态检索架构将文本与图片统一编码成向量", "img_desc": "架构图显示双塔编码器"}, {"text": "RAG流程包含索引构建、混合检索与生成", "img_desc": "流程图展示完整RAG管线"}, {"text": "对比学习让跨模态语义在向量空间中对齐", "img_desc": "示意图展示正负样本距离"}, ] rag = MultimodalRAG(docs) q = "多模态RAG是怎么实现的" print(rag.generate(q, top_k=2)) if __name__ == "__main__": main()
class MultimodalRAG定义多模态RAG核心类,同时保存文本向量与图像描述向量_build_index构建词表并为每篇文档生成“文本向量 + 图像向量”双通道索引_sparse_vector将一段文字转成L2归一化的稀疏词频向量_cosine计算两个向量的余弦相似度,作为深度学习检索的简化替代retrieve融合文本相似度、图像相似度和关键词重叠度,实现混合检索排序dense = alpha * text_sim + (1 - alpha) * img_sim跨模态融合:既看文字语义,也看图像语义fused = 0.8 * dense + 0.2 * overlap在语义基础上补充稀疏关键词证据generate把 hit 的图文信息拼成上下文,模拟“检索增强生成”输出if __name__ == "__main__":可执行入口,运行脚本即可看到检索证据和生成结果
常见误区
误区我以为是直接把图片文件存进数据库,用户提问时把整张图片作为附件丢给大模型解读就行了。
正解图片在进入索引前必须经过视觉编码器变成固定维度的向量,检索阶段只能比较向量,不能“看”原始图片。而且即便检索到了图片,注入时也要看模型能力:纯文本模型需要先把图片转成语义描述或OCR文本,多模态大模型才接收视觉 token。更关键的是,整张高清图 token 开销极大,通常需要把图表裁剪成局部块再注入,否则上下文瞬间超长。
为何常见:因为大家平时用多模态聊天时习惯直接发图给模型,误以为后台也是这样“原图直传”,忽略了检索系统与对话系统的本质区别。
误区文本放一个索引库,图片放另一个索引库,分别检索 top 结果,再拼在一起不就成了多模态RAG吗?
正解这种“事后拼接”的问题在于:文本查询和图片查询不在同一语义空间,无法度量“这段文字配上这张图”的整体相关度。多模态RAG的精髓是跨模态对齐——用对比学习让图文进入同一个向量空间,使“蓝色花瓶”的文字向量和蓝色花瓶的照片向量彼此靠近。否则检索到的图片可能与文本主话题完全无关,比如问的是“某产品售后政策”,却返回了一张毫不相干的品牌海报。
为何常见:初学时容易把“多模态”理解成“多个单模态系统的简单相加”,而忽略了跨模态对齐才是关键。
误区图片里的字用OCR提出来,当成文本去做RAG,不也能回答文档问题吗?何必再搞视觉模型?
正解OCR 只能提取文字,会丢失大量视觉语义:图表的坐标趋势、柱状图高低对比、结构的空间布局、照片中物体的形状颜色,这些信息无法被 OCR 文字还原。比如问“这张折线图哪个季度销量下滑最明显”,OCR 只能给出一堆数字,无法理解折线的走向。真正多模态RAG会保留图像块本身,用视觉编码器编码整张图表的结构信息。
为何常见:因为很多初学者最先接触的是“图片中的文字”,容易把文字识别的难度等同于视觉理解的全部难度。
误区反正大模型上下文窗口越来越大,干脆把 top-50 个图文块全塞进 Prompt,信息越多回答越全面。
正解多不等于好。过多的无关块会稀释注意力,图片块的 token 消耗尤其惊人,还可能引入互相矛盾的干扰信息,反而降低答案忠实度。工程实践通常检索 top-5~20,经过重排后只注入 top-3~5 个最相关的图文块,并对每块标注来源。知识不是堆出来的,而是精准挑出来的。
为何常见:直觉上“信息冗余比缺失安全”,但大模型的注意力机制对长上下文的噪声非常敏感,冗余信息常常成为幻觉的温床。
面试题
Q1. 多模态RAG中,处理一篇图文混合文档的首要步骤是什么?
- A.删除图片只保留文字
- B.将文本与图表分别切块← 正确答案
- C.把整份文档转成PDF
- D.用压缩算法缩小文件
答案:B。多模态文档必须先把文本块、图片块、表格块分别切分并建立图文关联,才能进入后续索引。删除图片丢失信息,整份文档塞入会超出上下文限制,转PDF或压缩都不是知识处理步骤。
Q2. 跨模态索引构建的核心目标是什么?
- A.减少向量文件的体积
- B.让图文对齐到同一向量空间← 正确答案
- C.提升图片的像素清晰度
- D.自动生成文档摘要标题
答案:B。跨模态索引的核心是借助双塔编码器和对比学习,把图片与文本映射到同一向量空间,使能互相描述的内容距离更近,这是图文互相检索的前提。体积、像素、摘要都不是多模态对齐的核心。
Q3. 多模态上下文注入时,图像块常用什么方式进入模型?
- A.压缩成Base64原文粘贴
- B.转为视觉Token或语义描述← 正确答案
- C.缩小尺寸后以附件邮件发送
- D.直接丢弃只保留OCR文字
答案:B。多模态大模型通过视觉编码器把图像转成视觉Token参与注意力计算;传统纯文本模型则需要把图片转成文字描述。Base64不利于语义建模,缩图发送和丢弃图片都在丢失信息。
Q4. 混合检索融合公式 s=λ·s_dense+(1-λ)·s_sparse 中的 λ 起什么作用?
- A.控制稠密与稀疏权重← 正确答案
- B.控制图像亮度参数
- C.控制模型参数量级
- D.控制输出答案字数
答案:A。λ 是稠密向量分数与稀疏关键词分数之间的平衡系数。λ 大更依赖语义向量,λ 小更依赖关键词精确匹配。参数、字数、亮度都与检索融合无关。
Q5. 为什么不能把检索到的所有图文块全部注入Prompt?
- A.因为模型永远不会读取图片
- B.会稀释注意力且图像Token开销大← 正确答案
- C.因为检索器因此无法工作
- D.网络传输速度会明显下降
答案:B。大模型长上下文中噪声会稀释注意力,图像Token消耗远高于文本,过多无关块降低忠实度。工程上通常只注入重排后的前3~5个块并附引用标记。
Q6. 对比损失中温度系数 τ 的作用是什么?
- A.控制图片的分辨率大小
- B.调节相似度分布尖锐程度← 正确答案
- C.决定向量数据库表数量
- D.设置关键词检索深度
答案:B。τ 分母上缩放相似度,τ 越小分布越尖锐,模型更积极地拉近正样本、推远负样本;τ 越大分布越平滑。它跟分辨率、库表、检索深度都无关。
Q7. 多模态RAG能够落地解决哪些实际问题?
- A.图表类文档的知识问答← 正确答案
- B.结合结构图解答运维问题← 正确答案
- C.让大模型训练速度翻倍
- D.回答附上可溯源的图文证据← 正确答案
答案:ABD。多模态RAG擅长让模型“看图回答问题”并提供溯源证据。C 是训练加速问题,与 RAG 推理架构无关。
Q8. 图像块被检索到后,为何仍需标注来源页码或文档ID?
- A.为了满足日志存储规范
- B.让回答具备可溯源性减少幻觉← 正确答案
- C.为了提升图床加载速度
- D.便于压缩图片文件体积
答案:B。来源标注本质上是“证据链”:模型回答时看到出处编号,会更倾向于忠实于材料;工程师也能用引用回溯纠错。存储规范、加载速度、压缩体积都不是引用溯源的目的。
Q9. 评估多模态RAG系统时,通常关注哪些指标?
- A.答案的忠实度与可读性← 正确答案
- B.图文混合检索的召回率← 正确答案
- C.生成图片的色彩饱和度
- D.噪声图的参考像素比例
答案:AB。忠实度衡量答案是否由上下文支持,可读性衡量回答质量,检索召回率衡量系统能不能找回该找的证据。色彩饱和度与噪声像素是图像处理指标,与RAG评估无关。
Q10. 多模态RAG目前仍然面临的主要挑战有哪些?
- A.跨模态特征存在对齐偏差← 正确答案
- B.图像块消耗上下文预算大← 正确答案
- C.图片越多检索必定越准确
- D.缺乏统一健全的评估基准← 正确答案
答案:ABD。对偏差导致图文语义匹配不稳定,图像Token开销大限制可注入信息量,评估基准不统一导致方案难以横向对比。C 是错误直觉:图片多但切分差反而引入噪声。