☰
多模态RAG实战:企业知识库架构设计与检索增强生成
2026/9/26 5:51:02 网站建设 项目流程

1. 企业知识库的困境与多模态RAG的破局思路

做过企业知识管理的人都有一个共同感受:文档越攒越多,找东西却越来越难。传统知识库本质上就是一个全文检索系统,你输入关键词,它返回包含这个词的文档列表,至于文档里到底讲了什么、能不能回答你的问题,它一概不管。这就是“可搜索”的天花板。

我去年帮一家做工业设备的客户梳理他们的售后知识库,光是PDF格式的设备手册就有两千多份,还有大量的CAD图纸、维修视频、客服录音。他们之前用的是一个开源全文检索方案,客服人员查一个故障代码,搜出来几十个文档,得挨个打开翻,平均处理一单要十几分钟。问题不在于搜不到,而在于搜到了也看不懂、用不上。

多模态知识库要解决的就是这个断层。它不只是把文本、图片、音频、视频都塞进一个库里面,而是要让这些不同形态的知识能够被统一理解、互相关联,最终做到你问一个问题,系统能直接从图纸里找到对应部件、从录音里定位到相似故障描述、从手册里提取出维修步骤,然后生成一段人能直接看的答案。这背后涉及三个核心技术点:多模态数据的统一表征、RAG检索增强生成架构、以及AI Agent对复杂查询的调度能力。

适合读这篇内容的人,我大致分三类:一是正在做企业知识管理选型的技术负责人,你需要搞清楚多模态RAG到底能解决什么、不能解决什么;二是已经有一定RAG基础的开发者,想从纯文本RAG升级到多模态场景;三是业务侧的产品经理,想理解这套东西的落地边界在哪里。不管你是哪一类,我都会尽量把原理讲透、把操作步骤写清楚、把踩过的坑说明白。

2. 多模态知识库的整体架构设计

2.1 为什么传统RAG撑不住多模态场景

传统RAG的流程很直白:文档切块、向量化、存向量库、查询时做相似度检索、把检索结果拼进Prompt让LLM生成答案。这套流程处理纯文本没问题,但一旦引入图片、表格、音频,就会遇到几个硬伤。

第一个硬伤是切块策略失效。文本可以按段落切,但一张设备结构图你怎么切?切开了就丢失了空间关系。一段客服录音你怎么切?按时间切可能把一句话切成两半。第二个硬伤是向量化模型不统一。文本用文本嵌入模型,图片用CLIP之类的视觉模型,它们生成的向量不在同一个语义空间里,你没法直接比较一张图和一段文字的相似度。第三个硬伤是检索结果的融合。就算你分别检索到了文本块和图片,怎么判断哪些该放进Prompt、哪些该丢弃?简单拼接会导致上下文超长,而且噪声极大。

我在实际项目中的做法是,不追求把所有模态映射到同一个向量空间,而是采用“统一索引层+模态专属处理管道”的架构。统一索引层负责维护所有知识单元的元数据、关联关系和检索路由,模态专属管道负责各自模态的解析、表征和检索。这样既避免了强行统一带来的信息损失,又能在检索时做跨模态的关联召回。

2.2 分层架构拆解:从数据接入到生成输出

整个系统我把它拆成五层,每一层的职责和选型逻辑如下。

数据接入层负责对接企业现有的各种知识源。常见的包括:文件系统(PDF、Word、Excel、PPT)、对象存储(图片、视频)、数据库(结构化数据)、API接口(工单系统、CRM)。这一层的关键是做好增量同步和变更捕获,不能每次全量重建索引。我一般用Apache Tika做文档解析,用FFmpeg做音视频转码,用Debezium做数据库变更捕获。

内容解析层是差异最大的部分。文本文档需要做版面分析,区分标题、正文、表格、图片区域。图片需要做OCR和视觉特征提取。音频需要做语音转文字和说话人分离。视频需要抽帧、ASR、以及关键帧的视觉理解。这一层的输出是标准化的“知识单元”,每个单元包含:原始内容、模态类型、文本表征(如果有)、向量表征、元数据。

索引存储层需要同时支持向量检索、全文检索、图关系检索。我通常用Milvus或Qdrant做向量存储,用Elasticsearch做全文索引,用Neo4j做知识图谱关系。三者通过统一的ID体系关联。这里有个经验:不要试图用一个数据库解决所有问题,向量库做向量的事,搜索引擎做文本的事,图数据库做关系的事,通过应用层做融合。

