AgentHubAgentHub
Back to Blog

AI 是怎么翻到你要的那一页的:它不找关键词,只找“离得近”的话

AgentHub 编辑部··21 min read·9 views
AI 是怎么翻到你要的那一页的:它不找关键词,只找“离得近”的话

你上传了一份 200 页的 PDF,问一个只有里面写过的问题,它三秒钟回你两行字。你大概想象不出中间发生了什么:它是把整本书读完了吗?读了一遍还是三遍?它怎么知道答案在第 137 页?

答案跟直觉正好相反:它一页都没读完。它只是从整本书里挑出一小把段落,塞到你问题旁边。

这不是偷懒,而是一整套独立的技术。名字有两层:外面那层叫 RAG(检索增强生成,Retrieval-Augmented Generation),里面真正干活的那个零件叫向量检索。这篇只靠两个类比就能把它们讲完:

  • 给每段话发一张体检报告——解释什么叫向量、远近是怎么比出来的;
  • 把闭卷考试改成开卷——解释 AI 为什么需要检索,以及检索到的东西到底给了谁。

看完你会拿到三道具体的判断题,可以当场去验你现在正在用的那个知识库是不是真的在检索。很多人花几百块建的知识库,其实从来没翻开过你的文件。

先把整件事压缩成三步

一套检索系统干活的顺序是固定的三段:

  1. 存的时候:把文档切成一小段一小段,每一段算出一串数字,把“原文+这串数字”一起存起来。这一步只做一次,行话叫索引(indexing)。
  2. 问的时候:把你的问题也算成一串同规格的数字,去那堆数字里找最接近的若干条。这一步叫检索(retrieval)。
  3. 答的时候:把问题、和找回来的这几段原文一起交给模型,让它照着材料回答。这一步叫生成(generation)。

关键认知:模型从头到尾没读过你的文件。它读到的只是第 2 步挑出来的那一小把。 挑得好,它答得准;挑错了,它就只能凭印象编。这也是绝大部分“知识库答错”的真正原因,而不是模型太笨。

图 1|三个数就是这条流水线的形状:1024 维坐标、512 tokens 一块、一次捞 50 段
图 1|三个数就是这条流水线的形状:1024 维坐标、512 tokens 一块、一次捞 50 段

那这三步里“算出一串数字”“找最接近”到底是什么意思?下面一格一格拆开。

第一个零件:给每段话发一张体检报告

先解释最核心的词。嵌入(embedding,动词是 embed)就是用一段文字,换一串固定长度的小数。这串数字叫向量(vector),你只要理解成“一串有顺序的数字”,比如长度是 5 的话可能长这样:

[0.12, -0.88, 0.03, 0.51, -1.07]

真实系统里这串数字的长度叫维度,常见是 1024、1536 或者 3072。为什么要这么多项?因为每一个位置大致对应一个说不清名字的“特征”。你可以把它当成一张体检报告:身高、血压、血脂……一项一项打分,一个 40 岁的男人和另一个 41 岁的男人,报告上大部分项目都接近。文字也一样:说的事越接近,这 1024 项得分的整体形状就越接近。

这里要提醒两件容易想错的事。

第一,这不是分类,不是打标签。 标签是“这属于财务类”,只有或者没有;向量是一个连续的位置。两张报告可以“像到 87%”,也可以完全不相干,中间是渐变的。所以它能回答“有多像”,而不只是“像不像”。这就是为什么它能排序:50 段材料可以按像的程度排出先后。

第二,这 1024 项没有人手写规则,是模型从海量文本里学出来的。 你不需要知道第 7 项到底在测什么(没人知道),只需要知道“经过训练之后,意思接近的文字会拿到接近的报告”。

各家的规格都是公开的,而且价格比多数人想象的低得多:

嵌入模型向量维度单段输入上限价格
阿里云百炼 text-embedding-v4默认 1024,可改成 2048/1536/512/64 等每段最长 8192 tokens0.0005 元/千 tokens,约 0.5 元/百万
OpenAI text-embedding-3-small15368192 tokens(微软那份文档一处写 8191)0.02 美元/百万 tokens
OpenAI text-embedding-3-large30728192 tokens0.13 美元/百万 tokens
智谱 embedding-210248K tokens0.5 元/百万 tokens
BGE-M3(智源,开源)10248192 tokens自己跑,只花机器钱

