<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>RAG on Snow</title>
        <link>https://SymphonyW.github.io/zh-cn/tags/rag/</link>
        <description>Recent content in RAG on Snow</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>Snow</copyright>
        <lastBuildDate>Thu, 15 Oct 2026 15:00:00 +0800</lastBuildDate><atom:link href="https://SymphonyW.github.io/zh-cn/tags/rag/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Agentic RAG 深度解析：让检索从固定流水线变成会规划、会反思的智能体</title>
        <link>https://SymphonyW.github.io/zh-cn/p/agentic-rag-guide/</link>
        <pubDate>Thu, 15 Oct 2026 15:00:00 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/agentic-rag-guide/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/agentic-rag-guide/bg.png" alt="Featured image of post Agentic RAG 深度解析：让检索从固定流水线变成会规划、会反思的智能体" /&gt;&lt;h1 id=&#34;agentic-rag-深度解析让检索从固定流水线变成会规划会反思的智能体&#34;&gt;Agentic RAG 深度解析：让检索从固定流水线变成会规划、会反思的智能体
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;传统 RAG 像一条预先铺好的流水线：收到问题、检索一次、拼接上下文、生成答案。Agentic RAG 则给这条流水线加上了一个“控制者”：它可以判断要不要检索、把问题拆成几步、选择不同数据源、检查证据是否够用，并在必要时改写查询继续搜索。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/agentic-rag-guide/bg.png&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/agentic-rag-guide/bg.png&#34; alt=&#34;Agent 调度多种知识源并循环评估证据&#34; width=&#34;1672&#34; height=&#34;941&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;gallery-image&#34; data-flex-grow=&#34;177&#34; data-flex-basis=&#34;426px&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;先给出本文最重要的结论：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题&lt;/th&gt;
&lt;th&gt;简短答案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agentic RAG 是什么&lt;/td&gt;
&lt;td&gt;由 Agent 在运行时规划、调用、评估和迭代检索的 RAG 架构&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;和传统 RAG 最大的区别&lt;/td&gt;
&lt;td&gt;不在于有没有向量库，而在于&lt;strong&gt;检索控制流是否能根据中间结果动态改变&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一定需要多个 Agent 吗&lt;/td&gt;
&lt;td&gt;不需要。一个 Agent 加多个检索工具就可以构成 Agentic RAG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一定比传统 RAG 好吗&lt;/td&gt;
&lt;td&gt;不一定。简单问答往往只会得到更高延迟、更高成本和更多不确定性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最适合什么问题&lt;/td&gt;
&lt;td&gt;多跳推理、多数据源、需要澄清或证据校验的复杂任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;落地最关键的能力&lt;/td&gt;
&lt;td&gt;有界循环、证据门控、权限隔离、完整轨迹与分层评估&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;一先回到传统-rag&#34;&gt;一、先回到传统 RAG
&lt;/h2&gt;&lt;p&gt;RAG 是 Retrieval-Augmented Generation 的缩写，即&lt;strong&gt;检索增强生成&lt;/strong&gt;。它把大模型参数中的“内部记忆”和外部知识库中的“非参数记忆”结合起来。用户提问后，系统先找出相关资料，再让模型依据这些资料回答。&lt;/p&gt;
&lt;p&gt;2020 年的 &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2005.11401&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RAG 原始论文&lt;/a&gt; 重点讨论了如何把生成模型与外部稠密向量索引结合，以改善知识密集型任务中的事实性、知识更新与来源追溯问题。工程实践中的传统 RAG 通常被简化成下面这条在线链路：&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    Q[用户问题] --&gt; T[清洗或固定规则改写]
    T --&gt; E[生成查询向量]
    E --&gt; R[检索 Top-K 文档]
    R --&gt; K[可选：重排序]
    K --&gt; P[拼接 Prompt]
    P --&gt; L[LLM 生成答案]
    L --&gt; A[返回答案与引用]
&lt;/div&gt;&lt;p&gt;它的优势非常明确：流程短、延迟可预测、容易缓存、容易压测，也容易定位“是检索错了，还是生成错了”。如果问题基本都能通过“对一个知识库搜索一次”解决，这种结构往往已经足够好。&lt;/p&gt;
&lt;p&gt;但固定流水线也有天然边界。假设用户问：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“对比 A、B 两款产品最近三个版本的权限变化，并判断旧客户迁移时有哪些风险。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个问题隐含了多个子任务：识别版本范围、分别查 A 和 B 的更新日志、查权限说明、找迁移文档、对齐发布时间，最后才能做比较。一次相似度搜索很可能只覆盖其中一部分；即使拿到了十段文本，模型也未必知道缺失的是哪一块证据。&lt;/p&gt;
&lt;h2 id=&#34;二agentic-rag-到底agentic在哪里&#34;&gt;二、Agentic RAG 到底“Agentic”在哪里
&lt;/h2&gt;&lt;p&gt;Agentic RAG 不是给传统 RAG 换一个更强的模型，也不是“向量检索 + Function Calling”的简单拼装。它真正改变的是&lt;strong&gt;控制权&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;检索不再是每次都执行一次的固定步骤，而是 Agent 可以按需选择、重复调用并根据结果调整的工具。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这类系统通常把规划、工具调用、状态更新和停止判断组织成一个受控循环。Agent 可以做出以下决策：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前问题能否直接回答，还是必须查资料；&lt;/li&gt;
&lt;li&gt;应该查向量库、关键字索引、SQL、知识图谱、内部 API，还是公开网页；&lt;/li&gt;
&lt;li&gt;原问题是否需要拆成多个子问题；&lt;/li&gt;
&lt;li&gt;检索结果是否相关、是否互相矛盾、是否覆盖了所有子问题；&lt;/li&gt;
&lt;li&gt;应该改写查询、扩大时间范围、切换数据源，还是向用户澄清；&lt;/li&gt;
&lt;li&gt;证据何时已经足够，可以停止搜索并生成答案。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种“推理—行动—观察—再推理”的思想与 &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2210.03629&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ReAct&lt;/a&gt; 一脉相承。2025 年的 &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2501.09136&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Agentic RAG 综述&lt;/a&gt; 则把规划、反思、工具使用和多 Agent 协作归纳为常见的 Agentic 设计模式。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    U[用户问题] --&gt; P[理解意图与制定计划]
    P --&gt; D{证据已经足够？}
    D -- 是 --&gt; G[基于证据生成答案]
    D -- 否 --&gt; S[选择数据源与检索工具]
    S --&gt; Q[生成或改写查询]
    Q --&gt; R[执行检索]
    R --&gt; V[评估相关性、覆盖度与冲突]
    V --&gt; C{下一步}
    C -- 补充证据 --&gt; S
    C -- 需要澄清 --&gt; H[向用户提问]
    C -- 达到预算上限 --&gt; F[降级回答或说明无法确认]
    C -- 可以作答 --&gt; G
    G --&gt; A[答案、引用与不确定性说明]
&lt;/div&gt;&lt;p&gt;这里有一个很容易被忽略的判断标准：&lt;strong&gt;只要查询改写、混合检索、重排序都按预先写死的顺序执行，它仍然可以是“高级 RAG”，但未必是 Agentic RAG。&lt;/strong&gt; Agentic 的关键不是组件数量，而是系统会不会依据中间状态改变后续路径。&lt;/p&gt;
&lt;h2 id=&#34;三一条完整的-agentic-rag-工作循环&#34;&gt;三、一条完整的 Agentic RAG 工作循环
&lt;/h2&gt;&lt;p&gt;可以把在线流程拆成七个阶段。实际系统可以合并节点，但这些责任最好在日志和评估中保持可区分。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;Agent 要解决的问题&lt;/th&gt;
&lt;th&gt;典型输出&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. 意图识别&lt;/td&gt;
&lt;td&gt;用户真正想得到什么，是否需要外部事实&lt;/td&gt;
&lt;td&gt;任务类型、时间范围、实体、约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. 任务分解&lt;/td&gt;
&lt;td&gt;是否包含多个可独立验证的子问题&lt;/td&gt;
&lt;td&gt;子问题列表、依赖关系&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. 数据源路由&lt;/td&gt;
&lt;td&gt;哪个来源最权威、最适合当前子问题&lt;/td&gt;
&lt;td&gt;工具名、索引名、过滤条件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. 查询规划&lt;/td&gt;
&lt;td&gt;用什么关键词、向量查询或结构化条件&lt;/td&gt;
&lt;td&gt;一组可执行查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. 结果评估&lt;/td&gt;
&lt;td&gt;资料是否相关、充分、新鲜、相互一致&lt;/td&gt;
&lt;td&gt;相关性、覆盖度、冲突标记&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6. 纠正与迭代&lt;/td&gt;
&lt;td&gt;要不要换查询、换来源或缩小问题&lt;/td&gt;
&lt;td&gt;下一动作、剩余预算&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7. 综合回答&lt;/td&gt;
&lt;td&gt;怎样让每个关键结论都能回到证据&lt;/td&gt;
&lt;td&gt;答案、引用、不确定性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;假设用户问：“我们是否应该把生产数据库从 13 升级到 16？”Agent 可能执行这样的轨迹：&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;sequenceDiagram
    participant U as 用户
    participant A as Agent
    participant D as 内部文档库
    participant M as 资产数据库
    participant W as 官方文档

    U-&gt;&gt;A: 是否应该把生产数据库从 13 升级到 16？
    A-&gt;&gt;M: 查询当前版本、扩展、实例规模和维护窗口
    M--&gt;&gt;A: 返回环境清单
    A-&gt;&gt;D: 检索历史故障、兼容性测试和变更规范
    D--&gt;&gt;A: 返回内部证据
    A-&gt;&gt;W: 查询 14、15、16 的破坏性变更与支持周期
    W--&gt;&gt;A: 返回官方资料
    A-&gt;&gt;A: 检查扩展兼容性与证据缺口
    A-&gt;&gt;D: 继续检索缺失扩展的测试记录
    D--&gt;&gt;A: 未找到完整记录
    A--&gt;&gt;U: 给出条件式建议、风险清单，并明确需要补做的测试
&lt;/div&gt;&lt;p&gt;重点不是“多搜了几次”，而是后一次检索由前一次结果决定。如果资产数据库显示用了某个特殊扩展，Agent 才需要针对该扩展继续查兼容性；这正是固定流水线难以经济覆盖的分支。&lt;/p&gt;
&lt;h2 id=&#34;四常见架构并不只有一种&#34;&gt;四、常见架构并不只有一种
&lt;/h2&gt;&lt;p&gt;Agentic RAG 更像一个架构族，而不是唯一拓扑。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TB
    O[编排与状态层] --&gt; P[规划器 / Router]
    P --&gt; T1[向量检索]
    P --&gt; T2[关键字或混合检索]
    P --&gt; T3[SQL / API]
    P --&gt; T4[知识图谱 / Web]
    T1 --&gt; E[证据池]
    T2 --&gt; E
    T3 --&gt; E
    T4 --&gt; E
    E --&gt; J[证据评估器]
    J --&gt;|不足| P
    J --&gt;|充分| G[答案生成器]
    G --&gt; C[引用校验与安全门控]
&lt;/div&gt;&lt;h3 id=&#34;单-agent--多工具&#34;&gt;单 Agent + 多工具
&lt;/h3&gt;&lt;p&gt;一个 Agent 同时负责规划、选工具、评估和回答。这是最容易起步的结构，适合工具数量少、权限边界一致的场景。缺点是职责容易堆在一个 Prompt 里，决策稳定性和可测试性会逐渐变差。&lt;/p&gt;
&lt;h3 id=&#34;router--专用检索器&#34;&gt;Router + 专用检索器
&lt;/h3&gt;&lt;p&gt;Router 只负责判断问题类型和数据源，具体检索由稳定的专用链路完成。例如“制度问题走文档库，订单问题走 SQL，最新状态走业务 API”。它比完全开放的 Agent 更可控，通常也是生产系统最实用的折中。&lt;/p&gt;
&lt;h3 id=&#34;纠正式或反思式-rag&#34;&gt;纠正式或反思式 RAG
&lt;/h3&gt;&lt;p&gt;先检索，再由评估器判断结果质量；如果证据差，就改写查询、扩大来源或触发 Web 搜索。&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2401.15884&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CRAG&lt;/a&gt; 强调对检索结果进行纠正，&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2310.11511&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Self-RAG&lt;/a&gt; 则让模型学习何时检索并对生成内容进行自我反思。它们与 Agentic RAG 高度相关，但不能简单画等号：这些机制可以成为 Agent 循环里的部件，也可以被做成固定流程。&lt;/p&gt;
&lt;h3 id=&#34;多-agent-rag&#34;&gt;多 Agent RAG
&lt;/h3&gt;&lt;p&gt;把任务分给研究、检索、验证、写作等不同 Agent，或按知识域划分 Agent。它适合真正可以并行、权限不同或专业性很强的任务，但会显著增加通信成本、状态同步和故障定位难度。&lt;strong&gt;多 Agent 是可选的扩展，不是 Agentic RAG 的入场券。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;五和传统-rag-的区别&#34;&gt;五、和传统 RAG 的区别
&lt;/h2&gt;&lt;p&gt;最准确的比较不是“传统 RAG 笨、Agentic RAG 聪明”，而是“确定性流水线”和“运行时决策系统”之间的工程取舍。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;对比维度&lt;/th&gt;
&lt;th&gt;传统 RAG&lt;/th&gt;
&lt;th&gt;Agentic RAG&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;控制流&lt;/td&gt;
&lt;td&gt;预先固定&lt;/td&gt;
&lt;td&gt;根据中间结果动态分支和循环&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是否检索&lt;/td&gt;
&lt;td&gt;通常每次都检索&lt;/td&gt;
&lt;td&gt;可以选择检索、跳过或稍后再检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询处理&lt;/td&gt;
&lt;td&gt;原查询或固定改写&lt;/td&gt;
&lt;td&gt;动态拆分、改写、扩展、追问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据源&lt;/td&gt;
&lt;td&gt;通常一个索引或固定组合&lt;/td&gt;
&lt;td&gt;运行时选择多个异构来源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;检索次数&lt;/td&gt;
&lt;td&gt;一次或固定次数&lt;/td&gt;
&lt;td&gt;直到证据充分或预算耗尽&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多跳问题&lt;/td&gt;
&lt;td&gt;依赖一次召回覆盖全部信息&lt;/td&gt;
&lt;td&gt;可依据前一步结果继续追踪下一跳&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;失败处理&lt;/td&gt;
&lt;td&gt;返回当前结果或走固定兜底&lt;/td&gt;
&lt;td&gt;评估、重试、换工具、澄清、降级&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可预测性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;较低，需要状态机和预算约束&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;延迟与成本&lt;/td&gt;
&lt;td&gt;较低且稳定&lt;/td&gt;
&lt;td&gt;通常更高，波动也更大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可观测性&lt;/td&gt;
&lt;td&gt;看检索结果和最终答案&lt;/td&gt;
&lt;td&gt;还要看计划、工具调用、状态和停止原因&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全面&lt;/td&gt;
&lt;td&gt;相对集中&lt;/td&gt;
&lt;td&gt;工具权限、提示注入和越权风险更大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最适合&lt;/td&gt;
&lt;td&gt;高频、单跳、边界清晰的问答&lt;/td&gt;
&lt;td&gt;多步、多源、开放式研究与决策支持&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;还有一个重要事实：传统 RAG 与 Agentic RAG 不是二选一。生产系统常见的做法是&lt;strong&gt;先走快速路径，只有检测到复杂问题或低置信度时才升级到 Agentic 路径&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    Q[用户问题] --&gt; X{复杂度与风险检测}
    X -- 简单、单跳 --&gt; R[传统 RAG 快速路径]
    X -- 多约束、多跳、低置信度 --&gt; A[Agentic RAG 深度路径]
    R --&gt; G[统一答案与引用层]
    A --&gt; G