检索增强层是RAG的核心。它接收用户查询,先做查询理解(意图识别、模态判断、实体抽取),然后路由到不同的检索通道,最后做结果融合和重排序。多模态场景下,查询本身也可能是多模态的,比如用户上传一张故障照片问“这个部件怎么换”,这就需要图片检索加文本检索的联合。

生成输出层负责把检索结果组装成Prompt,调用LLM生成答案。这里的关键是上下文管理:检索回来的内容可能很多,需要做压缩、摘要、去重,确保放进Prompt的内容既相关又不超长。另外还要做引用溯源,让生成的答案能对应到原始知识单元,方便用户验证。

2.3 技术选型对比:开源方案与自建方案怎么选

市面上已经有一些开源的多模态知识库方案,比如Dify的知识库流水线、WeKnora、以及一些基于LangChain或LlamaIndex的RAG项目。我列一个对比表,方便你根据团队情况做选择。

方案类型代表项目优势劣势适用场景
低代码平台Dify、FastGPT上手快,可视化编排,内置多种检索策略定制能力有限,多模态支持较浅快速验证,中小团队
开源框架LlamaIndex、LangChain灵活度高,社区活跃,组件丰富需要自己组装,多模态需额外开发有开发能力的团队
垂直方案WeKnora等针对特定场景优化,开箱即用通用性差,迁移成本高场景匹配度高时
自建方案基于Milvus+ES+Neo4j完全可控,可深度定制开发周期长,维护成本高大型企业,有专门团队

我的建议是:如果你的团队没有专门的AI工程团队,先从Dify或FastGPT入手,把文本RAG跑通,再逐步接入图片和音频。如果你已经有RAG实战经验,想深入多模态,那就在LlamaIndex基础上做扩展,重点解决跨模态检索和融合的问题。自建方案只推荐给有明确长期需求且团队配置齐全的情况。

3. 核心细节解析与实操要点

3.1 多模态数据的统一表征策略

多模态知识库最核心的技术难点,就是如何让不同模态的内容能够互相“理解”。我试过几种方案,这里把优缺点都说清楚。

第一种是统一向量空间方案,用CLIP或其变体把文本和图片映射到同一个向量空间。优点是检索简单,直接算余弦相似度就行。缺点是CLIP对中文文本的支持一般,而且对表格、图纸这类结构化内容的表征能力很弱。我实测下来,用CLIP做图片和文本的跨模态检索,在通用场景下召回率还行,但在专业领域(比如工业图纸)就明显不够用。

第二种是模态专属表征+关联映射方案。文本用BGE或M3E做嵌入,图片用SigLIP或EVA-CLIP做嵌入,音频用Whisper转文字后再做文本嵌入。然后在知识图谱层建立跨模态关联,比如“这张图纸”对应“这段文字描述”对应“这个故障代码”。检索时先在各模态内检索,再通过关联关系做跨模态扩展。这个方案实现复杂一些,但效果明显更好,也是我目前主要采用的方式。

第三种是多模态大模型直接表征方案。用GPT-4V或Qwen-VL这类模型,直接把图片和文本一起输入,让模型生成统一的描述文本,再对描述文本做嵌入。这个方案的好处是利用了大模型的语义理解能力,坏处是成本高、延迟大,而且描述文本会丢失原始模态的细节信息。我一般用它来做知识单元的摘要生成,而不是直接做检索表征。

实际操作中,我建议采用混合策略:文本和音频转写用文本嵌入模型,图片用视觉嵌入模型,表格和图纸先用多模态大模型生成结构化描述再嵌入。然后在检索层做多路召回和融合。

3.2 文档切块与知识单元设计

切块策略直接决定了检索质量。纯文本RAG常用的固定长度切块(比如512个token)在多模态场景下完全不适用。我的做法是按“知识单元”来切,而不是按长度切。

一个知识单元是一个语义完整的片段,可以是一个段落、一张图片加它的图注、一个表格、一段录音转写、一个视频关键帧加它的描述。每个知识单元包含以下字段:

  • unit_id:全局唯一标识
  • modality:模态类型(text/image/table/audio/video)
  • content:原始内容或转写文本
  • embedding:向量表征
  • metadata:来源文件、页码、时间戳、作者等
  • relations:与其他知识单元的关联关系