token 是大模型计量文字的单元,各家切法不同,粗略地说一个汉字算 1 个上下。它跟钱到底怎么换算,看每百万 tokens 到底是多少字:三步算清一次 AI 调用要花多少钱。

这张表对普通人的实际意义是一句话:建知识库的钱,几乎全在“回答”那一步,不在“存”这一步。 把一整本书算成向量,用的是上面这个便宜价;而你每问一次、模型每答一次,走的是对话模型的价格,那是另一个量级。所以“我文档很大,会不会很贵”这个担心,多半放错了地方。

表里“自己跑”那一行也值得说一句:BGE-M3 是 MIT 协议开源的(可以免费商用),维度 1024,官方模型卡写着支持超过 100 种工作语言。这意味着“算坐标”这一步完全可以不出你的电脑。私密性要求高的场景里,这是最容易本地化的一环。

远近怎么算:比的是方向,不是长短

有了两串数字,“像不像”就变成一道数学题。最常用的算法叫余弦相似度(cosine similarity):把两串数字想象成两个方向,算它们夹角有多大,结果落在 -1 到 1 之间,越接近 1 越像。

这里有一个反直觉但很关键的性质:它比的是方向,不是长度。 同一个意思,你用 20 个字说,也可以用 200 个字说,两段话算出来的向量方向差不多——啰嗦不会让它觉得你不像。 这在搜索场景里太重要了:文档里的句子往往又长又书面,你的提问往往又短又口语,长度差十倍,方向却可以一致。

微软官方文档给的标准例子是:“dog”和“canine”(犬科)概念上很接近,但字面上完全不同(原文是 conceptually similar but linguistically distinct)。同一页还列了跨语言(英文 dog 对德文 hund)和跨形态(一段文字对一张狗的图片)。这三种在关键词匹配里都是零分,在向量空间里都是有分的。

再说“找最近的多少条”。这个参数就叫 k(或者 top-k),意思是“取回最像的前 k 段”。微软搜索服务的文档里,不指定时默认返回 50 条;而当你要在向量结果上再做一层语义重排时,官方的写法是把 k 设成 50。翻译成大白话:先把 50 段候选捞上来摊在桌上,再从里面挑真正相关的几条交给模型。 一次检索从来不是只找一条答案,而是找一把相关材料。

顺带说一个几乎没人讲的事实:文档有上百万段的时候,跟你的问题逐一比对 1024 项,慢到不可用。所以工程上用的是近似算法。最流行的一族叫 HNSW(分层可导航小世界图),出自 2016 年 3 月 30 日的一篇论文,摘要里对它的定义是“approximate K-nearest neighbor search”(近似 K 最近邻搜索),并提到分层之后能带来“对数级的复杂度增长”。思路很像你在一个陌生城市找人:不挨家挨户敲门,先看城市地图圈一个区,再看街道图圈一条街,最后进巷子里一家家看。

“近似”这两个字请记住。 它意味着检索天生就不保证一定能找回全局最像的那一段。所以“文档里明明有,它却说没有”是这类系统的固有失败模式,不一定是谁配置错了。这个区别,后面判断题那节会给你一条可以用的分界线。

第二个零件:先把书撕成卡片

向量算得再好,也得先决定“给哪一段算”。整本算一个向量是不行的——那等于把一整本书押在一个位置上,里面讲了八件事,结果哪件都不像。微软那份切块文档里就有这句话:如果内容用单个向量表示得很差,切块同样有益,并且专门举了“一个 wiki 页面讲了许多彼此无关的子话题”当例子,建议切得更细。

所以第一步永远是切段,行话叫切块(chunking),切出来的一小段叫一个 chunk(块/卡片)。

这一步是全流程里最不性感、却最影响成败的。好消息是:它有非常具体的官方参考值,而且微软用一本书做过真实对照实验。

参考值出自同一个页面,有三组:起点建议是每块 512 tokens(约 2000 个字符),块间重叠 25%,也就是重叠 128 tokens;它自带的文本切分技能默认参数是每块 2000 字符、重叠 500;同一篇里另一段 LangChain 的例子用的是 1000/200。三个数不一样,不是文档打架,而是这类参数没有标准答案,只有起点。

