最近几乎每隔几天就会有人问我同一个问题:RAG项目到底怎么做?我翻了一下近半年的聊天记录,发现大家问得最密集的点高度集中在两个地方——"文本块怎么切"和"向量怎么算"。好像只要把文档切成小块、扔进embedding模型转成向量、再塞进向量数据库,一个RAG系统就算搭完了。
这种想法也不能说错,但离真正能上线跑业务还差得很远。我陆续做过几个完整的RAG落地项目,踩了不少坑,一个很深的体会是:分块和向量化只是数据管道里的两个环节,真正决定系统能不能用的,往往是那些不显眼的前置和后置工序——数据清洗、格式解析、索引维护、重排序、上下文组装。这篇文章我想把这整条数据管道摊开来讲,把每个环节的设计逻辑、实操方法和常见坑都交代清楚,希望能帮你少走点弯路。
1. 重新认识 RAG:分块和向量化只是冰山一角
1.1 为什么"块切得好不好"决定系统上限
先说一个观念问题。很多人以为分块是RAG的"最后一公里",切完块、做完向量化,系统就基本成型了。但实际上,分块是数据管道的第一个核心关卡,它决定了后面所有环节的上限。你选的embedding模型再强、向量数据库再快,如果文本块本身切得乱七八糟——一个块里混了三个主题、或者把一个完整的表格拆得七零八落——那检索环节召回的内容质量必然差,大模型拿到的上下文就是一堆碎片,生成出来的答案自然会幻觉频出。
这里可以借用矩阵分块的思想打个比方。做矩阵运算时,把一个大规模矩阵拆成若干子块,不是随便拆的,拆完之后要做乘法和求逆,块与块之间的边界必须保证运算能够闭环。文本分块也是同理:切出来的每一块,应该是语义上相对独立、能够"自洽"的一个信息单元。如果块边界恰好切在了一个完整论点的中间,那这块文本无论怎么向量化,它表征出来的语义都是残缺的。后面检索再精准,拿到的也是一个不完整的片段。
1.2 数据管道全流程:从源头到上下文组装
抛开那些花哨的概念,一个生产级RAG系统的数据管道,我习惯分成八个阶段:
- 数据接入:确定数据源的类型、数量、格式,把文件从各处收拢到统一的数据湖或临时目录。
- 格式解析与文本抽取:PDF、Word、HTML、Markdown、图片、音视频……不同格式有各自的解析方案,这一步要把原始文件变成干净的纯文本或半结构化内容。
- 数据清洗:去重、去噪、纠错、统一编码、剔除无关信息,得到可用的语料。
- 文本分块:结合文档结构和语义边界,设计合理的chunk策略,输出带元数据(来源、章节、页码等)的文本块。
- 向量化(Embedding):把每个文本块通过embedding模型转成向量,同时保留原始文本用于后续展示和关键词检索。
- 索引与存储:把向量写入向量数据库,建立合适的索引结构(如HNSW、IVF),同时保留一份关键词倒排索引。
- 检索与重排序:用户查询进来之后,先做召回(向量检索+关键词检索),再做重排序(重排模型或规则打分),选出最优的top-k上下文。
- 上下文组装与生成:把检索结果按逻辑顺序拼装,填入Prompt模板,交给大模型生成答案。
为什么我说分块和向量化只是其中两个环节?因为从我的实际经验看,如果前面的数据接入、清洗、解析做不好,后面分块和向量化再认真也白搭;如果后面的索引和维护跟不上,系统上线两星期就会因为数据更新、冗余堆积而逐渐变傻。整条管道是一个整体,任何一个环节掉链子,最终效果都会打折。
2. 数据接入与清洗:最脏最累却最值钱的环节
2.1 多源数据接入与格式解析
做RAG第一件事,不是写embedding代码,而是搞清楚你的数据到底长什么样。我之前接过一个燃气管道巡检相关的知识库项目,数据源包括:十几年前的纸质扫描件、Excel台账、PDF检测报告、摄像头抓拍的现场图片、还有运维人员的Word操作手册。每个格式都要单独处理,而且同一类格式在不同供应商手里,版式还完全不一样。
遇到这种多源数据场景,我建议优先做三件事:
- 建一个标准化的数据目录,记录每个文件的来源、类型、采集时间、归属部门,方便后续追溯和权限管理。
- 为每种格式建立独立的解析模块,不要在同一个函数里试图"通吃"所有格式,否则后期维护会非常痛苦。
- 在解析之后统一转成一种中间格式(纯文本或Markdown),让下游环节只依赖这一种格式,这样管道内做任何升级都只需要改对应模块。
具体到格式解析,PDF是最麻烦的。纯文字型PDF用PyMuPDF或pdfplumber效果好;扫描件必须走OCR,我用过PaddleOCR和Tesseract,前者中文识别准确率高很多,但需要GPU加速;表格类PDF直接抽纯文本会把行列关系打乱,建议先用pdfplumber提取表格结构,再保留为Markdown表格或者JSON结构。Word类文件用python-docx,走document的paragraph和table接口分别提取文本和表格;HTML文档要先用BeautifulSoup或类似工具去掉script、style标签,再把正文段落和标题层级保留下来。
2.2 清洗规则与去重策略
文本抽取出来之后,你会很快发现语料里全是"垃圾":页眉页脚、页码、目录、重复的段落、乱码字符、无意义的空行。这些如果不清理,分块的时候会被当成正常内容一起切进去,既稀释了向量语义,又浪费存储。
我总结了一套在工程里落地过的清洗流程:
- 字符级清洗:统一编码为UTF-8,全角转半角,去除空字符、乱码、多余空白。这一步别看简单,做不好后面的分词和embedding都会受干扰。
- 结构级清洗:识别并去除页眉页脚、页码、水印文字、版权声明等模板化字符串。这类字符串往往在多个文档里重复出现,可以通过"跨文档频率"来识别——某个字符串在大量文档里以完全相同的形式出现,大概率是模板噪音。
- 语义级去重:对文档做近似去重,用SimHash或MinHash计算文本指纹,把相似度超过阈值的文档标记出来。别小看这一步,我遇到过一个知识库,光重复上传的文档就占了30%的体量,不做去重,检索出来的top3里可能有两份是内容重复的,大模型会把两个版本混在一起,给出的答案反而更差。
这里有一个容易被忽略的细节:清洗一定要在分块之前完成,而不是分块之后。分块之后再清洗,块的边界已经定死,去重和纠错都很难处理,重做成本极高。数据管道里的顺序问题,往往比算法选择更值得你花时间想清楚。
2.3 从非结构化到半结构化的升级
很多RAG项目对数据的处理停留在"把PDF变成txt",也就是纯粹的纯文本化。但对于真正要上线跑业务的知识库,纯文本是不够的。我举个具体例子:你在燃气管道数据集里检索"3号阀门的维修记录",如果文档本身只是纯文本,无法把"维修时间、维修内容、负责人、阀门口径"这些字段对应起来,检索召回之后,大模型仅凭一段流水账很难回答得条理清晰。
如果解析阶段能保留表格结构、标题层级、列表等半结构化信息,后续分块就能按语义边界切,检索时也能用字段元数据做过滤(比如只搜"阀门"类型的内容),效果会提升非常多。所以,请别省下把文档解析成Markdown或结构化JSON的这一步,它为你后面的分块和检索提供了巨大的操作空间。哪怕只是把段落标题标出来,都能让下游的检索逻辑多一个强有力的维度。
3. 分块策略:把"分块矩阵"的思想用到文本上
3.1 常见分块方式与优缺点对比
分块这件事,业界方案已经非常多了,我把常见的分块方式整理成一张表,方便你按场景选:
| 分块方式 | 核心思路 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 固定长度分块 | 按字符数或token数均匀切分 | 实现简单、长度可控 | 容易切断语义单元 | 技术验证、文本长度均衡的非技术文档 |
| 递归字符分块 | 按段落、句子、标点等优先级逐级切割 | 能在一定程度上保持语义完整 | 依赖分割符质量 | 大多数通用文本,LangChain默认方案之一 |
| 文档结构分块 | 按Markdown标题层级、章节边界切分 | 保留文档逻辑结构 | 需要文档结构规整 | 手册、教程、说明书类文档 |
| 语义分块 | 利用embedding的相似度变化识别语义边界 | 切出的块语义更内聚 | 计算成本高、需要调试阈值 | 著作、长文、论文等长文本 |
| 父子分块 | 小块用于向量检索,大块作为生成上下文 | 兼顾召回精度与上下文完整性 | 需要维护两套索引,消耗更多存储 | 对话问答、多跳推理等复杂场景 |
固定长度分块确实是很多新手的第一选择,因为"切就完了"看起来最省事。但它的坑非常多:块长度设小了,一个完整的方案说明被拦腰截断;设大了,一个块里塞进好几段不相干的内容,向量表示变得"四不像"。我做项目时喜欢"先按文档结构粗切,再按语义或长度细分"的两步策略:先用标题层级把文档切成"章",再在章内部按段落或句号边界切成"块",这样既保留结构信息,又避免块过长。
3.2 动态规划式的分块优化思路
网络热词里出现了"分块矩阵相乘 节约计算量 动态规划"和"分块矩阵求逆",这两件事表面上看是线性代数内容,但它背后的思想用在文本分块上特别妙。分块矩阵的核心观点是:你要关注块与块之间的运算关系,而不是孤立地看每一块。文本分块也一样,碎片化之后还要能在检索环节"拼"回来,所以块之间的边界要尽量保证语义的连贯性和可组合性。
我实际用过的做法是:把分块任务定义成一个带约束的最优化问题。目标是让每个块的语义内聚度尽量高(可以用块内句子的向量相似度均值来衡量),同时控制块的长度在预设范围内。求解方法可以用类似动态规划的方式:先对文档做句子级切分,把每个句子embedding算好,然后从左到右遍历,记录"以第i句结尾时,最优分块方案对应的总得分",转移方程考虑"从上一块结束位置到当前句是否能组成一个语义内聚且长度合规的块"。这样虽然前期计算成本高一点,但能明显减少劣质分块。
当然,我不建议每个项目都上动态规划这么重的方案。大多数场景用递归字符分块加长度约束就够用了。动态规划思想真正的价值在于:它提醒你,分块不是"无脑切段",而是要在语义完整性、长度约束、检索召回效果之间做权衡。把这个权衡模型想清楚,哪怕你最终用简单方案,也知道该怎么调参数。
3.3 父子分块与多粒度检索
如果说有一个分块技巧能让检索效果立刻上一个台阶,我一定会推荐父子分块(Parent-Child Chunking)。原理非常简单:索引时,把一份文档切出两套块,小块的粒度比如200字符,大块的粒度比如1000字符;小块负责向量检索(召回精度高),检索命中后用小块对应的父块信息,把父块(完整段落)作为上下文送去给大模型生成。这样既解决了"小分块语义不全"的问题,又解决了"大分块检索不精准"的问题。
我在地铁检修规程类文档项目中用过这个方案,效果非常明显。用户问"夹钳气缸的作用",小块能精准命中描述夹钳气缸的句子,但如果只有这一小句,大模型回答会很干瘪;通过父子映射把完整段落带出来,模型就能结合前后文给出"是什么、怎么维护、常见故障"这类结构性答案。
实现父子分块也有代价:需要维护子块到父块的映射关系,向量库里要存两类向量,查询时要做一次额外的关联查询。但对比它在答案质量上的提升,这点成本完全值得。
4. 向量化:模型选型、部署与替代方案
4.1 嵌入模型怎么选
分块定好之后,就是把文本块变成向量。embedding模型的选择,我有一条核心原则:不要只看排行榜分数,要拿你真实的语料去测。通用榜单上排名靠前的模型,不一定适配你的垂直领域。
选模型时可以重点考察几个维度:
- 语言能力:中文场景必须选中文效果好的模型,比如BAAI/bge系列、智源的文本向量模型等,英文模型跑中文文本效果会大打折扣。
- 最大输入长度:模型的max token上限决定你能喂多长的文本块。如果你的分块策略是800字符,模型输入上限只有512 token,那就只能截断,这会损失语义。
- 向量维度:维度影响存储成本和检索速度,现在的模型普遍在768~1024维,老一些的模型可能高得多。维度不是越高越好,维度高虽然表征能力强,但存储和计算开销也大。
- 领域适配性:有些模型在代码、生物、法律、金融等领域做过专门微调。你如果做燃气管道、水下管道这类工业场景,尽量找在工科文本上表现好的模型。computer vision相关的应用如果要做图文联合检索,还需要看模型是否原生支持多模态输入,现在像SigLIP2这类多模态向量模型就是一个方向。
我自己的习惯是:在服务器上预先部署一个embedding服务,把全量语料跑一遍向量,再抽一些典型问题做召回测试,对比命中率。百闻不如一试,这比看任何测评都靠谱。
4.2 向量化服务器的部署与性能调优
热搜词里出现"向量化服务器",这个词挺有画面感。关于embedding服务,有几个在工程上会遇到的坑:
- 单个请求embedding很慢:如果频繁调用embedding接口,单条文本的HTTP往返开销会吃掉大量时间。解决办法是批量请求,一次传多段文本,利用GPU并行处理。
- embedding服务和高负载应用跑在一起:embedding模型虽然比大模型轻,但也会吃显存和CPU,建议单独部署一个推理服务,和主应用解耦。
- 模型量化:如果资源有限,可以用半精度(FP16)甚至INT8量化来降低显存占用。量化后的embedding模型在大多数场景下精度损失很小,我实测下来多数任务和全精度差距在1%以内。
- 缓存机制:对重复出现的文本块缓存向量结果,避免反复调用。清洗之后的全量语料一旦确定,向量化结果应该落盘持久化,下次启动直接加载,不需要重新计算。
这里的实操细节挺多,但核心就一句话:向量化本身不复杂,复杂的是让它跑得又快又省。做embedding服务,优先保证批量吞吐,其次再看单条延迟。
4.3 不只有向量:本地轻量化记忆库的替代思路
热搜词里还有一句"本地轻量化记忆库 除了向量化还有什么方案?",这个问题特别值得展开。很多人一提到"记忆库""知识库"就默认要上embedding,其实对于规模不大、更新频繁、计算资源有限的项目,纯向量方案未必是最优解。
替代方案主要有三种:
- 倒排索引(BM25):对文本做分词,建立词到文档的倒排索引,查询时按词频和逆文档频率打分。实现简单、效果稳定、资源占用极低,是经典搜索引擎的底子。缺点是纯词汇匹配,对近义词、语义改写不敏感。
- 词向量加倒排混合:用一个轻量的词向量模型做语义扩展,查询时把近义词也扩展到检索词集合里,再用BM25打分。这个方案在"词汇漂移"问题上比朴素BM25好很多,又比全量文档embedding轻量得多。
- 基于关系图谱的记忆库:如果知识本身是高度结构化的(设备、人员、位置、事件之间有明确关系),用图数据库或者轻量的RDF三元组存储反而更合适。查询走图遍历,天然支持多跳推理,这就是ontology驱动的RAG路线。
我的结论是:向量化不是万能银弹,它擅长的是"语义相似度匹配";关键词和结构化存储擅长的是"精确匹配和关系推理"。一个工程成熟的RAG系统,通常不是"二选一",而是混合使用。很多开源项目能做得又轻又快,就是因为它在BM25上做了不少优化。
5. 索引存储与混合检索
5.1 向量数据库选型与索引参数
向量数据落库,你可以选择专业的向量数据库(Milvus、Qdrant、Weaviate),也可以用传统数据库的向量插件(PostgreSQL+pgvector、Redisearch、SQLite+VSS)。选哪个,取决于你的规模、预算和团队熟悉度:
| 方案 | 优点 | 适用场景 |
|---|---|---|
| Milvus | 功能全、支持分布式、索引类型丰富 | 大规模、高实时并发 |
| Qdrant | 轻量、Rust写的、易部署 | 中小规模、快速落地 |
| PostgreSQL + pgvector | 复用现有数据库、事务能力强 | 已有PostgreSQL生态、数据量不大 |
| SQLite + VSS | 零部署、单文件存储 | 本地原型、边缘设备 |
索引参数方面,最常用的是HNSW(分层可导航小世界图)和IVF(倒排文件)。HNSW是我个人默认选型,里有两个核心参数:M(每个节点的最大连接数)和efConstruction(构建时考虑的候选集大小)。M越大,图越稠密,召回率越高,但构建和检索越慢;efConstruction越大,构建质量越高,但时间和内存消耗更大。一般项目可以从M=16、efConstruction=200起步,再根据召回效果调。
IVF更适合超大向量集(百万级以上),它先聚类再检索,速度极快,但精度会损失一点点。如果数据量几百万,HNSW基本够用;到几千万上亿,再考虑IVF或者Milvus的分片架构。这个选型过程,本质上就是"你想要什么样的速度精度平衡"的问题。
5.2 混合检索:向量 + 关键词的互补
纯向量检索有一个天生弱点:它是按"语义"匹配,不是按"关键词"匹配。用户如果问一个专有名词的精确缩写,比如"K3-12-8型阀门",embedding匹配的效果可能还不如一个简单倒排索引。反过来,纯关键词检索又处理不了"这个阀门的维修周期"这种描述性查询。所以生产系统里,混合检索+重排是最稳的组合。
我团队里搭的标准做法是:
- 查询进来后,同时发起向量检索(query embedding后取top50)和BM25关键词检索(取top50)。
- 两个结果集合并,按文档ID去重。
- 由重排模型(如bge-reranker)对合并后的候选集重新打分,取top5。
混合检索的好处是:向量搜索负责"找意思相近的",关键词搜索负责"找字符串匹配的",两者互补之后,召回质量会明显提高。很多教程只讲了向量检索半套,如果你在实际项目里发现"啥都搜不出来",大概率是只做了向量没做关键词。这个坑我犯过不止一次。
5.3 RAG知识库建设中的索引生命周期管理
知识库不是建完就完了,数据会持续更新。索引生命周期管理是我踩坑最多的地方之一。常见问题:
- 文档更新了,旧向量还在库里,结果检索到过时内容;解决方案是维护文档级版本号,更新时按文档ID批量删除旧向量再写新向量。
- 数据删除时,忘记删索引;应该实现一个统一的"写入/更新/删除"接口,任何数据变更都走这个接口。
- 增量数据处理:新文档进来只对新增部分做分块和向量化;全量重建需要定期做一次一致性校验,把孤儿向量清掉。
有一个经验分享:在向量库里一定要为每个向量打上丰富的元数据,包括文档ID、chunk ID、来源、时间戳、权限标签。这不仅是生命周期管理的基础,也是后续做权限过滤和按日期筛选的钥匙。很多人初始建向量库只存了文本和向量,后续想按部门、按项目过滤内容,发现完全无从下手,只能推倒重建。
6. 检索增强:召回、重排与上下文组装
6.1 重排序:为什么top-k不能直接用
很多RAG项目做出来效果差,问题不完全在索引和检索,而在"召回一堆之后直接用"。embedding检索返回的top5里,可能只有两三条真正和问题强相关,其余都是"沾边"。如果直接把top5全部塞给大模型,模型会被干扰信息带偏,输出质量自然拉胯。
这时要做重排序。我用得最多的是交叉编码器(Cross-Encoder)类的rerank模型,比如bge-reranker系列。和双塔式embedding不同,交叉编码器会把<问题,候选文本>拼接在一起输入模型,输出一个相关度分数。它比向量相似度精确很多,代价是计算慢,所以一般只对top50左右的结果做重排。
有一个低成本替代方案:如果不想额外部署rerank模型,可以用规则打分来重排,比如给"同时包含所有查询关键词"的候选加权重、"标题命中的候选加权重"。效果不如模型重排,但胜在零成本。我在小项目里就这么干过,至少能把最不相关的几条压到底部。
6.2 上下文组装:从"堆片段"到"讲故事"
重排选出top5之后,不是简单地把5段文本拼一起扔给大模型。前几步的信息在这里要被充分利用。我常用的组装思路是:
- 按逻辑顺序排列检索块(比如文章阅读顺序、时间顺序),而不是按相似度分数排列。
- 给每块附上来源元数据(文档名、章节、页码),在Prompt里标注清楚,方便大模型引用。
- 避免上下文过载。大模型的上下文窗口虽然越来越长,但并非越长越好。我一般控制在3000~6000 token,去掉与问题无关的片段。
- 设计Prompt时,明确告诉大模型"优先依据提供的文档回答,不要在文档未覆盖的部分编造"。
"堆片段"和"讲故事"的区别在于:人类阅读一段论证,需要前提-证据-结论的递进关系;大模型生成答案也一样。如果你把检索块按相似度降序排列,常常会出现先看到结论、后看到论据的情况,答案的条理性就差很多。手动把块按文档结构重排,答案质量会有可感知的提升。这一条经验在我做java rag问答等项目时尤其明显,同一个库、同一个问题,仅仅是调整了上下文块顺序,答案的完整度就完全不一样。
6.3 从单轮RAG走向Agentic RAG:反思、改写与多跳检索
基础管道跑通之后,我强烈建议研究一下Agentic RAG——它解决的是单轮RAG"一次检索定生死"的缺陷。
单轮RAG的问题是:用户一开始的query往往不够具体,比如"给我讲一下3号管道的问题",你可能不知道要检索"裂缝""腐蚀"还是"维修记录"。Agentic RAG的做法是:让大模型先做一个"查询改写",把模糊的问题改写为多个具体子问题,分别检索后再汇总;或者通过RAG-Fusion的思路,用多个改写出来的query做并行召回,最后融合重排。另外,遇到检索结果不足时,Agentic框架可以回溯、重新构造查询再试一轮,类似"反思"机制。
如果知识是高度结构化的,ontology RAG也是一种方向:用本体定义实体和关系,检索时先在知识图谱里做实体链接和关系遍历,再把结构化三元组和文档片段一起送给大模型。这种方式在工业设备巡检、医疗知识问答等领域特别有前景。至于MCP(Model Context Protocol),它是模型和外部工具、数据源之间的一套标准化接口协议,跟RAG是互补关系——RAG决定"用什么内容",MCP解决"模型如何按标准方式访问这些内容"。这两个概念不冲突,在一个工程系统里可以同时用。
7. 常见问题排查与实测心得
7.1 典型问题速查表
我在多个RAG项目里反复遇到类似问题,整理成一张速查表,方便大家对号入座:
| 症状 | 可能原因 | 排查思路 |
|---|---|---|
| 答案里没有检索内容,全靠模型脑补 | 检索召回到空或top-k太少 | 检查查询改写、混合检索、索引是否有数据 |
| 检索出来的内容与问题不相关 | 分块粒度太大、向量模型不匹配 | 调整分块策略,评估embedding模型 |
| 答案答非所问,但单看每段都对 | 上下文组装顺序乱、片断多且杂 | 重排后按文档逻辑排序,限制上下文长度 |
| 同一问题隔天答案不同 | 数据更新或向量库重建导致检索结果漂移 | 版本管理、固定随机种子、记录检索日志 |
| 性能太慢,一次问答要十几秒 | 向量检索慢、重排模型重、prompt过长 | 优化索引参数、减少重排候选数、控制上下文 |
| 知识库更新后仍检索到旧内容 | 旧向量未清理 | 按文档ID做增量更新,加缓存过期策略 |
7.2 增量更新与一致性维护
数据管道上线后,最容易被低估的就是"一致性维护"。我在一个项目里吃过亏:文档库每周更新,但向量库只在第一次构建时跑过,半年后系统检索出来的内容大量是过时的,业务方误以为仓库没更新,还为此开了好几场会对齐"知识同步"问题。
后来定了一套流程:任何数据变更都走统一的异步任务队列——文档上传后触发解析、清洗、分块、向量化、写入;变更完成后再对旧向量做删除和重建。元数据里记录数据版本号和更新时间,查询时如果切了版本过滤条件,必须带上校验。定期做全量一致性校验,跑脚本对比源文档和向量库的chunk数量、内容指纹,不匹配的标记出来重新同步。
7.3 资源受限场景下的轻量化落地建议
最后聊一下很多个人开发者会遇到的场景:没有GPU服务器、没有大存储、还要把RAG跑起来。我踩过一轮坑后的建议是:
- 本地轻量化方案优先选SQLite+VSS或者Chroma这类嵌入式向量库,省去部署分布式数据库的成本。
- embedding模型尽量选小尺寸版本,量化后跑在CPU也能接受。
- 加一层BM25关键词检索兜底,如果语义检索召回不好,至少关键词能接住一部分。
- 控制知识库规模,不要一股脑全塞进去。先用清洗和去重把语料压缩到"够用"的级别,比盲目堆数量有效得多。
- 分块和索引配置做成可配置化,方便随时调参,避免每次改一个参数就要重新跑全流程。
做RAG项目这几年,我最大的一个体会是:这个领域不缺少漂亮的算法和框架,缺的是把数据管道每个环节都做扎实的耐心。很多时候系统效果差,不是模型不够强,而是前面几道"脏活"没干到位。把数据接入、清洗、分块、索引这些基础功夫练好,再复杂的检索策略往上叠才有意义。希望这篇文章能帮你在自己的RAG项目里少踩几个坑,把时间花在真正影响效果的地方。