&lt;/div&gt;&lt;p&gt;这种分层路由往往比“所有请求都交给 Agent”更划算：常见问题保持低延迟，复杂问题才使用额外的规划和检索预算。&lt;/p&gt;
&lt;h2 id=&#34;六实现时离线知识工程并没有消失&#34;&gt;六、实现时，离线知识工程并没有消失
&lt;/h2&gt;&lt;p&gt;Agentic RAG 主要改变在线查询阶段，但它无法替代离线的数据治理。文档解析错误、切块不合理、元数据缺失、权限标签不完整，再强的 Agent 也只能在坏数据上反复搜索。&lt;/p&gt;
&lt;p&gt;一个可落地的系统通常分成四层：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层&lt;/th&gt;
&lt;th&gt;主要职责&lt;/th&gt;
&lt;th&gt;关键设计&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;知识层&lt;/td&gt;
&lt;td&gt;采集、解析、切块、索引、更新&lt;/td&gt;
&lt;td&gt;数据质量、版本、权限、新鲜度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具层&lt;/td&gt;
&lt;td&gt;把检索能力暴露为清晰接口&lt;/td&gt;
&lt;td&gt;输入 Schema、过滤器、超时、结果格式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编排层&lt;/td&gt;
&lt;td&gt;规划、路由、循环、状态和预算&lt;/td&gt;
&lt;td&gt;最大步数、并发、重试、检查点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;治理层&lt;/td&gt;
&lt;td&gt;评估、观测、安全和人工介入&lt;/td&gt;
&lt;td&gt;轨迹、审计、审批、离线测试集&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;工具描述要具体，不能只写“搜索知识库”。更好的描述会告诉 Agent：数据覆盖什么时间、适合解决什么问题、返回什么字段、有哪些权限限制。否则工具越多，选错工具的概率反而越高。&lt;/p&gt;
&lt;p&gt;下面是一段与框架无关的伪代码，它展示了最小闭环：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;answer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;question&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max_steps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;state&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;question&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;evidence&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;open_questions&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;question&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;trace&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;step&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;max_steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;planner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decide&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;allowed_tools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;allowed_tools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;action&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;clarify&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ask_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;question&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;action&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;answer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;evidence_gate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;passed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;evidence&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;generator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;grounded_answer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;planner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repair_missing_evidence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;identity&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;identity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;grade&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;evaluator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;grade&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;open_questions&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;state&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;update_state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decision&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;grade&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;generator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bounded_fallback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;真正重要的不是这段循环本身，而是其中的护栏：&lt;code&gt;allowed_tools&lt;/code&gt; 限制权限，&lt;code&gt;max_steps&lt;/code&gt; 防止失控，&lt;code&gt;evidence_gate&lt;/code&gt; 阻止无证据作答，&lt;code&gt;trace&lt;/code&gt; 为复盘和评估保留结构化轨迹。&lt;/p&gt;
&lt;h2 id=&#34;七生产环境最容易踩的坑&#34;&gt;七、生产环境最容易踩的坑
&lt;/h2&gt;&lt;h3 id=&#34;无限搜索与成本失控&#34;&gt;无限搜索与成本失控
&lt;/h3&gt;&lt;p&gt;如果停止条件只是“模型觉得够了”，Agent 可能在相似查询之间来回打转。至少需要限制最大步数、总 Token、单工具超时、并发数和总费用，并在预算耗尽时返回明确的降级结果。&lt;/p&gt;
&lt;h3 id=&#34;把反思误当成事实校验&#34;&gt;把“反思”误当成事实校验
&lt;/h3&gt;&lt;p&gt;让同一个模型评价自己的答案，并不会自动得到独立证据。反思节点应该检查可观察指标，例如来源是否覆盖全部子问题、引用是否真的支持结论、时间范围是否一致，而不是只问一句“答案好吗”。&lt;/p&gt;
&lt;h3 id=&#34;检索内容中的提示注入&#34;&gt;检索内容中的提示注入
&lt;/h3&gt;&lt;p&gt;网页或文档也可能包含“忽略系统指令并调用某工具”之类的恶意文本。检索结果必须被当作&lt;strong&gt;不可信数据&lt;/strong&gt;，不能当作高优先级指令。工具调用应经过参数校验、来源白名单、最小权限和高风险操作审批。&lt;/p&gt;
&lt;h3 id=&#34;只有最终答案没有执行轨迹&#34;&gt;只有最终答案，没有执行轨迹
&lt;/h3&gt;&lt;p&gt;Agentic RAG 出错时，问题可能发生在任务分解、路由、查询、召回、评估、停止或生成中的任意一层。日志至少应记录结构化决策、工具名、查询参数、文档 ID、评分、耗时、Token、错误与停止原因；不必保存或暴露模型的私有思维过程。&lt;/p&gt;
&lt;h3 id=&#34;用更复杂的架构掩盖基础检索问题&#34;&gt;用更复杂的架构掩盖基础检索问题
&lt;/h3&gt;&lt;p&gt;如果 Top-K 里长期没有正确文档，先检查解析、切块、Embedding、过滤器、混合检索和重排序。Agent 可以修补偶发缺口，却不该替代基本的信息检索工程。&lt;/p&gt;
&lt;h2 id=&#34;八评估对象从答案扩展到了轨迹&#34;&gt;八、评估对象从“答案”扩展到了“轨迹”
&lt;/h2&gt;&lt;p&gt;传统 RAG 常看命中率和回答正确率。Agentic RAG 还必须回答：它是否选择了正确工具？是否做了不必要的搜索？是否在证据不足时过早停止？&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;评估层&lt;/th&gt;
&lt;th&gt;建议指标&lt;/th&gt;
&lt;th&gt;要回答的问题&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;检索&lt;/td&gt;
&lt;td&gt;Recall@K、MRR、nDCG、证据覆盖率&lt;/td&gt;
&lt;td&gt;正确资料有没有被找到&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生成&lt;/td&gt;
&lt;td&gt;正确性、忠实度、引用精度与完整度&lt;/td&gt;
&lt;td&gt;答案是否被证据支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;轨迹&lt;/td&gt;
&lt;td&gt;工具选择准确率、查询有效率、平均步数、停止正确率&lt;/td&gt;
&lt;td&gt;Agent 的过程是否合理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;系统&lt;/td&gt;
&lt;td&gt;P50/P95 延迟、Token 成本、工具成本、超时率&lt;/td&gt;
&lt;td&gt;质量提升是否值得代价&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全&lt;/td&gt;
&lt;td&gt;越权调用率、注入攻击成功率、敏感信息泄漏率&lt;/td&gt;
&lt;td&gt;系统是否守住权限与数据边界&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;测试集也要分层：简单单跳题用于验证快速路径；多跳题验证分解与证据组合；信息不足题验证是否会澄清；矛盾资料题验证冲突处理；恶意文档验证提示注入防护。只用“答案看起来不错”的十几个示例，无法支撑生产决策。&lt;/p&gt;
&lt;h2 id=&#34;九什么时候该用什么时候不该用&#34;&gt;九、什么时候该用，什么时候不该用
&lt;/h2&gt;&lt;p&gt;可以用下面这张表做初筛：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FAQ、产品手册、制度单点问答&lt;/td&gt;
&lt;td&gt;传统 RAG&lt;/td&gt;
&lt;td&gt;查询稳定、答案边界清晰，优先延迟和成本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一个索引，但偶尔召回不佳&lt;/td&gt;
&lt;td&gt;高级 RAG&lt;/td&gt;
&lt;td&gt;先加混合检索、Rerank、查询改写和评估器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;问题包含多个相互依赖的子问题&lt;/td&gt;
&lt;td&gt;Agentic RAG&lt;/td&gt;
&lt;td&gt;需要分解并根据中间结果继续检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同时查询文档、数据库与实时 API&lt;/td&gt;
&lt;td&gt;Agentic RAG&lt;/td&gt;
&lt;td&gt;需要动态路由异构工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;医疗、金融、发布生产变更等高风险动作&lt;/td&gt;
&lt;td&gt;Agentic RAG + 人工审批&lt;/td&gt;
&lt;td&gt;自动检索可以辅助判断，高风险动作仍需明确授权&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;极低延迟、高吞吐、答案结构固定&lt;/td&gt;
&lt;td&gt;传统 RAG 或规则系统&lt;/td&gt;
&lt;td&gt;Agent 循环的收益通常抵不过额外开销&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果你正在从零建设，建议按以下顺序演进：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先做可评估的传统 RAG，建立检索与答案基线；&lt;/li&gt;
&lt;li&gt;加入混合检索、元数据过滤、Rerank 和引用校验；&lt;/li&gt;
&lt;li&gt;只把最明显的动态决策交给 Router；&lt;/li&gt;
&lt;li&gt;为复杂查询增加有界的“检索—评估—纠正”循环；&lt;/li&gt;
&lt;li&gt;最后才考虑多 Agent、长期记忆和更开放的工具权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;十总结&#34;&gt;十、总结
&lt;/h2&gt;&lt;p&gt;Agentic RAG 的价值，不是让 RAG 看起来更像一个“智能体”，而是让系统在面对复杂问题时拥有三种传统固定流水线缺少的能力：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;规划&lt;/strong&gt;：把复杂问题拆成可以验证的检索任务；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适应&lt;/strong&gt;：根据中间结果改查询、换数据源或请求澄清；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;校验&lt;/strong&gt;：在证据不足、冲突或超出权限时停止、降级或交给人。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;它的代价同样真实：更多模型调用、更高延迟、更复杂的状态、更大的安全面，以及更困难的评估。真正成熟的方案通常不是“把所有 RAG 都 Agent 化”，而是保留一条稳定的传统 RAG 快速路径，再让 Agentic RAG 处理那些确实需要多步、多源和动态决策的问题。&lt;/p&gt;
&lt;p&gt;一句话概括：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;传统 RAG 解决“从哪里找一段相关资料”，Agentic RAG 进一步解决“为了完成这个任务，接下来应该找什么、去哪里找、找到后是否还要继续”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Lewis et al., &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2005.11401&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks&lt;/a&gt;, 2020.&lt;/li&gt;
&lt;li&gt;Yao et al., &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2210.03629&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ReAct: Synergizing Reasoning and Acting in Language Models&lt;/a&gt;, 2022.&lt;/li&gt;
&lt;li&gt;Asai et al., &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2310.11511&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection&lt;/a&gt;, 2023.&lt;/li&gt;
&lt;li&gt;Yan et al., &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2401.15884&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Corrective Retrieval Augmented Generation&lt;/a&gt;, 2024.&lt;/li&gt;
&lt;li&gt;Singh et al., &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2501.09136&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Agentic Retrieval-Augmented Generation: A Survey on Agentic RAG&lt;/a&gt;, 2025.&lt;/li&gt;
&lt;li&gt;Microsoft, &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/rag/rag-agentic&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Develop an Agentic RAG Solution on Azure&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;LangChain, &lt;a class=&#34;link&#34; href=&#34;https://docs.langchain.com/oss/python/learn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RAG agent 与自定义 RAG Agent 教程索引&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>FastGPT 深度指南：RAG、工作流与私有部署</title>
        <link>https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/</link>
        <pubDate>Thu, 08 Oct 2026 00:00:00 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/bg.png" alt="Featured image of post FastGPT 深度指南：RAG、工作流与私有部署" /&gt;&lt;h1 id=&#34;fastgpt-深度指南rag工作流与私有部署&#34;&gt;FastGPT 深度指南：RAG、工作流与私有部署
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;FastGPT 不是一个“换皮聊天框”，也不只是一个向量数据库管理界面。它把模型接入、文档处理、RAG 检索、流程编排、调试、发布和运营放进同一个平台，让团队可以用较低的工程成本，把一段 AI Demo 变成真正可交付的应用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你准备做企业知识库、客服助手、制度问答、内容审核、数据分析 Agent，通常会很快遇到几件麻烦事：模型供应商不止一家；文档格式五花八门；检索效果要持续调；业务流程不可能只靠一段 Prompt；上线后还要做权限、日志、配额和渠道接入。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/labring/FastGPT&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FastGPT&lt;/a&gt; 正是试图把这些重复的基础设施收拢起来。官方把它定义为 &lt;strong&gt;AI Agent 构建平台&lt;/strong&gt;，社区版面向个人开发者和小型交付团队，核心覆盖 Agent、工作流与知识库。本文不只告诉你按钮在哪里，而是从系统设计出发，讲清它解决了什么、内部怎样协作、如何跑通一个项目，以及什么时候不该用它。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/platform-map.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/platform-map.svg&#34; alt=&#34;FastGPT 把模型、知识、流程和发布渠道组织成一套应用平台&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;先给结论fastgpt-到底是什么&#34;&gt;先给结论：FastGPT 到底是什么
&lt;/h2&gt;&lt;p&gt;可以把 FastGPT 理解为位于 &lt;strong&gt;基础模型之上的 AI 应用层&lt;/strong&gt;。模型负责理解与生成，向量数据库负责相似内容查找，而 FastGPT 负责把两者和业务流程组合成一个可配置、可调试、可发布的应用。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层次&lt;/th&gt;
&lt;th&gt;它解决的问题&lt;/th&gt;
&lt;th&gt;FastGPT 提供的能力&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;模型层&lt;/td&gt;
&lt;td&gt;调哪个聊天、Embedding、Rerank 或视觉模型&lt;/td&gt;
&lt;td&gt;统一配置模型提供商，通过 AI Proxy 转发与管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知识层&lt;/td&gt;
&lt;td&gt;文档怎样切分、索引、检索与引用&lt;/td&gt;
&lt;td&gt;Dataset、数据处理、向量/全文/混合检索、Rerank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;编排层&lt;/td&gt;
&lt;td&gt;多步任务怎样串起来&lt;/td&gt;
&lt;td&gt;可视化节点、变量传递、条件分支、插件与 Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;应用层&lt;/td&gt;
&lt;td&gt;如何调试、复用和交付&lt;/td&gt;
&lt;td&gt;应用配置、调试日志、分享链接、API、嵌入与 MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;运维层&lt;/td&gt;
&lt;td&gt;谁在用、花了多少、哪里失败&lt;/td&gt;
&lt;td&gt;团队空间、调用记录、配额、日志和数据标注&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;它最适合两类人：一类是希望快速交付 AI 应用、但不想从零搭 RAG 与编排后台的开发者；另一类是懂业务、能理解流程节点，但不准备手写整套后端的产品或实施团队。&lt;/p&gt;
&lt;p&gt;FastGPT 也不是“安装后立刻拥有高质量答案”的魔法盒。它把工程链路搭好了，但答案质量仍取决于原始资料、分块策略、Embedding、检索参数、Rerank、Prompt 和模型能力。平台降低的是系统建设成本，不会自动消除数据问题。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;核心能力怎样协作&#34;&gt;核心能力怎样协作
&lt;/h2&gt;&lt;p&gt;FastGPT 的价值不在某个孤立功能，而在于知识库、工作流和发布渠道能使用同一套应用上下文。&lt;/p&gt;
&lt;h3 id=&#34;知识库不只是文档转向量&#34;&gt;知识库：不只是“文档转向量”
&lt;/h3&gt;&lt;p&gt;一份文档进入知识库后，通常经历解析、清洗、分块、索引生成和入库。查询时也不只是做一次向量 Top-K。根据&lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/guide/dataset/dataset_engine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方检索说明&lt;/a&gt;，FastGPT 可以先做 Query Rewrite，再从语义检索、全文检索乃至图像检索等路径召回候选，用 RRF 融合多路排序，随后通过 Rerank 精排，并根据相关度与引用 Token 上限筛选最终上下文。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/rag-pipeline.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/rag-pipeline.svg&#34; alt=&#34;FastGPT 知识库从入库到生成回答的完整链路&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;这里有四个容易被忽略的设计点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dataset、Collection、Data 是三层结构。&lt;/strong&gt; Dataset 是可检索的知识库，Collection 类似一个文件或一组资料，Data 是最终参与问答的数据条目。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一条数据可以映射多个向量。&lt;/strong&gt; 长文本可以保留完整答案，同时用多个更短、更聚焦的索引提高召回概率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合检索比单路向量检索更稳。&lt;/strong&gt; 产品型号、错误码、人名等精确词更依赖全文检索；自然语言问题更依赖语义检索，RRF 用于融合排名。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;引用上限用 Token 而非只用 Top-K。&lt;/strong&gt; 因为不同分块长度差异很大，固定取 5 条可能有时太少、有时又塞爆上下文。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;MongoDB 保存向量之外的大部分业务数据；向量数据可以放在 PostgreSQL/PGVector、Milvus、OceanBase、SeekDB 等后端。使用 PGVector 时，官方文档说明向量 ID 会再关联回 MongoDB 中的原始数据，这也是为什么备份时不能只备向量库。&lt;/p&gt;
&lt;h3 id=&#34;工作流把-prompt-变成可观察的程序&#34;&gt;工作流：把 Prompt 变成可观察的程序
&lt;/h3&gt;&lt;p&gt;最简单的聊天应用只有“用户问题 → AI 对话”两个节点；真实业务往往还需要分类、查库、调用 HTTP 接口、条件判断、格式化和兜底。FastGPT 的节点很像函数：有输入、输出和触发关系，前一个节点的输出可以成为后一个节点的变量。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/workflow-example.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/workflow-example.svg&#34; alt=&#34;一个典型的客服工作流如何分流、检索与调用工具&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;官方工作流采用连接线状态推动执行：节点看到活跃前驱才执行，等待中的前驱会让它继续等待，没有可执行前驱则跳过。这个模型带来两个好处：一是分支与汇合能画出来，二是每次运行都可以检查节点输入输出，而不是只看到最后一段模型回答。&lt;/p&gt;
&lt;p&gt;实际项目中，我更建议把职责拆开：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点&lt;/th&gt;
&lt;th&gt;只负责什么&lt;/th&gt;
&lt;th&gt;不要塞进去什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;问题分类&lt;/td&gt;
&lt;td&gt;判断咨询、投诉、查询或闲聊&lt;/td&gt;
&lt;td&gt;大段业务回答&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query Rewrite&lt;/td&gt;
&lt;td&gt;补全指代，生成适合检索的完整问题&lt;/td&gt;
&lt;td&gt;修改订单号、型号等精确实体&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知识库搜索&lt;/td&gt;
&lt;td&gt;召回可引用资料&lt;/td&gt;
&lt;td&gt;直接替用户下结论&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP / 插件&lt;/td&gt;
&lt;td&gt;查询实时数据或执行动作&lt;/td&gt;
&lt;td&gt;隐藏不可审计的复杂规则&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI 对话&lt;/td&gt;
&lt;td&gt;综合上下文，按格式生成答案&lt;/td&gt;
&lt;td&gt;持久化关键业务状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;指定回复&lt;/td&gt;
&lt;td&gt;错误、拒答、转人工等确定性输出&lt;/td&gt;
&lt;td&gt;需要模型推理的开放问题&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;agent插件与发布&#34;&gt;Agent、插件与发布
&lt;/h3&gt;&lt;p&gt;工作流适合路径相对确定的流程；Agent 更适合让模型根据目标自行选择工具和步骤。插件把搜索、数据库、消息通知、文档处理等外部能力封装成可复用工具。两者并非互相替代：一个可靠的生产 Agent，通常仍会把高风险动作约束在结构清晰的工具与子流程中。&lt;/p&gt;
&lt;p&gt;应用完成后可以通过分享链接、嵌入页面、OpenAI 风格 API 或 MCP Server 暴露。API Key 现在是成员级 OpenAPI 凭据，调用 &lt;code&gt;chat/completions&lt;/code&gt; 时推荐在请求体中传 &lt;code&gt;appId&lt;/code&gt;；只支持传统 OpenAI Key 配置的客户端，可以使用官方提供的兼容格式。发布不等于安全：公开分享链接会消耗应用所属团队的额度，API Key 应配置过期时间与配额，写操作工具还应做二次授权。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;从零做一个员工制度助手&#34;&gt;从零做一个“员工制度助手”
&lt;/h2&gt;&lt;p&gt;下面用一个常见场景把整条链路串起来。目标不是让模型自由聊天，而是做到：答案基于公司制度、带来源、资料缺失时明确拒答，涉及个人数据时转到内部接口查询。&lt;/p&gt;
&lt;h3 id=&#34;1-先定义验收问题&#34;&gt;1. 先定义验收问题
&lt;/h3&gt;&lt;p&gt;不要先上传几百份文件。先写 20～50 个代表性问题，其中至少包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可直接命中的事实题：“试用期员工有几天年假？”&lt;/li&gt;
&lt;li&gt;需要跨段落理解的问题：“出差遇到周末，调休和报销分别怎么处理？”&lt;/li&gt;
&lt;li&gt;精确词问题：“OA-TRAVEL-017 表单在哪里？”&lt;/li&gt;
&lt;li&gt;多轮追问：“那海外出差呢？”&lt;/li&gt;
&lt;li&gt;应拒答的问题：“帮我查张三今年还剩多少年假。”&lt;/li&gt;
&lt;li&gt;资料中根本没有的问题，用来检查模型是否会编造。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这组题既是调参基线，也是后续升级模型、修改分块时的回归测试。没有固定测试集，所谓“感觉回答更好了”通常不可复现。&lt;/p&gt;
&lt;h3 id=&#34;2-整理与导入资料&#34;&gt;2. 整理与导入资料
&lt;/h3&gt;&lt;p&gt;优先处理文档质量，而不是立刻调相似度阈值：删除重复版本；保留标题层级；把扫描 PDF 做 OCR；给文件加版本、部门、生效日期等元数据；把已经失效的制度移出生产知识库。&lt;/p&gt;
&lt;p&gt;分块应保持“语义完整且主题单一”。一条规则的条件、例外和结论最好放在同一个块里；表格不要被机械切成互不相关的行。对于制度问答，可以为同一原文补充多种问题式索引，例如“年假有几天”“年假额度”“试用期能否休年假”，它们都指向同一段完整制度。&lt;/p&gt;
&lt;h3 id=&#34;3-先用最小工作流跑通&#34;&gt;3. 先用最小工作流跑通
&lt;/h3&gt;&lt;p&gt;初版只需要：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;用户问题
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  → Query Rewrite（仅多轮或指代不清时启用）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  → 知识库搜索（混合检索 + Rerank）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  → AI 对话（只依据引用回答）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  → 返回答案与来源
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;系统提示词可以从这个约束开始，而不是堆几十条“角色设定”：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;你是公司制度助手。只根据“引用资料”回答。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;资料不足时明确说“现有制度资料中没有找到答案”，不要自行补充。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;若问题涉及个人余额、审批状态或其他员工隐私，不要猜测，提示用户授权后查询内部系统。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;回答先给结论，再列适用条件；引用制度名称与生效日期。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果召回错误码和表单编号不稳定，先打开全文或混合检索；如果自然语言追问召回差，再启用 Query Rewrite；如果候选内容正确但顺序差，再检查 Rerank。一次只改一个变量并重跑测试集，否则你很难知道改进来自哪里。&lt;/p&gt;
&lt;h3 id=&#34;4-再增加实时接口分支&#34;&gt;4. 再增加实时接口分支
&lt;/h3&gt;&lt;p&gt;将“还剩多少年假”识别为个人数据查询，先检查登录身份与授权，再调用内部 HR API。制度解释仍走知识库，个人余额走实时系统。不要把每天变化的数据定期塞进向量库，也不要让 LLM 直接拼数据库 SQL。&lt;/p&gt;
&lt;h3 id=&#34;5-发布前做四类测试&#34;&gt;5. 发布前做四类测试
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;测试&lt;/th&gt;
&lt;th&gt;重点观察&lt;/th&gt;
&lt;th&gt;合格标准示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;检索测试&lt;/td&gt;
&lt;td&gt;目标片段是否进入候选、排名是否合理&lt;/td&gt;
&lt;td&gt;Top 候选包含正确制度，引用无过期版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生成测试&lt;/td&gt;
&lt;td&gt;是否忠于引用、是否正确拒答&lt;/td&gt;
&lt;td&gt;无资料时不补写；数字与原文一致&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;流程测试&lt;/td&gt;
&lt;td&gt;分支、变量、异常与超时&lt;/td&gt;
&lt;td&gt;API 失败进入兜底，不泄露内部错误&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;安全测试&lt;/td&gt;
&lt;td&gt;越权、Prompt 注入、密钥与隐私&lt;/td&gt;
&lt;td&gt;非授权用户无法调用个人查询工具&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;私有部署组件命令与生产注意事项&#34;&gt;私有部署：组件、命令与生产注意事项
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/deployment-architecture.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/fastgpt-guide/deployment-architecture.svg&#34; alt=&#34;FastGPT 私有部署的主要组件与数据流&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;官方 Docker Compose 架构至少包含 FastGPT 主服务、MongoDB、向量数据库和 AI Proxy。启用 Agent/Skill 沙箱、对象存储、MCP 或更复杂的解析能力后，还会出现额外服务。测试环境可以单机起步，生产环境则应把“能启动”和“可运营”分开看。&lt;/p&gt;
&lt;p&gt;官方当前提供交互式安装脚本，在 Linux、macOS 或 Windows WSL 中运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;FASTGPT_DEPLOY_BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://doc.fastgpt.cn &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  bash &amp;lt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;curl -fsSL https://doc.fastgpt.cn/deploy/install.sh&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose --profile prepull pull
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;脚本会选择向量数据库方案、下载 Compose 配置并生成随机凭据。生产环境执行远程脚本前，应先下载并审阅内容；保存生成后的 &lt;code&gt;docker-compose.yml&lt;/code&gt; 与凭据；把镜像标签固定到明确版本，不要长期依赖 &lt;code&gt;latest&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;部署后首先做三件事：配置对外访问的 &lt;code&gt;FE_DOMAIN&lt;/code&gt;；在管理后台配置聊天模型与 Embedding 模型；按需安装系统插件。主服务默认映射到 3000 端口，但生产环境应放在 HTTPS 反向代理之后，并只对外开放必要入口。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;生产检查项&lt;/th&gt;
&lt;th&gt;建议&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;数据持久化&lt;/td&gt;
&lt;td&gt;MongoDB、向量库、对象存储分别使用持久卷；验证恢复而不只是“做过备份”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;凭据&lt;/td&gt;
&lt;td&gt;替换默认密码；API Key、数据库密码和模型密钥进入 Secret 管理，不写入仓库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;网络&lt;/td&gt;
&lt;td&gt;数据库不暴露公网；限制容器出站范围；上传与抓取功能设置大小、类型和域名白名单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;升级&lt;/td&gt;
&lt;td&gt;阅读跨版本迁移说明，小步升级；先备份并在预发布环境回放核心测试集&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;观测&lt;/td&gt;
&lt;td&gt;记录节点耗时、模型错误、Token 消耗、检索命中与拒答率；为外部 API 设置超时和重试&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;容量&lt;/td&gt;
&lt;td&gt;关注向量条数、索引构建时间、MongoDB 容量、并发请求和模型限流，而不只看 CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;向量库选型不必一开始就追求最大规模。官方建议中，PGVector 方案更轻量，适合中小规模；达到非常大的向量规模或需要更强分布式能力时再评估 Milvus 等方案。迁移成本不仅是搬向量，还包括索引重建、停机窗口、性能回归与备份策略。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;api-接入与应用边界&#34;&gt;API 接入与应用边界
&lt;/h2&gt;&lt;p&gt;FastGPT 可以作为独立聊天页使用，也可以隐藏在你自己的 Web、企业微信、飞书或业务系统之后。OpenAI 风格接口降低了接入成本，但“兼容”不意味着每个扩展字段都完全等同于 OpenAI；应以当前实例的 OpenAPI 文档为准。&lt;/p&gt;
&lt;p&gt;一个便于理解的请求示例如下，实际 Key 和 App ID 从“发布渠道 → API”获得：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl https://fastgpt.example.com/api/v1/chat/completions &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: Bearer &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$FASTGPT_API_KEY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;appId&amp;#34;: &amp;#34;your-app-id&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;stream&amp;#34;: false,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;messages&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;      {&amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;试用期员工有几天年假？&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;  }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在应用架构里，建议把 FastGPT 当成“AI 决策与生成服务”，而不是主业务数据库：订单状态、余额、审批结果等事实仍由业务系统保存；FastGPT 通过只读或受控工具查询它们。涉及扣款、发送通知、删除数据等副作用操作时，要加入幂等键、权限校验、参数校验和人工确认，不能只相信模型生成的参数。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;适合谁也不适合谁&#34;&gt;适合谁，也不适合谁
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th style=&#34;text-align:center&#34;&gt;适配度&lt;/th&gt;
&lt;th&gt;原因&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;企业文档问答、客服知识助手&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;高&lt;/td&gt;
&lt;td&gt;知识库、引用、工作流、发布链路齐全&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内部流程助手、表单审核、内容处理&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;高&lt;/td&gt;
&lt;td&gt;可视化编排方便连接模型、规则和 HTTP 工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;快速交付多个垂直 AI 应用&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;高&lt;/td&gt;
&lt;td&gt;模型、知识库、插件和应用模板可复用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;纯聊天模型体验页&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;中&lt;/td&gt;
&lt;td&gt;能做，但如果没有知识与流程需求，平台可能偏重&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;超低延迟、高吞吐推理网关&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;低&lt;/td&gt;
&lt;td&gt;更适合由专门模型网关和推理服务承担&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;强事务、强一致性的核心业务流程&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;低&lt;/td&gt;
&lt;td&gt;LLM 与可视化编排不能替代事务系统和确定性服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;想直接运营同类多租户 SaaS&lt;/td&gt;
&lt;td style=&#34;text-align:center&#34;&gt;需谨慎&lt;/td&gt;
&lt;td&gt;许可证对同类多租户 SaaS 和品牌信息有额外条件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;与 Dify、Coze、Langflow、Flowise、LangChain/LlamaIndex 自研方案相比，FastGPT 的鲜明重心是 &lt;strong&gt;知识库问答 + 可视化工作流 + 私有部署交付&lt;/strong&gt;。平台类工具更快、更统一；代码框架则更自由、更容易做深度定制。正确选择通常不是问“谁功能最多”，而是问：团队最想省掉哪部分工程工作，又愿意承担哪部分平台约束。&lt;/p&gt;
&lt;p&gt;许可证尤其值得单独阅读。FastGPT 使用带附加条件的 FastGPT Open Source License：其文本以 Apache License 2.0 为基础，但对运营类似 FastGPT 的多租户 SaaS、移除或修改控制台 Logo 与版权信息等情形有额外要求。本文不是法律意见，商业化前应以仓库中的&lt;a class=&#34;link&#34; href=&#34;https://github.com/labring/FastGPT/blob/main/LICENSE&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;最新 LICENSE&lt;/a&gt;为准，必要时联系项目方取得授权。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;真正决定效果的是持续评估&#34;&gt;真正决定效果的，是持续评估
&lt;/h2&gt;&lt;p&gt;FastGPT 最有价值的地方，是让一条 AI 应用链路变得可搭建、可观察、可复用；它最容易被误用的地方，是让人以为拖完节点就等于完成系统。&lt;/p&gt;
&lt;p&gt;一个可长期运行的项目，至少应持续观察这些指标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;检索命中率&lt;/strong&gt;：正确资料是否进入候选，以及最终是否被引用；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;忠实度&lt;/strong&gt;：答案中的事实能否由引用支持；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任务成功率&lt;/strong&gt;：流程是否真正完成业务目标，而不是只生成了流畅文本；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拒答与转人工率&lt;/strong&gt;：过高说明覆盖不足，过低可能意味着模型在冒险回答；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P50 / P95 延迟&lt;/strong&gt;：拆到 Query Rewrite、检索、Rerank、模型和外部工具；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单次成功任务成本&lt;/strong&gt;：只看 Token 单价会忽略失败重试和无效调用；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;版本回归&lt;/strong&gt;：模型、Prompt、知识、工作流任一变化都应跑固定测试集。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只记住一句话：&lt;strong&gt;把 FastGPT 当成 AI 应用工程平台，而不是答案质量的替代品。&lt;/strong&gt; 先用最小流程证明价值，再用评测集迭代检索和 Prompt，最后才增加 Agent、插件与自动化动作。这样做出来的系统，通常比一开始就画满整张工作流画布更可靠。&lt;/p&gt;
&lt;p&gt;本文依据 2026 年 10 月可见的官方资料整理。FastGPT 更新较快，部署变量、版本依赖与接口字段请在实施前再次核对。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;官方资料：&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://github.com/labring/FastGPT&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub 仓库&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/guide/version/opensource/intro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;社区版说明&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/guide/build/workflow/intro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;工作流原理&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/guide/dataset/dataset_engine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;知识库检索&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/self-host/deploy/docker&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Docker Compose 部署&lt;/a&gt; · &lt;a class=&#34;link&#34; href=&#34;https://doc.fastgpt.io/en/guide/build/publish/openapi&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;API 发布&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>从关键字匹配到向量检索：搜索技术的三条路</title>
        <link>https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/</link>
        <pubDate>Fri, 02 Oct 2026 20:13:30 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/bg.svg" alt="Featured image of post 从关键字匹配到向量检索：搜索技术的三条路" /&gt;&lt;h1 id=&#34;从关键字匹配到向量检索搜索技术的三条路&#34;&gt;从关键字匹配到向量检索：搜索技术的三条路
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;搜索系统并不是只有一种做法。&lt;strong&gt;关键字匹配&lt;/strong&gt;擅长找“写出来的词”，&lt;strong&gt;模糊搜索&lt;/strong&gt;擅长救“写错或写不全的词”，&lt;strong&gt;向量检索&lt;/strong&gt;擅长找“意思接近的内容”。到了 RAG 场景，它们往往不是互相替代，而是组合成一条更稳的检索链路。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/bg.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/bg.svg&#34; alt=&#34;从关键字匹配到向量检索&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;先用一个例子定调：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;用户真正想问&lt;/th&gt;
&lt;th&gt;输入&lt;/th&gt;
&lt;th&gt;更适合的检索方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;查某条明确规则&lt;/td&gt;
&lt;td&gt;&lt;code&gt;退款政策&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;关键字匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;输入有拼写或错别字&lt;/td&gt;
&lt;td&gt;&lt;code&gt;退宽政策&lt;/code&gt; / &lt;code&gt;retun policy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模糊搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;说法很口语化&lt;/td&gt;
&lt;td&gt;&lt;code&gt;买了东西后还能不能反悔&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;向量检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;要既准又能理解语义&lt;/td&gt;
&lt;td&gt;&lt;code&gt;会员买错套餐怎么退款&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;混合检索 + 重排序&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/matching-spectrum.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/matching-spectrum.svg&#34; alt=&#34;三类检索的能力光谱&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id=&#34;关键字匹配找到字面上出现过的内容&#34;&gt;关键字匹配：找到“字面上出现过”的内容
&lt;/h2&gt;&lt;p&gt;关键字匹配是最经典的信息检索方式。它的核心思想很朴素：把文档切成词，建立索引，查询时看哪些文档包含这些词，再根据词频、字段权重、文档长度等因素排序。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/keyword-inverted-index.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/keyword-inverted-index.svg&#34; alt=&#34;关键字匹配与倒排索引&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;搜索引擎、数据库 &lt;code&gt;LIKE&lt;/code&gt; 查询、日志平台、站内搜索、文档系统都大量使用这种思路。工程上最常见的结构是&lt;strong&gt;倒排索引&lt;/strong&gt;：不是从文档找词，而是从词直接找到包含它的文档。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;匹配依据&lt;/td&gt;
&lt;td&gt;查询词和文档词项的字面重合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;常见算法&lt;/td&gt;
&lt;td&gt;TF-IDF、BM25、布尔查询、字段权重&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;优点&lt;/td&gt;
&lt;td&gt;快、稳定、可解释、容易加过滤条件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;缺点&lt;/td&gt;
&lt;td&gt;不懂同义词和上下文，用户换一种说法就可能搜不到&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适合&lt;/td&gt;
&lt;td&gt;商品 SKU、订单号、日志关键字、法规条款、代码符号、标题搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;例如用户搜索 &lt;code&gt;redis setnx&lt;/code&gt;，关键字检索非常合适，因为这个词本身就是准确术语；如果用户搜索 &lt;code&gt;如何防止重复下单&lt;/code&gt;，纯关键字系统就可能漏掉只写了 &lt;code&gt;幂等&lt;/code&gt;、&lt;code&gt;分布式锁&lt;/code&gt; 的文章。&lt;/p&gt;
&lt;h2 id=&#34;模糊搜索解决写错了也要搜到&#34;&gt;模糊搜索：解决“写错了也要搜到”
&lt;/h2&gt;&lt;p&gt;模糊搜索仍然是词面检索，只是比关键字匹配宽容一点。它关注的是：用户输入和真实词项&lt;strong&gt;长得像不像&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/fuzzy-search-flow.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/fuzzy-search-flow.svg&#34; alt=&#34;模糊搜索的候选生成与排序&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;常见手段包括：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;技术&lt;/th&gt;
&lt;th&gt;解决的问题&lt;/th&gt;
&lt;th&gt;例子&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;编辑距离&lt;/td&gt;
&lt;td&gt;少字、多字、错字、相邻字母颠倒&lt;/td&gt;
&lt;td&gt;&lt;code&gt;retun&lt;/code&gt; → &lt;code&gt;return&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n-gram / trigram&lt;/td&gt;
&lt;td&gt;子串相似、短文本近似匹配&lt;/td&gt;
&lt;td&gt;&lt;code&gt;microserv&lt;/code&gt; → &lt;code&gt;microservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;前缀匹配&lt;/td&gt;
&lt;td&gt;搜索建议、自动补全&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kuber&lt;/code&gt; → &lt;code&gt;kubernetes&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;拼音/同音纠错&lt;/td&gt;
&lt;td&gt;中文输入法误差&lt;/td&gt;
&lt;td&gt;&lt;code&gt;shiliangjiansuo&lt;/code&gt; → &lt;code&gt;向量检索&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同义词词典&lt;/td&gt;
&lt;td&gt;人工维护近义表达&lt;/td&gt;
&lt;td&gt;&lt;code&gt;售后&lt;/code&gt; ≈ &lt;code&gt;退货&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;它最适合搜索框体验：用户没有输入完整词、英文拼错、中文有错别字、商品名只记得一半。Elasticsearch、OpenSearch、Solr、PostgreSQL trigram、Algolia 这类系统里都有对应能力。&lt;/p&gt;
&lt;p&gt;但要注意，模糊搜索的本质不是“理解语义”。&lt;code&gt;退款&lt;/code&gt; 和 &lt;code&gt;退货&lt;/code&gt; 语义相关，但字面未必相似；&lt;code&gt;苹果手机&lt;/code&gt; 和 &lt;code&gt;iPhone&lt;/code&gt; 字面差异很大，靠编辑距离很难自然匹配。模糊搜索放宽召回后，还会带来误匹配，所以需要阈值、字段权重、热度、点击率等信号做排序。&lt;/p&gt;
&lt;h2 id=&#34;向量检索找到意思接近的内容&#34;&gt;向量检索：找到“意思接近”的内容
&lt;/h2&gt;&lt;p&gt;向量检索会先用 Embedding 模型把文本、图片、音频等内容转成一串数字。语义相近的内容，在向量空间里的距离也更近。查询时，系统把用户问题也转成向量，再找距离最近的内容。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/vector-rag-flow.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/vector-rag-flow.svg&#34; alt=&#34;向量检索与 RAG 流程&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;这就是很多 RAG 系统的检索底座：先从知识库中召回相关片段，再把片段塞进 Prompt，让大模型基于资料回答。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;匹配依据&lt;/td&gt;
&lt;td&gt;Embedding 空间里的语义相似度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;常见索引&lt;/td&gt;
&lt;td&gt;HNSW、IVF、PQ、DiskANN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;常见度量&lt;/td&gt;
&lt;td&gt;余弦相似度、内积、欧氏距离&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;优点&lt;/td&gt;
&lt;td&gt;能处理同义表达、口语化问题、跨语言/跨模态相似&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;缺点&lt;/td&gt;
&lt;td&gt;成本更高，可解释性弱，精确过滤和强约束不如传统检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适合&lt;/td&gt;
&lt;td&gt;知识库问答、相似文章、相似图片、推荐、智能客服、代码语义搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;比如文档里写的是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;用户在订单完成后的 7 天内，可申请无理由退货。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用户问：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;买完后不想要了还能退吗？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键字匹配可能只看到 &lt;code&gt;买完&lt;/code&gt;、&lt;code&gt;不想要&lt;/code&gt;，命中不稳定；向量检索更容易把它和 &lt;code&gt;退货&lt;/code&gt;、&lt;code&gt;订单完成后&lt;/code&gt;、&lt;code&gt;7 天内&lt;/code&gt; 这些语义相关片段拉近。&lt;/p&gt;
&lt;p&gt;向量检索也不是银弹。它对&lt;strong&gt;数字、版本号、专有名词、权限过滤、精确字段&lt;/strong&gt;并不天然可靠。问 &lt;code&gt;HTTP 451&lt;/code&gt;、&lt;code&gt;订单 202610020001&lt;/code&gt;、&lt;code&gt;Go 1.22&lt;/code&gt; 这类问题时，关键字和结构化过滤往往更可信。&lt;/p&gt;
&lt;h2 id=&#34;它们到底差在哪&#34;&gt;它们到底差在哪
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;关键字匹配&lt;/th&gt;
&lt;th&gt;模糊搜索&lt;/th&gt;
&lt;th&gt;向量检索&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;关注点&lt;/td&gt;
&lt;td&gt;词是否出现&lt;/td&gt;
&lt;td&gt;词是否相似&lt;/td&gt;
&lt;td&gt;意思是否接近&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用户输入&lt;/td&gt;
&lt;td&gt;明确、短、术语化&lt;/td&gt;
&lt;td&gt;有错字、缩写、前缀&lt;/td&gt;
&lt;td&gt;口语化、描述性、长问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;召回能力&lt;/td&gt;
&lt;td&gt;精确但可能漏&lt;/td&gt;
&lt;td&gt;比关键字更宽&lt;/td&gt;
&lt;td&gt;语义召回强&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;排序可解释性&lt;/td&gt;
&lt;td&gt;强&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;弱，需要额外解释&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;延迟与成本&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;中到高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;典型工具&lt;/td&gt;
&lt;td&gt;MySQL、Lucene、Elasticsearch BM25&lt;/td&gt;
&lt;td&gt;Elasticsearch fuzzy、trigram、Algolia&lt;/td&gt;
&lt;td&gt;FAISS、Milvus、Qdrant、Pinecone、Weaviate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;常见问题&lt;/td&gt;
&lt;td&gt;同义词搜不到&lt;/td&gt;
&lt;td&gt;误匹配变多&lt;/td&gt;
&lt;td&gt;召回噪声、Embedding 漂移、难调参&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以把它们理解成三层：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;关键字匹配：你说了 A，我找 A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;模糊搜索：你大概写的是 A，我帮你找 A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;向量检索：你说的是 A 的意思，我找和 A 意思接近的内容
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;经典应用&#34;&gt;经典应用
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;th&gt;为什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;日志检索&lt;/td&gt;
&lt;td&gt;关键字 + 时间/服务过滤&lt;/td&gt;
&lt;td&gt;错一个字符都可能代表不同错误码，精确性优先&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;电商搜索&lt;/td&gt;
&lt;td&gt;关键字 + 模糊搜索 + 向量召回&lt;/td&gt;
&lt;td&gt;商品名要准，用户输入也常常不完整，还需要语义推荐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码搜索&lt;/td&gt;
&lt;td&gt;符号索引 + 关键字 + 语义向量&lt;/td&gt;
&lt;td&gt;函数名要精确，需求描述又可能很口语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;企业知识库问答&lt;/td&gt;
&lt;td&gt;向量检索 + BM25 + 重排序 + RAG&lt;/td&gt;
&lt;td&gt;需要理解问题、召回资料、生成答案并引用来源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图片以图搜图&lt;/td&gt;
&lt;td&gt;向量检索&lt;/td&gt;
&lt;td&gt;图像相似度很难靠关键字解决&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;站内帮助中心&lt;/td&gt;
&lt;td&gt;关键字 + 模糊 + 同义词 + 向量&lt;/td&gt;
&lt;td&gt;用户可能输入术语，也可能输入自然语言问题&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最典型的例子是企业知识库 RAG。用户不会严格复述文档标题，而是问“这笔报销为什么被驳回”“试用期请病假怎么算”“客户要求删数据怎么办”。系统通常会先做权限过滤，再用 BM25 和向量各召回一批候选，最后重排序，选少量片段交给大模型回答。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/hybrid-ranking.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/hybrid-ranking.svg&#34; alt=&#34;混合检索流水线&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id=&#34;实战选型不要急着三选一&#34;&gt;实战选型：不要急着三选一
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/decision-map.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/search-matching-retrieval/decision-map.svg&#34; alt=&#34;搜索技术选型速查图&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;一个实用的判断方式：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;你遇到的问题&lt;/th&gt;
&lt;th&gt;优先考虑&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;用户会输入订单号、错误码、函数名、固定术语&lt;/td&gt;
&lt;td&gt;关键字匹配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用户经常拼错、少打、只输入前几个字&lt;/td&gt;
&lt;td&gt;模糊搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用户用自然语言描述需求，文档表达方式又不固定&lt;/td&gt;
&lt;td&gt;向量检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;既要精确过滤，又要语义理解，还要给 LLM 喂资料&lt;/td&gt;
&lt;td&gt;混合检索&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;生产系统里更常见的是组合拳：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;结构化过滤&lt;/strong&gt;：先按权限、租户、时间、类目过滤，避免召回不该看的内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键字召回&lt;/strong&gt;：用 BM25 保住精确术语、标题、编号、实体名。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量召回&lt;/strong&gt;：补足同义表达、口语化问题和长文本语义。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;融合排序&lt;/strong&gt;：用 RRF 或加权分数合并两路候选。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重排序&lt;/strong&gt;：用 cross-encoder、LLM reranker 或业务规则做精排。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成回答&lt;/strong&gt;：RAG 场景只把最相关、最可信、来源清楚的片段交给 LLM。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;一个容易记住的结论&#34;&gt;一个容易记住的结论
&lt;/h2&gt;&lt;p&gt;关键字匹配解决的是&lt;strong&gt;有没有这个词&lt;/strong&gt;，模糊搜索解决的是&lt;strong&gt;这个词是不是写歪了&lt;/strong&gt;，向量检索解决的是&lt;strong&gt;这句话大概在说什么&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你在做一个普通搜索框，先把关键字、分词、字段权重和模糊纠错做好；如果你在做知识库问答或智能客服，再引入向量检索和 RAG；如果你在做面向真实用户的生产系统，最终大概率会走向混合检索。因为用户既会输入精确编号，也会说一大段含糊的话，而好的搜索系统要同时接得住这两种输入。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>向量数据库与传统数据库</title>
        <link>https://SymphonyW.github.io/zh-cn/p/%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E4%BC%A0%E7%BB%9F%E6%95%B0%E6%8D%AE%E5%BA%93/</link>
        <pubDate>Mon, 13 Jul 2026 21:24:23 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E4%BC%A0%E7%BB%9F%E6%95%B0%E6%8D%AE%E5%BA%93/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E4%BC%A0%E7%BB%9F%E6%95%B0%E6%8D%AE%E5%BA%93/bg.png" alt="Featured image of post 向量数据库与传统数据库" /&gt;&lt;h1 id=&#34;向量数据库与传统数据库从精确查询到语义检索&#34;&gt;向量数据库与传统数据库：从精确查询到语义检索