真正让人感受到切块分量的,是那张实验表。同一本 NASA 的电子书《地球夜晚》(Earth at Night),一共 200 页,用不同参数切,得到的块数是这样的:

每块长度(字符)重叠长度(字符)切出多少块
10000172
1000200216
2000085
2000500113
5000034
500050038
按句子切不适用13361

同一本书,最少 34 块,最多 13361 块,差了近 393 倍。 这就是为什么两个用同一个模型的知识库,效果能差到天上去:模型那一环完全一样,卡片箱却根本不是一个东西。

用类比把这张表读成人话:

  • 块切太大(5000 字符,全书只剩 34 张卡)=一张卡片抄了四页纸,里面什么都有。你问“极光是怎么形成的”,这张卡里确实有答案,但同时混着火山、城市灯光和叶绿浮游生物。它的体检报告被这些无关内容拉了平均,位置变得谁都不太像。大而杂的一段,坐标是模糊的。
  • 块切太小(按句子切,13361 张卡)=一句话一张卡。上下文丢了。“它指的是上个月那次调整”——这句单独看没有任何意义,“它”指什么在上一张卡里。切得太碎,等于把句子之间的手指剪断了。
  • 重叠(那个 500/200/128)是缝合线:每张卡尾部重复一点下一张的开头,让被切开的那句话在两张卡里都出现,怎么切都不至于丢。

再补两个反直觉的细节。

一个是:加上重叠之后块数会变多(2000 字符那组,85 块变成 113 块),因为它在重复存内容。很多人以为重叠是浪费,其实它是用存储换连续性——而“存”这一环恰好便宜到可以忽略(前面那张价格表就是依据)。这是一笔明确划算的买卖。

