系列:100 天系统学习 AI Agent 开发
当前阶段:RAG、知识库与工具边界
今日目标:Embedding 把文本映射到向量空间,向量检索用相似度找出最相关的片段。

搜到“意思差不多”,离答对还很远

关键词搜索擅长找相同字词。用户问“Agent 断线后怎么接着跑”,资料里写的是“checkpoint 支持恢复执行”,两边没有完全相同的表达,关键词可能错过。Embedding 的用处,是把文本编码成一组数字,让语义接近的文本在向量空间里更靠近。

但“靠近”只是统计意义上的相似,不代表事实正确,更不代表片段足以回答问题。部署文档和卸载文档会共享大量词;旧版本与新版本也可能非常相似。向量检索解决的是候选召回,不是最终判断。

从文本到候选片段

文档片段

Embedding 模型

向量 + 原文 + metadata

用户问题

同一 Embedding 模型

查询向量

相似度搜索

过滤/重排后的 Top K

交给模型基于证据回答

向量数据库实际保存的不应只有向量。至少还要有原始文本、chunk_id、来源、版本、权限和更新时间。否则即使搜到了,也无法引用、过滤或删除。

常见相似度可以直观理解为“方向是否接近”。下面只是数学演示,不负责生成真实 Embedding:

from math import sqrt

def cosine_similarity(a: list[float], b: list[float]) -> float:
    if len(a) != len(b) or not a:
        raise ValueError("向量维度必须相同且不能为空")
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = sqrt(sum(x * x for x in a))
    norm_b = sqrt(sum(y * y for y in b))
    if norm_a == 0 or norm_b == 0:
        raise ValueError("零向量没有可用方向")
    return dot / (norm_a * norm_b)

真实系统必须使用同一套、同一版本的 Embedding 生成文档向量和查询向量。更换模型后直接混用旧索引,维度可能不同;即便维度碰巧相同,空间含义也不保证一致,通常需要重建索引或维护明确的索引版本。

五段学习笔记怎么准备

chunk_id 笔记主题 关键词 是否独立成块 理由
d006-loop Agent Loop 与最大轮数 loop、停止条件、observation 能独立回答循环控制
d007-retry 可重试错误与幂等 timeout、retry、idempotency 与参数缺失策略不同
d007-input 缺参数时如何追问 missing field、ask user 不应和自动重试混为一谈
d008-memory 短期/长期记忆 scope、TTL、source 有完整的概念边界
d009-cli CLI 与安全计算器 router、allowlist、trace 可按标题再拆 代码和设计理由检索意图不同

这里我会保留标题路径,例如“Day 007 > 错误分类 > 需要补充”,而不是只存正文。很多短片段脱离标题后会失去“它在讨论什么”的信息。

向量、关键词还是混合检索

查询特点 更合适的起点
精确错误码、函数名、订单号 关键词/倒排检索
同义表达、自然语言问题 向量检索
既有专有名词又有语义描述 混合检索
强版本或权限约束 先做 metadata 过滤,再检索

只用向量检索的一个典型反例是错误码。“E_CONN_1042”几乎不需要语义联想,精确匹配更可靠。工程上经常把关键词和向量候选合并,再用规则或重排模型排序。

我会怎样比较,而不是凭感觉

准备五个问题,为每题预先标注应命中的 chunk_id,再记录 Top 1、Top 3 是否包含目标:

{
  "query": "网络超时可以自动重试吗?",
  "expected_chunk_ids": ["d007-retry"],
  "retrieved_chunk_ids": [],
  "hit_at_1": null,
  "hit_at_3": null,
  "notes": "真实运行后填写"
}

列表保留空值,是为了明确本文没有运行向量模型。之后改变 chunk 大小、Embedding 模型或过滤条件时,用同一批问题复跑,才知道提升发生在哪里。

今天留下的判断

Embedding 像一张语义地图,向量数据库像管理这张地图的检索系统;它们都不是事实裁判。真正可靠的 RAG 还需要切分、元数据、过滤、重排、引用和拒答。下一篇研究 Chunking,正是因为“地图上的一个点代表多大一段文本”会直接影响能否找对。

面试官会追问:换一个 Embedding 模型,怎么证明更好?

不能只看某个问题“搜得更像”。同一批查询要固定语料、切分和 top-k,比较 Recall@k、MRR、索引体积、构建时间与单次检索延迟;中文、英文、代码和缩写查询还要分桶统计。向量维度更大可能提升表达能力,也会增加存储、内存和 ANN 搜索成本。

我会准备三类难例:同义改写、精确编号、跨语言表达。若向量检索擅长同义改写但漏掉产品编号,就用 BM25 与向量检索做混合召回,而不是逼一个 Embedding 模型同时解决全部问题。

面试时最重要的一句是:Embedding 选型是检索系统实验,不是模型排行榜抄答案;判断标准来自自己的语料和查询分布。

今日检查清单

  • 文档向量和查询向量来自同一模型版本
  • 每个向量能追溯到原文、来源、版本和权限
  • 精确标识符没有强行只走语义检索
  • 用预标注问题计算命中,不用一条漂亮回答下结论
  • 更换 Embedding 模型时有索引迁移或重建计划
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