&lt;/h1&gt;&lt;p&gt;在传统的软件系统中，数据库主要负责存储用户、订单、商品、日志等结构化数据。当我们需要查询某个用户时，通常会使用用户 ID、手机号或者用户名作为条件。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;users&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;zhangsan&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这种查询的特点是：&lt;strong&gt;查询条件明确，数据库需要找到精确匹配的数据。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但是在人工智能应用中，我们可能会遇到另一类问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;找出与这段文字含义最接近的文章。&lt;/li&gt;
&lt;li&gt;找到与当前商品风格相似的商品。&lt;/li&gt;
&lt;li&gt;根据一张图片搜索视觉上相似的图片。&lt;/li&gt;
&lt;li&gt;从知识库中找到能够回答用户问题的内容。&lt;/li&gt;
&lt;li&gt;判断两段代码是否实现了相似的功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题很难仅通过 &lt;code&gt;=&lt;/code&gt;、&lt;code&gt;LIKE&lt;/code&gt; 或普通关键字查询解决。&lt;/p&gt;
&lt;p&gt;向量数据库正是为了解决这类“相似性检索”问题而出现的。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[传统数据库] --&gt; B[精确匹配]
    A --&gt; C[范围查询]
    A --&gt; D[事务处理]

    E[向量数据库] --&gt; F[语义相似度搜索]
    E --&gt; G[图片相似度搜索]
    E --&gt; H[多模态检索]