另一个是微软文档里明写的一个坑:重叠值设得太大,最后可能出现完全不重叠的情况(原文:setting an overlap value that's too large can result in no overlap appearing at all)。参数不是设了就生效,是设得合理才生效。

关键词搜索为什么会漏:这是一个有名字的老问题

到这里你可能想问:我不搞这些花活,老老实实用关键词搜自己写的笔记,为什么会找不到?

因为这件事在信息检索领域里一直有个正式的名字:vocabulary mismatch(词汇失配,字面意思就是“你用的词和文档里的词对不上”)。近年的论文里还会直接写 “the vocabulary mismatch problem”,并把它当作需要额外补救的已知难题。

它有多老?到今天仍然在当默认打分算法的 BM25,是 Robertson 等人在 1994 年 TREC 会议上提出的(Apache Lucene 的官方注释里就是这么标注的),三十多年过去,Elasticsearch 的官方文档仍然写着它是“Elasticsearch 和 Lucene 中默认使用的算法”。换句话说,你现在用的绝大多数搜索框,本质上跑的是一套 1994 年的打分逻辑:你的词和文档的词重合多少、重合的那几个词多重要,就排多前。

这套逻辑有三个结构性缺口:

  1. 同义不同词:文档写“发票抬头”,你搜“报销单上的名字”。零重合,零分。
  2. 口语对书面:文档写“该参数仅在启用二级缓存时生效”,你问“这个开关为啥没用”。
  3. 一词多义:你搜“部署”,文档里有 40 处,其中 38 处说的是另一件事。

向量检索天生处理这三个,因为它比的是“体检报告的整体形状”,不是“这个字出现过没有”。

但向量不是万能的。 它有自己的死角:那些必须精确命中的东西。一个错误码 ERR-2041、一个函数名 getUserProfileById、一份合同编号——这些在向量空间里几乎没有“意义”可言,字面匹配反而一击必中。所以正经系统两条都做,叫混合检索(hybrid search)。微软的定义写得很干脆:“在同一次请求里同时执行向量搜索和关键词搜索”,并且明确说两条一起跑再合并结果“通常比只做向量或只做关键词提供更好的结果”。

两份榜单怎么合成一份,有个名字叫 RRF(倒数排名融合)。算法简单到能口算:一份名单里第 1 名得 1/(1+k) 分,第 2 名得 1/(2+k) 分,越靠后加分越小,两份名单的分数相加再排一次。微软文档里这个 k 的建议值就是 60,原话是“实验显示把 k 设成一个小值、比如 60 的时候效果最好”。

站内有一篇把这个思路做到代码库场景的架构长文。要给几万行文件建索引的话,看混合搜索与 AST 代码索引架构:打造万级文件代码库的高精度定位引擎,本文不重复它的工程部分。

RAG:把闭卷考试改成开卷

零件讲完,现在把它们拼成那件事:检索增强生成(RAG)。

最准确的类比是这个:模型自己背下来的东西是闭卷,RAG 是把相关材料印在草稿纸上带进考场。

模型在训练时读过的海量公开文本,就是它“背下来的那本书”。你的公司规章、上个月的会议记录、项目的配置文件——它一个字都没背过。你不递材料,它只有两个选择:说不知道,或者按“这类东西一般长什么样”给你编一个。为什么它常常选后者,见AI 为什么会一本正经地胡说八道:它认得出自己的错,却不会主动说。

“递材料”这个动作的正式出处,是 2020 年 5 月 22 日的一篇论文(arXiv 编号 2005.11401,被 NeurIPS 2020 收录,作者来自 Facebook AI Research、伦敦大学学院和纽约大学,一共 12 人)。它当时那句定义值得原样搬过来:模型“combine pre-trained parametric and non-parametric memory for language generation”(把参数化记忆和非参数化记忆结合起来生成语言)。这句太学术,翻译成人话就是:一半知识长在模型权重里(参数化记忆),一半知识放在外面的一个索引里(非参数记忆),回答的时候两边一起用。

同一篇论文里还有两句更实用的话,那才是它今天被全行业采用的原因:

  • 知识“can be directly revised and expanded”(可以被直接修订和扩充),而且论文另外明说“非参数记忆可以被替换掉,从而更新模型的知识”。因为那半记忆是外面的一个索引,改文档就行,不用重训模型。
  • 取用过的知识“can be inspected and interpreted”(可以被检查和解读)。因为它能告诉你这句话是从哪一段取的。

这两句决定了你今天习不习惯的两个体验:知识库能跟着文件更新,以及回答能带出处。一个只会给答案、永远说不出来源的“知识库”,多半连第一步都没做对。

论文当年的组合是一个检索器(DPR,稠密段落检索)配一个生成模型(BART):检索器负责找材料,生成器负责照着材料写。今天所有产品里的“文档问答”都是这个骨架,只是换成了更大的模型和更讲究的检索层。

后来一篇 2023 年 12 月的综述(arXiv:2312.10997,十位作者)把这条路线分成三代,措辞非常好懂:Naive RAG(朴素版)就是“索引 → 检索 → 生成”三步直线;Advanced RAG 是为补朴素版的短板,在检索前后加处理,比如把你的问题改写几遍再分别去搜、或者把找回来的 50 段重排一遍;Modular RAG 则把每一步拆成可替换的模块。你听到的“我们做了 rerank”“我们做了查询改写”,都落在第二、第三代里。

那不如整本塞进去?上下文不是越来越大吗

这是最多人问的:现在动辄百万 token 的上下文窗口(上下文窗口到底限制了什么,看AI 为什么聊着聊着就忘了你说的话:它没有“记住”这一步,只有“这次递进去多少”),我把整本书直接塞给它不是更省事?

诚实的回答是:塞得下,读不好,而且贵。 三条都有出处。

读不好。 Chroma 在 2025 年 7 月发布的一份测试(《Context Rot》,注意这是技术报告、不是同行评审论文,测了 18 个模型)里的结论是,模型对自己上下文的使用并不均匀;其中有一条特别关键:输入越长、性能下滑越快的,正是“问题和材料本身相似度低”的那一组。也就是说,真正需要模型费劲做关联的时候,长输入最先顶不住——而这恰好是知识库场景的常态。同一份报告还给了一个反常识的结果:“结构连贯性一贯地损害模型表现”(structural coherence consistently hurts model performance),即把材料按原文顺序、结构完整地递进去,反而比打乱更差。

贵。 微软那份切块文档里给了一个尺度参照:text-embedding-3-small 的 8191 tokens 上限,大约相当于 6000 个英文单词的正文。你的 200 页 PDF 换成 token 是几十万的量级,而且每次提问都要重新付一次这笔输入费;检索路线每次只递几千 token。差价从哪来、怎么算,站内长上下文经济学:Prompt Caching 如何改变大模型商业变现与应用形态 讲得更细。

而这两条的取舍,有论文直接对比过。 谷歌研究院 2024 年 7 月的一篇(arXiv:2407.16833)专门比较长上下文(LC)和 RAG,摘要原话是:“when resourced sufficiently, LC consistently outperforms RAG in terms of average performance. However, RAG's significantly lower cost remains a distinct advantage.”(资源给足时,长上下文在平均表现上稳定强于 RAG;但 RAG 显著更低的成本仍然是它的一项明显优势。)

这句话要读仔细:它没有说检索更好。 它说的是长上下文在钱给够的时候更强,检索在便宜这条轴上无解。所以正确的结论不是“要不要检索”,而是这两件事是分工:装得下、而且需要全局理解的(比如让模型总结整本书),直接给全文;装不下、或者你只关心其中三段的,检索。

顺手把两个常被混为一谈的概念分清楚。

Prompt Caching(提示词缓存)不是检索。 它是“我这次塞进去的那一大坨前缀,下次再塞时打个折”,省的是重复输入的钱;检索是“我根本不塞那么多”。两者经常一起用,但机制完全不同,企业侧的降本组合拳在降低企业 LLM 调用成本 70%:Prompt Caching、智能分流与小模型蒸馏策略 里有实操版本。

微调(fine-tuning,再训练模型让它“学会”你的东西)也不是检索。 一句话分别:检索是每次给它材料,微调是把它教会。 前者改文件立刻生效,后者要重训、改一次训一次,而且学进去的东西拿不出来给你看出处。这一层的技术权衡站内有专文,见大模型微调 vs 提示词上下文工具感知:工具调用的工程架构权衡。

你的知识库为什么答错:三道当场能做的判断题

前面全是解释,这一节给你能立刻做的事。判断一个“知识库/文档问答”是不是真在检索,不需要任何代码,三个问题就够。

判断题 1:文档里根本没有的东西,它会不会老实说没有? 挑一个你的文件里确实没有、但看起来很会有的问题。比如给员工手册问“加班可以调休几天”,而手册里真没写这条。

  • 回答“材料里没有相关条款”=检索在起作用,而且模型被约束在给定材料内。
  • 回答得斩钉截铁、条目清晰=两种可能:要么根本没检索(它在背网上的公版知识),要么检索回来的是不相干段落还硬写。这是坏知识库最常见的样子。

判断题 2:同一个问题,换个说法还找得到吗? 先用文档里的原话问一次(“发票抬头”),再用你的口语说法问一次(“报销单上的名字写错了怎么办”)。

  • 两次都对=有语义检索这一层。
  • 第一次对、第二次说没有=基本可以判定它只做关键词匹配。这就是上面那三个结构性缺口的现场版。

判断题 3:需要跨两段拼的答案,它给得全吗? 挑一个答案天然分在两处的问题,比如“这个功能谁负责、什么时候上线”——负责人写在会议纪要里,时间写在计划表里。

  • 只答出一半=切块把上下文切断了,或者一次取回的块数太少。
  • 完整答出=它取回了多块并且做了合并。

这三道题的套路,和怎么读一份大模型发布稿:六个数分三组看,三个地方最容易讲错 是同一个方法:先定下“什么算数”的口径,再去找证据,只是对象从发布会变成了你手上正在用的那个产品。

三道题之外,还有两个动作值得马上做。

别把长表格、长截图当“文档”直接扔进去。 表格被切块之后,列名和数值会被分进不同的块里——“3 月”那一行配上“总计”那一列,坐标完全错乱。扫描件和图片同理:多数知识库的默认链路根本不读图(这是产品链路的现实,不是模型不行)。有表格就转成文字版,或者单独给它一整块。

自己建的时候,先别急着接模型。 只做一件事:索引建完,问一句“这份文档的标题是什么”这种答案就在第一块里的问题。这一步能确认“文件真的被读进索引”这一环通了。很多人第一次搭知识库卡住,卡在的不是模型答得差,是文件压根没进去。

现在能做的三件事

一、给你手上正在用的那个知识库做一次判断题。 上面三道,五分钟。如果发现它只会关键词匹配,你为它花的钱有一半是白花。

二、把“怎么写笔记”往“好检索”的方向调一点。 这是普通人唯一能直接影响检索质量的地方,三条就够:

  • 一段只说一件事。 前面那张表已经说明,大而杂的一段,坐标是模糊的。你的笔记一屏塞四个话题,就是在给自己制造“全书 34 块”那种情况。
  • 给每段一个自包含的开头。 写“关于年假:入职满一年后 5 天……”,而不是“补充一下:满一年后 5 天”。指代不清是切块的头号副作用。
  • 少用图片存信息。 图上写的字,检索层看不见。

三、真想动手,站内有现成的链路。 从零建一个能用的私有知识库,看基于 Qdrant 向量数据库构建私有知识库 RAG MCP Server;想先搞懂“AI 怎么把外部东西接到你的编辑器里”这个前置概念,看MCP 到底是什么?从 AI 工具调用到 Agent 工作流,一文看懂 MCP。站内也有可以直接接的现成组件,比如Qdrant 向量库只读 MCP 和RAG 知识库 MCP,详情页里有可以直接复制的配置命令。想接到自己的笔记上,看使用 Notion 与 Obsidian MCP 打造 AI 驱动的个人第二大脑知识管理;要给代码库做,看借助 Meilisearch MCP 打造毫秒级代码库全文本与语义搜索工具;想更进一步搞清“AI 的记忆分几层”,看智能体记忆体系架构:工作记忆、短期会话缓冲与长期知识图谱的融合。

一句话版本

AI 翻到你那一页,靠的不是读完,而是先把每段话换成一张“体检报告”,再把你的问题也换成同规格的一张,然后按形状像不像取回最近的一小把,最后才把这一小把和你的问题一起交给模型。 所以它答得准不准,一半取决于模型,另一半取决于你的文档有没有被切成合适大小的块——后一半,是你能改的。

Related Articles

Tutorials

AI 为什么总顺着你说:它不是同意你,是被打分教出来的

你明明说错了,它却顺着你说一段。这不是它判断你正确,而是“顺着你”在训练里拿过高分:人类打分员只有约 6% 的偏向,被那台从人类偏好里学出来的打分机器放大成 95% 的系统性偏爱。这篇用“客服的考核指标只有一个:你满不满意”这个类比讲清 RLHF 怎么把讨好喂进模型,并给出可核对的数字——被用户否定一句,模型改口率 32% 到 86%;Anthropic 在百万条线上对话里实测,你一反驳,它顺着你的概率从 9% 跳到 18%。末尾附三道判断题和四个能立刻改的提问动作。

Tutorials

AI 为什么聊着聊着就忘了你说的话:它没有“记住”这一步,只有“这次递进去多少”

它不是记住了又忘掉。模型没有“记住”这个动作:你每问一次,程序都要把这次要它看的东西整份重新递一遍,而这一块地方有边界、单位是 token 不是字、还要和它的回答共用同一份预算。这篇用官方文档和有出处的研究讲清三件事:规格页上的数字该怎么读、装不下时各家怎么处理(截断还是摘要)、以及为什么装得下它照样会看漏——中间那段最容易漏,把要求拆成多轮说六类任务平均降 39%。最后给六个你当场就能用的动作,附可直接抄的话术。

Tutorials

AI 为什么会一本正经地胡说八道:它认得出自己的错,却不会主动说

模型不是在查资料,是在接话——这一句能解释所有现象。这篇用四条有出处的事实讲清它为什么编得这么像:GPT-4 报告自陈不可靠、2023 年那项研究发现它能识别自己 87% 的错误、2026 年《自然》论文指出只按准确率打分等于奖励瞎猜、以及 2025 年一年里 146,932 条不存在的引文进入学术库。再给出六种你在对话框里就能做的自查,附可直接抄的话术。

Tutorials

每百万 tokens 到底是多少字:三步算清一次 AI 调用要花多少钱

先把元/千 tokens、元/百万 tokens、万字这三种单位钉死,再按标定、算单次、核账单三步走:用自己的素材测字 token 比,把系统提示、本轮内容、历史轮次、工具定义四块输入加总,最后换算成每业务单位多少钱。附一个可复算的例子,和 Agent 场景下输入按 n(n+1)/2 平方增长的解释。

Explore AI Ecosystem

Ready to take action? Explore AI tools & MCPs

Discover ChatGPT 6, Claude 3.7, Devin and 3000+ open-source MCP tools with 1-click config.

向量检索与 RAG 通俗解释:AI 是怎么翻到你要的那一页的 - AgentHub