切块的时候有几个实操要点。PDF文档要先做版面分析,把多栏排版、页眉页脚、表格区域识别出来,否则切出来的文本是乱的。我一般用LayoutParser或PaddleOCR的版面分析功能。图片要保留原始分辨率,同时生成缩略图用于展示。音频转写要保留时间戳,方便定位到原始录音的对应位置。表格要保留行列结构,不能简单转成文本,否则丢失了表头和数据的关系。

注意:切块大小不是越小越好。我见过有人把文档切成100个token的小块,结果检索时召回了很多碎片,生成答案时上下文拼不起来。一般建议文本块在300-800token之间,图片和表格作为独立单元不切分。

3.3 检索策略:从单路召回 to 多路融合

多模态知识库的检索比纯文本复杂得多,因为查询本身可能是多模态的,知识库也是多模态的。我通常设计三路召回加一层融合。

第一路是文本语义召回。用户查询经过查询理解后,提取出文本意图,用文本嵌入模型生成查询向量,在文本知识单元中做相似度检索。这一路处理的是“文字问文字”的场景。

第二路是视觉语义召回。如果查询包含图片,或者查询意图指向视觉内容(比如“这个部件长什么样”),就用视觉嵌入模型生成查询向量,在图片知识单元中检索。这一路处理的是“图片问图片”或“文字问图片”的场景。

第三路是关键词与结构化召回。用Elasticsearch做全文检索,同时利用知识图谱的关系做结构化查询。比如用户问“XX型号设备的故障代码E102怎么处理”,全文检索能精确匹配到包含“E102”的文档,图关系能沿着“设备型号-故障代码-处理步骤”的路径找到关联知识。

三路召回的结果需要融合。我一般用RRF(Reciprocal Rank Fusion)做初步融合,再用一个交叉编码器做重排序。RRF的好处是不需要调权重,对各路召回结果的尺度不敏感。重排序用BGE-Reranker或Cohere Rerank,把最相关的知识单元排到前面。

这里有个容易忽略的点:检索结果的多样性。如果Top-10结果全是同一份文档的相邻段落,那上下文就太单一了。我会在融合阶段加一个多样性惩罚,对来自同一来源的知识单元做降权,确保检索结果覆盖不同的知识来源。

3.4 生成阶段的上下文组装与引用溯源

检索回来一堆知识单元,不能直接全塞进Prompt。我的做法是分三步处理。

第一步是上下文压缩。对每个知识单元,如果内容太长,先用LLM做摘要,保留与查询最相关的部分。比如一张图纸的OCR文本有2000字,但查询只涉及其中一个部件,那就只保留该部件相关的描述。

第二步是上下文排序。把最相关的知识单元放在Prompt的开头和结尾,中间放次要的。这是利用了LLM的“中间遗忘”现象,放在中间的内容容易被忽略。

第三步是引用标注。每个知识单元在Prompt中都有一个编号,生成答案时要求LLM在引用处标注编号。这样用户看到答案后,可以点击编号跳转到原始知识单元验证。

Prompt模板我一般这样设计:

你是一个企业知识助手。根据以下知识单元回答用户问题。 如果知识单元中没有相关信息,请明确说明“知识库中未找到相关内容”,不要编造。 知识单元: [1] {unit_1_content} [2] {unit_2_content} ... 用户问题:{query} 回答要求: 1. 答案必须基于上述知识单元,引用时标注编号如[1] 2. 如果涉及操作步骤,按顺序列出 3. 如果涉及多个知识单元的综合,说明推理过程

提示:引用溯源不仅是给用户看的,也是调试RAG系统的重要手段。当生成答案有问题时,你可以快速定位是检索错了还是生成错了。

4. 实操过程与核心环节实现

4.1 环境准备与依赖安装

我以一套典型的自建多模态RAG系统为例,把关键步骤和配置写清楚。这套方案在我的测试环境(Ubuntu 22.04,32GB内存,一张RTX 4090)上跑通,中小规模企业知识库(十万级知识单元)完全够用。

基础依赖包括:

# 向量数据库 docker run -d --name milvus -p 19530:19530 milvusdb/milvus:latest # 全文检索 docker run -d --name elasticsearch -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.11.0 # 图数据库 docker run -d --name neo4j -p 7474:7474 -p 7687:7687 neo4j:latest

Python侧的核心依赖:

