[{"data":1,"prerenderedAt":2754},["ShallowReactive",2],{"about:header-avatar":3,"content:\u002F2026\u002Farticle-20260907-174336-383eaaa7":53,"surround:\u002F2026\u002Farticle-20260907-174336-383eaaa7":2743},{"id":4,"title":5,"author":6,"avatar":7,"body":8,"categories":32,"date":34,"description":14,"draft":35,"extension":36,"image":6,"meta":37,"navigation":39,"path":40,"permalink":6,"published":6,"readingTime":41,"recommend":6,"references":6,"seo":46,"sitemap":6,"stem":47,"summary":48,"tags":49,"type":50,"updated":6,"updatedAt":51,"__hash__":52},"content\u002Fabout\u002Fprofile.md","关于我",null,"https:\u002F\u002Fflyovo.cc.cd\u002Fmedia\u002Fpublic\u002Fprofile\u002F917a55b1-a628-406b-8bdf-76a0a8ad81fa.gif",{"type":9,"value":10,"toc":28},"minimark",[11,15],[12,13,14],"p",{},"你好，我是 fly，热爱VibeCoding。",[12,16,17,18,21],{},"这里记录技术、学习与生活，也保存那些值得回看的瞬间。比起给自己贴上固定标签，我更愿意把这个页面当作一份持续更新的自述。",[19,20],"br",{},[22,23],"img",{"alt":24,"height":25,"src":26,"width":27},"infj.png",657,"https:\u002F\u002Fflyovo.cc.cd\u002Fmedia\u002Fpublic\u002Fprofile\u002F3000773f-11b2-4991-9690-5dae22d4295e.png",2394,{"title":29,"searchDepth":30,"depth":30,"links":31},"",4,[],[33],"未分类","2026-08-03",false,"md",{"slots":38},{},true,"\u002Fabout\u002Fprofile",{"text":42,"minutes":43,"time":44,"words":45},"1 min read",0.31,18600,62,{"title":5,"description":14},"about\u002Fprofile","一个持续学习、写代码，也认真生活的人。",[],"tech","2026-08-15T16:30:01.712Z","lh9cPHNRLSqkb9FCNmSSp2fFeGPq6_IT7NaiH-elDUA",{"id":54,"title":55,"author":6,"avatar":6,"body":56,"categories":2725,"date":2728,"description":2729,"draft":35,"extension":36,"image":6,"meta":2730,"navigation":39,"path":2732,"permalink":6,"published":6,"readingTime":2733,"recommend":6,"references":6,"seo":2738,"sitemap":2739,"stem":2740,"summary":6,"tags":2741,"type":50,"updated":6,"updatedAt":6,"__hash__":2742},"content\u002Fposts\u002F2026\u002Farticle-20260907-174336-383eaaa7.md","RAG 全流程（切分\u002F向量检索\u002F召回\u002F生成）",{"type":9,"value":57,"toc":2647},[58,62,65,73,81,92,95,98,108,111,114,117,240,244,247,252,255,265,271,277,280,284,290,296,302,308,311,317,319,323,326,332,335,341,344,350,353,355,359,364,370,373,379,382,387,389,393,396,402,405,411,414,422,425,431,434,440,442,447,450,456,462,464,468,473,476,481,483,489,492,498,501,507,510,515,518,520,524,527,533,536,542,545,548,555,558,564,567,570,576,579,586,590,593,599,602,608,610,616,619,625,628,634,637,643,646,652,655,659,662,912,915,920,922,928,931,937,940,953,956,963,967,977,982,985,991,994,999,1036,1041,1045,1048,1053,1056,1061,1069,1073,1082,1085,1091,1094,1100,1103,1109,1112,1118,1125,1129,1134,1137,1143,1146,1152,1155,1161,1164,1169,1172,1179,1182,1188,1191,1195,1198,1204,1207,1212,1215,1220,1223,1229,1235,1241,1244,1250,1254,1257,1261,1264,1270,1273,1276,1282,1285,1290,1293,1299,1302,1306,1309,1315,1318,1324,1327,1333,1336,1343,1352,1356,1359,1365,1368,1375,1378,1384,1387,1393,1397,1403,1414,1422,1425,1431,1435,1438,1441,1448,1452,1458,1461,1468,1472,1475,1481,1484,1486,1492,1495,1501,1504,1510,1513,1516,1523,1527,1530,1536,1538,1544,1547,1553,1556,1573,1579,1582,1586,1589,1591,1597,1600,1602,1608,1611,1616,1619,1625,1631,1635,1642,1645,1651,1656,1660,1663,1665,1671,1676,1680,1683,1689,1694,1697,1703,1706,1710,1717,1729,1735,1740,1743,1759,1763,1766,1772,1775,1801,1805,1808,1814,1818,1824,1828,1831,1837,1839,1845,1849,1852,1858,1861,2404,2407,2414,2420,2423,2430,2433,2440,2444,2447,2450,2453,2459,2462,2494,2496,2500,2503,2507,2512,2516,2521,2525,2530,2534,2539,2543,2548,2552,2557,2561,2566,2570,2575,2579,2584,2588,2593,2597,2602,2606,2611,2615,2620,2624,2629,2633,2638,2642],[59,60,55],"h2",{"id":61},"rag-全流程切分向量检索召回生成",[12,63,64],{},"RAG 整体分成知识库构建阶段和在线检索生成阶段",[12,66,67],{},[68,69,72],"span",{"className":70},[71],"article-highlight","离线知识入库：文档解析 → 清洗 → 切分 Chunk → Embedding 向量化 → 向量库建索引",[12,74,75],{},[68,76,78,79],{"className":77},[71],"在线问答：用户 Query → Query 向量化 → 召回 TopK → 重排 Rerank → 上下文组装 → Prompt → LLM 生成",[19,80],{},[12,82,83,91],{},[84,85,86],"strong",{},[87,88,90],"text-color",{"color":89},"#EF4444","知识库构建时","，",[12,93,94],{},"首先对 PDF、Word、Markdown 等文件做解析和文本清洗，然后按照固定长度、递归分段或者语义边界把文档切成多个 Chunk，并保留一定 overlap，避免上下文在切分边界处丢失。",[12,96,97],{},"每一个 Chunk 会通过 Embedding 模型转成高维向量，同时保存 chunkId、documentId、原文、标题、页码等 Metadata，然后写入向量数据库，通过 HNSW、IVF 等 ANN 索引加速相似度检索。",[12,99,100,91,105,107],{},[84,101,102],{},[87,103,104],{"color":89},"用户提问时",[19,106],{},"同样使用相同的 Embedding 模型把 Query 转成向量，然后通过 cosine similarity、dot product 等方式从向量库召回 TopK 个候选 Chunk。",[12,109,110],{},"实际生产环境一般不直接把 TopK 全部交给大模型，而是结合关键词检索、Metadata Filter，甚至 Hybrid Search，再通过 Reranker 对候选结果重新排序。",[12,112,113],{},"最后选择相关度最高的几个 Chunk，在控制上下文窗口和 Token 数量的情况下组装 Prompt，把“用户问题 + 检索上下文”一起交给 LLM，让模型基于检索内容生成答案。",[12,115,116],{},"同时我们还会保留引用来源，并通过召回率、MRR、NDCG、答案正确率等指标评估整个 RAG 链路。",[118,119,120,124,130,134,155,159,162,174],"mac-window",{},[59,121,123],{"id":122},"_1文档为什么一定要切分","1.文档为什么一定要切分？",[12,125,126,127,129],{},"比如一份 100 页的《支付系统设计》很多个语义主题，如果整个文档只生成一个向量，这个向量实际上是所有语义的“平均表示”",[19,128],{},"用户Query 和整份文档的向量相似度可能并不高",[59,131,133],{"id":132},"_2chunk-应该切多大","2.Chunk 应该切多大？",[135,136,137,146],"copy-block",{},[12,138,139,140,142,143,145],{},"Chunk 太小：",[19,141],{},"优势：检索精准",[19,144],{},"问题：语义不完整 上下文缺失",[12,147,148,149,151,152,154],{},"Chunk 太大：",[19,150],{},"优势：上下文完整",[19,153],{},"问题：噪声多，Embedding 语义被稀释，Token 成本增加",[59,156,158],{"id":157},"_3为什么-chunk-之间需要-overlap","3.为什么 Chunk 之间需要 overlap？",[12,160,161],{},"比如原文：",[12,163,164],{},[68,165,167,168,170,171,173],{"className":166},[71],"支付宝支付成功以后，",[19,169],{},"系统首先校验签名，然后判断订单状态，",[19,172],{},"如果订单已经支付，则直接返回 success。",[135,175,176,187,193,202,208,222],{},[12,177,178,179,181,182,167,184,186],{},"如果切成：",[19,180],{},"Chunk1：",[19,183],{},[19,185],{},"系统首先校验签名，然后判断订单状态",[12,188,189,190,192],{},"Chunk2：",[19,191],{},"如果订单已经支付，则直接返回 success",[12,194,195,196,198],{},"两个 Chunk 语义被割裂。",[19,197],{},[68,199,201],{"className":200},[71],"加入 overlap：",[12,203,181,204,167,206,186],{},[19,205],{},[19,207],{},[12,209,189,210,212,213,192,215,217],{},[19,211],{},"判断订单状态，",[19,214],{},[19,216],{},[84,218,219],{},[87,220,221],{"color":89},"语义连续性更好。",[223,224,226],"alert",{"type":225},"tip",[12,227,228,231,233,234,236,237,239],{},[84,229,230],{},"代价是：",[19,232],{},"数据量增加、Embedding 成本增加",[19,235],{},"可能召回大量重复 Chunk",[19,238],{},"所以 overlap 不能无限加。",[59,241,243],{"id":242},"_4文档到底怎么切","4.文档到底怎么切？",[12,245,246],{},"可以分成四种。",[248,249,251],"h3",{"id":250},"固定长度切分","① 固定长度切分",[12,253,254],{},"例如：",[256,257,262],"pre",{"className":258,"code":260,"language":261},[259],"language-text","每 500 token 一段\noverlap 100 token\n","text",[263,264,260],"code",{"__ignoreMap":29},[12,266,267,268,270],{},"优点：",[19,269],{},"简单、快。",[12,272,273,274,276],{},"缺点：",[19,275],{},"可能把一句话、一个代码块、一张表切断。",[278,279],"hr",{},[248,281,283],{"id":282},"recursive-chunking递归切分","② Recursive Chunking（递归切分）",[12,285,286,287,289],{},"实际项目很常见。",[19,288],{},"本质上不是按某一个固定“维度”拆，而是按一组从粗到细的文本结构层级递归拆分，直到每个 Chunk 满足目标大小。",[256,291,294],{"className":292,"code":293,"language":261},[259],"标题\n↓\n段落\n↓\n换行\n↓\n句号\n↓\n固定字符数\n",[263,295,293],{"__ignoreMap":29},[12,297,298,299,301],{},"递归切。",[19,300],{},"比如 LangChain 的：",[256,303,306],{"className":304,"code":305,"language":261},[259],"RecursiveCharacterTextSplitter\n",[263,307,305],{"__ignoreMap":29},[12,309,310],{},"核心思想：",[312,313,314],"blockquote",{},[12,315,316],{},"尽可能保留自然语义边界。",[278,318],{},[248,320,322],{"id":321},"结构化切分","③ 结构化切分",[12,324,325],{},"Markdown：",[256,327,330],{"className":328,"code":329,"language":261},[259],"# 一级标题\n## 二级标题\n### 三级标题\n",[263,331,329],{"__ignoreMap":29},[12,333,334],{},"Word：",[256,336,339],{"className":337,"code":338,"language":261},[259],"Heading 标题\nParagraph 段落\nTable 表格\n",[263,340,338],{"__ignoreMap":29},[12,342,343],{},"代码：",[256,345,348],{"className":346,"code":347,"language":261},[259],"Class\nMethod\nFunction\n",[263,349,347],{"__ignoreMap":29},[12,351,352],{},"这种通常比单纯固定字符切分效果好。",[278,354],{},[248,356,358],{"id":357},"semantic-chunking","④ Semantic Chunking",[12,360,361,362,254],{},"通过 Embedding 判断相邻句子的语义变化。",[19,363],{},[256,365,368],{"className":366,"code":367,"language":261},[259],"A A A A B B B C C\n",[263,369,367],{"__ignoreMap":29},[12,371,372],{},"语义发生明显变化时再切：",[256,374,377],{"className":375,"code":376,"language":261},[259],"[A A A A]\n\n[B B B]\n\n[C C]\n",[263,378,376],{"__ignoreMap":29},[12,380,381],{},"效果可能更好，但：",[312,383,384],{},[12,385,386],{},"预处理成本也明显更高。",[278,388],{},[59,390,392],{"id":391},"_5-chunk-切完之后发生什么","5. Chunk 切完之后发生什么？",[12,394,395],{},"每个 Chunk 一般会形成：",[256,397,400],{"className":398,"code":399,"language":261},[259],"{\n  \"chunkId\": \"chunk-001\",\n  \"documentId\": \"doc-001\",\n  \"content\": \"支付宝回调必须保证幂等...\",\n  \"title\": \"支付回调\",\n  \"page\": 21,\n  \"embedding\": [...]\n}\n",[263,401,399],{"__ignoreMap":29},[12,403,404],{},"实际上可以进一步写成：",[256,406,409],{"className":407,"code":408,"language":261},[259],"{\n  \"chunkId\": \"chunk-001\",\n  \"content\": \"支付宝回调必须保证幂等...\",\n  \"embedding\": [0.12, -0.31, 0.78, ...],\n  \"metadata\": {\n    \"documentId\": \"doc-001\",\n    \"projectId\": \"10086\",\n    \"userId\": \"u001\",\n    \"title\": \"支付回调\",\n    \"page\": 21,\n    \"chunkIndex\": 15,\n    \"fileName\": \"支付宝支付接入.pdf\",\n    \"fileType\": \"pdf\",\n    \"source\": \"knowledge-base\",\n    \"createdAt\": \"2026-09-09\"\n  }\n}\n",[263,410,408],{"__ignoreMap":29},[12,412,413],{},"这里有一个非常重要的东西：",[12,415,416,419,421],{},[84,417,418],{},"Metadata。",[19,420],{},"metadata = 这个 Chunk 是谁、从哪来、属于谁、在哪一页、能不能被你搜到",[12,423,424],{},"因为实际 RAG 不只是：",[256,426,429],{"className":427,"code":428,"language":261},[259],"Vector Search\n",[263,430,428],{"__ignoreMap":29},[12,432,433],{},"还经常：",[256,435,438],{"className":436,"code":437,"language":261},[259],"Vector Search\n+\nMetadata Filter\n",[263,439,437],{"__ignoreMap":29},[12,441,254],{},[312,443,444],{},[12,445,446],{},"查询 projectId=10086 的知识库。",[12,448,449],{},"不是全公司文档里检索，而是：",[256,451,454],{"className":452,"code":453,"language":261},[259],"WHERE project_id = 10086\nAND user_id = xxx\n",[263,455,453],{"__ignoreMap":29},[12,457,458,459,461],{},"之后再做向量搜索。",[19,460],{},"在满足这些条件的 Chunk 中，寻找向量最相似的 TopK",[278,463],{},[59,465,467],{"id":466},"_6-embedding-到底是什么","6. Embedding 到底是什么？",[312,469,470],{},[12,471,472],{},"Embedding 干了什么？",[12,474,475],{},"一句话：",[312,477,478],{},[12,479,480],{},"Embedding 是把文本映射到一个高维稠密向量空间，使语义相近的文本在向量空间中的距离也比较接近。",[12,482,254],{},[256,484,487],{"className":485,"code":486,"language":261},[259],"\"Java线程池\"\n→\n[0.12, -0.42, 0.73, ...]\n",[263,488,486],{"__ignoreMap":29},[12,490,491],{},"假设是：",[256,493,496],{"className":494,"code":495,"language":261},[259],"1536维\n",[263,497,495],{"__ignoreMap":29},[12,499,500],{},"那么就是：",[256,502,505],{"className":503,"code":504,"language":261},[259],"x1\nx2\nx3\n...\nx1536\n",[263,506,504],{"__ignoreMap":29},[12,508,509],{},"不是：",[312,511,512],{},[12,513,514],{},"每一个维度对应一个具体单词。",[12,516,517],{},"而是神经网络学习出来的高维语义特征。",[278,519],{},[59,521,523],{"id":522},"_7-为什么-query-和文档必须使用同一个-embedding-模型","7. 为什么 Query 和文档必须使用同一个 Embedding 模型？",[12,525,526],{},"比如知识库：",[256,528,531],{"className":529,"code":530,"language":261},[259],"Document\n↓\nEmbedding Model A\n↓\nvector A\n",[263,532,530],{"__ignoreMap":29},[12,534,535],{},"查询：",[256,537,540],{"className":538,"code":539,"language":261},[259],"Query\n↓\nEmbedding Model B\n↓\nvector B\n",[263,541,539],{"__ignoreMap":29},[12,543,544],{},"即使维度碰巧一样，也不能可靠比较。",[12,546,547],{},"因为两个模型学习出来的：",[312,549,550],{},[12,551,552],{},[84,553,554],{},"向量空间坐标系不同。",[12,556,557],{},"就像：",[256,559,562],{"className":560,"code":561,"language":261},[259],"一个使用经纬度\n一个使用笛卡尔坐标\n",[263,563,561],{"__ignoreMap":29},[12,565,566],{},"直接计算距离没有意义。",[12,568,569],{},"所以一般必须保证：",[256,571,574],{"className":572,"code":573,"language":261},[259],"Document Embedding Model\n=\nQuery Embedding Model\n",[263,575,573],{"__ignoreMap":29},[12,577,578],{},"更换 Embedding 模型后通常需要：",[312,580,581],{},[12,582,583],{},[84,584,585],{},"全量重新向量化。",[59,587,589],{"id":588},"_8-什么叫向量检索","8. 什么叫向量检索？",[12,591,592],{},"用户问：",[256,594,597],{"className":595,"code":596,"language":261},[259],"RabbitMQ 如何保证消息不丢失？\n",[263,598,596],{"__ignoreMap":29},[12,600,601],{},"先做：",[256,603,606],{"className":604,"code":605,"language":261},[259],"Query\n ↓\nEmbedding\n ↓\nQuery Vector\n",[263,607,605],{"__ignoreMap":29},[12,609,254],{},[256,611,614],{"className":612,"code":613,"language":261},[259],"Q = [0.1, 0.8, -0.3 ...]\n",[263,615,613],{"__ignoreMap":29},[12,617,618],{},"数据库里面：",[256,620,623],{"className":621,"code":622,"language":261},[259],"Chunk A → Vector A\nChunk B → Vector B\nChunk C → Vector C\n",[263,624,622],{"__ignoreMap":29},[12,626,627],{},"然后计算：",[256,629,632],{"className":630,"code":631,"language":261},[259],"Similarity(Q, A)\nSimilarity(Q, B)\nSimilarity(Q, C)\n",[263,633,631],{"__ignoreMap":29},[12,635,636],{},"假设：",[256,638,641],{"className":639,"code":640,"language":261},[259],"A = 0.86\nB = 0.32\nC = 0.91\n",[263,642,640],{"__ignoreMap":29},[12,644,645],{},"取 TopK：",[256,647,650],{"className":648,"code":649,"language":261},[259],"C\nA\n...\n",[263,651,649],{"__ignoreMap":29},[12,653,654],{},"这就是最基础的向量召回。",[59,656,658],{"id":657},"_9-cosine-similarity余弦相似度-是什么","9. Cosine Similarity（余弦相似度） 是什么？",[12,660,661],{},"公式：",[68,663,666],{"className":664},[665],"katex-display",[68,667,670,746],{"className":668},[669],"katex",[68,671,674],{"className":672},[673],"katex-mathml",[675,676,679],"math",{"xmlns":677,"display":678},"http:\u002F\u002Fwww.w3.org\u002F1998\u002FMath\u002FMathML","block",[680,681,682,741],"semantics",{},[683,684,685,689,693,697,700,704,707,710,713],"mrow",{},[686,687,688],"mi",{},"cos",[690,691,692],"mo",{},"⁡",[690,694,696],{"stretchy":695},"false","(",[686,698,699],{},"A",[690,701,703],{"separator":702},"true",",",[686,705,706],{},"B",[690,708,709],{"stretchy":695},")",[690,711,712],{},"=",[714,715,716,725],"mfrac",{},[683,717,718,720,723],{},[686,719,699],{},[690,721,722],{},"⋅",[686,724,706],{},[683,726,727,731,733,735,737,739],{},[686,728,730],{"mathvariant":729},"normal","∥",[686,732,699],{},[686,734,730],{"mathvariant":729},[686,736,730],{"mathvariant":729},[686,738,706],{},[686,740,730],{"mathvariant":729},[742,743,745],"annotation",{"encoding":744},"application\u002Fx-tex","\\cos(A,B)=\\frac{A \\cdot B}{\\|A\\|\\|B\\|}",[68,747,750,800],{"className":748,"ariaHidden":702},[749],"katex-html",[68,751,754,759,763,767,772,776,781,785,789,793,797],{"className":752},[753],"base",[68,755],{"className":756,"style":758},[757],"strut","height:1em;vertical-align:-0.25em;",[68,760,688],{"className":761},[762],"mop",[68,764,696],{"className":765},[766],"mopen",[68,768,699],{"className":769},[770,771],"mord","mathnormal",[68,773,703],{"className":774},[775],"mpunct",[68,777],{"className":778,"style":780},[779],"mspace","margin-right:0.1667em;",[68,782,706],{"className":783,"style":784},[770,771],"margin-right:0.0502em;",[68,786,709],{"className":787},[788],"mclose",[68,790],{"className":791,"style":792},[779],"margin-right:0.2778em;",[68,794,712],{"className":795},[796],"mrel",[68,798],{"className":799,"style":792},[779],[68,801,803,807],{"className":802},[753],[68,804],{"className":805,"style":806},[757],"height:2.2963em;vertical-align:-0.936em;",[68,808,810,814,909],{"className":809},[770],[68,811],{"className":812},[766,813],"nulldelimiter",[68,815,817],{"className":816},[714],[68,818,822,900],{"className":819},[820,821],"vlist-t","vlist-t2",[68,823,826,895],{"className":824},[825],"vlist-r",[68,827,831,858,869],{"className":828,"style":830},[829],"vlist","height:1.3603em;",[68,832,834,839],{"style":833},"top:-2.314em;",[68,835],{"className":836,"style":838},[837],"pstrut","height:3em;",[68,840,842,845,848,852,855],{"className":841},[770],[68,843,730],{"className":844},[770],[68,846,699],{"className":847},[770,771],[68,849,851],{"className":850},[770],"∥∥",[68,853,706],{"className":854,"style":784},[770,771],[68,856,730],{"className":857},[770],[68,859,861,864],{"style":860},"top:-3.23em;",[68,862],{"className":863,"style":838},[837],[68,865],{"className":866,"style":868},[867],"frac-line","border-bottom-width:0.04em;",[68,870,872,875],{"style":871},"top:-3.677em;",[68,873],{"className":874,"style":838},[837],[68,876,878,881,885,889,892],{"className":877},[770],[68,879,699],{"className":880},[770,771],[68,882],{"className":883,"style":884},[779],"margin-right:0.2222em;",[68,886,722],{"className":887},[888],"mbin",[68,890],{"className":891,"style":884},[779],[68,893,706],{"className":894,"style":784},[770,771],[68,896,899],{"className":897},[898],"vlist-s","​",[68,901,903],{"className":902},[825],[68,904,907],{"className":905,"style":906},[829],"height:0.936em;",[68,908],{},[68,910],{"className":911},[788,813],[12,913,914],{},"本质：",[312,916,917],{},[12,918,919],{},"比较两个向量方向是否相似。",[12,921,254],{},[256,923,926],{"className":924,"code":925,"language":261},[259],"A → ↗\nB → ↗\n",[263,927,925],{"__ignoreMap":29},[12,929,930],{},"方向非常接近：",[256,932,935],{"className":933,"code":934,"language":261},[259],"Cosine Similarity ≈ 1 相似度\n",[263,936,934],{"__ignoreMap":29},[12,938,939],{},"Embedding 经常使用：",[941,942,943,947,950],"ul",{},[944,945,946],"li",{},"Cosine Similarity 余弦相似度",[944,948,949],{},"Dot Product 点积",[944,951,952],{},"Euclidean Distance 欧几里得距离",[12,954,955],{},"具体要看 Embedding 模型和向量数据库设计。",[223,957,958],{"type":225},[12,959,960],{},[84,961,962],{},"在 RAG 中，用户 Query 和知识库 Chunk 都会通过 Embedding 模型转成高维向量，然后使用 Cosine Similarity 计算 Query Vector 与 Chunk Vector 的相似度，按照得分排序并获取 TopK Chunk，作为上下文交给 LLM。相比关键词匹配，它能够捕获文字不同但语义相近的内容。",[59,964,966],{"id":965},"_10-几百万条向量难道每一条都算一次","10. 几百万条向量难道每一条都算一次？",[12,968,969,972,974],{},[84,970,971],{},"1000 万 Chunk，每次 Query 都和 1000 万向量计算 cosine 吗？不会",[19,973],{},[84,975,976],{},"HNSW 是什么？",[312,978,979],{},[12,980,981],{},"HNSW 是一种基于多层邻接图的近似最近邻搜索算法。它会把向量构建成多层图结构，查询时先从高层快速定位大致区域，然后逐层下降，在底层进行更精细的邻居搜索，从而避免全量遍历所有向量。",[12,983,984],{},"理解成：",[256,986,989],{"className":987,"code":988,"language":261},[259],"Level 3       A ────── Z\n               ↓\n\nLevel 2       A ── H ── Z\n                  ↓\n\nLevel 1       A-B-C-D-E-F...\n                    ↓\n\n找到最接近 Query 的节点\n",[263,990,988],{"__ignoreMap":29},[12,992,993],{},"核心：",[312,995,996],{},[12,997,998],{},"不是遍历所有向量，而是沿着邻居图快速逼近最近向量。",[135,1000,1001,1004,1009,1012,1018,1021,1027,1030],{},[12,1002,1003],{},"想象你人在中国，要找：",[312,1005,1006],{},[12,1007,1008],{},"距离你最近的一家星巴克。",[12,1010,1011],{},"正常会：",[256,1013,1016],{"className":1014,"code":1015,"language":261},[259],"中国\n ↓\n广东\n ↓\n广州\n ↓\n天河区\n ↓\n附近门店\n",[263,1017,1015],{"__ignoreMap":29},[12,1019,1020],{},"只不过：",[256,1022,1025],{"className":1023,"code":1024,"language":261},[259],"地理空间\n",[263,1026,1024],{"__ignoreMap":29},[12,1028,1029],{},"换成了：",[256,1031,1034],{"className":1032,"code":1033,"language":261},[259],"向量空间\n",[263,1035,1033],{"__ignoreMap":29},[87,1037,1038],{"color":89},[84,1039,1040],{},"先快速缩小搜索范围，再在附近精细搜索。",[59,1042,1044],{"id":1043},"_11为什么只做向量检索不够","11.为什么只做向量检索不够？",[12,1046,1047],{},"Embedding 关注：",[312,1049,1050],{},[12,1051,1052],{},"语义。",[12,1054,1055],{},"但对：",[941,1057,1058],{},[944,1059,1060],{},"ID、产品型号、错误码、人名、精确版本号、API 名称、专有名词",[223,1062,1063],{"type":225},[12,1064,1065,1066,1068],{},"可能不够精准。",[19,1067],{},"所以：精确关键词匹配+向量检索",[59,1070,1072],{"id":1071},"_12什么叫倒排索引","12.什么叫倒排索引？",[12,1074,1075,1076,1078,1079,1081],{},"为什么 LIKE 不等于关键词检索？",[19,1077],{},"1，性能低，大数据量需要扫描大量文本。",[19,1080],{},"2，搜索能力弱（相关度排序，同义词。。。",[12,1083,1084],{},"正向：",[256,1086,1089],{"className":1087,"code":1088,"language":261},[259],"Doc1 → Java Redis MQ\nDoc2 → Java MySQL\n",[263,1090,1088],{"__ignoreMap":29},[12,1092,1093],{},"倒排：",[256,1095,1098],{"className":1096,"code":1097,"language":261},[259],"Java  → Doc1, Doc2\nRedis → Doc1\nMQ    → Doc1\nMySQL → Doc2\n",[263,1099,1097],{"__ignoreMap":29},[12,1101,1102],{},"用户搜索：",[256,1104,1107],{"className":1105,"code":1106,"language":261},[259],"Redis\n",[263,1108,1106],{"__ignoreMap":29},[12,1110,1111],{},"直接：",[256,1113,1116],{"className":1114,"code":1115,"language":261},[259],"Redis → Doc1\n",[263,1117,1115],{"__ignoreMap":29},[12,1119,1120],{},[84,1121,1122],{},[87,1123,1124],{"color":89},"不需要扫描所有文档。所以全文检索效率高。",[59,1126,1128],{"id":1127},"_13-什么是召回","13. 什么是召回？",[12,1130,1131],{},[84,1132,1133],{},"召回 Retrieval \u002F Recall：",[12,1135,1136],{},"从整个知识库：",[256,1138,1141],{"className":1139,"code":1140,"language":261},[259],"100 万 Chunk\n",[263,1142,1140],{"__ignoreMap":29},[12,1144,1145],{},"里面快速找：",[256,1147,1150],{"className":1148,"code":1149,"language":261},[259],"Top 20 \u002F Top 50\n",[263,1151,1149],{"__ignoreMap":29},[12,1153,1154],{},"候选文档。例如：",[256,1156,1159],{"className":1157,"code":1158,"language":261},[259],"1000000\n  ↓ Vector \u002F BM25\nTop 50\n",[263,1160,1158],{"__ignoreMap":29},[12,1162,1163],{},"这一步最重要的目标不是：",[312,1165,1166],{},[12,1167,1168],{},"把第一名排得绝对准确。",[12,1170,1171],{},"而是：",[312,1173,1174],{},[12,1175,1176],{},[84,1177,1178],{},"尽量不要漏掉真正相关的文档。",[12,1180,1181],{},"所以召回阶段通常：",[256,1183,1186],{"className":1184,"code":1185,"language":261},[259],"高 Recall\n",[263,1187,1185],{"__ignoreMap":29},[12,1189,1190],{},"优先。",[59,1192,1194],{"id":1193},"_14什么叫-rerank重排序","14.什么叫 Rerank？重排序",[12,1196,1197],{},"流程：",[256,1199,1202],{"className":1200,"code":1201,"language":261},[259],"100000 个 Chunk\n\n       ↓ Recall\n\nTop 50\n\n       ↓ Reranker\n\nTop 5\n\n       ↓\n\nLLM\n",[263,1203,1201],{"__ignoreMap":29},[12,1205,1206],{},"Recall：",[312,1208,1209],{},[12,1210,1211],{},"快，但精度相对低。",[12,1213,1214],{},"Reranker：",[312,1216,1217],{},[12,1218,1219],{},"慢，但是精度高。",[12,1221,1222],{},"所以不能对：",[256,1224,1227],{"className":1225,"code":1226,"language":261},[259],"100 万个 Chunk\n",[263,1228,1226],{"__ignoreMap":29},[12,1230,1231,1232,1234],{},"全部 rerank。",[19,1233],{},"一般：",[256,1236,1239],{"className":1237,"code":1238,"language":261},[259],"召回 Top20~100\n↓\nRerank\n↓\nTop3~10\n",[263,1240,1238],{"__ignoreMap":29},[12,1242,1243],{},"实际企业 RAG一般是",[256,1245,1248],{"className":1246,"code":1247,"language":261},[259],"用户 Query\n    ↓\nMetadata Filter\n\nprojectId = 10086\ntenantId = xxx\npermission = xxx\n\n    ↓\nRecall \u002F Retrieval\n\nVector Search\nBM25\nHybrid Search\n\n    ↓\nTop 50\n\n    ↓\nReranker\n\n    ↓\nTop 5\n\n    ↓\nLLM\n",[263,1249,1247],{"__ignoreMap":29},[59,1251,1253],{"id":1252},"_15-embedding-和-reranker-有什么区别","15. Embedding 和 Reranker 有什么区别？",[12,1255,1256],{},"Embedding 负责“从海量文档里快速找出可能相关的候选”，Reranker 负责“把这些候选再仔细比较，重新排出最相关的顺序”。",[59,1258,1260],{"id":1259},"_16-topk-越大越好吗不是","16. TopK 越大越好吗？不是。",[12,1262,1263],{},"TopK 太小：",[256,1265,1268],{"className":1266,"code":1267,"language":261},[259],"相关文档可能没召回来\n",[263,1269,1267],{"__ignoreMap":29},[12,1271,1272],{},"Recall 低。",[12,1274,1275],{},"TopK 太大：",[256,1277,1280],{"className":1278,"code":1279,"language":261},[259],"大量无关 Chunk\n↓\nPrompt 噪声增加\n↓\nToken Cost 增加\n↓\nLLM 甚至可能被错误上下文干扰\n",[263,1281,1279],{"__ignoreMap":29},[12,1283,1284],{},"所以：",[312,1286,1287],{},[12,1288,1289],{},"TopK 本质上是 Recall、Precision、Latency、Token Cost 的权衡。",[12,1291,1292],{},"常见：",[256,1294,1297],{"className":1295,"code":1296,"language":261},[259],"Recall TopK = 20~100\n\nRerank TopK = 3~10\n",[263,1298,1296],{"__ignoreMap":29},[12,1300,1301],{},"实际通过评测集确定。",[59,1303,1305],{"id":1304},"_17-context-是怎么组装的","17. Context 是怎么组装的？",[12,1307,1308],{},"例如最终 Top3：",[256,1310,1313],{"className":1311,"code":1312,"language":261},[259],"Chunk A\nChunk B\nChunk C\n",[263,1314,1312],{"__ignoreMap":29},[12,1316,1317],{},"Prompt：",[256,1319,1322],{"className":1320,"code":1321,"language":261},[259],"System:\n你是一名技术助手。\n只能根据下面提供的知识回答。\n如果知识库没有答案，请回答不知道。\n\nContext:\n[文档1]\n...\n\n[文档2]\n...\n\n[文档3]\n...\n\nQuestion:\nRabbitMQ 如何保证消息不丢？\n",[263,1323,1321],{"__ignoreMap":29},[12,1325,1326],{},"然后：",[256,1328,1331],{"className":1329,"code":1330,"language":261},[259],"Prompt\n↓\nLLM\n↓\nAnswer\n",[263,1332,1330],{"__ignoreMap":29},[12,1334,1335],{},"这就是：",[312,1337,1338],{},[12,1339,1340],{},[84,1341,1342],{},"Retrieval-Augmented Generation",[12,1344,1345,1346,1348,1349,1351],{},"Retrieval：找到知识",[19,1347],{},"Augmented：把知识补进 Prompt",[19,1350],{},"Generation：LLM 生成答案",[59,1353,1355],{"id":1354},"_18-rag-为什么能够降低幻觉","18. RAG 为什么能够降低幻觉？",[12,1357,1358],{},"RAG 可以降低幻觉，但不能完全消除幻觉。",[256,1360,1363],{"className":1361,"code":1362,"language":261},[259],"外部知识\n↓\n作为上下文提供给 LLM\n",[263,1364,1362],{"__ignoreMap":29},[12,1366,1367],{},"减少模型单纯依赖参数记忆。",[12,1369,1370],{},[84,1371,1372],{},[87,1373,1374],{"color":89},"但仍然可能发生：",[248,1376,1377],{"id":1377},"召回错",[256,1379,1382],{"className":1380,"code":1381,"language":261},[259],"Retrieval Failure\n",[263,1383,1381],{"__ignoreMap":29},[248,1385,1386],{"id":1386},"上下文本身错误",[256,1388,1391],{"className":1389,"code":1390,"language":261},[259],"Knowledge Error\n",[263,1392,1390],{"__ignoreMap":29},[248,1394,1396],{"id":1395},"模型没按照-context-回答","模型没按照 Context 回答",[256,1398,1401],{"className":1399,"code":1400,"language":261},[259],"Generation Hallucination\n",[263,1402,1400],{"__ignoreMap":29},[223,1404,1405,1408],{"type":225},[12,1406,1407],{},"因此完整方案还可以加：",[256,1409,1412],{"className":1410,"code":1411,"language":261},[259],"引用来源\nGroundedness 检查\nAnswer Verification\n拒答策略\n",[263,1413,1411],{"__ignoreMap":29},[12,1415,1416],{},[68,1417,1419],{"className":1418},[71],[84,1420,1421],{},"如何排查？",[12,1423,1424],{},"先拆链路：",[256,1426,1429],{"className":1427,"code":1428,"language":261},[259],"Question\n   ↓\nQuery理解有没有问题？\n   ↓\nRetrieval有没有召回来？\n   ↓\nRerank有没有排错？\n   ↓\nContext有没有丢失？\n   ↓\nPrompt有没有问题？\n   ↓\nLLM有没有生成错误？\n",[263,1430,1428],{"__ignoreMap":29},[59,1432,1434],{"id":1433},"_19-query-rewrite-是什么","19. Query Rewrite 是什么？",[12,1436,1437],{},"Query Rewrite 是在 RAG 检索前，将当前 Query 与多轮对话历史交给 LLM，把代词、省略信息和上下文补全为一个 Standalone Question，再使用改写后的 Query 进行向量检索和关键词检索，从而解决多轮对话中 Query 语义不完整导致的召回下降问题；改写只补全用户意图，不应该引入新的事实。",[12,1439,1440],{},"多轮 RAG 经常需要：",[312,1442,1443],{},[12,1444,1445],{},[84,1446,1447],{},"Standalone Question Generation \u002F Query Rewrite。",[59,1449,1451],{"id":1450},"_20-rag-最常见的完整生产架构","20. RAG 最常见的完整生产架构",[256,1453,1456],{"className":1454,"code":1455,"language":261},[259],"                    离线知识库构建\n                         │\nPDF \u002F Word \u002F Markdown \u002F Web\n                         ↓\n                       Parser\n                         ↓\n                    Text Clean\n                         ↓\n                      Chunk\n                         ↓\n                    Embedding\n                         ↓\n            ┌────────────┴────────────┐\n            ↓                         ↓\n        Vector DB                 Search Engine\n        HNSW                     BM25\u002F倒排索引\n            │                         │\n            └────────────┬────────────┘\n\n\n                    在线 Query\n                         │\n                         ↓\n                  Query Rewrite\n                         │\n             ┌───────────┴──────────┐\n             ↓                      ↓\n       Query Embedding          Keyword Query\n             ↓                      ↓\n       Vector Recall            BM25 Recall\n             └───────────┬──────────┘\n                         ↓\n                    RRF Fusion\n                         ↓\n                    Top50 Candidate\n                         ↓\n                       Rerank\n                         ↓\n                       Top5\n                         ↓\n               Context Assembly\n                         ↓\n              Prompt + Question\n                         ↓\n                        LLM\n                         ↓\n                 Answer + Citation\n",[263,1457,1455],{"__ignoreMap":29},[12,1459,1460],{},"这已经不是“Demo RAG”，而是比较标准的：",[312,1462,1463],{},[12,1464,1465],{},[84,1466,1467],{},"Production RAG Pipeline。",[59,1469,1471],{"id":1470},"_21你的知识库更新怎么办","21.你的知识库更新怎么办？",[248,1473,1474],{"id":1474},"新增",[256,1476,1479],{"className":1477,"code":1478,"language":261},[259],"Document\n↓\nChunk\n↓\nEmbedding\n↓\nINSERT Vector\n",[263,1480,1478],{"__ignoreMap":29},[248,1482,1483],{"id":1483},"修改",[12,1485,1234],{},[256,1487,1490],{"className":1488,"code":1489,"language":261},[259],"根据 documentId\n↓\n删除旧 chunks\n↓\n重新 Parse \u002F Chunk \u002F Embedding\n↓\n写入\n",[263,1491,1489],{"__ignoreMap":29},[248,1493,1494],{"id":1494},"删除",[256,1496,1499],{"className":1497,"code":1498,"language":261},[259],"documentId\n↓\n删除全部 chunk\u002Fvector\u002Findex\n",[263,1500,1498],{"__ignoreMap":29},[12,1502,1503],{},"不能只删除：",[256,1505,1508],{"className":1506,"code":1507,"language":261},[259],"MySQL 文档记录\n",[263,1509,1507],{"__ignoreMap":29},[12,1511,1512],{},"却把向量留在向量库里。",[12,1514,1515],{},"否则：",[312,1517,1518],{},[12,1519,1520],{},[84,1521,1522],{},"脏向量 \u002F Ghost Retrieval。",[59,1524,1526],{"id":1525},"_22文档重复上传怎么办","22.文档重复上传怎么办？",[12,1528,1529],{},"可以做：",[256,1531,1534],{"className":1532,"code":1533,"language":261},[259],"SHA256(file)\n或者：\ncontentHash\n",[263,1535,1533],{"__ignoreMap":29},[12,1537,254],{},[256,1539,1542],{"className":1540,"code":1541,"language":261},[259],"fileHash = SHA256(fileContent)\n",[263,1543,1541],{"__ignoreMap":29},[12,1545,1546],{},"数据库判断：",[256,1548,1551],{"className":1549,"code":1550,"language":261},[259],"fileHash 是否已存在\n",[263,1552,1550],{"__ignoreMap":29},[12,1554,1555],{},"避免重复：",[941,1557,1558,1561,1564,1567],{},[944,1559,1560],{},"Parse",[944,1562,1563],{},"Chunk",[944,1565,1566],{},"Embedding",[944,1568,1569,1570,1572],{},"Storage",[19,1571],{},"Chunk 也可以做 hash：",[256,1574,1577],{"className":1575,"code":1576,"language":261},[259],"chunkHash\n",[263,1578,1576],{"__ignoreMap":29},[12,1580,1581],{},"进行增量向量化。",[59,1583,1585],{"id":1584},"_23embedding-是不是很贵","23.Embedding 是不是很贵？",[12,1587,1588],{},"Embedding 通常比 LLM Generation 便宜很多，但是海量数据依然需要优化。",[12,1590,254],{},[256,1592,1595],{"className":1593,"code":1594,"language":261},[259],"100万篇文档\n×\n大量 Chunk\n",[263,1596,1594],{"__ignoreMap":29},[12,1598,1599],{},"不能每次启动服务重新向量化。",[12,1601,1284],{},[256,1603,1606],{"className":1604,"code":1605,"language":261},[259],"文档 Embedding\n",[263,1607,1605],{"__ignoreMap":29},[12,1609,1610],{},"属于：",[312,1612,1613],{},[12,1614,1615],{},"Offline Precomputation。离线预计算",[12,1617,1618],{},"只有：",[256,1620,1623],{"className":1621,"code":1622,"language":261},[259],"Query Embedding\n",[263,1624,1622],{"__ignoreMap":29},[12,1626,1627,1628,1630],{},"在请求时实时计算。",[19,1629],{},"这是 RAG 能做到低延迟的重要原因。",[59,1632,1634],{"id":1633},"_24pgvectormilvuselasticsearch-怎么选","24.pgvector、Milvus、Elasticsearch 怎么选？",[248,1636,1638,1639],{"id":1637},"pgvector-可以理解为给-postgresql-增加向量存储-向量相似度检索能力的扩展","pgvector 可以理解为：",[84,1640,1641],{},"给 PostgreSQL 增加“向量存储 + 向量相似度检索”能力的扩展。",[12,1643,1644],{},"适合：",[256,1646,1649],{"className":1647,"code":1648,"language":261},[259],"现有系统已经使用 PostgreSQL\n数据规模中小\n希望业务数据 + 向量数据事务管理简单\n",[263,1650,1648],{"__ignoreMap":29},[312,1652,1653],{},[12,1654,1655],{},"优势：系统复杂度低。",[248,1657,1659],{"id":1658},"milvus-qdrant-weaviate","Milvus \u002F Qdrant \u002F Weaviate",[12,1661,1662],{},"专门向量数据库。",[12,1664,1644],{},[256,1666,1669],{"className":1667,"code":1668,"language":261},[259],"千万 \u002F 亿级 Vector\n高并发\n复杂 ANN\n",[263,1670,1668],{"__ignoreMap":29},[312,1672,1673],{},[12,1674,1675],{},"优势：专业向量搜索能力更强。",[248,1677,1679],{"id":1678},"elasticsearch-opensearch","Elasticsearch \u002F OpenSearch",[12,1681,1682],{},"优势： 既能做“关键词搜索”，又能做“语义搜索”，还能按 Metadata 过滤，所以特别适合 RAG 的 Hybrid Search。",[256,1684,1687],{"className":1685,"code":1686,"language":261},[259],"BM25\n+\nVector Search\n+\nFilter\n",[263,1688,1686],{"__ignoreMap":29},[312,1690,1691],{},[12,1692,1693],{},"适合： Hybrid Search。",[12,1695,1696],{},"如果你的项目本身要求：",[256,1698,1701],{"className":1699,"code":1700,"language":261},[259],"中文关键词全文检索 + 向量检索\n",[263,1702,1700],{"__ignoreMap":29},[12,1704,1705],{},"ES\u002FOpenSearch 会非常自然。",[59,1707,1709],{"id":1708},"_25rag-怎么评估","25.RAG 怎么评估？",[12,1711,1712,1713,1716],{},"可以把 ",[84,1714,1715],{},"RAG 评估","简单理解成检查两件事：",[312,1718,1719],{},[12,1720,1721,1724,1726],{},[84,1722,1723],{},"① 有没有把正确资料搜出来？",[19,1725],{},[84,1727,1728],{},"② 搜出来以后，LLM 有没有根据资料正确回答？",[1730,1731,1732],"ol",{},[944,1733,1734],{},"Retrieval Evaluation：评估“搜得好不好”",[312,1736,1737],{},[12,1738,1739],{},"HikariCP 为什么连接超时？",[12,1741,1742],{},"正确答案所在 Chunk 应该被 Retriever 搜出来。",[941,1744,1745,1750,1753,1756],{},[944,1746,1747],{},[84,1748,1749],{},"Recall@K：有没有搜到",[944,1751,1752],{},"Precision@K：搜出来的结果有多少是有用的",[944,1754,1755],{},"MRR：正确答案排得靠不靠前",[944,1757,1758],{},"NDCG：整体排序质量怎么样",[248,1760,1762],{"id":1761},"_2-generation-evaluation评估答得好不好","2. Generation Evaluation：评估“答得好不好”",[12,1764,1765],{},"假设 Retriever 已经把正确资料给 LLM：",[256,1767,1770],{"className":1768,"code":1769,"language":261},[259],"Context：\nHikariCP connection timeout\n通常表示等待数据库连接超过 connectionTimeout。\n",[263,1771,1769],{"__ignoreMap":29},[12,1773,1774],{},"然后检查：",[941,1776,1777,1783,1789,1795],{},[944,1778,1779,1782],{},[84,1780,1781],{},"Faithfulness \u002F Groundedness","：回答是不是基于 Context，有没有瞎编。",[944,1784,1785,1788],{},[84,1786,1787],{},"Answer Relevance","：有没有真正回答用户的问题。",[944,1790,1791,1794],{},[84,1792,1793],{},"Correctness","：最终结论是否正确。",[944,1796,1797,1800],{},[84,1798,1799],{},"Citation Correctness","：引用的 Chunk \u002F 文档是不是真的支持这个答案。",[59,1802,1804],{"id":1803},"_26rag-性能怎么优化","26.RAG 性能怎么优化？",[248,1806,1807],{"id":1807},"文档侧",[256,1809,1812],{"className":1810,"code":1811,"language":261},[259],"异步解析\n批量 Embedding\nEmbedding Cache\n增量更新\n",[263,1813,1811],{"__ignoreMap":29},[248,1815,1817],{"id":1816},"retrieval","Retrieval",[256,1819,1822],{"className":1820,"code":1821,"language":261},[259],"ANN\nHNSW 参数优化\nMetadata Filter\n合理 TopK\n",[263,1823,1821],{"__ignoreMap":29},[248,1825,1827],{"id":1826},"rerank","Rerank",[12,1829,1830],{},"不要：",[256,1832,1835],{"className":1833,"code":1834,"language":261},[259],"Top1000 → Rerank\n",[263,1836,1834],{"__ignoreMap":29},[12,1838,1171],{},[256,1840,1843],{"className":1841,"code":1842,"language":261},[259],"Top30 \u002F Top50\n",[263,1844,1842],{"__ignoreMap":29},[248,1846,1848],{"id":1847},"generation","Generation",[12,1850,1851],{},"控制：",[256,1853,1856],{"className":1854,"code":1855,"language":261},[259],"Context Token\nChunk 数量\n模型尺寸\nPrompt 长度\n",[263,1857,1855],{"__ignoreMap":29},[12,1859,1860],{},"完整延迟：",[68,1862,1864],{"className":1863},[665],[68,1865,1867,2008],{"className":1866},[669],[68,1868,1870],{"className":1869},[673],[675,1871,1872],{"xmlns":677,"display":678},[680,1873,1874,2005],{},[683,1875,1876,1879,1881,1907,1910,1939,1941,1968,1970,1989,1991],{},[686,1877,1878],{},"T",[690,1880,712],{},[1882,1883,1884,1886],"msub",{},[686,1885,1878],{},[683,1887,1888,1891,1894,1897,1899,1902,1905],{},[686,1889,1890],{},"r",[686,1892,1893],{},"e",[686,1895,1896],{},"w",[686,1898,1890],{},[686,1900,1901],{},"i",[686,1903,1904],{},"t",[686,1906,1893],{},[690,1908,1909],{},"+",[1882,1911,1912,1914],{},[686,1913,1878],{},[683,1915,1916,1918,1921,1924,1926,1929,1931,1933,1936],{},[686,1917,1893],{},[686,1919,1920],{},"m",[686,1922,1923],{},"b",[686,1925,1893],{},[686,1927,1928],{},"d",[686,1930,1928],{},[686,1932,1901],{},[686,1934,1935],{},"n",[686,1937,1938],{},"g",[690,1940,1909],{},[1882,1942,1943,1945],{},[686,1944,1878],{},[683,1946,1947,1949,1951,1953,1955,1957,1959,1962,1965],{},[686,1948,1890],{},[686,1950,1893],{},[686,1952,1904],{},[686,1954,1890],{},[686,1956,1901],{},[686,1958,1893],{},[686,1960,1961],{},"v",[686,1963,1964],{},"a",[686,1966,1967],{},"l",[690,1969,1909],{},[1882,1971,1972,1974],{},[686,1973,1878],{},[683,1975,1976,1978,1980,1982,1984,1986],{},[686,1977,1890],{},[686,1979,1893],{},[686,1981,1890],{},[686,1983,1964],{},[686,1985,1935],{},[686,1987,1988],{},"k",[690,1990,1909],{},[1882,1992,1993,1995],{},[686,1994,1878],{},[683,1996,1997,2000,2002],{},[686,1998,1999],{},"L",[686,2001,1999],{},[686,2003,2004],{},"M",[742,2006,2007],{"encoding":744},"T =\nT_{rewrite}\n+\nT_{embedding}\n+\nT_{retrieval}\n+\nT_{rerank}\n+\nT_{LLM}",[68,2009,2011,2031,2119,2199,2282,2349],{"className":2010,"ariaHidden":702},[749],[68,2012,2014,2018,2022,2025,2028],{"className":2013},[753],[68,2015],{"className":2016,"style":2017},[757],"height:0.6833em;",[68,2019,1878],{"className":2020,"style":2021},[770,771],"margin-right:0.1389em;",[68,2023],{"className":2024,"style":792},[779],[68,2026,712],{"className":2027},[796],[68,2029],{"className":2030,"style":792},[779],[68,2032,2034,2038,2110,2113,2116],{"className":2033},[753],[68,2035],{"className":2036,"style":2037},[757],"height:0.8333em;vertical-align:-0.15em;",[68,2039,2041,2044],{"className":2040},[770],[68,2042,1878],{"className":2043,"style":2021},[770,771],[68,2045,2048],{"className":2046},[2047],"msupsub",[68,2049,2051,2101],{"className":2050},[820,821],[68,2052,2054,2098],{"className":2053},[825],[68,2055,2058],{"className":2056,"style":2057},[829],"height:0.3117em;",[68,2059,2061,2065],{"style":2060},"top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;",[68,2062],{"className":2063,"style":2064},[837],"height:2.7em;",[68,2066,2072],{"className":2067},[2068,2069,2070,2071],"sizing","reset-size6","size3","mtight",[68,2073,2075,2079,2082,2086,2089,2092,2095],{"className":2074},[770,2071],[68,2076,1890],{"className":2077,"style":2078},[770,771,2071],"margin-right:0.0278em;",[68,2080,1893],{"className":2081},[770,771,2071],[68,2083,1896],{"className":2084,"style":2085},[770,771,2071],"margin-right:0.0269em;",[68,2087,1890],{"className":2088,"style":2078},[770,771,2071],[68,2090,1901],{"className":2091},[770,771,2071],[68,2093,1904],{"className":2094},[770,771,2071],[68,2096,1893],{"className":2097},[770,771,2071],[68,2099,899],{"className":2100},[898],[68,2102,2104],{"className":2103},[825],[68,2105,2108],{"className":2106,"style":2107},[829],"height:0.15em;",[68,2109],{},[68,2111],{"className":2112,"style":884},[779],[68,2114,1909],{"className":2115},[888],[68,2117],{"className":2118,"style":884},[779],[68,2120,2122,2126,2190,2193,2196],{"className":2121},[753],[68,2123],{"className":2124,"style":2125},[757],"height:0.9694em;vertical-align:-0.2861em;",[68,2127,2129,2132],{"className":2128},[770],[68,2130,1878],{"className":2131,"style":2021},[770,771],[68,2133,2135],{"className":2134},[2047],[68,2136,2138,2181],{"className":2137},[820,821],[68,2139,2141,2178],{"className":2140},[825],[68,2142,2145],{"className":2143,"style":2144},[829],"height:0.3361em;",[68,2146,2147,2150],{"style":2060},[68,2148],{"className":2149,"style":2064},[837],[68,2151,2153],{"className":2152},[2068,2069,2070,2071],[68,2154,2156,2159,2163,2166,2170,2174],{"className":2155},[770,2071],[68,2157,1893],{"className":2158},[770,771,2071],[68,2160,2162],{"className":2161},[770,771,2071],"mb",[68,2164,1893],{"className":2165},[770,771,2071],[68,2167,2169],{"className":2168},[770,771,2071],"dd",[68,2171,2173],{"className":2172},[770,771,2071],"in",[68,2175,1938],{"className":2176,"style":2177},[770,771,2071],"margin-right:0.0359em;",[68,2179,899],{"className":2180},[898],[68,2182,2184],{"className":2183},[825],[68,2185,2188],{"className":2186,"style":2187},[829],"height:0.2861em;",[68,2189],{},[68,2191],{"className":2192,"style":884},[779],[68,2194,1909],{"className":2195},[888],[68,2197],{"className":2198,"style":884},[779],[68,2200,2202,2205,2273,2276,2279],{"className":2201},[753],[68,2203],{"className":2204,"style":2037},[757],[68,2206,2208,2211],{"className":2207},[770],[68,2209,1878],{"className":2210,"style":2021},[770,771],[68,2212,2214],{"className":2213},[2047],[68,2215,2217,2265],{"className":2216},[820,821],[68,2218,2220,2262],{"className":2219},[825],[68,2221,2223],{"className":2222,"style":2144},[829],[68,2224,2225,2228],{"style":2060},[68,2226],{"className":2227,"style":2064},[837],[68,2229,2231],{"className":2230},[2068,2069,2070,2071],[68,2232,2234,2237,2240,2243,2246,2249,2252,2255,2258],{"className":2233},[770,2071],[68,2235,1890],{"className":2236,"style":2078},[770,771,2071],[68,2238,1893],{"className":2239},[770,771,2071],[68,2241,1904],{"className":2242},[770,771,2071],[68,2244,1890],{"className":2245,"style":2078},[770,771,2071],[68,2247,1901],{"className":2248},[770,771,2071],[68,2250,1893],{"className":2251},[770,771,2071],[68,2253,1961],{"className":2254,"style":2177},[770,771,2071],[68,2256,1964],{"className":2257},[770,771,2071],[68,2259,1967],{"className":2260,"style":2261},[770,771,2071],"margin-right:0.0197em;",[68,2263,899],{"className":2264},[898],[68,2266,2268],{"className":2267},[825],[68,2269,2271],{"className":2270,"style":2107},[829],[68,2272],{},[68,2274],{"className":2275,"style":884},[779],[68,2277,1909],{"className":2278},[888],[68,2280],{"className":2281,"style":884},[779],[68,2283,2285,2288,2340,2343,2346],{"className":2284},[753],[68,2286],{"className":2287,"style":2037},[757],[68,2289,2291,2294],{"className":2290},[770],[68,2292,1878],{"className":2293,"style":2021},[770,771],[68,2295,2297],{"className":2296},[2047],[68,2298,2300,2332],{"className":2299},[820,821],[68,2301,2303,2329],{"className":2302},[825],[68,2304,2306],{"className":2305,"style":2144},[829],[68,2307,2308,2311],{"style":2060},[68,2309],{"className":2310,"style":2064},[837],[68,2312,2314],{"className":2313},[2068,2069,2070,2071],[68,2315,2317,2320,2324],{"className":2316},[770,2071],[68,2318,1890],{"className":2319,"style":2078},[770,771,2071],[68,2321,2323],{"className":2322,"style":2078},[770,771,2071],"er",[68,2325,2328],{"className":2326,"style":2327},[770,771,2071],"margin-right:0.0315em;","ank",[68,2330,899],{"className":2331},[898],[68,2333,2335],{"className":2334},[825],[68,2336,2338],{"className":2337,"style":2107},[829],[68,2339],{},[68,2341],{"className":2342,"style":884},[779],[68,2344,1909],{"className":2345},[888],[68,2347],{"className":2348,"style":884},[779],[68,2350,2352,2355],{"className":2351},[753],[68,2353],{"className":2354,"style":2037},[757],[68,2356,2358,2361],{"className":2357},[770],[68,2359,1878],{"className":2360,"style":2021},[770,771],[68,2362,2364],{"className":2363},[2047],[68,2365,2367,2396],{"className":2366},[820,821],[68,2368,2370,2393],{"className":2369},[825],[68,2371,2374],{"className":2372,"style":2373},[829],"height:0.3283em;",[68,2375,2376,2379],{"style":2060},[68,2377],{"className":2378,"style":2064},[837],[68,2380,2382],{"className":2381},[2068,2069,2070,2071],[68,2383,2385,2389],{"className":2384},[770,2071],[68,2386,2388],{"className":2387},[770,771,2071],"LL",[68,2390,2004],{"className":2391,"style":2392},[770,771,2071],"margin-right:0.109em;",[68,2394,899],{"className":2395},[898],[68,2397,2399],{"className":2398},[825],[68,2400,2402],{"className":2401,"style":2107},[829],[68,2403],{},[12,2405,2406],{},"通常真正的大头往往是：",[312,2408,2409],{},[12,2410,2411],{},[84,2412,2413],{},"LLM Generation。",[256,2415,2418],{"className":2416,"code":2417,"language":261},[259],"用户 Query\n   ↓\nRetriever\n   ↓\n正确 Chunk 有没有搜出来？\n   │\n   ├─ 没搜出来 → Retrieval 问题\n   │\n   └─ 搜出来了\n          ↓\n        LLM\n          ↓\n       仍然答错 → Generation 问题\n",[263,2419,2417],{"__ignoreMap":29},[12,2421,2422],{},"可以这样理解：",[312,2424,2425],{},[12,2426,2427],{},[84,2428,2429],{},"RAG 评估必须把 Retrieval 和 Generation 分开。Retrieval 用 Recall@K、Precision@K、MRR、NDCG 等指标评估召回和排序；Generation 用 Faithfulness、Answer Relevance、Correctness、Citation Correctness 等指标评估答案质量。",[12,2431,2432],{},"一句话记忆：",[312,2434,2435],{},[12,2436,2437],{},[84,2438,2439],{},"Retrieval 看“资料找对没有”，Generation 看“拿到资料后回答对没有”。",[59,2441,2443],{"id":2442},"_27为什么不直接使用大模型超长上下文","27.为什么不直接使用大模型超长上下文？",[12,2445,2446],{},"大模型上下文再长，也只是“这一次最多能读多少内容”；RAG 解决的是“先从海量知识里挑出当前最需要的内容再给模型”。",[248,2448,2449],{"id":2449},"如果只靠超长上下文",[12,2451,2452],{},"相当于：",[256,2454,2457],{"className":2455,"code":2456,"language":261},[259],"100GB 公司文档\n      ↓\n全部塞给 LLM\n      ↓\n让它自己找答案\n",[263,2458,2456],{"__ignoreMap":29},[12,2460,2461],{},"问题很明显：",[941,2463,2464,2470,2476,2482,2488],{},[944,2465,2466,2469],{},[84,2467,2468],{},"贵","：输入 Token 越多，成本越高",[944,2471,2472,2475],{},[84,2473,2474],{},"慢","：模型要先处理大量 Context",[944,2477,2478,2481],{},[84,2479,2480],{},"噪声多","：真正有用的可能只有 5 个 Chunk",[944,2483,2484,2487],{},[84,2485,2486],{},"放不下","：128K、1M 也装不下几十 GB \u002F TB 知识库",[944,2489,2490,2493],{},[84,2491,2492],{},"权限难控制","：不能把用户无权看到的资料先塞给模型",[248,2495],{"id":29},[59,2497,2499],{"id":2498},"_28简短","28.简短",[12,2501,2502],{},"你最好把下面这套练熟。",[248,2504,2506],{"id":2505},"q什么是-rag","Q：什么是 RAG？",[312,2508,2509],{},[12,2510,2511],{},"Retrieval-Augmented Generation，先从外部知识库检索与 Query 相关的信息，再把检索结果作为上下文输入 LLM，让模型基于外部知识生成答案。",[248,2513,2515],{"id":2514},"q为什么切-chunk","Q：为什么切 Chunk？",[312,2517,2518],{},[12,2519,2520],{},"提升检索粒度，避免整篇文档 Embedding 后多个主题的语义被平均掉。",[248,2522,2524],{"id":2523},"qchunk-越小越好吗","Q：Chunk 越小越好吗？",[312,2526,2527],{},[12,2528,2529],{},"不是。太小会丢上下文，太大语义容易被稀释，而且增加 Token 和噪声，需要在 Recall、Precision 和 Context Completeness 之间平衡。",[248,2531,2533],{"id":2532},"qoverlap-为什么存在","Q：Overlap 为什么存在？",[312,2535,2536],{},[12,2537,2538],{},"避免关键信息刚好跨越 Chunk 边界导致语义断裂。",[248,2540,2542],{"id":2541},"qembedding-是什么","Q：Embedding 是什么？",[312,2544,2545],{},[12,2546,2547],{},"把文本编码成高维稠密向量，使语义相近文本在向量空间距离也更接近。",[248,2549,2551],{"id":2550},"q为什么-query-和文档必须一个-embedding-模型","Q：为什么 Query 和文档必须一个 Embedding 模型？",[312,2553,2554],{},[12,2555,2556],{},"因为必须处于同一个向量空间，否则两个向量的距离没有可靠语义。",[248,2558,2560],{"id":2559},"q怎么找最相似向量","Q：怎么找最相似向量？",[312,2562,2563],{},[12,2564,2565],{},"可以使用 Cosine、Dot Product 等相似度指标，大规模场景一般通过 HNSW 等 ANN 索引近似搜索，而不是全量扫描。",[248,2567,2569],{"id":2568},"q什么是-topk","Q：什么是 TopK？",[312,2571,2572],{},[12,2573,2574],{},"Retriever 返回相似度最高的 K 个候选 Chunk。",[248,2576,2578],{"id":2577},"qtopk-越大越好吗","Q：TopK 越大越好吗？",[312,2580,2581],{},[12,2582,2583],{},"不是，会增加噪声、Rerank 成本和 LLM Token 消耗。",[248,2585,2587],{"id":2586},"q召回和向量检索区别","Q：召回和向量检索区别？",[312,2589,2590],{},[12,2591,2592],{},"召回是一个阶段，向量检索只是召回手段之一，还可以通过 BM25、Graph、SQL 等召回。",[248,2594,2596],{"id":2595},"q为什么还要-bm25","Q：为什么还要 BM25？",[312,2598,2599],{},[12,2600,2601],{},"Vector 擅长语义，BM25 擅长错误码、编号、专有名词等精确关键词，二者互补。",[248,2603,2605],{"id":2604},"q怎么融合","Q：怎么融合？",[312,2607,2608],{},[12,2609,2610],{},"可以使用 RRF 根据多个 Retriever 中的排名进行融合，而不是直接比较不同体系的原始 Score。",[248,2612,2614],{"id":2613},"qrerank-是什么","Q：Rerank 是什么？",[312,2616,2617],{},[12,2618,2619],{},"对召回阶段得到的少量候选文档用更精确的模型重新计算 Query-Document 相关度，然后选 TopN。",[248,2621,2623],{"id":2622},"q为什么不直接全部-rerank","Q：为什么不直接全部 Rerank？",[312,2625,2626],{},[12,2627,2628],{},"Cross-Encoder 计算成本高，只适合候选集，Retriever 负责大范围快速筛选。",[248,2630,2632],{"id":2631},"qrag-可以消灭幻觉吗","Q：RAG 可以消灭幻觉吗？",[312,2634,2635],{},[12,2636,2637],{},"不能，只能降低。检索错误、知识错误、上下文利用错误都仍然会产生幻觉。",[248,2639,2641],{"id":2640},"q回答错误怎么排查","Q：回答错误怎么排查？",[312,2643,2644],{},[12,2645,2646],{},"先看正确 Chunk 有没有召回，再看 Rerank 有没有排掉，最后看正确 Context 已经进入 Prompt 后 LLM 是否仍然生成错误。",{"title":29,"searchDepth":30,"depth":30,"links":2648},[2649,2651,2652,2653,2654,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2679,2680,2681,2686,2687,2688,2694,2697,2703,2707],{"id":61,"depth":2650,"text":55},2,{"id":122,"depth":2650,"text":123},{"id":132,"depth":2650,"text":133},{"id":157,"depth":2650,"text":158},{"id":242,"depth":2650,"text":243,"children":2655},[2656,2658,2659,2660],{"id":250,"depth":2657,"text":251},3,{"id":282,"depth":2657,"text":283},{"id":321,"depth":2657,"text":322},{"id":357,"depth":2657,"text":358},{"id":391,"depth":2650,"text":392},{"id":466,"depth":2650,"text":467},{"id":522,"depth":2650,"text":523},{"id":588,"depth":2650,"text":589},{"id":657,"depth":2650,"text":658},{"id":965,"depth":2650,"text":966},{"id":1043,"depth":2650,"text":1044},{"id":1071,"depth":2650,"text":1072},{"id":1127,"depth":2650,"text":1128},{"id":1193,"depth":2650,"text":1194},{"id":1252,"depth":2650,"text":1253},{"id":1259,"depth":2650,"text":1260},{"id":1304,"depth":2650,"text":1305},{"id":1354,"depth":2650,"text":1355,"children":2675},[2676,2677,2678],{"id":1377,"depth":2657,"text":1377},{"id":1386,"depth":2657,"text":1386},{"id":1395,"depth":2657,"text":1396},{"id":1433,"depth":2650,"text":1434},{"id":1450,"depth":2650,"text":1451},{"id":1470,"depth":2650,"text":1471,"children":2682},[2683,2684,2685],{"id":1474,"depth":2657,"text":1474},{"id":1483,"depth":2657,"text":1483},{"id":1494,"depth":2657,"text":1494},{"id":1525,"depth":2650,"text":1526},{"id":1584,"depth":2650,"text":1585},{"id":1633,"depth":2650,"text":1634,"children":2689},[2690,2692,2693],{"id":1637,"depth":2657,"text":2691},"pgvector 可以理解为：给 PostgreSQL 增加“向量存储 + 向量相似度检索”能力的扩展。",{"id":1658,"depth":2657,"text":1659},{"id":1678,"depth":2657,"text":1679},{"id":1708,"depth":2650,"text":1709,"children":2695},[2696],{"id":1761,"depth":2657,"text":1762},{"id":1803,"depth":2650,"text":1804,"children":2698},[2699,2700,2701,2702],{"id":1807,"depth":2657,"text":1807},{"id":1816,"depth":2657,"text":1817},{"id":1826,"depth":2657,"text":1827},{"id":1847,"depth":2657,"text":1848},{"id":2442,"depth":2650,"text":2443,"children":2704},[2705,2706],{"id":2449,"depth":2657,"text":2449},{"id":29,"depth":2657,"text":29},{"id":2498,"depth":2650,"text":2499,"children":2708},[2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724],{"id":2505,"depth":2657,"text":2506},{"id":2514,"depth":2657,"text":2515},{"id":2523,"depth":2657,"text":2524},{"id":2532,"depth":2657,"text":2533},{"id":2541,"depth":2657,"text":2542},{"id":2550,"depth":2657,"text":2551},{"id":2559,"depth":2657,"text":2560},{"id":2568,"depth":2657,"text":2569},{"id":2577,"depth":2657,"text":2578},{"id":2586,"depth":2657,"text":2587},{"id":2595,"depth":2657,"text":2596},{"id":2604,"depth":2657,"text":2605},{"id":2613,"depth":2657,"text":2614},{"id":2622,"depth":2657,"text":2623},{"id":2631,"depth":2657,"text":2632},{"id":2640,"depth":2657,"text":2641},[2726,2727],"技术","开发","2026-09-07","自我总结",{"slots":2731},{},"\u002F2026\u002Farticle-20260907-174336-383eaaa7",{"text":2734,"minutes":2735,"time":2736,"words":2737},"23 min read",22.795,1367700,4559,{"title":55,"description":2729},{"loc":2732},"posts\u002F2026\u002Farticle-20260907-174336-383eaaa7",[],"XmUkeuFM31CSGvKDALRHLofh2M7MrfNRcJyPuLuzphE",[2744,2749],{"title":2745,"path":2746,"stem":2747,"date":2748,"type":50,"children":-1},"AI中转站科普与揭秘-如何赚钱？","\u002F2026\u002Farticle-20260830-023446-fa104da8","posts\u002F2026\u002Farticle-20260830-023446-fa104da8","2026-08-29",{"title":2750,"path":2751,"stem":2752,"date":2753,"type":50,"children":-1},"2026-09-14日记简记","\u002F2026\u002Farticle-20260914-171310-9a2aee84","posts\u002F2026\u002Farticle-20260914-171310-9a2aee84","2026-09-14",1789377375209]