最近半年,找我聊知识库的人明显多了。不只是技术同学,连业务方也开始问:"我们能不能搞一个内部知识库,让AI帮我们查文档?"
这个需求听起来简单——把公司的文档、代码、wiki全喂给AI,问什么答什么,多美好。但真正动手做过的人才知道,"知识库"三个字背后,方案差异大得离谱。
我自己从去年开始陆陆续续试过几种路线,有些效果超出预期,有些踩了不小的坑。趁记忆还新鲜,把目前市面上比较热的几条路梳理一下,也给正在选型的朋友一点参考。
最朴素的做法:切片 → 向量化 → 检索 → 生成
这是大部分人入门RAG的方式,也是很多教程里的"标准答案"。把文档切成几百token的小块,用embedding模型转成向量,存进向量数据库,查询的时候找最相似的几块拼到prompt里让模型回答。
这个方案能跑。对于文档量不大、问题比较直接的场景(比如FAQ、简单的产品手册问答),效果还行。
但它有一个根本性的问题:切片会破坏上下文。
举个例子。一份财报里有一段写"营收同比增长12%",被单独切出来之后,它属于哪家公司、哪个季度、跟谁比的——全丢了。用户问"A公司Q3营收增速多少",向量检索可能找到一堆"营收增长"的片段,但答不对。
我们最早做内部知识库时就遇到了这个问题。技术文档里到处都是"该接口"、"这个配置"、"上一节提到的参数"这种依赖上下文的表述,切片之后完全不知道在说什么。
Contextual Retrieval:给每个片段补一句"我是谁"
Anthropic去年提出了一个思路,我觉得挺巧妙的。他们不改变检索架构,而是在入库之前,让模型先给每个片段加一段简短的上下文说明。
比如原来一个片段是"The company's revenue grew by 3% over the previous quarter",入库时会被改成:"This chunk is from an SEC filing on ACME Corp's performance in Q2 2023; the previous quarter's revenue was $314 million. The company's revenue grew by 3% over the previous quarter."
就多了前面那几十个字,检索准确率提升了将近50%。配合BM25做混合检索(语义+关键词匹配),检索失败率能降67%。
这个方案的优点是改动小、兼容性强,可以叠加在其他方案上面。缺点也很明显——每个片段都要调一次模型来生成上下文,文档量大的时候,光这一步的token消耗就不低。Anthropic自己做这个实验用的是Claude的prompt caching来降成本,但换了别的模型,这笔开销得好好算算。
我自己试下来,对中小规模的知识库(几千页以内),这是目前性价比最高的改进方式。但如果文档量到了几十万页的级别,成本就上来了。
GraphRAG:不找片段,找关系
微软研究院的GraphRAG走了一条完全不同的路。它不是把文档切成片段存起来,而是先用LLM从文档里抽取实体和关系,构建一张知识图谱。然后对图谱做社区聚类,给每个社区生成摘要。查询的时候,不直接检索文档片段,而是基于图谱结构和社区摘要来回答。
这个方案在回答"全局性"问题时优势很大。比如"这份数据集里有哪些主题?"、"这几个项目之间有什么关联?"——这类问题需要跨文档的综合理解,传统RAG基本答不上来,GraphRAG可以。
但代价是入库成本非常高。每一批文档都要跑一遍图谱抽取和社区聚类,这个过程需要大量的LLM调用。我们之前在一个中等规模的项目上试,几万篇文档的索引构建花了大半天时间,而且token费用相当可观。
另一个问题是,图谱的质量高度依赖抽取的prompt。如果实体关系抽错了,后面的检索和回答就全歪了。这需要针对你的领域反复调prompt,不是开箱即用的那种方案。
我目前的判断是:如果你的知识库需要回答大量"关联型"问题(比如客户360画像、供应链溯源),GraphRAG值得投入。如果只是做普通的文档问答,有点杀鸡用牛刀。
Corrective RAG:检索完了,先判一下靠不靠谱
CRAG的思路是在检索之后、生成之前,加一个"评估器"。它会判断检索出来的文档质量够不够好——如果够好,就用;如果不好,就触发补救措施,比如用搜索引擎去网上找补充材料,或者对检索结果做二次筛选。
这个方案解决的是"检索到了垃圾怎么办"的问题。在实际业务中,知识库不可能覆盖所有问题,用户问到知识库里没有的内容时,传统RAG会硬凑一个答案出来,幻觉就是这么来的。CRAG至少能在检索不靠谱的时候踩一脚刹车。
实现上不复杂,一个分类器就能搞定。但它增加了一次模型调用,延迟会涨。而且那个"评估器"本身也需要训练或调prompt,效果取决于你对"什么是好检索"的定义有多清晰。
Agentic RAG:让Agent来决定怎么找
这是最近讨论比较多的一个方向。与其写死一套检索流程(切片→检索→拼接→生成),不如让AI Agent自己决定:这个问题需要查哪些数据源?检索结果够不够?要不要换个关键词再查一次?要不要交叉验证?
好处是灵活。不同的问题走不同的检索路径,复杂问题可以分多步拆解,还可以同时调用向量检索、全文搜索、SQL查询、API调用等多种工具。相当于把检索策略从"固定管线"变成了"动态决策"。
但这也意味着系统的不可预测性增加了。Agent可能在一个简单问题上绕很多圈才给答案,也可能在复杂问题上偷懒只查了一次就下结论。调试起来比传统管线复杂得多,而且每次查询可能触发多次LLM调用,成本和延迟都不好控制。
我自己的观察是,Agentic RAG在"复杂研究型问题"上效果很好——比如竞品分析、技术选型调研这种需要多源交叉验证的场景。但对大部分内部知识库问答来说,有点过头了。
Self-RAG:模型自己学会什么时候该查
学术界还有一种思路,通过训练让模型自己判断"这个问题我需要检索吗"以及"检索到的内容跟我的回答相关吗"。模型在生成过程中会产出一种叫"reflection token"的特殊标记,用来表达对自己输出的反思。
这个方向的研究意义很大,但工程落地还比较远。需要专门fine-tune模型,而且reflection token的质量依赖训练数据。目前更像是一种"未来的可能性",而不是今天就能拿来用的方案。
Late Chunking:先编码再切片
Jina AI提出的Late Chunking跟传统流程正好反过来。传统做法是先切片再编码,它先把整篇文档送进一个长上下文embedding模型做编码,然后再把embedding向量按chunk切分。这样每个chunk的向量实际上包含了整篇文档的上下文信息。
这个方案的好处是检索质量高,因为向量本身就编码了全局上下文,不会出现"片段不知道自己属于哪篇文档"的问题。缺点是对embedding模型有要求——需要支持足够长的上下文输入,而且长文档编码的计算成本不低。
目前这个方向还在演进中,Jina的长上下文embedding模型能处理到8k token。对于大部分文档来说够用了,但如果是特别长的技术文档或法律合同,可能还是会有截断。
怎么选?没有万能药
聊了这么多方案,我自己目前的体会是:
如果知识库在500页以内,甚至不需要RAG。直接把文档塞进长上下文模型的prompt就行,简单粗暴但效果不错。现在有些模型支持200k token以上的上下文,够用了。
如果是几千页到几万页的规模,朴素RAG + Contextual Retrieval + 混合检索(向量+BM25),这套组合拳是目前最稳的选择。改动小、效果可验证、成本可控。
如果文档之间有大量关联关系需要推理,可以考虑叠加GraphRAG。但要做好prompt调优和成本预算的准备。
如果你面对的是一个需要多步研究才能回答的复杂问题,Agentic RAG可能更适合。但这基本是在搭建一个Agent系统了,知识库只是它的数据源之一。
这些方案之间不是互斥的,更像是可以叠加的积木。我自己目前在用的组合是Contextual Retrieval做入库增强 + 混合检索做查询 + CRAG做兜底,效果在我们的场景下还不错。
不过说实话,知识库这件事,技术方案只占一半。另一半更难的问题在于:数据质量、文档更新频率、用户预期管理。文档本身就是过时或错误的,再好的检索方案也救不了。
写到这里我发现自己越写越想列清单了,打住。每个团队的场景不一样,照搬别人的方案不如搞清楚自己的问题在哪。先把"用户最常问什么类型的问题"这件事想明白,方案自然就出来了。
添加新评论