pip install pymilvus elasticsearch neo4j pip install sentence-transformers FlagEmbedding pip install layoutparser paddleocr pip install openai whisper pip install llama-index-core llama-index-vector-stores-milvus

模型方面,文本嵌入我用BGE-M3,它支持多语言且对中文优化好。视觉嵌入用SigLIP,比CLIP在中文场景下表现更稳。重排序用BGE-Reranker-v2-M3。语音转写用Whisper-large-v3。这些模型都可以本地部署,不需要依赖外部API。

4.2 文档解析与知识单元入库

以一份PDF设备手册为例,完整流程如下。

第一步,用LayoutParser做版面分析,识别出标题、正文、表格、图片区域。这一步的输出是一个带区域类型标注的版面结构。

import layoutparser as lp model = lp.Detectron2LayoutModel( config_path='lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config', label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"} ) layout = model.detect(image)

第二步,按区域类型分别处理。文本区域用PaddleOCR提取文字,表格区域用TableTransformer做结构识别,图片区域裁剪出来单独存储。

第三步,生成知识单元。每个文本段落作为一个知识单元,每张图片加它的图注作为一个知识单元,每个表格作为一个知识单元。然后调用BGE-M3生成文本嵌入,调用SigLIP生成图片嵌入。

第四步,建立关联关系。同一页的文本和图片建立“同页”关系,图注和图片建立“描述”关系,表格和它所在的章节建立“所属”关系。这些关系写入Neo4j。

第五步,入库。向量写入Milvus,全文索引写入Elasticsearch,关系写入Neo4j。三个存储通过unit_id关联。

4.3 查询理解与检索路由的实现

用户输入查询后,先做查询理解。我用一个轻量LLM(比如Qwen2-7B)做意图分类和实体抽取。

query_understanding_prompt = """ 分析用户查询,输出JSON格式: { "intent": "查询类型(故障排查/操作步骤/参数查询/对比分析)", "modalities": ["涉及的模态类型"], "entities": ["关键实体"], "rewritten_query": "改写后的检索查询" } 用户查询:{query} """

意图分类决定了检索路由。如果是“故障排查”,优先走全文检索和图关系检索,因为故障代码这类精确匹配很重要。如果是“操作步骤”,优先走文本语义检索。如果查询包含图片,走视觉语义检索。

检索路由的代码逻辑:

def route_retrieval(query_analysis): channels = [] if query_analysis['intent'] in ['故障排查', '参数查询']: channels.append('keyword') channels.append('graph') if query_analysis['intent'] in ['操作步骤', '对比分析']: channels.append('text_semantic') if 'image' in query_analysis['modalities']: channels.append('visual_semantic') return channels

4.4 多路召回融合与重排序的代码实现

三路召回各自返回Top-20结果,然后用RRF融合。

def rrf_fusion(results_list, k=60): scores = {} for results in results_list: for rank, unit_id in enumerate(results): if unit_id not in scores: scores[unit_id] = 0 scores[unit_id] += 1 / (k + rank + 1) return sorted(scores.items(), key=lambda x: x[1], reverse=True)

融合后取Top-20,用BGE-Reranker做重排序。

from FlagEmbedding import FlagReranker reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True) pairs = [(query, unit_content) for unit_id, unit_content in top20_units] scores = reranker.compute_score(pairs) reranked = sorted(zip(top20_units, scores), key=lambda x: x[1], reverse=True)

重排序后取Top-5作为最终上下文。这里有个经验:重排序的输入不要超过20个,否则延迟太高。另外,如果某一路召回的结果特别少(比如图片检索只返回了2个),可以适当放宽其他路的召回数量,保证最终上下文有足够的信息量。

4.5 生成答案与引用标注的完整流程

最后一步是把检索结果组装成Prompt,调用LLM生成答案。

def generate_answer(query, units): context = "" for i, unit in enumerate(units): context += f"[{i+1}] {unit['content']}\n" prompt = f"""根据以下知识单元回答用户问题。 知识单元: {context} 用户问题:{query} 回答要求: 1. 答案必须基于上述知识单元,引用时标注编号如[1] 2. 如果涉及操作步骤,按顺序列出 3. 如果知识单元中没有相关信息,明确说明""" response = llm.generate(prompt) return response

生成答案后,前端把引用编号渲染成可点击的链接,用户点击后跳转到原始知识单元。如果是图片,展示图片和它的图注;如果是音频,播放对应时间段的录音;如果是表格,展示表格结构。