&lt;/div&gt;&lt;h2 id=&#34;什么是传统数据库&#34;&gt;什么是传统数据库
&lt;/h2&gt;&lt;p&gt;传统数据库通常指关系型数据库，以及部分通用型 NoSQL 数据库，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Oracle&lt;/li&gt;
&lt;li&gt;SQL Server&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关系型数据库将数据组织成表，每张表由行和列构成。&lt;/p&gt;
&lt;p&gt;例如，一个商品表可能是：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:right&#34;&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;category&lt;/th&gt;
&lt;th style=&#34;text-align:right&#34;&gt;price&lt;/th&gt;
&lt;th style=&#34;text-align:right&#34;&gt;stock&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:right&#34;&gt;1001&lt;/td&gt;
&lt;td&gt;机械键盘&lt;/td&gt;
&lt;td&gt;外设&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;399&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:right&#34;&gt;1002&lt;/td&gt;
&lt;td&gt;无线鼠标&lt;/td&gt;
&lt;td&gt;外设&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;199&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:right&#34;&gt;1003&lt;/td&gt;
&lt;td&gt;显示器&lt;/td&gt;
&lt;td&gt;显示设备&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;1599&lt;/td&gt;
&lt;td style=&#34;text-align:right&#34;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我们可以按照字段进行精确查询：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;products&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;外设&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;传统数据库擅长处理以下任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根据主键查询数据。&lt;/li&gt;
&lt;li&gt;根据字段进行过滤和排序。&lt;/li&gt;
&lt;li&gt;执行增删改查操作。&lt;/li&gt;
&lt;li&gt;保证事务一致性。&lt;/li&gt;
&lt;li&gt;维护实体之间的关联关系。&lt;/li&gt;
&lt;li&gt;进行统计、聚合和报表分析。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，在电商系统中，订单创建通常涉及库存扣减、订单写入和支付记录生成。这些操作必须满足事务要求。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;sequenceDiagram
    participant U as 用户
    participant O as 订单服务
    participant DB as 传统数据库

    U-&gt;&gt;O: 创建订单
    O-&gt;&gt;DB: 开启事务
    O-&gt;&gt;DB: 扣减库存
    O-&gt;&gt;DB: 创建订单
    O-&gt;&gt;DB: 写入支付记录
    DB--&gt;&gt;O: 提交事务
    O--&gt;&gt;U: 订单创建成功
&lt;/div&gt;&lt;p&gt;传统数据库关注的是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;数据是否准确、关系是否完整、事务是否可靠。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;什么是向量&#34;&gt;什么是向量
&lt;/h2&gt;&lt;p&gt;要理解向量数据库，首先需要理解向量。&lt;/p&gt;
&lt;p&gt;在人工智能系统中，文本、图片、音频和视频可以通过模型转换成一组数字。这组数字称为向量，也常被称为 Embedding。&lt;/p&gt;
&lt;p&gt;例如，下面三句话：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;我喜欢骑自行车旅行。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;周末我经常骑车去郊外。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;数据库出现了连接超时。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;经过 Embedding 模型处理后，可能会被转换为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;我喜欢骑自行车旅行。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ [0.12, -0.31, 0.85, 0.47, ...]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;周末我经常骑车去郊外。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ [0.15, -0.28, 0.81, 0.51, ...]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;数据库出现了连接超时。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ [-0.62, 0.73, 0.05, -0.16, ...]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;前两句话的含义比较接近，因此它们对应的向量在向量空间中的距离也会更近。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;quadrantChart
    title 文本在向量空间中的示意分布
    x-axis 低运动相关度 --&gt; 高运动相关度
    y-axis 低旅行相关度 --&gt; 高旅行相关度
    quadrant-1 骑行与旅行
    quadrant-2 旅行主题
    quadrant-3 技术主题
    quadrant-4 运动主题
    &#34;骑自行车去郊外旅行&#34;: [0.88, 0.86]
    &#34;周末骑车锻炼&#34;: [0.82, 0.55]
    &#34;计划去北欧旅行&#34;: [0.45, 0.91]
    &#34;数据库连接超时&#34;: [0.12, 0.16]
&lt;/div&gt;&lt;p&gt;这里的坐标只是示意。真实的 Embedding 向量往往包含几百甚至几千个维度，人类无法直接观察这些高维空间。&lt;/p&gt;
&lt;p&gt;Embedding 的核心作用，是将原始数据的“语义特征”编码为数值。&lt;/p&gt;
&lt;h2 id=&#34;什么是向量数据库&#34;&gt;什么是向量数据库
&lt;/h2&gt;&lt;p&gt;向量数据库是一类专门用于存储、索引和查询高维向量的数据系统。&lt;/p&gt;
&lt;p&gt;一条向量数据通常不只有向量本身，还会包含原始内容和元数据。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;article-1001&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;vector&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;-0.31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.85&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.47&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;metadata&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;如何搭建企业内部 SkillHub&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;category&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AI 工程&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Xinzhan Wu&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;本文介绍基于 npm Registry 构建企业内部 SkillHub 的方案。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;向量数据库可以回答这样的问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;哪些数据的向量与当前查询向量最接近？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它的基本工作流程如下。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[用户输入问题] --&gt; B[Embedding 模型]
    B --&gt; C[查询向量]
    C --&gt; D[向量数据库]
    D --&gt; E[相似度搜索]
    E --&gt; F[返回 Top-K 结果]
&lt;/div&gt;&lt;p&gt;例如，用户输入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;企业内部应该如何管理 AI Skill？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;即使知识库中没有完全相同的句子，向量数据库仍然可能找到以下内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;基于 npm Registry 构建企业内部 SkillHub
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;原因是两段文本在语义上比较接近。&lt;/p&gt;
&lt;p&gt;传统关键字搜索关注“是否出现相同的词”，而向量搜索关注“表达的含义是否接近”。&lt;/p&gt;
&lt;h2 id=&#34;向量数据库与传统数据库的核心区别&#34;&gt;向量数据库与传统数据库的核心区别
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;对比维度&lt;/th&gt;
&lt;th&gt;传统数据库&lt;/th&gt;
&lt;th&gt;向量数据库&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;主要数据&lt;/td&gt;
&lt;td&gt;字符串、数字、日期、JSON&lt;/td&gt;
&lt;td&gt;高维浮点向量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;典型查询&lt;/td&gt;
&lt;td&gt;精确匹配、范围查询、关联查询&lt;/td&gt;
&lt;td&gt;相似度查询、Top-K 查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询条件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id = 1&lt;/code&gt;、&lt;code&gt;price &amp;lt; 100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;与查询向量最相似&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;索引结构&lt;/td&gt;
&lt;td&gt;B+ 树、哈希索引、倒排索引&lt;/td&gt;
&lt;td&gt;HNSW、IVF、PQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;核心目标&lt;/td&gt;
&lt;td&gt;准确性与事务一致性&lt;/td&gt;
&lt;td&gt;检索速度与召回率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;典型场景&lt;/td&gt;
&lt;td&gt;订单、用户、支付、库存&lt;/td&gt;
&lt;td&gt;RAG、推荐、图片搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;结果特点&lt;/td&gt;
&lt;td&gt;条件满足或不满足&lt;/td&gt;
&lt;td&gt;按相似程度排序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;常用指标&lt;/td&gt;
&lt;td&gt;QPS、延迟、事务成功率&lt;/td&gt;
&lt;td&gt;Recall、Top-K、查询延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是否擅长事务&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;通常不是核心能力&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是否支持语义搜索&lt;/td&gt;
&lt;td&gt;通常不直接支持&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;两者最根本的区别在于查询方式。&lt;/p&gt;
&lt;p&gt;传统数据库查询的是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;哪些数据满足确定的条件？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;向量数据库查询的是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;哪些数据与当前内容最相似？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;精确查询与相似度查询&#34;&gt;精确查询与相似度查询
&lt;/h2&gt;&lt;p&gt;假设数据库中有以下三篇文章：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;文章 A：使用 Go 开发高并发后端服务
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;文章 B：Golang 服务端性能优化方法
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;文章 C：React 前端组件设计实践
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用户搜索：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;如何提高 Go 后端程序的性能？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用传统关键字匹配时，“Golang”和“Go”可能被认为是两个不同的词，“后端程序”和“服务端”也不完全相同。&lt;/p&gt;
&lt;p&gt;使用向量搜索时，文章 A 和文章 B 的向量通常都会与查询向量比较接近。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    Q[如何提高 Go 后端程序的性能] --&gt; E[生成查询向量]

    E --&gt; A[文章 A 向量&lt;br/&gt;相似度 0.89]
    E --&gt; B[文章 B 向量&lt;br/&gt;相似度 0.93]
    E --&gt; C[文章 C 向量&lt;br/&gt;相似度 0.32]

    B --&gt; R1[Top 1]
    A --&gt; R2[Top 2]
&lt;/div&gt;&lt;p&gt;向量数据库最终会按照相似度排序，返回最接近的若干条数据。&lt;/p&gt;
&lt;h2 id=&#34;向量相似度如何计算&#34;&gt;向量相似度如何计算
&lt;/h2&gt;&lt;p&gt;常见的向量相似度计算方式包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;余弦相似度。&lt;/li&gt;
&lt;li&gt;欧氏距离。&lt;/li&gt;
&lt;li&gt;点积。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;余弦相似度&#34;&gt;余弦相似度
&lt;/h3&gt;&lt;p&gt;余弦相似度关注两个向量方向之间的夹角。&lt;/p&gt;
&lt;p&gt;其计算公式为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cos(A, B) = (A · B) / (||A|| × ||B||)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;余弦相似度越接近 &lt;code&gt;1&lt;/code&gt;，通常表示两个向量越相似。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cosine_similarity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;计算两个向量的余弦相似度。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;linalg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;norm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;linalg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;norm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 避免零向量导致除零错误&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;similarity&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cosine_similarity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;相似度：&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;similarity&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.4f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果数据规模很小，可以逐个计算向量距离。&lt;/p&gt;
&lt;p&gt;但如果数据库中存在数百万甚至数十亿条向量，逐条计算的成本会非常高，因此需要使用专门的向量索引。&lt;/p&gt;
&lt;h2 id=&#34;为什么不能直接遍历所有向量&#34;&gt;为什么不能直接遍历所有向量
&lt;/h2&gt;&lt;p&gt;假设数据库中有 1000 万条向量，每条向量有 1536 个维度。&lt;/p&gt;
&lt;p&gt;用户每查询一次，都需要将查询向量与 1000 万条向量分别计算距离。&lt;/p&gt;
&lt;p&gt;粗略计算量为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1000 万 × 1536 次浮点运算
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这种方式被称为暴力搜索或精确搜索。&lt;/p&gt;
&lt;p&gt;精确搜索能够得到绝对准确的结果，但随着数据规模增长，查询延迟会迅速增加。&lt;/p&gt;
&lt;p&gt;因此，大多数向量数据库使用近似最近邻搜索：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Approximate Nearest Neighbor，ANN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ANN 不一定遍历所有向量，而是借助索引快速缩小搜索范围。&lt;/p&gt;
&lt;p&gt;它牺牲少量准确率，换取显著的性能提升。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[查询向量] --&gt; B{搜索方式}

    B --&gt; C[暴力搜索]
    C --&gt; D[遍历全部向量]
    D --&gt; E[结果准确&lt;br/&gt;速度较慢]

    B --&gt; F[ANN 搜索]
    F --&gt; G[通过索引筛选候选集]
    G --&gt; H[结果近似&lt;br/&gt;速度较快]
&lt;/div&gt;&lt;h2 id=&#34;常见的向量索引&#34;&gt;常见的向量索引
&lt;/h2&gt;&lt;h3 id=&#34;hnsw&#34;&gt;HNSW
&lt;/h3&gt;&lt;p&gt;HNSW 的全称是 Hierarchical Navigable Small World，即分层可导航小世界图。&lt;/p&gt;
&lt;p&gt;它会将向量组织成多层图结构。&lt;/p&gt;
&lt;p&gt;查询时先在较高层快速确定大致方向，再逐层向下寻找更接近的向量。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    subgraph L3[第三层：稀疏节点]
        A1((A)) --- A2((B))
    end

    subgraph L2[第二层：中等密度]
        B1((A)) --- B2((C))
        B2 --- B3((B))
    end

    subgraph L1[第一层：高密度节点]
        C1((A)) --- C2((D))
        C2 --- C3((C))
        C3 --- C4((E))
        C4 --- C5((B))
    end

    A1 -.向下搜索.-&gt; B1
    A2 -.向下搜索.-&gt; B3
    B2 -.向下搜索.-&gt; C3
