RAG
为什么不直接将知识库作为提示词的一部分?
这样会使得上下文变得很长,长上下文窗口会带来以下问题:
- 成本急剧飙升:token告急
- “中间迷失”效应:模型会忽略文档中间的内容
- 信息过载与精度下降:模型可能“抓不住重点
- 可追溯性与可信度问题:你无法知道答案的来源
- 技术实现的硬约束:上下文长度上限
Indexing 索引
这个步骤需要将知识库以某种格式保存起来,方便后续匹配
Split 分割
- 字符分割:按固定字符数切割
- 递归分割:按分隔符优先级递归切割
- Token分割:按LLM token数切割
- 语义分割:基于嵌入向量相似度
- LLM智能分割:使用LLM理解内容后分割
- 混合分割:组合多种策略
Embedding 嵌入
嵌入的工作,是将一段文本变成一个多维向量的数学表达,为后续的检索提供便利。
python
# 将城市公园这个概念拆解成空间相关的语义维度
city_park_spatial_vector = {
"维度1 - 开放空间占比": 0.95, # 正数:以开阔绿地/广场为主,封闭建筑少
"维度2 - 可达性(城市中心)": 0.85, # 正数:靠近居民区/市中心,交通便利
"维度3 - 自然植被覆盖度": 0.90, # 正数:树木草坪多,人工硬质景观少
"维度4 - 地形起伏程度": -0.30, # 弱负数:地势平缓,几乎无陡坡高山
"维度5 - 建筑密度": -0.80, # 强负数:建筑极少,以露天空间为主
"维度6 - 噪音污染程度": -0.70, # 强负数:环境安静,远离主干道
"维度7 - 服务半径覆盖": 0.75, # 正数:能覆盖周边1-3km居民
"维度8 - 夜间照明覆盖率": -0.20, # 弱负数:夜间照明有限,偏自然
"维度9 - 水体占比": 0.30, # 弱正数:常见有小湖/溪流
"维度10 - 边界开放性": 0.90 # 正数:多为开放式入口,无封闭围墙
...
}可见,向量维度越高,对语言的理解就越准确越细腻。
要实现对一个完整语句的嵌入,有多种方法,比如传统统计、静态词嵌入、上下文感知嵌入等等。目前,绝对主流的嵌入方法是基于Transformer的上下文感知嵌入。
空间向量维度
| 维度大小 | 代表模型 / 技术 | 典型应用场景 |
|---|---|---|
| 128 维 | 轻量版 Sentence-BERT、MiniLM | 资源受限设备、简单检索、快速原型 |
| 256 维 | 部分轻量 BERT、DistilBERT 变种 | 移动端 / 边缘设备、低延迟场景 |
| 512 维 | GPT-2 基础版、部分早期嵌入模型 | 中等规模文本任务、平衡性能与精度 |
| 768 维 | BERT-base、Sentence-BERT-base、LLaMA-2 7B/13B 词嵌入 | 通用 NLP 任务、主流语义检索 |
| 1024 维 | BERT-large、GPT-2 large、LLaMA-1 7B/13B | 复杂语义理解、高精度检索 / 生成 |
| 1536 维 | OpenAI text-embedding-ada-002 | 通用商业级语义检索、RAG 系统 |
| 2048 维 | GPT-3 基础版、部分大模型中间层 | 大规模语言建模、复杂上下文理解 |
| 3072 维 | LLaMA-2 70B、Mistral 8x7B | 超大参数量模型、长文本理解 |
| 4096 维 | GPT-3.5/4 部分版本、PaLM 2 基础版 | 高端语义理解、复杂生成与检索任务 |
| 8192 维 | GPT-4 高级版、PaLM 2 大参数量版 | 超大规模上下文、复杂推理任务 |
nomic-embed-text
模型安装:nomic-embed-text
bash
ollama pull nomic-embed-text直接封装方法进行测试:传入一个字符串,通过ollama调用,返回一个向量
ts
import ollama from 'ollama';
const embeddings = async (text: string) => {
const response = await ollama.embed({
model: 'nomic-embed-text',
input: text
});
console.log(response.embeddings);
};
await embeddings('hello world');Storage 存储
存储嵌入结果通常使用向量数据库
- 小型项目(<10万向量):
Chroma、pgvector、SQLite - 中型应用(10万-1000万):
Qdrant、Weaviate、ElasticSearch - 大型系统(>1000万):
Milvus、专用云服务
Retrieval 检索
这个步骤需要将用户的问题与之前建立的索引进行匹配,得到相关度较高的结果
余弦相似度
余弦相似度仅与方向有关,和向量长度无关。 它的取值范围是-1~1
- -1:两个向量方向完全相反,属于反义
- 0:两个向量垂直,含义完全无关
- 1:两个向量方向完全相同,属于同义
为什么余弦相似度只看方向,不看长度?
长度无关性:因为长度仅表示意思的程度,不会改变含义本身
Generation 生成
这个步骤是将匹配的知识和用户问题混合投递给LLM,从而得到准确的结果