5. 常见问题与排查技巧实录

5.1 检索召回不准的排查思路

这是最常见的问题。用户问了一个问题,检索回来的内容完全不相关。排查顺序如下。

先看查询理解是否正确。把查询理解模块的输出打出来,看意图分类和实体抽取有没有错。我遇到过用户问“E102故障怎么处理”,意图分类成了“参数查询”,导致走了全文检索而不是图关系检索,召回结果全是参数表。修正意图分类的Prompt后问题解决。

再看嵌入模型是否匹配。文本嵌入模型和知识单元的文本表征必须用同一个模型。我见过有人入库用BGE,查询用OpenAI的embedding,向量空间不一致,检索结果完全是随机的。

然后看切块是否合理。如果知识单元切得太碎,检索回来的都是片段,生成时拼不起来。如果切得太大,检索精度会下降。我一般会做一个切块质量检查:随机抽100个知识单元,人工判断它们是否语义完整。

最后看融合和重排序。把各路召回的原始结果和融合后的结果都打出来对比。如果某一路召回的结果明显更好,可以调整融合权重。如果重排序后反而变差了,可能是重排序模型和嵌入模型不匹配,换一个重排序模型试试。

5.2 多模态对齐失败的典型场景

多模态知识库最常见的问题是对齐失败,也就是图片和文本的关联关系建错了。

一个典型场景是PDF解析时,图片和它的图注被分到了不同的知识单元,而且没有建立关联。用户检索图注文字时,召回了图注但没召回图片,生成答案时缺少视觉信息。解决办法是在版面分析阶段就把图注和图片绑定,作为一个知识单元入库。

另一个场景是表格解析错误。复杂表格(合并单元格、多级表头)用OCR提取后结构全乱了,导致检索时匹配不到正确的数据。我一般对复杂表格用专门的表格识别模型,如果识别效果不好,就人工标注一批表格作为训练数据微调模型。

还有一个场景是音频转写的时间戳对齐。Whisper转写出来的文本有时间戳,但切块时如果按固定长度切,可能把一句话切成两半,时间戳就对不上了。我的做法是按语义切分,用标点符号和停顿做边界,确保每个知识单元对应一个完整的语义片段。

5.3 生成答案幻觉的抑制方法

RAG系统最怕的就是LLM编造答案。明明知识库里没有相关内容,它硬是编了一段看起来很像真的回答。

抑制幻觉有几个手段。第一是在Prompt中明确要求“如果知识单元中没有相关信息,明确说明未找到”,并且给一个few-shot示例。第二是降低生成温度,我一般设0.1-0.3,不要太高。第三是加一个后置校验,用另一个LLM检查生成的答案是否能在知识单元中找到依据,如果找不到就重新生成或返回“未找到”。

我实测下来,最有效的手段是引用标注加后置校验。要求LLM每句话都标注引用编号,然后检查每个引用编号是否真的支持该句话。如果发现无引用的句子,就标记为可疑内容。

5.4 性能优化的实操经验

多模态RAG的性能瓶颈通常在检索和重排序阶段。以下是我总结的优化手段。

问题原因解决方案
检索延迟高向量库索引未优化使用HNSW索引,调整ef参数
重排序慢交叉编码器计算量大减少重排序候选数,用GPU加速
入库慢嵌入模型推理慢批量推理,用ONNX或TensorRT加速
内存占用高向量维度过大用PCA降维或换用更小的嵌入模型
并发差单点服务向量库和嵌入服务做水平扩展

我一般会把嵌入模型和重排序模型部署成独立的推理服务,用Triton或vLLM做批处理,这样并发能力会好很多。另外,Milvus的索引参数需要根据数据量调整,十万级数据用HNSW就够了,百万级以上考虑IVF_PQ。

5.5 知识库更新与增量索引的处理

企业知识库不是一成不变的,文档会更新、新增、删除。全量重建索引成本太高,必须做增量。

我的做法是维护一个变更日志。文件系统用inotify监控变更,数据库用CDC捕获变更,API接口用轮询或webhook。变更事件写入消息队列(Kafka或RabbitMQ),由消费者进程处理。

处理逻辑是:新增文档走完整入库流程;更新文档先删除旧的知识单元,再重新入库;删除文档标记为失效,检索时过滤掉。这里有个坑:删除向量库中的数据时,Milvus的删除是软删除,需要定期做compaction才能真正释放空间。