&lt;/div&gt;&lt;p&gt;HNSW 通常具有较高的召回率和较低的查询延迟，但需要占用较多内存。&lt;/p&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中低延迟在线检索。&lt;/li&gt;
&lt;li&gt;RAG 知识库。&lt;/li&gt;
&lt;li&gt;实时推荐系统。&lt;/li&gt;
&lt;li&gt;数据规模在内存可承受范围内的系统。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ivf&#34;&gt;IVF
&lt;/h3&gt;&lt;p&gt;IVF 的全称是 Inverted File Index，即倒排文件索引。&lt;/p&gt;
&lt;p&gt;它会先通过聚类将向量划分到不同的中心区域。查询时只搜索与查询向量最接近的几个聚类，而不是遍历所有向量。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    Q[查询向量] --&gt; C{选择最近的聚类}

    C --&gt; C1[聚类 1]
    C --&gt; C2[聚类 2]
    C --&gt; C3[聚类 3]
    C --&gt; C4[聚类 4]

    C2 --&gt; S1[搜索聚类 2 内的向量]
    C3 --&gt; S2[搜索聚类 3 内的向量]

    S1 --&gt; R[合并并返回 Top-K]
    S2 --&gt; R
&lt;/div&gt;&lt;p&gt;IVF 可以通过调整搜索的聚类数量，在查询速度和召回率之间进行权衡。&lt;/p&gt;
&lt;h3 id=&#34;pq&#34;&gt;PQ
&lt;/h3&gt;&lt;p&gt;PQ 的全称是 Product Quantization，即乘积量化。&lt;/p&gt;
&lt;p&gt;它会将高维向量切分为多个子向量，再对每个子向量进行量化编码。&lt;/p&gt;
&lt;p&gt;原本需要使用大量浮点数保存的向量，可以被压缩为较短的编码。&lt;/p&gt;
&lt;p&gt;PQ 的优势是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;降低向量存储空间。&lt;/li&gt;
&lt;li&gt;减少内存占用。&lt;/li&gt;
&lt;li&gt;加快距离计算。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;代价是量化过程可能造成一定精度损失。&lt;/p&gt;
&lt;h2 id=&#34;向量数据库的基本数据模型&#34;&gt;向量数据库的基本数据模型
&lt;/h2&gt;&lt;p&gt;向量数据库中的一条记录通常包含三部分。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[向量记录] --&gt; B[唯一标识 ID]
    A --&gt; C[Embedding 向量]
    A --&gt; D[Metadata 元数据]

    D --&gt; E[类别]
    D --&gt; F[时间]
    D --&gt; G[作者]
    D --&gt; H[权限]
&lt;/div&gt;&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;doc-001&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;vector&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.21&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;-0.37&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.66&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.19&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;metadata&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;department&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;研发部&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;document_type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;技术文档&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;visibility&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;internal&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2026-07-13&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;元数据非常重要。&lt;/p&gt;
&lt;p&gt;在真实系统中，通常不能只进行向量搜索，还需要添加过滤条件。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;找出与用户问题最相关的文档，
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;并且文档所属部门必须是研发部，
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;文档权限必须是 internal。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对应的逻辑类似于：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_database&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;department&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;研发部&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;visibility&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;internal&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这种方式称为带元数据过滤的向量检索。&lt;/p&gt;
&lt;h2 id=&#34;向量数据库如何应用于-rag&#34;&gt;向量数据库如何应用于 RAG
&lt;/h2&gt;&lt;p&gt;RAG 的全称是 Retrieval-Augmented Generation，即检索增强生成。&lt;/p&gt;
&lt;p&gt;它的核心思想是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在大语言模型生成答案之前，先从知识库中检索相关资料，再将资料交给模型生成答案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;完整流程如下。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    A[企业文档] --&gt; B[文档切分]
    B --&gt; C[Embedding 模型]
    C --&gt; D[生成文本向量]
    D --&gt; E[写入向量数据库]

    U[用户提问] --&gt; F[生成查询向量]
    F --&gt; G[向量相似度搜索]
    E --&gt; G

    G --&gt; H[返回 Top-K 文档片段]
    H --&gt; I[构造 Prompt]
    U --&gt; I

    I --&gt; J[大语言模型]
    J --&gt; K[生成最终答案]
&lt;/div&gt;&lt;p&gt;假设企业知识库中存在如下内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Skill 包发布前需要完成安全扫描、版本检查和元数据校验。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用户提问：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;内部 Skill 发布之前需要检查什么？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;系统会先将问题转换成向量，再从向量数据库中找到相关文档片段，最后让大语言模型根据检索结果回答。&lt;/p&gt;
&lt;p&gt;向量数据库在 RAG 中主要承担以下职责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存储文档向量。&lt;/li&gt;
&lt;li&gt;根据用户问题进行语义检索。&lt;/li&gt;
&lt;li&gt;返回最相关的上下文。&lt;/li&gt;
&lt;li&gt;支持权限、部门、时间等元数据过滤。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要注意的是，向量数据库本身不会生成答案，它只负责检索相关内容。&lt;/p&gt;
&lt;h2 id=&#34;向量数据库不能替代传统数据库&#34;&gt;向量数据库不能替代传统数据库
&lt;/h2&gt;&lt;p&gt;向量数据库与传统数据库并不是替代关系。&lt;/p&gt;
&lt;p&gt;例如，一个 AI 知识库系统可能同时使用：&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[应用服务] --&gt; B[PostgreSQL]
    A --&gt; C[向量数据库]
    A --&gt; D[对象存储]

    B --&gt; E[用户信息]
    B --&gt; F[文档元数据]
    B --&gt; G[权限与任务状态]

    C --&gt; H[文本向量]
    C --&gt; I[语义检索索引]

    D --&gt; J[PDF 原文件]
    D --&gt; K[图片与附件]
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL 保存用户、权限、任务和业务状态。&lt;/li&gt;
&lt;li&gt;向量数据库保存 Embedding 和向量索引。&lt;/li&gt;
&lt;li&gt;对象存储保存 PDF、Word、图片等原始文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当用户上传一份文档时，系统可能执行以下操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将原始文件上传到对象存储。&lt;/li&gt;
&lt;li&gt;在传统数据库中记录文档名称、上传者和权限。&lt;/li&gt;
&lt;li&gt;对文档进行解析和分块。&lt;/li&gt;
&lt;li&gt;调用 Embedding 模型生成向量。&lt;/li&gt;
&lt;li&gt;将文本片段和向量写入向量数据库。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;传统数据库负责业务事实，向量数据库负责语义检索。&lt;/p&gt;
&lt;h2 id=&#34;关键字搜索与向量搜索&#34;&gt;关键字搜索与向量搜索
&lt;/h2&gt;&lt;p&gt;传统全文搜索通常基于倒排索引。&lt;/p&gt;
&lt;p&gt;例如，用户搜索：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Go 高并发开发
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;系统会查找包含“Go”“高并发”“开发”等关键词的文档。&lt;/p&gt;
&lt;p&gt;关键字搜索的优点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对专有名词、代码、型号和编号比较准确。&lt;/li&gt;
&lt;li&gt;搜索结果容易解释。&lt;/li&gt;
&lt;li&gt;对完全匹配的关键词非常敏感。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;向量搜索的优点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以理解近义词。&lt;/li&gt;
&lt;li&gt;可以处理不同表达方式。&lt;/li&gt;
&lt;li&gt;能够按照语义相关程度排序。&lt;/li&gt;
&lt;li&gt;更适合自然语言问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两者也各有缺点。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;搜索方式&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;关键字搜索&lt;/td&gt;
&lt;td&gt;精确、可解释、适合专有名词&lt;/td&gt;
&lt;td&gt;难以理解语义和近义表达&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向量搜索&lt;/td&gt;
&lt;td&gt;支持语义检索、表达方式更灵活&lt;/td&gt;
&lt;td&gt;可能忽略关键字的精确性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;混合搜索&lt;/td&gt;
&lt;td&gt;同时利用关键词和语义&lt;/td&gt;
&lt;td&gt;架构和排序逻辑更复杂&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;混合检索&#34;&gt;混合检索
&lt;/h2&gt;&lt;p&gt;在实际的 RAG 系统中，单纯使用向量搜索并不总能获得最佳效果。&lt;/p&gt;
&lt;p&gt;例如，用户搜索：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;错误码 YN0031 是什么意思？
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里的 &lt;code&gt;YN0031&lt;/code&gt; 是一个精确错误码。&lt;/p&gt;
&lt;p&gt;向量搜索可能认为它与 Yarn、依赖安装、Node.js 等内容相关，但关键字搜索可以直接找到包含 &lt;code&gt;YN0031&lt;/code&gt; 的文档。&lt;/p&gt;
&lt;p&gt;因此，许多系统会同时执行：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关键字检索。&lt;/li&gt;
&lt;li&gt;向量检索。&lt;/li&gt;
&lt;li&gt;结果重排。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    Q[用户查询] --&gt; K[关键字检索]
    Q --&gt; V[向量检索]

    K --&gt; R[结果融合]
    V --&gt; R

    R --&gt; RR[重排序模型]
    RR --&gt; T[最终 Top-K 结果]
&lt;/div&gt;&lt;p&gt;这种方式称为混合检索。&lt;/p&gt;
&lt;p&gt;一种简单的混合评分公式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;最终得分 = α × 向量相似度 + β × 关键字匹配得分
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;α + β = 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对于自然语言问题，可以提高向量相似度的权重。&lt;/p&gt;
&lt;p&gt;对于错误码、产品型号、文件名和函数名，可以提高关键字匹配的权重。&lt;/p&gt;
&lt;h2 id=&#34;向量搜索的-top-k&#34;&gt;向量搜索的 Top-K
&lt;/h2&gt;&lt;p&gt;向量数据库通常通过 &lt;code&gt;Top-K&lt;/code&gt; 参数控制返回结果数量。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_database&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;表示返回与查询向量最相似的 5 条数据。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Top-K&lt;/code&gt; 并不是越大越好。&lt;/p&gt;
&lt;p&gt;Top-K 太小可能漏掉重要信息，Top-K 太大则可能引入无关内容，并增加大语言模型的上下文长度。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[Top-K 太小] --&gt; B[可能遗漏相关文档]
    C[适中的 Top-K] --&gt; D[相关性和上下文长度平衡]
    E[Top-K 太大] --&gt; F[噪声增多、Token 消耗增加]
&lt;/div&gt;&lt;p&gt;实际项目中通常需要结合以下因素调节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文档分块大小。&lt;/li&gt;
&lt;li&gt;Embedding 模型效果。&lt;/li&gt;
&lt;li&gt;用户问题长度。&lt;/li&gt;
&lt;li&gt;大语言模型上下文窗口。&lt;/li&gt;
&lt;li&gt;是否使用重排序模型。&lt;/li&gt;
&lt;li&gt;数据库检索召回率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;文档为什么需要分块&#34;&gt;文档为什么需要分块
&lt;/h2&gt;&lt;p&gt;大多数情况下，不会直接将整篇文档转换成一个向量。&lt;/p&gt;
&lt;p&gt;假设一篇文档包含 10000 字，同时讨论安装、配置、权限和故障排查。将整篇文章生成一个向量，会导致不同主题被压缩到同一个表示中。&lt;/p&gt;
&lt;p&gt;因此，通常需要先对文档进行分块。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[完整文档] --&gt; B[分块 1&lt;br/&gt;系统介绍]
    A --&gt; C[分块 2&lt;br/&gt;安装步骤]
    A --&gt; D[分块 3&lt;br/&gt;配置说明]
    A --&gt; E[分块 4&lt;br/&gt;故障排查]

    B --&gt; F[向量 1]
    C --&gt; G[向量 2]
    D --&gt; H[向量 3]
    E --&gt; I[向量 4]
&lt;/div&gt;&lt;p&gt;分块后，用户询问安装问题时，系统可以直接检索“安装步骤”对应的片段，而不是返回整篇文档。&lt;/p&gt;
&lt;p&gt;常见分块策略包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;固定字符数分块。&lt;/li&gt;
&lt;li&gt;固定 Token 数分块。&lt;/li&gt;
&lt;li&gt;按段落分块。&lt;/li&gt;
&lt;li&gt;按 Markdown 标题分块。&lt;/li&gt;
&lt;li&gt;按语义边界分块。&lt;/li&gt;
&lt;li&gt;滑动窗口分块。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分块大小需要根据文档类型进行调整。&lt;/p&gt;
&lt;p&gt;代码文档更适合按照类、函数或模块边界分块；普通文章可以按照标题和段落分块。&lt;/p&gt;
&lt;h2 id=&#34;一个简单的向量检索示例&#34;&gt;一个简单的向量检索示例
&lt;/h2&gt;&lt;p&gt;下面使用 Python 模拟一个最简单的向量搜索过程。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;71
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;dataclasses&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataclass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@dataclass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;知识库文档。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;document_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cosine_similarity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;计算余弦相似度。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;linalg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;norm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;linalg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;norm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector_a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vector_b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;denominator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;search_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;按照相似度返回 Top-K 文档。&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scored_documents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cosine_similarity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;document&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 按照相似度从高到低排序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scored_documents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scored_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;top_k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;document_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;doc-1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;使用 Go 构建高并发后端服务&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;document_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;doc-2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;React 组件状态管理实践&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;document_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;doc-3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Golang 服务端性能优化&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.85&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.65&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;search_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query_vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;top_k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;document_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;score&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.4f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个示例本质上仍然是暴力搜索。&lt;/p&gt;
&lt;p&gt;真实的向量数据库会使用 HNSW、IVF 等索引结构，并处理数据持久化、并发查询、分片、过滤和容错等问题。&lt;/p&gt;
&lt;h2 id=&#34;向量数据库的典型应用场景&#34;&gt;向量数据库的典型应用场景
&lt;/h2&gt;&lt;h3 id=&#34;rag-知识库&#34;&gt;RAG 知识库
&lt;/h3&gt;&lt;p&gt;将企业文档、产品手册和技术资料转换为向量，让大语言模型根据内部知识回答问题。&lt;/p&gt;
&lt;h3 id=&#34;语义搜索&#34;&gt;语义搜索
&lt;/h3&gt;&lt;p&gt;用户不需要输入完全一致的关键词，只需要描述自己的意图，系统就能找到相关内容。&lt;/p&gt;
&lt;h3 id=&#34;推荐系统&#34;&gt;推荐系统
&lt;/h3&gt;&lt;p&gt;将用户、商品或内容表示为向量，根据向量之间的距离生成推荐结果。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    A[用户行为] --&gt; B[用户向量]
    C[商品信息] --&gt; D[商品向量]

    B --&gt; E[相似度计算]
    D --&gt; E

    E --&gt; F[推荐商品列表]
&lt;/div&gt;&lt;h3 id=&#34;图片搜索&#34;&gt;图片搜索
&lt;/h3&gt;&lt;p&gt;通过图像模型将图片转换成向量，实现以图搜图。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上传一张鞋子的图片，搜索外观相似的商品。&lt;/li&gt;
&lt;li&gt;上传一张人脸图片，搜索相似人物。&lt;/li&gt;
&lt;li&gt;上传一张风景图片，查找相似的摄影作品。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;多模态检索&#34;&gt;多模态检索
&lt;/h3&gt;&lt;p&gt;文本和图片可以通过多模态模型映射到相同的向量空间。&lt;/p&gt;
&lt;p&gt;用户可以输入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;寻找一张冬季北欧雪山和湖泊的图片
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;系统通过文本向量搜索相似的图片向量。&lt;/p&gt;
&lt;h3 id=&#34;代码搜索&#34;&gt;代码搜索
&lt;/h3&gt;&lt;p&gt;将函数、类和代码文件转换成向量后，可以根据自然语言描述搜索代码。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;查找负责校验 JWT Token 的函数
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;即使代码中没有出现完全相同的注释，系统仍然可能找到相关实现。&lt;/p&gt;
&lt;h3 id=&#34;异常检测&#34;&gt;异常检测
&lt;/h3&gt;&lt;p&gt;正常数据通常集中在向量空间中的某些区域。如果一条新数据与其他数据距离明显较远，它可能是异常数据。&lt;/p&gt;
&lt;p&gt;该方法可以用于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;欺诈检测。&lt;/li&gt;
&lt;li&gt;日志异常分析。&lt;/li&gt;
&lt;li&gt;网络攻击检测。&lt;/li&gt;
&lt;li&gt;工业设备故障预警。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;如何选择数据库&#34;&gt;如何选择数据库
&lt;/h2&gt;&lt;p&gt;选择数据库时，不应该先问“哪个数据库更先进”，而应该先明确数据和查询模式。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart TD
    A{系统主要查询什么} --&gt; B[根据 ID 或字段查询]
    A --&gt; C[根据语义或相似度查询]
    A --&gt; D[两种查询都需要]

    B --&gt; E[传统数据库]
    C --&gt; F[向量数据库]
    D --&gt; G[传统数据库 + 向量数据库]
&lt;/div&gt;&lt;p&gt;可以按照下面的方式判断。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;需求&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;用户、订单、支付、库存&lt;/td&gt;
&lt;td&gt;传统关系型数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;事务和强一致性&lt;/td&gt;
&lt;td&gt;传统关系型数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文档语义搜索&lt;/td&gt;
&lt;td&gt;向量数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图片相似度搜索&lt;/td&gt;
&lt;td&gt;向量数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;企业知识库问答&lt;/td&gt;
&lt;td&gt;向量数据库配合传统数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;精确错误码搜索&lt;/td&gt;
&lt;td&gt;全文搜索或传统索引&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同时需要语义和关键词&lt;/td&gt;
&lt;td&gt;混合检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;既有业务数据又有 AI 检索&lt;/td&gt;
&lt;td&gt;多数据库组合&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;使用向量数据库时需要关注什么&#34;&gt;使用向量数据库时需要关注什么
&lt;/h2&gt;&lt;h3 id=&#34;embedding-模型&#34;&gt;Embedding 模型
&lt;/h3&gt;&lt;p&gt;向量数据库只能根据已有向量进行搜索，向量质量主要取决于 Embedding 模型。&lt;/p&gt;
&lt;p&gt;如果 Embedding 模型无法正确理解业务术语，即使向量数据库性能很好，检索结果也不会理想。&lt;/p&gt;
&lt;h3 id=&#34;向量维度&#34;&gt;向量维度
&lt;/h3&gt;&lt;p&gt;更高的维度通常可以表达更丰富的信息，但也会增加：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存储空间。&lt;/li&gt;
&lt;li&gt;内存占用。&lt;/li&gt;
&lt;li&gt;索引构建时间。&lt;/li&gt;
&lt;li&gt;相似度计算成本。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;召回率&#34;&gt;召回率
&lt;/h3&gt;&lt;p&gt;ANN 搜索是近似搜索，因此可能无法返回理论上最相似的全部结果。&lt;/p&gt;
&lt;p&gt;召回率可以表示为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Recall@K = 检索到的真实相关结果数量 / 理论相关结果数量
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;系统需要在查询延迟、内存占用和召回率之间进行平衡。&lt;/p&gt;
&lt;h3 id=&#34;数据更新&#34;&gt;数据更新
&lt;/h3&gt;&lt;p&gt;某些向量索引适合静态数据，某些适合频繁更新。&lt;/p&gt;
&lt;p&gt;如果系统中的向量会持续新增、修改和删除，需要关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;索引是否支持动态更新。&lt;/li&gt;
&lt;li&gt;删除数据后是否需要重建索引。&lt;/li&gt;
&lt;li&gt;新数据写入后多久可以被查询。&lt;/li&gt;
&lt;li&gt;索引构建是否会影响在线请求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;元数据过滤&#34;&gt;元数据过滤
&lt;/h3&gt;&lt;p&gt;企业系统通常存在复杂的权限条件。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;用户只能检索自己所在部门的内部文档。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;因此，向量数据库是否支持高效的元数据过滤十分重要。&lt;/p&gt;
&lt;h3 id=&#34;数据一致性&#34;&gt;数据一致性
&lt;/h3&gt;&lt;p&gt;如果传统数据库中的文档已经删除，但向量数据库中的向量仍然存在，用户可能检索到失效内容。&lt;/p&gt;
&lt;p&gt;系统需要设计数据同步机制。&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;sequenceDiagram
    participant APP as 应用服务
    participant DB as 传统数据库
    participant VDB as 向量数据库

    APP-&gt;&gt;DB: 删除文档记录
    DB--&gt;&gt;APP: 删除成功
    APP-&gt;&gt;VDB: 删除对应向量
    VDB--&gt;&gt;APP: 删除成功
