主题
第 3 章 · 文档切分与向量化:RAG 的"地基工程"
🎯 本章目标:理解切分和向量化为什么是 RAG 的"地基",掌握选型决策框架,能解释"为什么我的 RAG 召回不准"。
💡 业内黄金法则:RAG 系统 80% 的效果,由切分和 Embedding 决定。再好的 LLM 也救不了垃圾的检索。
目录
1. 文档切分 Chunking 深度解析
1.1 为什么切分是地基?
一个真实的反面案例
公司知识库:50 份产品手册,平均每份 100 页。
工程师小王:用默认 1000 字符切分。
用户问:「产品 A 的退货政策是什么?」
召回 Top-3:
Chunk 1(相似度 0.85): 「产品 A 的退货政策详见附录 C,需要满足以下条件...」
↑ 注意!这里 "退货政策" 出现了,但实际内容在附录 C 没切到这块
Chunk 2(相似度 0.78): 「产品 B 的售后服务包括...」 ← 不相关
Chunk 3(相似度 0.72): 「公司物流合作伙伴...」 ← 不相关
LLM 回答:「产品 A 的退货政策详见附录 C,请查阅相关章节。」 ← 等于没答1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
问题根源:切分时把"指引"和"实际内容"切开了,召回到的全是无效片段。
1.2 切分的核心矛盾
💡 切分的本质是 "在语义完整性"和"检索精度"之间找平衡。
1.3 好切分的三个标准
| 标准 | 解释 | 反例 |
|---|---|---|
| 语义完整 | 一个 Chunk 内容讲清楚一件事 | 一个事实跨两个 Chunk |
| 信息密度高 | Chunk 内大部分内容和某个语义点强相关 | 一个 Chunk 同时混了 5 个主题 |
| 大小适中 | 既能装下完整语义,又不至于稀释相关性 | 1 句话 / 10000 字 |
2. 五种主流切分策略详解
2.1 策略一:固定长度切分(Fixed-size Chunking)
思路
每 N 个字符 / Token 切一刀,简单粗暴。
例子
原文(300 字):「猫咪是一种常见的宠物动物,它们通常活泼好动……
关于猫咪的饮食,主要分为干粮和湿粮两种……
当猫咪生病时,常见症状包括……」
按 100 字符切:
Chunk 1: 「猫咪是一种常见的宠物动物,它们通常活泼好动……关于猫咪」
Chunk 2: 「的饮食,主要分为干粮和湿粮两种……当猫咪生病时」
Chunk 3: 「,常见症状包括……」1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
优缺点
| 优点 | 缺点 |
|---|---|
| ✅ 实现极简 | ❌ 经常把句子切断 |
| ✅ 速度快 | ❌ 不考虑语义 |
| ✅ 长度可控 | ❌ 效果差 |
适合场景
⚠️ 只适合 Demo 和原型验证。生产环境不推荐。
2.2 策略二:递归字符切分(Recursive Character Splitter)⭐ 最常用
思路
按优先级分隔符递归尝试切分:
优先级:段落分隔(\n\n) → 行(\n) → 句号(。)→ 逗号(,)→ 字符1
如果按 \n\n 切完,某个 Chunk 还是太大,就用 \n 继续切,依此类推。
例子
原文:「
猫咪发烧的常见原因:
1. 病毒感染
2. 细菌感染
3. 中暑
猫咪退烧的处理方法:
1. 保持环境凉爽
2. 提供充足饮水
3. 必要时送医
」
目标 Chunk 大小 100 字符:
第 1 步:按 \n\n 切分
Chunk A: 「猫咪发烧的常见原因:1. 病毒感染 2. 细菌感染 3. 中暑」(45 字符)
Chunk B: 「猫咪退烧的处理方法:1. 保持环境凉爽 2. 提供充足饮水 3. 必要时送医」(60 字符)
第 2 步:所有 Chunk 都小于 100 字符,无需进一步切分 ✓1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
✅ 关键优势:尽量保留 段落 → 句子 → 短语 的语义边界。
LangChain 的实现思路
python
RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", "!", "?", ",", " ", ""]
)1
2
3
4
5
2
3
4
5
适合场景
🌟 绝大多数通用场景的首选,无脑选这个不会错。
2.3 策略三:按文档结构切分(Markdown / HTML Splitter)
思路
利用文档自身的结构(Markdown 标题、HTML 标签)切分。
Markdown 例子
markdown
# 宠物医疗手册
## 第一章 猫咪疾病
### 1.1 发烧
猫咪发烧的常见原因...
### 1.2 腹泻
猫咪腹泻的常见原因...
## 第二章 狗狗疾病
### 2.1 皮肤病
狗狗皮肤病的常见类型...1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
按 H2/H3 标题切分,每个 Chunk 还能带上层级路径:
Chunk 1:
metadata: { h1: "宠物医疗手册", h2: "第一章 猫咪疾病", h3: "1.1 发烧" }
content: "猫咪发烧的常见原因..."
Chunk 2:
metadata: { h1: "宠物医疗手册", h2: "第一章 猫咪疾病", h3: "1.2 腹泻" }
content: "猫咪腹泻的常见原因..."1
2
3
4
5
6
7
2
3
4
5
6
7
优点
| 优点 | 解释 |
|---|---|
| ✅ 完美保留结构 | 章节、小节边界清晰 |
| ✅ Metadata 丰富 | 层级路径可用于过滤检索 |
| ✅ 召回准 | 一个小节通常就是一个完整知识点 |
适合场景
- 技术文档、API 文档
- 法律法规(章/节/条)
- 教科书
- Wiki 类内容
2.4 策略四:语义切分(Semantic Chunking)
思路
不按字符数切,而是按语义相似度自动判断在哪里切。
💡 类比:你读一本小说,作者在 "场景切换" 时会自然换段。语义切分就是让算法自动识别这种 "语义切换点"。
算法步骤
例子
句子序列:
S1: "今天天气很好" (相似度 → S2: 0.92)
S2: "适合户外活动" (相似度 → S3: 0.88)
S3: "公园里很多人在散步" (相似度 → S4: 0.30 ← 突然下降!)
S4: "Python 是一门解释型语言" (相似度 → S5: 0.85)
S5: "适合初学者上手"
→ 在 S3 和 S4 之间切一刀(语义跳跃点)
Chunk 1: S1 + S2 + S3 (讲天气和户外)
Chunk 2: S4 + S5 (讲编程)1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
优缺点
| 优点 | 缺点 |
|---|---|
| ✅ 语义边界精准 | ❌ 计算成本高(每句都要 Embedding) |
| ✅ 适合长连续文本 | ❌ 实现复杂 |
| ✅ 不依赖文档格式 | ❌ 阈值难调 |
适合场景
- 小说、长篇连续文本
- 没有明显结构的口语化转写
- 对召回质量极致追求的场景
2.5 策略五:基于 Token 的切分
思路
不按字符切,按大模型的 Token 数切。
为什么?
- 中文一个汉字通常对应 1-2 个 Token
- 英文一个单词通常 1-4 个 Token
- LLM 收费按 Token 算,按 Token 切能精确控制成本和长度
工具
python
import tiktoken
encoder = tiktoken.encoding_for_model("gpt-4")
tokens = encoder.encode("你的文本")
# 按 500 Token 切
chunks = []
for i in range(0, len(tokens), 500):
chunk_tokens = tokens[i:i+500]
chunks.append(encoder.decode(chunk_tokens))1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
适合场景
- 严格控制 LLM 输入长度的场景
- 需要精确预估 API 成本
2.6 五种策略对比速查表
| 策略 | 实现难度 | 召回质量 | 速度 | 推荐度 | 适合 |
|---|---|---|---|---|---|
| 固定长度 | ⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | Demo |
| 递归字符 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 通用首选 |
| 文档结构 | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 结构化文档 |
| 语义切分 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | 极致追求 |
| 基于 Token | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | 严控长度 |
2.7 进阶组合策略
实际生产中往往组合多种策略:
组合方案 A:父子文档(Parent-Child)
父 Chunk: 完整章节(2000 字,提供完整上下文)
子 Chunk: 细粒度切分(300 字,用于精准检索)
检索时:
1. 用子 Chunk 检索(精准)
2. 召回后用对应的父 Chunk 喂给 LLM(上下文完整)1
2
3
4
5
6
2
3
4
5
6
💡 效果:兼顾"检索精度"和"上下文完整性",是企业级 RAG 的标配。
组合方案 B:摘要 + 原文
对每个章节生成一个 LLM 摘要
向量库存储:摘要的 Embedding
关联:摘要 ↔ 原文
检索时:
1. 用摘要做向量检索(信息密度高,检索精准)
2. 召回后取对应的原文喂给 LLM1
2
3
4
5
6
7
2
3
4
5
6
7
3. 切分参数怎么调
3.1 三个关键参数
| 参数 | 含义 | 经验值 |
|---|---|---|
chunk_size | 每个 Chunk 大小(字符 / Token) | 300-1500 字符 |
chunk_overlap | 相邻 Chunk 重叠大小 | chunk_size 的 10%-20% |
separators | 切分优先级分隔符 | 按段落 → 行 → 句子 → 字符 |
3.2 chunk_size 怎么定?
决策框架
实战经验
| 文档类型 | 推荐 chunk_size | 原因 |
|---|---|---|
| FAQ 问答对 | 200-300 | 每个 Q-A 就是一个原子单位 |
| 技术文档 | 500-800 | 一个小节一个 Chunk |
| 法律法规 | 300-500 | 一条法律就是一个独立逻辑 |
| 论文/书籍 | 800-1500 | 上下文跨度大 |
| 客服对话日志 | 200-400 | 一组对话一个 Chunk |
| 代码 | 按函数切 | 函数是天然单元 |
3.3 chunk_overlap 怎么定?
为什么需要重叠?
不重叠:
Chunk 1: "猫咪发烧的判断标准是体温超过 39.2 度,处理方法包括"
Chunk 2: "保持环境凉爽、提供充足饮水、必要时送医。"
↑
问题:"怎么处理猫咪发烧?"
检索到 Chunk 2,但 LLM 不知道是在讨论什么,可能答错。
有重叠:
Chunk 1: "猫咪发烧的判断标准是体温超过 39.2 度,处理方法包括"
Chunk 2: "猫咪发烧的处理方法包括保持环境凉爽、提供充足饮水、必要时送医。"
↑ 上文重叠了1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
取值建议
| chunk_size | 推荐 overlap | 比例 |
|---|---|---|
| 300 | 30-60 | 10%-20% |
| 500 | 50-100 | 10%-20% |
| 1000 | 100-200 | 10%-20% |
⚠️ 不要超过 30%,否则同一信息被存多份,浪费向量库,召回也会冗余。
3.4 怎么验证切分质量?
方法一:人工抽检
随机抽 20 个 Chunk,看:
- ✅ 内容是否完整?
- ✅ 是否在句中被切断?
- ✅ Chunk 是否聚焦一个主题?
方法二:召回测试
准备 10-20 个真实问题,跑检索,看:
- ✅ 是否能召回到 "应该被召回" 的 Chunk?
- ✅ 召回的 Chunk 相似度分数分布是否合理?
方法三:端到端评估
用 RAGAS 等工具评估 Context Recall、Context Precision 指标(详见第 6 章)。
4. Embedding 模型原理
4.1 什么是 Embedding?
直观理解
Embedding 模型 = "给文本算 DNA" 的机器。
输入:一段文本 输出:一个固定长度的向量(一串数字),代表文本的 "语义指纹"。
"猫咪发烧" → [0.12, -0.45, 0.78, 0.23, ..., 0.55] (1536 维)
"小猫体温升高" → [0.13, -0.43, 0.80, 0.21, ..., 0.54] ← 几乎相同
"狗狗腹泻" → [-0.20, 0.18, 0.42, -0.31, ..., 0.10]
"今天股市大跌" → [-0.55, 0.21, -0.30, 0.65, ..., -0.42]1
2
3
4
2
3
4
4.2 为什么向量能代表语义?
训练原理(极简版)
Embedding 模型通过 "对比学习" 训练:
训练数据:
正样本对(语义相近的句子对):
("猫咪发烧", "小猫体温升高")
("RAG 是什么", "检索增强生成的概念")
负样本对(语义无关的句子对):
("猫咪发烧", "今天股市大跌")
("RAG 是什么", "如何做红烧肉")
训练目标:
→ 让正样本对的向量距离尽可能近
→ 让负样本对的向量距离尽可能远1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
经过亿级语料的训练,模型学会了 "把语义相近的文本映射到向量空间的相近位置"。
4.3 向量空间的神奇属性
语义相似性
python
similarity("猫", "狗") = 0.85 # 都是宠物,相近
similarity("猫", "汽车") = 0.20 # 不相关1
2
2
语义代数(经典例子)
vector("国王") - vector("男人") + vector("女人") ≈ vector("女王")
vector("巴黎") - vector("法国") + vector("日本") ≈ vector("东京")1
2
2
这说明向量空间隐含了抽象的语义关系。
4.4 Embedding 的维度
| 维度 | 典型模型 | 含义 |
|---|---|---|
| 384 | bge-small | 小模型,速度快 |
| 768 | bge-base | 中等 |
| 1024 | bge-large、BGE-M3 | 主流 |
| 1536 | text-embedding-3-small | OpenAI 默认 |
| 3072 | text-embedding-3-large | OpenAI 高精度 |
💡 维度越高,理论表达能力越强,但存储和计算成本也越高。 经验上 768-1024 维是性价比之选。
5. 主流 Embedding 模型对比
5.1 选型核心维度
| 维度 | 关注点 |
|---|---|
| 语言 | 中文/英文/多语 |
| 领域 | 通用/垂直(医疗/法律/代码) |
| 长度 | 最大支持多长输入? |
| 维度 | 影响存储和计算 |
| 价格 | 免费开源 / 按 Token 付费 |
| 部署 | API / 自部署 |
| 性能 | MTEB 榜单排名 |
5.2 推荐模型清单
中文场景
| 模型 | 维度 | 部署方式 | 特点 |
|---|---|---|---|
| BGE-Large-zh-v1.5 | 1024 | 开源/自部署 | 中文 SOTA,免费 |
| BGE-M3 | 1024 | 开源/自部署 | 中英文+长文本(8192 Token) |
| Qwen3-Embedding | 1024 | API/开源 | 阿里出品,中文优秀 |
| M3E-large | 1024 | 开源/自部署 | 早期中文经典 |
英文/多语场景
| 模型 | 维度 | 部署方式 | 特点 |
|---|---|---|---|
| text-embedding-3-small | 1536 | OpenAI API | 性价比之王 |
| text-embedding-3-large | 3072 | OpenAI API | 效果好 |
| Cohere embed-v3 | 1024 | Cohere API | 检索优化 |
| Jina Embeddings v3 | 1024 | API/开源 | 多语支持好 |
| Voyage AI | 1024 | API | 垂直领域强 |
5.3 怎么选?决策表
| 你的情况 | 推荐 |
|---|---|
| 中文为主,预算有限 | BGE-Large-zh-v1.5(开源自部署) |
| 中英混合,文档很长 | BGE-M3(支持 8192 Token) |
| 全英文,省心想用 API | text-embedding-3-small |
| 追求 SOTA,预算充足 | text-embedding-3-large + Cohere Rerank |
| 数据敏感不能上云 | BGE 系列开源版自部署 |
| 代码搜索 | text-embedding-3 / Voyage Code 系列 |
5.4 评估 Embedding 模型的标准:MTEB
MTEB(Massive Text Embedding Benchmark) 是 Embedding 模型的"高考"。
中文版叫 C-MTEB,查中文模型排名看这个。
官方榜单:MTEB Leaderboard
5.5 一个 Embedding 实操例子
python
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
sentences = [
"猫咪发烧怎么办",
"小猫体温升高的处理",
"今天股市大跌",
]
embeddings = model.encode(sentences, normalize_embeddings=True)
import numpy as np
sim_1_2 = np.dot(embeddings[0], embeddings[1])
sim_1_3 = np.dot(embeddings[0], embeddings[2])
print(f"猫咪发烧 vs 小猫体温升高: {sim_1_2:.3f}")
print(f"猫咪发烧 vs 股市大跌: {sim_1_3:.3f}")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
6. 向量数据库选型
6.1 主流向量数据库全景
6.2 选型决策表
| 你的情况 | 推荐 |
|---|---|
| 上千万到亿级向量,要分布式 | Milvus |
| 千万级以下,重性能轻运维 | Qdrant |
| 已经在用 PostgreSQL | pgvector(不要再多引一个组件) |
| 已经在用 Elasticsearch | ES 向量字段(混合检索方便) |
| 本地开发 Demo | Chroma |
| 完全不想运维 | Pinecone / Zilliz Cloud |
| 需要"语义+关键词"混合检索原生支持 | Weaviate / ES |
6.3 关键能力对比
| 能力 | Milvus | Qdrant | Weaviate | Chroma | pgvector | ES |
|---|---|---|---|---|---|---|
| 分布式 | ✅ | ⭕ | ✅ | ❌ | 依赖 PG | ✅ |
| 元数据过滤 | ✅ | ✅✅ | ✅ | ✅ | ✅✅ | ✅✅ |
| 混合检索 | ✅ | ✅ | ✅✅ | ❌ | ⭕ | ✅✅ |
| 多向量字段 | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
| 学习曲线 | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐ | ⭐⭐ | ⭐⭐⭐ |
✅✅ = 原生强支持,✅ = 支持,⭕ = 部分支持,❌ = 不支持
7. 实战避坑指南
7.1 切分阶段的常见坑
坑 1:表格被切碎
原表格:
| 产品 | 价格 | 库存 |
|--------|------|------|
| 产品 A | 100 | 50 |
| 产品 B | 200 | 30 |
按字符切后:
Chunk 1: "| 产品 | 价格 | 库存 || 产品 A | 100 |"
Chunk 2: "50 || 产品 B | 200 | 30 |"
→ 表格语义彻底破碎1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
解决方案:
- 表格单独识别和处理(用
unstructured提取表格) - 把每行转成 "产品名: A, 价格: 100, 库存: 50" 这种独立 Chunk
坑 2:代码块被切断
原代码:
def foo():
return bar()
按字符切:
Chunk 1: "def foo():"
Chunk 2: " return bar()"
→ 单看 Chunk 2 不知道在讲什么1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
解决方案:
- 用
LangChain的RecursiveCharacterTextSplitter.from_language(Language.PYTHON) - 按函数/类作为最小切分单元
坑 3:标题和正文被切开
Chunk 1: "## 第二章 退货政策"
Chunk 2: "退货需要在 7 天内提出,并保持商品完好..."
→ 用户搜"退货政策"匹到 Chunk 1,但 Chunk 1 只有标题没有内容1
2
3
4
2
3
4
解决方案:
- 在 Chunk 内 复制上下文标题(如
[第二章 退货政策] 退货需要在 7 天内...) - 或者用文档结构切分(Markdown Splitter)
7.2 Embedding 阶段的常见坑
坑 1:入库和查询用了不同模型
入库:BGE-Large-zh-v1.5
查询:text-embedding-3-small
→ 两个完全不同的向量空间,相似度毫无意义
→ 召回乱七八糟1
2
3
4
5
2
3
4
5
解决方案:
- 严格固定一个模型
- 在向量库里加 metadata 记录用的什么模型
坑 2:归一化与否不一致
入库时:向量归一化(normalize_embeddings=True)
查询时:向量未归一化
→ 余弦相似度计算偏差1
2
3
4
2
3
4
解决方案:
- 入库和查询保持一致的归一化策略
- 推荐:都归一化(多数向量库默认期望归一化向量)
坑 3:中文用了英文模型
入库:text-embedding-ada-002(早期版本对中文不友好)
查询:中文问题
→ 中文召回质量差1
2
3
2
3
解决方案:
- 中文场景优先选 BGE / Qwen-Embedding / text-embedding-3
- 至少跑 MTEB 中文榜单看排名
7.3 向量库阶段的常见坑
坑 1:没建索引
向量数据库默认有索引但参数可能不优化,亿级数据下检索能慢到秒级。
解决方案:
- Milvus 用 HNSW 或 IVF_FLAT
- 调好
nlist、nprobe、ef_construction、ef_search等参数
坑 2:元数据没存够
入库时只存了 vector 和 text,没存 source、page、date、category
→ 后期想 "只检索 2024 年的文档",做不到
→ 想给用户展示来源出处,做不到1
2
3
4
2
3
4
解决方案:
- 入库时尽可能多存 metadata
- 至少包含:
source(文件名)、page(页码)、section(章节)、update_time、category
8. 思考题
为什么不直接把整本 1000 页的书 Embedding 成一个向量?
参考答案
- 信息稀释:1000 页有上千个主题,压成一个向量等于全是"平均语义",啥都搜不到。
- 召回粒度:你想找的可能就是其中一段,整本书的向量没法定位到那一段。
- Token 限制:Embedding 模型有最大输入长度(通常 512-8192 Token)。
- 解决方案:先切分再 Embedding,每个 Chunk 一个向量。
chunk_overlap 设成 0 会怎样?设成 chunk_size 的 50% 又会怎样?
参考答案
- 设为 0:相邻 Chunk 无重叠,跨边界的语义信息可能丢失,召回连续性差。
- 设为 50%:信息冗余严重,向量库膨胀 2 倍,召回时同一信息被多次检索到,浪费 Context。
- 最佳实践:10%-20% 是甜蜜点。
同样一个问题,BGE-Large-zh 召回的是 Chunk A,text-embedding-3 召回的是 Chunk B,哪个对?
参考答案
- 没有 "对错",只有 "哪个更适合你的场景"。
- 评估方法:
- 准备一个人工标注的评估集(问题 + 标准答案应该来自哪几个 Chunk)
- 用两个模型分别跑,计算 Recall@K(标准 Chunk 是否在 Top-K 召回里)
- 选 Recall 高的
- 中文场景一般 BGE 系列更强,但具体看数据集。
如果用户的问题是 "退货" 这种很短的查询,向量检索效果通常不好,为什么?怎么解决?
参考答案
原因:
- 短查询语义信息有限,Embedding 难以精准捕捉用户意图
- 短查询和长 Chunk 长度差异大,向量空间分布有偏
- 多义性强("退货" 可能涉及流程、政策、客诉等多个角度)
解决方案:
- 查询改写:用 LLM 把短查询扩展成完整问题("退货" → "如何申请退货?退货流程是怎样的?")
- 混合检索:加 BM25 关键词检索,短查询关键词匹配反而更准
- HyDE:先让 LLM 生成一个假设性回答,用回答做检索(详见第 4 章)
📌 本章小结
| 你应该已经知道 | ✅ |
|---|---|
| 为什么切分质量决定 RAG 上限 | □ |
| 五种切分策略各自适用场景 | □ |
| 递归字符切分是通用首选 | □ |
| chunk_size 和 overlap 的经验取值 | □ |
| Embedding 模型的原理(对比学习) | □ |
| 中文 / 英文 / 多语场景的模型选型 | □ |
| 主流向量数据库的选型决策 | □ |
| 入库和查询必须用同一个 Embedding 模型 | □ |
🚀 下一步
地基打好了,下一章看怎么把检索做到又快又准:第 4 章 · 检索优化技术