另外,知识单元的关联关系也要同步更新。比如一张图片被删除了,引用它的文本知识单元的关系也要清理。我一般用Neo4j的级联删除来处理。

6. 从RAG到Agent:多模态知识库的进阶玩法

6.1 AI Agent如何调度多模态知识库

基础的RAG是“一问一答”,用户问一个问题,系统检索一次、生成一次。但实际企业场景中,很多问题是需要多步推理的。比如“对比A型号和B型号设备在高温环境下的故障率差异”,这需要先查A型号的故障记录,再查B型号的,然后做对比分析。

AI Agent的价值就在这里。它可以把一个复杂查询拆解成多个子查询,依次调用知识库检索,最后综合生成答案。Agent的调度逻辑我一般用ReAct模式:思考-行动-观察循环。

agent_prompt = """ 你可以使用以下工具: 1. search_text(query): 文本语义检索 2. search_image(query): 图片检索 3. search_graph(entity, relation): 图关系查询 4. search_keyword(keyword): 全文检索 用户问题:{query} 请按以下格式输出: 思考:你需要什么信息 行动:调用哪个工具,参数是什么 观察:工具返回的结果 ...(循环直到可以回答) 最终答案:综合所有信息后的回答 """

Agent模式下,检索不再是单次调用,而是根据中间结果动态调整。比如第一次检索发现A型号的故障记录里提到了一个特定部件,Agent可以自动发起第二次检索,查这个部件的详细规格。

6.2 多模态记忆与上下文管理

Agent在多轮对话中需要维护上下文记忆。多模态场景下,记忆不只是文本,还包括用户上传的图片、系统检索到的图片、以及之前的检索结果。

我的做法是维护一个会话级的记忆池,每个记忆单元包含:内容、模态、时间戳、相关性分数。每次新查询进来,先做记忆检索,把相关的历史记忆和当前查询一起送入Agent。记忆池有容量限制,超过后按时间衰减和相关性做淘汰。

这里有个细节:图片记忆的存储。不能把原始图片一直放在内存里,我一般存图片的向量和缩略图,需要展示时再从对象存储拉取原图。

6.3 从知识库到知识图谱的演进路径

多模态知识库做到一定程度,自然会遇到关系查询的需求。比如“哪些设备使用了这个部件”“这个故障代码在哪些型号上出现过”。这些查询用向量检索做不好,需要知识图谱。

演进路径我建议分三步。第一步是纯向量检索,把文本和图片都向量化,做相似度检索。第二步是混合检索,加入全文检索和图关系检索,用RRF融合。第三步是知识图谱增强,把实体和关系抽取出来,构建领域知识图谱,检索时用图查询做多跳推理。

知识图谱的构建可以用LLM做实体关系抽取。我一般用Few-shot Prompt让LLM从知识单元中抽取三元组,然后人工校验一批,剩下的自动入库。图谱规模大了之后,可以用图嵌入做链接预测,发现潜在的关联关系。

6.4 企业级部署的注意事项

最后说几个企业级部署的实操经验。

权限控制是必须的。不同部门、不同角色的员工能访问的知识范围不同。我一般在知识单元入库时打上权限标签,检索时根据用户角色过滤。Milvus支持标量字段过滤,Elasticsearch支持权限过滤,Neo4j可以在查询时加权限条件。

审计日志也很重要。谁在什么时候查了什么、系统返回了什么、用户有没有采纳,这些都要记录。一方面是合规要求,另一方面也是优化知识库的依据。我一般用ELK栈做日志收集和分析。

成本控制方面,嵌入模型和LLM的推理成本是大头。我的经验是:嵌入模型用本地部署的小模型(BGE-M3就够用),LLM用API按需调用,重排序模型用本地GPU。这样混合部署,成本比全API方案低一个数量级。

我在实际项目中最深的体会是:多模态知识库的建设不是一次性工程,而是一个持续迭代的过程。第一版先把文本RAG跑通,第二版加入图片和表格,第三版引入Agent和图谱。每加一个模态,都要重新评估检索质量和生成效果。不要追求一步到位,小步快跑、持续优化才是正道。另外,知识库的质量取决于数据质量,如果原始文档本身就是扫描件、手写体、或者格式混乱,再好的RAG系统也救不回来。所以在做多模态之前,先把数据治理做好,该数字化的数字化,该结构化的结构化,这一步省不得。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询