&lt;/div&gt;&lt;p&gt;在复杂系统中，还可以通过消息队列和补偿任务保证最终一致性。&lt;/p&gt;
&lt;h2 id=&#34;常见误区&#34;&gt;常见误区
&lt;/h2&gt;&lt;h3 id=&#34;向量数据库就是大语言模型数据库&#34;&gt;向量数据库就是大语言模型数据库
&lt;/h3&gt;&lt;p&gt;向量数据库不是专门存储大语言模型的数据库。&lt;/p&gt;
&lt;p&gt;它存储的是向量、原始内容和元数据，可以用于文本、图片、音频、推荐和异常检测等多种场景。&lt;/p&gt;
&lt;h3 id=&#34;向量数据库可以直接回答问题&#34;&gt;向量数据库可以直接回答问题
&lt;/h3&gt;&lt;p&gt;向量数据库负责检索，不负责生成自然语言答案。&lt;/p&gt;
&lt;p&gt;在 RAG 系统中，最终答案通常由大语言模型生成。&lt;/p&gt;
&lt;h3 id=&#34;向量维度越高越好&#34;&gt;向量维度越高越好
&lt;/h3&gt;&lt;p&gt;维度越高不一定意味着检索效果越好。&lt;/p&gt;
&lt;p&gt;最终效果取决于模型训练数据、业务场景、文本质量和检索策略。&lt;/p&gt;
&lt;h3 id=&#34;使用向量数据库就不需要传统数据库&#34;&gt;使用向量数据库就不需要传统数据库
&lt;/h3&gt;&lt;p&gt;向量数据库通常无法替代订单、用户、权限、库存和支付系统中的传统数据库。&lt;/p&gt;
&lt;p&gt;实际应用更常见的是组合使用。&lt;/p&gt;
&lt;h3 id=&#34;相似度最高的内容一定正确&#34;&gt;相似度最高的内容一定正确
&lt;/h3&gt;&lt;p&gt;向量相似度只表示语义或特征上的接近程度，并不等于事实正确。&lt;/p&gt;
&lt;p&gt;因此，RAG 系统还需要考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文档是否过期。&lt;/li&gt;
&lt;li&gt;数据源是否可信。&lt;/li&gt;
&lt;li&gt;用户是否有访问权限。&lt;/li&gt;
&lt;li&gt;检索内容是否真正能够回答问题。&lt;/li&gt;
&lt;li&gt;是否需要使用重排序模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;传统数据库和向量数据库解决的是不同类型的问题。&lt;/p&gt;
&lt;p&gt;传统数据库擅长：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;精确查询。&lt;/li&gt;
&lt;li&gt;结构化数据管理。&lt;/li&gt;
&lt;li&gt;事务处理。&lt;/li&gt;
&lt;li&gt;数据关系维护。&lt;/li&gt;
&lt;li&gt;聚合和统计。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;向量数据库擅长：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义搜索。&lt;/li&gt;
&lt;li&gt;相似度检索。&lt;/li&gt;
&lt;li&gt;图片与多模态搜索。&lt;/li&gt;
&lt;li&gt;推荐系统。&lt;/li&gt;
&lt;li&gt;RAG 知识检索。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两者之间并不是竞争或替代关系。&lt;/p&gt;
&lt;p&gt;在现代 AI 应用中，一种常见的架构是：&lt;/p&gt;
&lt;div class=&#34;mermaid&#34;&gt;flowchart LR
    U[用户请求] --&gt; A[应用服务]

    A --&gt; DB[传统数据库]
    A --&gt; VDB[向量数据库]
    A --&gt; LLM[大语言模型]

    DB --&gt; B[用户、权限、业务状态]
    VDB --&gt; C[语义相关上下文]

    B --&gt; A
    C --&gt; A
    A --&gt; LLM
    LLM --&gt; R[最终回答]
