INNER 05 / RAG / 01 · ENGINE v1
向量表示与余弦相似度基础(Module 1: CosineExplorer)
先手算余弦相似度,再补上阈值、空结果和结构化返回。
30 SECONDS / 30 秒看懂
这一关只解决一件事:在 StepByStep-RAG 的第一模块 CosineExplorer 中,作者指出理解 RAG 的起点是搞懂计算机如何衡量两段文字“意思相近”。通过嵌入模型(Embedding Model),每段文本被映射为高维空间中的数值向量 A 与 B。
- 正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常(
- 5 分);
- 加入最低相似度阈值过滤(min_score =
3 MINUTES / 3 分钟拆解
先看来源里的例子:PDF 本关任务(来源)
参照 CosineExplorer.py 的教学精神,在不依赖重型黑盒框架的前提下,用基础 Python / NumPy 编写一个计算用戶问题向量与知识库候选文档向量矩阵余弦相似度、并返回大于阈值(threshold >= 0.75)的前 K 个文档索引与得分的核心函数。 待改造劣质代码:def search(q, docs): return sorted(docs, key=lambda d: sum(q*d))[:3](缺陷:仅算点积未做模长归一化,长文档或数值偏大的向量会霸榜,且无最低相关度阈值过滤。)
发生了什么
来源要求:正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常( / 5 分); / 加入最低相似度阈值过滤(min_score =
输出
参考答案:参考答案与代码解析(Answer Key) 以下提供全套 8 关的 Python 核心实现代码、算法公式与工业级配置模板,助你快速落地本地知识库项目。 第 1 关参考答案:零框架依赖的 NumPy 余弦相似度检索引擎实现 import numpy as np from typing import List, Dict, Any def cosine_similarity_search( query_vec: np.ndarray, do
术语拆开
- Embedding
- 把文本映射成数值向量。
- L2 范数
- 向量的长度,用于归一化。
为什么有效
来源核心原理:在 StepByStep-RAG 的第一模块 CosineExplorer 中,作者指出理解 RAG 的起点是搞懂计算机如何衡量两段文字“意思相近”。通过嵌入模型(Embedding Model),每段文本被映射为高维空间中的数值向量 A 与 B。衡量它们语义接近程度的核心指标是余弦相似度(Cosine Similarity):即两个向量夹角的余弦值 (点积除以各自模长的乘积),取值范围为 [-1, 1]。夹角越接近 0 度,余弦值越接近 1,代表语义高度重合;与向量绝对长度(文章字数多少)无关,只看方向是否一致。
结构长什么样
正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常(
5 分);
加入最低相似度阈值过滤(min_score =
75),当所有候选文档得分均低于阈值时返回空列表而非强行凑够 Top-K;
按相似度从高到低排序并返回包含 {"doc_id", "score", "text"} 的结构化列表。余弦相似度为什么与向量长度无关?
SOURCE READING / 来源精读
在 StepByStep-RAG 的第一模块 CosineExplorer 中,作者指出理解 RAG 的起点是搞懂计算机如何衡量两段文字“意思相近”。通过嵌入模型(Embedding Model),每段文本被映射为高维空间中的数值向量 A 与 B。
逐点读懂
- 正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常(
- 5 分);
- 加入最低相似度阈值过滤(min_score =
怎么对应本关练习
先读 30 秒与 3 分钟拆解,再读本关原文与实验,最后做客观题和实操题;答案在下方。
例子在哪
本关任务与参考答案见页面下方;来源为本册 PDF 对应关卡。
本关先记住:正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常(
核心原理
在 StepByStep-RAG 的第一模块 CosineExplorer 中,作者指出理解 RAG 的起点是搞懂计算机如何衡量两段文字“意思相近”。
通过嵌入模型(Embedding Model),每段文本被映射为高维空间中的数值向量 A 与 B。
衡量它们语义接近程度的核心指标是余弦相似度(Cosine Similarity):即两个向量夹角的余弦值 (点积除以各自模长的乘积),取值范围为 [-1, 1]。
夹角越接近 0 度,余弦值越接近 1,代表语义高度重合;与向量绝对长度(文章字数多少)无关,只看方向是否一致。
第 1 关实操练习题:编写零第三方框架依赖的余弦相似度检索函数
任务背景
参照 CosineExplorer.py 的教学精神,在不依赖重型黑盒框架的前提下,用基础 Python / NumPy 编写一个计算用戶问题向量与知识库候选文档向量矩阵余弦相似度、并返回大于阈值(threshold >= 0.75)的前 K 个文档索引与得分的核心函数。
待改造劣质代码:def search(q, docs): return sorted(docs, key=lambda d: sum(q*d))[:3](缺陷:仅算点积未做模长归一化,长文档或数值偏大的向量会霸榜,且无最低相关度阈值过滤。
)
通关硬性要求(满分 12.5 分)
1. 正确写出包含 L2 范数(模长)归一化的余弦相似度计算公式并防范除零异常(
4.5 分);
2. 加入最低相似度阈值过滤(min_score =
0.75),当所有候选文档得分均低于阈值时返回空列表而非强行凑够 Top-K(5 分);
3. 按相似度从高到低排序并返回包含 {"doc_id", "score", "text"} 的结构化列表(3 分)。
PRACTICE / 本关练习 · 本地规则 + 覆盖检查
编写零第三方框架依赖的余弦相似度检索函数
本地检查在你的浏览器里完成,不上传。覆盖检查需要先登录(免费注册),并把这段答案发送到服务器计算一次,算完即弃、不存档,需你点同意;只核对本关评分项覆盖的方向,不在评分项里的题目不会被检查。
评分项
结构分 — / 12.5 分
查看参考答案与得分点 先自己写,再打开+
参考答案与得分要点
参考答案:零框架依赖的 NumPy 余弦相似度检索引擎实现 import numpy as np from typing import List, Dict, Any def cosine_similarity_search( query_vec: np.ndarray, doc_matrix: np.ndarray, docs_meta: List[Dict[str, Any]], top_k: int = 3, min_score: float = 0.75 ) -> List[Dict[str, Any]]: # 1. 计算 L2 范数(模长),加上 1e-10 防止零向量导致除零异常 query_norm = np.linalg.norm(query_vec) + 1e-10 docs_norm = np.linalg.norm(doc_matrix, axis=1) + 1e-10 # 2. 计算全库余弦相似度: (A · B) / (||A|| * ||B||) similarities = np.dot(doc_matrix, query_vec) / (docs_norm * query_norm) # 3. 过滤低于 min_score 阈值的无关文档并按得分降序排列 valid_indices = np.where(similarities >= min_score)[0] if len(valid_indices) == 0: return [] # 严格触发无相关资料回退,绝不强凑低分噪音 sorted_indices = valid_indices[np.argsort(similarities[valid_indices])[::-1]][:top_k] return [ { "doc_id": docs_meta[idx]["id"], "score": round(float(similarities[idx]), 4), "text": docs_meta[idx]["text"] } for idx in sorted_indices ] 得分要点拆解:准确实现点积除以模长乘积并加 `1e-10` 防除零(4.5 分);严格过滤低于 `0.75` 的噪音文档、支持返回空列表(5 分);按降序输出结构化字典列表(3 分)。 第 2 关
网页永久免费。完整 PDF 会按顺序发给留邮箱的读者,不转售、不群发广告。
留邮箱,获取完整 PDF ↗