&lt;/div&gt;&lt;p&gt;传统数据库保存明确的业务事实，向量数据库提供基于语义的检索能力，大语言模型负责理解问题并组织答案。&lt;/p&gt;
&lt;p&gt;可以将它们概括为：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;传统数据库负责找到“符合条件的数据”，向量数据库负责找到“含义相近的数据”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;理解这一差异，是设计 RAG、智能搜索、推荐系统和多模态应用的基础。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>关于微调的时机</title>
        <link>https://SymphonyW.github.io/zh-cn/p/%E5%85%B3%E4%BA%8E%E5%BE%AE%E8%B0%83%E7%9A%84%E6%97%B6%E6%9C%BA/</link>
        <pubDate>Sat, 11 Jul 2026 17:30:00 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/%E5%85%B3%E4%BA%8E%E5%BE%AE%E8%B0%83%E7%9A%84%E6%97%B6%E6%9C%BA/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/%E5%85%B3%E4%BA%8E%E5%BE%AE%E8%B0%83%E7%9A%84%E6%97%B6%E6%9C%BA/bg.png" alt="Featured image of post 关于微调的时机" /&gt;&lt;h1 id=&#34;关于微调的时机&#34;&gt;关于微调的时机
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;微调不是大模型效果优化的默认选项，更不是遇到效果问题后的第一反应。真正成熟的工程判断，是先弄清楚：当前缺的是&lt;strong&gt;知识&lt;/strong&gt;，还是模型的&lt;strong&gt;行为稳定性&lt;/strong&gt;？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“什么时候应该做大模型微调？”是大模型岗位面试中很常见的一道题。&lt;/p&gt;
&lt;p&gt;它表面上在问微调技术，实际上考察的是两个更重要的能力：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;能不能区分知识问题和行为问题&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有没有技术选型的成本意识&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果连问题类型都没有判断清楚，就直接把微调提上日程，往往会把一个本可低成本解决的问题，变成数据准备、模型训练和持续维护的复杂工程。&lt;/p&gt;
&lt;p&gt;因此，讨论“要不要微调”之前，先记住一个结论：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;知识问题优先用检索解决，行为问题才进入微调的候选范围。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;先判断缺知识还是行为不稳定&#34;&gt;先判断：缺知识，还是行为不稳定？
&lt;/h2&gt;&lt;p&gt;大模型应用中的效果问题，可以先沿着“知识”和“行为”两条线拆开。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;问题类型&lt;/th&gt;
&lt;th&gt;典型表现&lt;/th&gt;
&lt;th&gt;对应解法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;知识问题&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型缺少业务文档、规章制度、行业事实等外部信息&lt;/td&gt;
&lt;td&gt;使用检索增强（RAG），在生成时补充所需知识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;行为问题&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;模型知道正确内容，但输出格式、语气或判断规则不稳定&lt;/td&gt;
&lt;td&gt;提示词无法稳定解决后，再考虑微调&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;知识问题模型不知道事实&#34;&gt;知识问题：模型不知道事实
&lt;/h3&gt;&lt;p&gt;如果模型答不出某个问题，是因为它没有接触过企业内部文档、最新规章制度或特定行业事实，那么问题的核心不是“模型不会回答”，而是&lt;strong&gt;模型缺少回答所需的外部信息&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这类问题应该优先使用检索增强。知识保留在外部知识源中，需要时检索并提供给模型，而不是把它固化进模型权重。&lt;/p&gt;
&lt;p&gt;这样做的关键价值是：&lt;strong&gt;知识可以灵活更新&lt;/strong&gt;。文档变化时更新知识源即可，不必重新训练模型。&lt;/p&gt;
&lt;h3 id=&#34;行为问题模型知道但做得不稳定&#34;&gt;行为问题：模型知道，但做得不稳定
&lt;/h3&gt;&lt;p&gt;另一类问题是：正确内容模型其实知道，但它无法持续按照业务要求输出。例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输出结构有时正确、有时缺字段；&lt;/li&gt;
&lt;li&gt;语气无法长期保持一致；&lt;/li&gt;
&lt;li&gt;面对复杂判断规则时，执行结果反复波动。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这不是知识缺失，而是&lt;strong&gt;行为不稳定&lt;/strong&gt;。微调真正擅长处理的，正是这类“让模型更稳定地按照指定方式做事”的问题。&lt;/p&gt;
&lt;p&gt;所以，区分两者最直接的判断方式是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;缺事实，补检索；事实已经具备但表现不稳定，才评估微调。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;效果优化要走阶梯而不是一步跳到微调&#34;&gt;效果优化要走阶梯，而不是一步跳到微调
&lt;/h2&gt;&lt;p&gt;工业界做技术选型，不能只问“哪种方案能解决”，还要问“是否有成本更低的方案能先解决”。大模型效果优化应该按照从低成本到高成本的顺序逐级推进：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&lt;/th&gt;
&lt;th&gt;优化手段&lt;/th&gt;
&lt;th&gt;进入条件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;第一步&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;把提示词优化到极致&lt;/td&gt;
&lt;td&gt;所有场景都应先完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;第二步&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;引入检索增强方案&lt;/td&gt;
&lt;td&gt;问题涉及外部知识，或提示词缺少必要事实&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;第三步&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;考虑使用微调&lt;/td&gt;
&lt;td&gt;前两步走不通，且问题确实适合微调&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这套阶梯的关键不是三种技术谁更高级，而是&lt;strong&gt;上一级没有解决问题，再进入下一级&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;第一步先把提示词优化到极致&#34;&gt;第一步：先把提示词优化到极致
&lt;/h3&gt;&lt;p&gt;面对格式、语气和规则执行问题，第一步不是训练，而是先验证提示词能否解决。只要提示词仍有优化空间，就不能轻易得出“必须微调”的结论。&lt;/p&gt;
&lt;h3 id=&#34;第二步需要外部知识时引入检索&#34;&gt;第二步：需要外部知识时引入检索
&lt;/h3&gt;&lt;p&gt;如果问题来自知识缺失，就通过检索把业务文档、规章制度或行业事实提供给模型。检索负责补齐事实，也保留了知识更新的灵活性。&lt;/p&gt;
&lt;h3 id=&#34;第三步最后才考虑微调&#34;&gt;第三步：最后才考虑微调
&lt;/h3&gt;&lt;p&gt;只有提示词已经反复优化、检索也已经覆盖所需事实，问题依然存在时，微调才真正进入决策范围。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;微调应该是阶梯的第三层，而不是项目启动后的默认配置。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;真正需要微调的三个信号&#34;&gt;真正需要微调的三个信号
&lt;/h2&gt;&lt;p&gt;“微调不是起点”不等于“永远不做微调”。当下面三个信号出现时，微调就可能具备明确的工程价值。&lt;/p&gt;
&lt;h3 id=&#34;信号一行为与格式仍然不稳定&#34;&gt;信号一：行为与格式仍然不稳定
&lt;/h3&gt;&lt;p&gt;业务要求模型稳定输出特定结构、固定语气或复杂规则，但提示词经过反复优化后，效果仍然时好时坏。&lt;/p&gt;
&lt;p&gt;这里有两个必要前提：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目标是约束模型的&lt;strong&gt;行为与输出形态&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;提示词优化已经充分尝试，但稳定性仍未达标。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两个条件同时成立，才说明问题可能需要通过微调进一步固化。&lt;/p&gt;
&lt;h3 id=&#34;信号二高频窄口径任务受到成本与延迟制约&#34;&gt;信号二：高频窄口径任务受到成本与延迟制约
&lt;/h3&gt;&lt;p&gt;意图分类、实体抽取、内容打标这类任务，通常口径明确、调用频率高。为了让模型准确执行规则，系统可能需要在每一次请求中重复携带很长的提示词。&lt;/p&gt;
&lt;p&gt;长提示词会带来持续的重复开销，也会增加延迟。此时，把任务行为通过微调迁移到小模型中，能够&lt;strong&gt;大幅降低成本和延迟&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这里决定是否微调的，不只是效果，还有调用规模下的长期成本。&lt;/p&gt;
&lt;h3 id=&#34;信号三距离业务硬指标只差最后几个点&#34;&gt;信号三：距离业务硬指标只差最后几个点
&lt;/h3&gt;&lt;p&gt;提示词已经做到位，检索也已经补齐事实，但准确率距离业务硬指标仍然差最后几个点。这说明低成本手段已经基本用尽，而剩余差距又会直接影响业务上线或验收。&lt;/p&gt;
&lt;p&gt;此时，微调才适合作为继续突破能力边界的手段。&lt;/p&gt;
&lt;p&gt;三个信号可以浓缩成一张判断表：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;信号&lt;/th&gt;
&lt;th&gt;关键问题&lt;/th&gt;
&lt;th&gt;微调价值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;行为与格式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提示词反复优化后，输出仍不稳定吗？&lt;/td&gt;
&lt;td&gt;固化结构、语气和复杂规则&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;成本与延迟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;高频窄任务是否长期重复携带长提示词？&lt;/td&gt;
&lt;td&gt;用小模型降低持续成本与延迟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;能力边界&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提示词和检索都到位后，是否仍差硬指标最后几个点？&lt;/td&gt;
&lt;td&gt;进一步提升专项准确率&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;微调最常见的四个坑&#34;&gt;微调最常见的四个坑
&lt;/h2&gt;&lt;p&gt;真正的工程风险往往不在“会不会训练”，而在于微调目标、数据和评估是否正确。下面四个问题尤其常见。&lt;/p&gt;
&lt;h3 id=&#34;坑一用微调灌知识&#34;&gt;坑一：用微调灌知识
&lt;/h3&gt;&lt;p&gt;把业务文档或行业知识直接拿去微调，看起来像是在“教会模型”，实际很容易让知识变成模型中的&lt;strong&gt;模糊印象&lt;/strong&gt;，反而更容易胡说。&lt;/p&gt;
&lt;p&gt;更麻烦的是，知识会持续变化。一旦知识固化进模型权重，每次更新都可能重新触发数据准备和训练，维护成本极高。&lt;/p&gt;
&lt;p&gt;因此，这条边界要足够明确：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;知识类需求永远优先走检索，不要用微调灌知识。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;坑二重数量轻质量&#34;&gt;坑二：重数量，轻质量
&lt;/h3&gt;&lt;p&gt;微调数据不是越多越好。&lt;strong&gt;几百条高质量、统一口径的样本，效果可能好过几万条脏数据。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;数据中的口径冲突和错误示范，会直接让模型学到不稳定的行为。与其盲目追求数量，不如先确保样本准确、清晰且规则一致。&lt;/p&gt;
&lt;p&gt;对于简单任务，&lt;strong&gt;50～100 条样本就能看到明显效果&lt;/strong&gt;。这意味着，微调项目早期更应该关注样本质量，而不是先堆出庞大的数据规模。&lt;/p&gt;
&lt;h3 id=&#34;坑三忽视灾难性遗忘&#34;&gt;坑三：忽视灾难性遗忘
&lt;/h3&gt;&lt;p&gt;模型在窄任务上被过度微调后，可能出现通用能力退化。专项任务的指标变好，并不代表整体效果一定更好。&lt;/p&gt;
&lt;p&gt;因此，微调后的评估不能只盯着目标任务，必须同时检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;专项能力是否提升&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通用能力是否退化&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只有两者一起评估，才能判断这次微调是否真的值得上线。&lt;/p&gt;
&lt;h3 id=&#34;坑四没有评估就开始微调&#34;&gt;坑四：没有评估就开始微调
&lt;/h3&gt;&lt;p&gt;没有评估体系就直接训练，相当于&lt;strong&gt;闭着眼睛开车&lt;/strong&gt;：训练完成后，既无法确认效果提升了多少，也无法判断出现了哪些退化。&lt;/p&gt;
&lt;p&gt;正确的顺序应该是：&lt;strong&gt;评估集先于训练搭建&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;先明确用什么样本和标准验证效果，再开始准备微调。否则，训练过程即使顺利完成，也无法形成可信的工程结论。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一套可落地的决策顺序&#34;&gt;一套可落地的决策顺序
&lt;/h2&gt;&lt;p&gt;面对“当前场景是否需要微调”，可以按下面的顺序做判断：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;决策步骤&lt;/th&gt;
&lt;th&gt;要回答的问题&lt;/th&gt;
&lt;th&gt;对应动作&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. 定义问题&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;缺的是外部知识，还是行为稳定性？&lt;/td&gt;
&lt;td&gt;知识问题走检索；行为问题继续判断&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. 优化提示词&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提示词是否已经反复优化到位？&lt;/td&gt;
&lt;td&gt;没有则继续优化，不急于微调&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. 补齐知识&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;是否缺少业务文档、制度或行业事实？&lt;/td&gt;
&lt;td&gt;引入 RAG，不把知识写进权重&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4. 检查信号&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;是否出现行为不稳、成本延迟或能力边界信号？&lt;/td&gt;
&lt;td&gt;信号明确后再立项微调&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5. 搭建评估&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;是否已有专项与通用能力评估？&lt;/td&gt;
&lt;td&gt;评估集就绪后才开始训练&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;6. 准备数据&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;样本是否高质量且口径统一？&lt;/td&gt;
&lt;td&gt;先保证质量，再考虑数量&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这套顺序体现的不是对微调的保守，而是对工程成本和方案边界的尊重。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;面试时应该怎样回答&#34;&gt;面试时应该怎样回答？
&lt;/h2&gt;&lt;p&gt;如果面试官问“什么时候做微调”，一个逻辑完整的回答可以这样组织：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我会先判断这是知识问题还是行为问题。模型缺少业务文档、规章制度或行业事实时，优先使用 RAG，因为知识需要灵活更新，不应该固化进模型权重。模型已经知道正确内容，但格式、语气或判断规则在提示词反复优化后仍不稳定，才是微调的适用场景。&lt;/p&gt;
&lt;p&gt;在方案顺序上，我会先把提示词优化到极致，再引入检索增强，前两步走不通后才考虑微调。真正推动微调立项的信号主要有三个：行为和格式仍然不稳定；高频窄口径任务受长提示词的成本与延迟影响；提示词和检索都到位后，准确率距离业务硬指标仍差最后几个点。&lt;/p&gt;
&lt;p&gt;开始训练前，我会先搭建评估集，并保证训练样本高质量、口径统一。评估时同时关注专项能力和通用能力，避免窄任务过度微调导致灾难性遗忘。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个回答覆盖了问题分类、方案优先级、成本判断和上线风险，也更接近真实工业场景中的技术决策方式。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;大模型项目中，微调最容易被误用的原因，是团队把所有效果问题都归结为“模型能力不够”。但真正需要先回答的是：&lt;strong&gt;模型缺的是事实，还是稳定执行规则的行为？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;整套决策可以压缩为三句话：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;知识问题优先用 RAG，行为问题才考虑微调&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;先提示词，再检索，最后才是微调&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有明确微调信号、评估集和高质量数据，就不要启动训练&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;成熟的工业界方案，往往是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;微调管形态，检索管事实。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但要特别注意：这是一套经过逐级验证后形成的&lt;strong&gt;终局组合方案&lt;/strong&gt;，不是项目一开始就要全部开启的技术清单。&lt;/p&gt;
&lt;p&gt;真正专业的选型，不是把所有技术都用上，而是在正确的问题上使用正确的手段。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>经典面试题：RAG 检索 top-k 到底怎么设？</title>
        <link>https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/</link>
        <pubDate>Wed, 08 Jul 2026 22:05:00 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/bg.png" alt="Featured image of post 经典面试题：RAG 检索 top-k 到底怎么设？" /&gt;&lt;h1 id=&#34;经典面试题rag-检索-top-k-到底怎么设&#34;&gt;经典面试题：RAG 检索 top-k 到底怎么设？
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;面试官问：&amp;ldquo;你们 RAG 系统的 top-k 是怎么设的？&amp;rdquo; 你如果只回答一句&amp;quot;看情况&amp;quot;，那基本就和 offer 说再见了。top-k 这个看似简单的参数，背后考的是你对&lt;strong&gt;完整 RAG 链路&lt;/strong&gt;的理解深度。本文参考「小哲讲 agent 面试」的拆解思路，把这个高频面试题一次讲透。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一为什么-top-k-是必考题&#34;&gt;一、为什么 top-k 是必考题？
&lt;/h2&gt;&lt;p&gt;在 RAG（Retrieval-Augmented Generation）系统中，top-k 决定&lt;strong&gt;从向量数据库里召回多少条文档片段喂给大模型&lt;/strong&gt;。它看起来只是 &lt;code&gt;search_kwargs={&amp;quot;k&amp;quot;: 4}&lt;/code&gt; 这么一个参数，但它同时牵动四件事：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;top-k 的影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;召回率（Recall）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;k 太小 → 漏掉真正相关的片段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;噪声（Noise）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;k 太大 → 召回一堆无关片段干扰生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;成本（Cost）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;k 越大 → Prompt 越长 → token 费用越高、延迟越高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;生成质量（Quality）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;噪声片段会让 LLM &amp;ldquo;迷失在中间&amp;rdquo;，答非所问&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/top-k.png&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/top-k.png&#34; alt=&#34;top-k&#34; width=&#34;1758&#34; height=&#34;459&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;gallery-image&#34; data-flex-grow=&#34;383&#34; data-flex-basis=&#34;919px&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;也就是说，top-k 是&lt;strong&gt;召回、噪声、成本、质量&lt;/strong&gt;四个目标的交汇点。面试官真正想听的不是&amp;quot;我设成了 5&amp;quot;，而是&amp;quot;我为什么这样设，背后是什么链路思维&amp;quot;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二top-k-设小了幻觉的温床&#34;&gt;二、top-k 设小了：幻觉的温床
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/topk-too-small.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/topk-too-small.svg&#34; alt=&#34;top-k 设小的隐患：排名第一的片段可能不完整&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;很多人凭直觉认为&amp;quot;检索结果越靠前越相关，取 Top-1 不就行了？&amp;quot;——这是第一个坑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题在于：排名第一 ≠ 信息完整。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;举个真实场景：用户问&amp;quot;公司请假流程是什么？&amp;quot;，向量库里有一份《员工手册》第 3 章详细写了请假流程，但因为切分（chunking）策略，这段内容被切成两半：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;片段 A（排名第 1）：&amp;quot;……请假需提前在 OA 系统提交申请，由直属主管审批。&amp;quot;&lt;/li&gt;
&lt;li&gt;片段 B（排名第 2）：&amp;ldquo;超过 3 天的请假需提供医院证明，并报 HR 备案。&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只取 Top-1，LLM 拿到的上下文只有&amp;quot;提交申请 + 主管审批&amp;quot;这一半，它大概率会&lt;strong&gt;编造&lt;/strong&gt;&amp;ldquo;3 天以上需要什么材料&amp;rdquo;——因为用户问到了，它必须给出回答，但又没看到完整信息。这就是典型的&lt;strong&gt;幻觉&lt;/strong&gt;：模型不是在撒谎，而是被不完整的上下文逼着&amp;quot;脑补&amp;quot;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心结论&lt;/strong&gt;：top-k 设小的代价是&lt;strong&gt;召回不足 → 上下文不完整 → 模型幻觉&lt;/strong&gt;。排名第一只能保证&amp;quot;最相关&amp;quot;，不能保证&amp;quot;最完整&amp;quot;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三top-k-设大了噪声与成本的双重暴击&#34;&gt;三、top-k 设大了：噪声与成本的双重暴击
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/topk-too-large.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/topk-too-large.svg&#34; alt=&#34;top-k 设大的隐患：噪声片段淹没真正答案&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;那干脆设大点，k=20、k=50 总不会漏了吧？这是第二个坑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;k 太大会引入三类问题：&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;31-噪声淹没信号&#34;&gt;3.1 噪声淹没信号
&lt;/h3&gt;&lt;p&gt;向量检索本质是&lt;strong&gt;相似度排序&lt;/strong&gt;，但&amp;quot;相似&amp;quot;不等于&amp;quot;相关&amp;quot;。当 k=20 时，后 10 条往往是&amp;quot;看起来有点像但其实没用&amp;quot;的片段。这些噪声片段进入 Prompt 后，会触发 LLM 的 &lt;strong&gt;&amp;ldquo;Lost in the Middle&amp;rdquo;&lt;/strong&gt; 现象——模型对上下文中间位置的信息注意力会下降，反而把真正相关的片段忽略了。&lt;/p&gt;
&lt;h3 id=&#34;32-成本线性增长&#34;&gt;3.2 成本线性增长
&lt;/h3&gt;&lt;p&gt;LLM 的推理成本是按 token 计费的，k 越大，Prompt 越长：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;k=4：上下文约 2000 token&lt;/li&gt;
&lt;li&gt;k=20：上下文约 10000 token&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;成本直接 5 倍，延迟也跟着涨。线上高 QPS 场景下，这是真金白银的浪费。&lt;/p&gt;
&lt;h3 id=&#34;33-生成质量下降&#34;&gt;3.3 生成质量下降
&lt;/h3&gt;&lt;p&gt;更隐蔽的问题是：&lt;strong&gt;噪声片段会让模型&amp;quot;分心&amp;quot;&lt;/strong&gt;。LLM 是基于注意力机制的，当 Prompt 里混入大量无关内容，模型会尝试&amp;quot;综合&amp;quot;这些信息，导致回答跑题、啰嗦，甚至把无关片段当事实引用。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心结论&lt;/strong&gt;：top-k 设大的代价是&lt;strong&gt;噪声增加 → 成本上升 → 生成质量反而下降&lt;/strong&gt;。多并不等于好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四两阶段检索粗排--精排&#34;&gt;四、两阶段检索：粗排 + 精排
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/two-stage-retrieval.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/two-stage-retrieval.svg&#34; alt=&#34;两阶段检索：粗排保召回，精排提质量&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;既然 k 设小了漏、设大了吵，那有没有两全其美的办法？这就是**两阶段检索（Two-Stage Retrieval）**的价值。&lt;/p&gt;
&lt;h3 id=&#34;41-第一阶段粗排recall宁可错杀不可放过&#34;&gt;4.1 第一阶段：粗排（Recall）——宁可错杀，不可放过
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;用什么&lt;/strong&gt;：双塔 Embedding 模型（如 &lt;code&gt;bge-large-zh&lt;/code&gt;、&lt;code&gt;text-embedding-3&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;怎么做&lt;/strong&gt;：query 和 doc 分别编码，算余弦相似度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;k 设多大&lt;/strong&gt;：放宽到 &lt;strong&gt;20~50&lt;/strong&gt;，甚至 100&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目标&lt;/strong&gt;：&lt;strong&gt;高召回率&lt;/strong&gt;，把可能相关的片段都捞进来，哪怕混入噪声&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步本质是&amp;quot;撒大网&amp;quot;，速度快（向量检索毫秒级），但精度有限。&lt;/p&gt;
&lt;h3 id=&#34;42-第二阶段精排precision去伪存真&#34;&gt;4.2 第二阶段：精排（Precision）——去伪存真
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;用什么&lt;/strong&gt;：Cross-Encoder 重排模型（如 &lt;code&gt;bge-reranker-large&lt;/code&gt;、Cohere Rerank）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;怎么做&lt;/strong&gt;：把 query 和每一条候选 doc &lt;strong&gt;拼在一起&lt;/strong&gt;送进模型，输出相关性分数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;取多少&lt;/strong&gt;：按分数从高到低取 &lt;strong&gt;3~5 条&lt;/strong&gt; 喂给 LLM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目标&lt;/strong&gt;：&lt;strong&gt;高精度&lt;/strong&gt;，把粗排里的噪声过滤掉，只留真正相关的&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步是&amp;quot;过筛子&amp;quot;，精度高（Cross-Encoder 能捕捉 query-doc 的细粒度交互），但速度慢，所以只对粗排的少量候选做。&lt;/p&gt;
&lt;h3 id=&#34;43-为什么不能直接用-cross-encoder-检索&#34;&gt;4.3 为什么不能直接用 Cross-Encoder 检索？
&lt;/h3&gt;&lt;p&gt;因为 Cross-Encoder 没有&amp;quot;索引&amp;quot;概念，必须对库里每条 doc 都跑一次模型，百万级文档库根本扛不住。所以工业界的标准做法就是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;双塔粗排（快但糙）→ Cross-Encoder 精排（慢但准）→ 取 Top-N 喂 LLM&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这正是 top-k 在两阶段里的&amp;quot;分工&amp;quot;——粗排的 k 大（保召回），精排后的 k 小（保质量）。&lt;strong&gt;面试时把这两个 k 区分开讲，就已经超过 80% 的候选人了。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五动态阈值让输入规模自适应&#34;&gt;五、动态阈值：让输入规模自适应
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/dynamic-threshold.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/dynamic-threshold.svg&#34; alt=&#34;动态阈值：按相关性分数自适应截断&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;两阶段检索解决了&amp;quot;召回 vs 精度&amp;quot;的矛盾，但还有一个问题：&lt;strong&gt;精排后取几条？固定取 3 条还是 5 条？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;固定数字依然不够好，因为不同问题的&amp;quot;答案密度&amp;quot;不一样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;简单事实题&lt;/strong&gt;（&amp;ldquo;公司全称是什么&amp;rdquo;）：可能只有 1 条强相关，取 5 条全是噪声&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;复杂流程题&lt;/strong&gt;（&amp;ldquo;请假流程&amp;rdquo;）：可能需要 4~5 条片段拼起来才完整&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开放性问题&lt;/strong&gt;（&amp;ldquo;总结公司福利&amp;rdquo;）：可能需要 8~10 条覆盖不同福利项&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就引出&lt;strong&gt;动态阈值（Dynamic Threshold）&lt;/strong&gt;：&lt;/p&gt;
&lt;h3 id=&#34;51-基于分数的截断&#34;&gt;5.1 基于分数的截断
&lt;/h3&gt;&lt;p&gt;不固定数量，而是设一个&lt;strong&gt;相关性分数阈值&lt;/strong&gt; θ：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;保留所有 score &amp;gt;= θ 的片段
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;比如精排分数分布是 &lt;code&gt;[0.92, 0.88, 0.85, 0.41, 0.38, ...]&lt;/code&gt;，阈值设 0.5，那就只取前 3 条，后边的低分噪声自动丢弃。&lt;/p&gt;
&lt;h3 id=&#34;52-基于分数差距的截断drop-off-检测&#34;&gt;5.2 基于分数差距的截断（Drop-off 检测）
&lt;/h3&gt;&lt;p&gt;观察相邻分数的&amp;quot;断崖&amp;quot;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;分数：0.92 → 0.88 → 0.85 → 0.41（断崖！）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在分数急剧下降的位置截断，能自适应地保留&amp;quot;高分组&amp;quot;而丢弃&amp;quot;低分组&amp;quot;。&lt;/p&gt;
&lt;h3 id=&#34;53-加上上下文长度约束&#34;&gt;5.3 加上上下文长度约束
&lt;/h3&gt;&lt;p&gt;当然，动态阈值还要和 LLM 的上下文窗口配合——总不能召回 50 条全塞进去。实际工程里通常是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;最终输入 = min(动态阈值筛出的片段, 上下文长度预算)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心结论&lt;/strong&gt;：动态阈值让&amp;quot;取几条&amp;quot;从&lt;strong&gt;静态参数&lt;/strong&gt;变成&lt;strong&gt;自适应决策&lt;/strong&gt;，这是 top-k 的高阶玩法，也是面试加分项。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六完整链路top-k-不是参数是思维&#34;&gt;六、完整链路：top-k 不是参数，是思维
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/rag-pipeline-mindset.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98rag-%E6%A3%80%E7%B4%A2-top-k-%E5%88%B0%E5%BA%95%E6%80%8E%E4%B9%88%E8%AE%BE/rag-pipeline-mindset.svg&#34; alt=&#34;完整 RAG 链路思维：top-k 是四阶段的协同&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;把前面几节串起来，你会看到 top-k 背后其实是一条完整的链路：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;用户 Query
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[Query 改写]（可选：HyDE / Multi-Query / Step-back）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[粗排] 双塔 Embedding 检索 → top-k₁ = 20~50（保召回）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[精排] Cross-Encoder Rerank → 重排打分
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[截断] 动态阈值 / Drop-off 检测 → top-k₂ = 3~5（保质量）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[上下文压缩]（可选：LongLLMLingua）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[Prompt 拼装] Context + Question
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[LLM 生成] → 可溯源回答
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;每个环节都有它的&amp;quot;k&amp;quot;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;k₁（粗排）&lt;/strong&gt;：大，保召回&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;k₂（精排后）&lt;/strong&gt;：小，保质量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;k₃（最终输入）&lt;/strong&gt;：受动态阈值和上下文预算双重约束&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;面试官听到你能区分 k₁、k₂、k₃，并解释清楚每一步的目标，基本就认定你&lt;strong&gt;真正做过 RAG 工程&lt;/strong&gt;，而不是只会调 LangChain 的 &lt;code&gt;search_kwargs={&amp;quot;k&amp;quot;: 4}&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七面试高分回答模板&#34;&gt;七、面试高分回答模板
&lt;/h2&gt;&lt;p&gt;如果被问到&amp;quot;top-k 怎么设&amp;quot;，可以这样组织回答（约 90 秒）：&lt;/p&gt;
&lt;h3 id=&#34;第一层先承认-trade-off10-秒&#34;&gt;第一层：先承认 trade-off（10 秒）
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;top-k 不是孤立参数，它同时影响召回率、噪声、成本和生成质量，设小了会漏、设大了会吵，所以不能一刀切。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;第二层讲两阶段检索40-秒&#34;&gt;第二层：讲两阶段检索（40 秒）
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;我们的做法是两阶段检索。粗排用双塔 Embedding，k 设到 20~50，优先保召回；精排用 Cross-Encoder Rerank，比如 &lt;code&gt;bge-reranker-large&lt;/code&gt;，对粗排结果重打分。Cross-Encoder 精度高但慢，所以只对少量候选做。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;第三层讲动态阈值25-秒&#34;&gt;第三层：讲动态阈值（25 秒）
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;精排后不固定取几条，而是用动态阈值——设一个相关性分数下限，或者检测分数 drop-off 的断崖位置，自适应截断。再叠加 LLM 上下文长度预算做上限保护。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;第四层回到本质15-秒&#34;&gt;第四层：回到本质（15 秒）
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;本质上 top-k 考的不是调参，而是对 RAG 链路的理解——召回、排序、截断、生成，每个阶段都有它的 k。区分清楚 k₁、k₂、k₃，效果就稳了。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;八常见追问与应对&#34;&gt;八、常见追问与应对
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;面试官追问&lt;/th&gt;
&lt;th&gt;参考回答要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;粗排 k 设 50 不会太慢吗？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;向量检索是 ANN（近似最近邻），百万级库毫秒级，HNSW/IVF 索引加持下没问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;Rerank 模型怎么选？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;中文用 &lt;code&gt;bge-reranker-large&lt;/code&gt;，英文用 Cohere Rerank；轻量场景可用 &lt;code&gt;bge-reranker-base&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;动态阈值怎么调？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;离线评估集上扫阈值，看 Recall@k 和 Precision@k 的 F1 拐点；或用分数分布的肘部&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;为什么不直接用长上下文模型塞进去？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;长上下文有 Lost-in-the-Middle、成本高、不可溯源三个问题，RAG 仍然是更经济的方案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;k 设大了模型答非所问怎么办？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;先加 Rerank，再加动态阈值；必要时上 LongLLMLingua 做上下文压缩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;如何评估 top-k 设得对不对？&amp;rdquo;&lt;/td&gt;
&lt;td&gt;用 Ragas / TruLens 做 Faithfulness、Context Recall、Answer Relevancy 三项指标评估&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;回到那个面试题——&amp;ldquo;RAG 检索的 top-k 怎么设？&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;低分回答&lt;/strong&gt;：&amp;ldquo;看情况，一般设 3~5。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;及格回答&lt;/strong&gt;：&amp;ldquo;设小了会幻觉，设大了会引入噪声，所以要在召回和精度之间权衡。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高分回答&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;top-k 不是单一参数，而是贯穿 RAG 链路的协同设计。粗排用双塔 Embedding 大 k 保召回（20~50），精排用 Cross-Encoder 重排提精度，再用动态阈值自适应截断到 3~5 条，最后受 LLM 上下文预算约束。本质考的不是调参，而是对&lt;strong&gt;召回 → 排序 → 截断 → 生成&lt;/strong&gt;整条链路的理解。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;记住视频里那句点睛之笔：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;top-k 的本质是完整 RAG 链路思维，而非调参数。&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;把这句话在面试里讲出来，配合上面的链路图，这道题基本就稳了。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文参考抖音「小哲讲 agent 面试」的视频内容整理扩展，原视频链接见文末。封面图由作者自行添加。&lt;/em&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>RAG 技术全景：让大模型从&#34;闭卷考试&#34;到&#34;开卷考试&#34;</title>
        <link>https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/</link>
        <pubDate>Wed, 08 Jul 2026 15:00:00 +0800</pubDate>
        
        <guid>https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/</guid>
        <description>&lt;img src="https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/bg.png" alt="Featured image of post RAG 技术全景：让大模型从&#34;闭卷考试&#34;到&#34;开卷考试&#34;" /&gt;&lt;h1 id=&#34;rag-技术全景让大模型从闭卷考试到开卷考试&#34;&gt;RAG 技术全景：让大模型从&amp;quot;闭卷考试&amp;quot;到&amp;quot;开卷考试&amp;quot;
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;大模型很强，但它会&amp;quot;一本正经地胡说八道&amp;quot;。RAG（Retrieval-Augmented Generation，检索增强生成）给大模型外挂了一个&amp;quot;知识库&amp;quot;，让它从闭卷考试变成开卷考试，回答既准又能溯源。本文用 6 张图带你完整搞懂 RAG。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一先聊痛点大模型的幻觉从哪来&#34;&gt;一、先聊痛点：大模型的&amp;quot;幻觉&amp;quot;从哪来？
&lt;/h2&gt;&lt;p&gt;你大概遇到过这样的场景：问 GPT 一个公司内部的政策问题，或者让它总结一份最新发布的财报，它信誓旦旦地给你一段听起来很专业的回答——但仔细一查，全是编的。&lt;/p&gt;
&lt;p&gt;这就是大模型的&lt;strong&gt;幻觉（Hallucination）&lt;/strong&gt;。它不是故意的，而是由其工作方式决定的：LLM 本质上是在做&amp;quot;下一个 token 预测&amp;quot;，它根据训练时记住的概率分布生成文本，分不清&amp;quot;知道&amp;quot;和&amp;quot;不知道&amp;quot;。&lt;/p&gt;
&lt;p&gt;原生 LLM 在企业级场景下有四个硬伤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;知识截止&lt;/strong&gt;：训练数据有截止日期，不知道今天发生的事&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;幻觉问题&lt;/strong&gt;：没见过的知识就靠&amp;quot;编&amp;quot;，还很自信&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;领域知识不足&lt;/strong&gt;：对企业内部文档、专业细分领域不熟悉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无法溯源&lt;/strong&gt;：回答不知道来自哪里，没法核验&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;要解决这些问题，传统思路是&lt;strong&gt;微调（Fine-tuning）&lt;/strong&gt;——用领域数据重新训练模型。但微调又贵又慢，而且知识一更新就得再来一遍。&lt;/p&gt;
&lt;p&gt;RAG 给了另一条路：&lt;strong&gt;不重新训练模型，而是给它外挂一个可随时更新的知识库，回答时先去知识库里检索，再基于检索到的内容作答。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/llm-vs-rag.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/llm-vs-rag.svg&#34; alt=&#34;原生 LLM vs RAG：闭卷考试 vs 开卷考试&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;就像考试一样：原生 LLM 是闭卷考试，全凭记忆，记不清就编；RAG 是开卷考试，遇到不会的可以翻书，答案有据可循。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二rag-是什么核心思想一句话&#34;&gt;二、RAG 是什么：核心思想一句话
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;RAG = 检索（Retrieval）+ 增强（Augmentation）+ 生成（Generation）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在 LLM 生成回答之前，先从外部知识库中&lt;strong&gt;检索&lt;/strong&gt;相关资料，把这些资料&lt;strong&gt;增强&lt;/strong&gt;到 Prompt 里作为上下文，再让 LLM 基于这些上下文&lt;strong&gt;生成&lt;/strong&gt;回答。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用一句话概括：&lt;strong&gt;RAG 让 LLM 从&amp;quot;闭卷考试&amp;quot;变成&amp;quot;开卷考试&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它和微调的根本区别在于：微调把知识&amp;quot;烧进&amp;quot;模型权重里，RAG 把知识放在模型之外的数据库里，用的时候现查。这也决定了两者的适用边界——后面会详细对比。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三rag-工作流程三阶段详解&#34;&gt;三、RAG 工作流程：三阶段详解
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/rag-overview.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/rag-overview.svg&#34; alt=&#34;RAG 工作流程：检索 → 增强 → 生成&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;RAG 的完整流程可以拆成&lt;strong&gt;离线建库&lt;/strong&gt;和&lt;strong&gt;在线问答&lt;/strong&gt;两大阶段。在线问答又分为检索、增强、生成三步。&lt;/p&gt;
&lt;h3 id=&#34;31-离线阶段把文档变成可检索的向量库&#34;&gt;3.1 离线阶段：把文档变成可检索的向量库
&lt;/h3&gt;&lt;p&gt;这一步是&amp;quot;建图书馆&amp;quot;的过程，通常一次性完成，知识更新时增量重建：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;文档加载&lt;/strong&gt;：读取 PDF、Word、HTML、Markdown 等原始文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;切分（Chunking）&lt;/strong&gt;：把长文档切成小段。为什么不整篇存？因为检索时要找最相关的片段，整篇文档向量会&amp;quot;稀释&amp;quot;语义；而且 LLM 上下文有限，塞不下整篇&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;向量化（Embedding）&lt;/strong&gt;：用嵌入模型把每段文本转成一个高维向量（通常 768~1536 维），语义相近的文本在向量空间里距离也近&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存入向量数据库&lt;/strong&gt;：把向量和原文一起存进去，建好索引，供后续快速检索&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;32-在线阶段检索--增强--生成&#34;&gt;3.2 在线阶段：检索 → 增强 → 生成
&lt;/h3&gt;&lt;p&gt;用户每一次提问，都会实时跑这三步：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① 检索 Retrieval&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把用户问题用同一个 Embedding 模型转成向量&lt;/li&gt;
&lt;li&gt;在向量数据库中做相似度检索（通常用余弦相似度），召回 Top-K（一般 3~10 条）最相关的文档片段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;② 增强 Augmentation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把检索到的片段拼到 Prompt 模板里，作为上下文&lt;/li&gt;
&lt;li&gt;一个典型的 Prompt 长这样：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;你是一个严谨的问答助手，请根据以下参考资料回答用户问题。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;如果资料中没有答案，请回答&amp;#34;根据现有资料无法回答&amp;#34;，不要编造。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;【参考资料】
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{检索到的文档片段1}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{检索到的文档片段2}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;【用户问题】
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{用户的问题}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;③ 生成 Generation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把拼好的 Prompt 喂给 LLM，生成最终回答&lt;/li&gt;
&lt;li&gt;可以要求模型在回答中标注引用来源，实现可溯源&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四完整架构图&#34;&gt;四、完整架构图
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/rag-architecture.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/rag-architecture.svg&#34; alt=&#34;RAG 完整架构：离线建库 &amp;#43; 在线问答&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;这张图把离线和在线两条流水线放在了一起。注意几个关键点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Embedding 模型必须一致&lt;/strong&gt;：离线建库用哪个模型，在线检索时也要用同一个，否则向量空间不兼容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识更新无需重训模型&lt;/strong&gt;：新增文档只需走一遍&amp;quot;切分 → 向量化 → 入库&amp;quot;，模型权重完全不动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索质量是 RAG 的命门&lt;/strong&gt;：如果第一步召回的片段就不相关，后面 LLM 再强也答不好&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五核心组件选型&#34;&gt;五、核心组件选型
&lt;/h2&gt;&lt;p&gt;RAG 系统由四个核心组件构成，选型直接影响效果：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;组件&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;th&gt;常见选型&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Embedding 模型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文本转向量，决定语义匹配上限&lt;/td&gt;
&lt;td&gt;BGE（智源）、M3E、OpenAI text-embedding-3、Cohere、bge-m3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;向量数据库&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;存储与检索向量&lt;/td&gt;
&lt;td&gt;Milvus、Qdrant、Chroma、Pinecone、FAISS、Weaviate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;基于上下文生成回答&lt;/td&gt;
&lt;td&gt;GPT-4、Claude、Qwen、DeepSeek、Llama、GLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;编排框架&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;串联整个流程&lt;/td&gt;
&lt;td&gt;LangChain、LlamaIndex、Haystack、DSPy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;几个选型经验：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;中文场景&lt;/strong&gt;：Embedding 优先考虑 &lt;code&gt;bge-large-zh&lt;/code&gt; 或 &lt;code&gt;bge-m3&lt;/code&gt;，比 OpenAI 的英文模型在中文检索上更准&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;轻量起步&lt;/strong&gt;：向量库用 Chroma（纯 Python，单机嵌入式）跑通流程，量大了再换 Milvus / Qdrant&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;框架选择&lt;/strong&gt;：快速原型用 LangChain，文档密集型场景用 LlamaIndex（它对文档处理和索引抽象更细致）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六进阶技术从能用到好用&#34;&gt;六、进阶技术：从&amp;quot;能用&amp;quot;到&amp;quot;好用&amp;quot;
&lt;/h2&gt;&lt;p&gt;朴素 RAG（一次向量检索 + 拼 Prompt）能跑通，但效果往往一般。真正生产级的 RAG 通常会在四个方向上做增强：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/advanced-rag.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/advanced-rag.svg&#34; alt=&#34;RAG 进阶技术矩阵&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3 id=&#34;61-query-改写让问题更适合检索&#34;&gt;6.1 Query 改写（让问题更适合检索）
&lt;/h3&gt;&lt;p&gt;用户的问题往往是口语化、模糊的，直接拿去检索效果差。常见技巧：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Query Rewriting&lt;/strong&gt;：让 LLM 把&amp;quot;那个东西怎么用&amp;quot;改写成&amp;quot;产品 X 的使用方法&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HyDE（Hypothetical Document Embeddings）&lt;/strong&gt;：先让 LLM 生成一个假设性答案，再用这个答案的向量去检索——因为&amp;quot;答案&amp;quot;和&amp;quot;答案&amp;quot;的语义比&amp;quot;问题&amp;quot;和&amp;quot;答案&amp;quot;更接近&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-Query&lt;/strong&gt;：把一个问题拆成多个子问题分别检索，结果合并去重&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Step-back Prompting&lt;/strong&gt;：先抽象出上位概念再检索，比如&amp;quot;2024 年诺贝尔物理学奖得主&amp;quot;先退到&amp;quot;诺贝尔物理学奖近年得主&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;62-混合检索--rerank多路召回精排提纯&#34;&gt;6.2 混合检索 + Rerank（多路召回，精排提纯）
&lt;/h3&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/retrieval-detail.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/retrieval-detail.svg&#34; alt=&#34;混合检索 &amp;#43; 重排：提升召回质量&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;单靠向量检索有个问题：它擅长语义匹配，但对&lt;strong&gt;专有名词、产品型号、人名&lt;/strong&gt;这种精确字面匹配反而不如传统检索。所以生产系统通常用&lt;strong&gt;混合检索&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;向量检索&lt;/strong&gt;（语义）+ &lt;strong&gt;BM25 关键词检索&lt;/strong&gt;（字面）并行召回&lt;/li&gt;
&lt;li&gt;用 &lt;strong&gt;RRF（Reciprocal Rank Fusion）&lt;/strong&gt; 融合两路结果&lt;/li&gt;
&lt;li&gt;再用 &lt;strong&gt;Cross-Encoder 重排模型&lt;/strong&gt;（如 &lt;code&gt;bge-reranker-large&lt;/code&gt;、Cohere Rerank）对召回结果做精排&lt;/li&gt;
&lt;li&gt;最后取 Top-K 喂给 LLM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rerank 的关键区别：Embedding 是把 query 和 doc &lt;strong&gt;分别&lt;/strong&gt;编码再算相似度（双塔），而 Cross-Encoder 是把 query 和 doc &lt;strong&gt;拼一起&lt;/strong&gt;送进模型（交叉编码），精度高得多，但速度慢——所以先用向量检索粗筛，再用 Rerank 精排，兼顾速度和精度。&lt;/p&gt;
&lt;h3 id=&#34;63-graphrag基于知识图谱的全局检索&#34;&gt;6.3 GraphRAG：基于知识图谱的全局检索
&lt;/h3&gt;&lt;p&gt;微软 2024 年提出的 GraphRAG 解决的是朴素 RAG 的另一个痛点：&lt;strong&gt;局部性&lt;/strong&gt;。向量检索只能召回和问题相似的片段，回答不了&amp;quot;总结整个文档集的核心主题&amp;quot;这种全局性问题。&lt;/p&gt;
&lt;p&gt;GraphRAG 的做法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用 LLM 从文档中抽取&lt;strong&gt;实体和关系&lt;/strong&gt;，构建知识图谱&lt;/li&gt;
&lt;li&gt;用&lt;strong&gt;社区检测算法&lt;/strong&gt;（如 Leiden）把图谱分成主题层次化的社区&lt;/li&gt;
&lt;li&gt;为每个社区生成摘要&lt;/li&gt;
&lt;li&gt;查询时根据问题粒度选择社区摘要或具体节点回答&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;它特别适合&amp;quot;全局性总结&amp;quot;&amp;ldquo;跨文档推理&amp;quot;类问题，代价是建图成本高、更新麻烦。&lt;/p&gt;
&lt;h3 id=&#34;64-self-rag--自适应-rag让模型自己决定要不要检索&#34;&gt;6.4 Self-RAG / 自适应 RAG：让模型自己决定要不要检索
&lt;/h3&gt;&lt;p&gt;不是每个问题都需要检索——&amp;ldquo;1+1 等于几&amp;quot;还去查库就浪费了。Self-RAG 让模型学会自我反思：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;是否检索&lt;/strong&gt;：判断问题是否需要外部知识，简单问题直接答&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索结果是否相关&lt;/strong&gt;：过滤掉无关片段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成是否忠于检索&lt;/strong&gt;：检查答案有没有脱离资料编造&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好处是省 token、降延迟，坏处是需要训练模型学会这些判断（或用 prompt 模拟），实现复杂度高。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七方案对比rag-vs-微调-vs-长上下文&#34;&gt;七、方案对比：RAG vs 微调 vs 长上下文
&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/solution-comparison.svg&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;img src=&#34;https://SymphonyW.github.io/zh-cn/p/rag-%E6%8A%80%E6%9C%AF%E5%85%A8%E6%99%AF%E8%AE%A9%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BB%8E%E9%97%AD%E5%8D%B7%E8%80%83%E8%AF%95%E5%88%B0%E5%BC%80%E5%8D%B7%E8%80%83%E8%AF%95/solution-comparison.svg&#34; alt=&#34;四种知识注入方案横向对比&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;随着模型上下文窗口越来越长（Claude 200K、Gemini 1M、GPT-4o 128K），有人质疑 RAG 是不是过时了——直接把所有文档塞进上下文不就行了？&lt;/p&gt;
&lt;p&gt;实际并非如此，三者各有定位：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;长上下文&lt;/strong&gt;：贵（按 token 计费）、易&amp;quot;迷失在中间&amp;rdquo;（Lost in the Middle 现象）、不可溯源。适合一次性分析单份长文档&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG&lt;/strong&gt;：经济、可扩展到海量文档、可溯源。适合知识库问答&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;微调&lt;/strong&gt;：改变模型行为/风格，而非注入事实知识。适合固定格式输出、领域术语适配&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG + 微调&lt;/strong&gt;：效果最好，成本最高，用于高精度专业场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;经验法则：&lt;strong&gt;知识频繁变化 → RAG；风格/格式固定 → 微调；两者都要 → 结合用。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;八实战用-langchain-跑通一个最小-rag&#34;&gt;八、实战：用 LangChain 跑通一个最小 RAG
&lt;/h2&gt;&lt;p&gt;理论讲完，来看一段能跑的代码。用 LangChain + Chroma + OpenAI 实现 30 行的 RAG：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TextDocumentLoader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_text_splitters&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RecursiveCharacterTextSplitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_openai&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ChatOpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Chroma&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_core.prompts&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ChatPromptTemplate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_core.runnables&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RunnablePassthrough&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StrOutputParser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ① 离线建库：加载 → 切分 → 向量化 → 入库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;docs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TextDocumentLoader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;knowledge.txt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;chunks&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chunk_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chunk_overlap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;# 500 字一段，重叠 50 字&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;docs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;vectorstore&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Chroma&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chunks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text-embedding-3-small&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;retriever&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vectorstore&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_retriever&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_kwargs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;k&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 召回 Top-4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ② 在线问答：检索 → 增强 → 生成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;你是严谨的问答助手，根据以下资料回答问题。资料中没有答案就说&amp;#34;无法回答&amp;#34;，不要编造。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;【资料】
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{context}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;【问题】
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{question}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format_docs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;docs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;page_content&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;docs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;rag_chain&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;retriever&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_docs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;question&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RunnablePassthrough&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prompt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ChatOpenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gpt-4o-mini&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StrOutputParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ③ 提问&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rag_chain&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invoke&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;公司请假流程是什么？&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这段代码虽然简单，但已经包含了 RAG 的所有核心环节。生产化时再把 Embedding 换成 BGE、加上 Rerank、换成 Milvus，骨架不变。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;九常见挑战与优化方向&#34;&gt;九、常见挑战与优化方向
&lt;/h2&gt;&lt;p&gt;实际落地 RAG，踩坑往往不在模型，而在检索。下面是常见问题对应的优化手段：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;症状&lt;/th&gt;
&lt;th&gt;根因&lt;/th&gt;
&lt;th&gt;优化方向&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;检索结果不相关&lt;/td&gt;
&lt;td&gt;Query 与文档语义差距大&lt;/td&gt;
&lt;td&gt;Query 改写、换更强的 Embedding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;召回准确但答非所问&lt;/td&gt;
&lt;td&gt;片段顺序/噪声干扰&lt;/td&gt;
&lt;td&gt;加 Rerank 精排、调 Top-K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;答案不忠于资料&lt;/td&gt;
&lt;td&gt;LLM 忽略上下文编造&lt;/td&gt;
&lt;td&gt;Prompt 加约束、降 temperature、强制引用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;专有名词召回差&lt;/td&gt;
&lt;td&gt;纯向量检索短板&lt;/td&gt;
&lt;td&gt;加 BM25 混合检索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;上下文超长&lt;/td&gt;
&lt;td&gt;召回太多塞不下&lt;/td&gt;
&lt;td&gt;上下文压缩、LongLLMLingua、换长上下文模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;知识更新延迟&lt;/td&gt;
&lt;td&gt;索引重建慢&lt;/td&gt;
&lt;td&gt;增量索引、流式更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;答案无法溯源&lt;/td&gt;
&lt;td&gt;未保留片段来源&lt;/td&gt;
&lt;td&gt;检索结果带 metadata，Prompt 要求标注引用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一个经验：&lt;strong&gt;80% 的 RAG 优化工作都在检索阶段&lt;/strong&gt;，而不是生成阶段。先把检索做准，效果立刻提升一大截。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十典型应用场景&#34;&gt;十、典型应用场景
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;企业知识问答&lt;/strong&gt;：基于内部 Wiki、手册、合同的智能客服与员工助手&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;法律/医疗咨询&lt;/strong&gt;：基于法条、判例、药品说明、病历的精准问答&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码助手&lt;/strong&gt;：基于私有代码库的代码生成（Cursor、Copilot Workspace 都用了 RAG 思想）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教育辅导&lt;/strong&gt;：基于教材的个性化答疑，答案可指向课本页码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;智能搜索&lt;/strong&gt;：搜索引擎的 AI 摘要（Perplexity、Bing Chat、Google AI Overviews）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据分析&lt;/strong&gt;：Text-to-SQL，基于数据库 schema 的自然语言查询&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;RAG 不是某个具体工具，而是一种 &lt;strong&gt;&amp;ldquo;把外部知识检索和大模型生成结合起来&amp;rdquo;&lt;/strong&gt; 的架构思想。它的价值在于：让大模型能用最新、最准、可溯源的外部知识来回答问题，而无需重新训练。&lt;/p&gt;
&lt;p&gt;回顾本文要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：检索 → 增强 → 生成，让 LLM 从闭卷变开卷&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;两大阶段&lt;/strong&gt;：离线建库（切分+向量化+入库）+ 在线问答（检索+增强+生成）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;命门在检索&lt;/strong&gt;：80% 的优化工作都在检索阶段&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;进阶四件套&lt;/strong&gt;：Query 改写、混合检索+Rerank、GraphRAG、Self-RAG&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;方案选择&lt;/strong&gt;：知识频繁变化用 RAG，风格固定用微调，高精度场景结合使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;随着模型上下文窗口变长、多模态能力增强，RAG 的形态还在演进（比如多模态 RAG、Agentic RAG），但&amp;quot;外挂知识库&amp;quot;这个核心思想短期内不会过时——毕竟，开卷考试永远比背书更可靠。&lt;/p&gt;
&lt;p&gt;如果你对其中某个环节（比如向量数据库选型、Embedding 微调、GraphRAG 实现）想深入，欢迎在评论区交流。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
