Appearance
RAG
RAG,全称Retrival-Augmented Generation,译为检索增强生成,它是一种在大语言模型(LLM)回答问题之前,先从外部可靠知识库中“查资料”,再结合这些资料生成答案的技术。
1. RAG 介绍
1.1 为什么需要RAG
由于LLM知识库的局限性以及模型工作原理,在回答某些问题时,会产生不精确的或过时的答案。LLM的局限性表现在:
- 知识截断:大模型的知识来自于预训练阶段,一旦训练完成,它的知识就定格在了那一刻。
- 现状:如果你问一个去年训练的模型关于“昨天的科技新闻”,它要么回答不知道,要么开始乱编;
- 代价:重新训练(Retraining)或微调(Fine-tuning)模型的成本极高,不可能为了更新每天的新知识而去重新训练模型;
- 缺乏私域数据:大模型主要学习的是互联网上的公开信息(如维基百科、书籍、开源代码)。
- 现状:它不知道某个公司的财务报表、你个人的笔记、或者是某个特定项目的内部技术文档;
- 安全:不能为了让 AI 了解某家公司,就将机密文档上传给第三方模型进行训练;
- 记忆的“模糊性”:大模型的知识是参数化的。这意味着知识被转化成了神经网络中的权重(Weight),更像是一种“肌肉记忆”或“印象”,而不是精确的存储。
- 后果:对于精确的数字、法律条文或特定的人名,模型很容易产生幻觉(Hallucination),因为它是在预测下一个字,而不是在精准“查字典”;
RAG就是用于增强LLM的技术,用于为LLM提供精确的外部参考数据,从而让大模型在回答时,能参考RAG给出的数据,给出精确回答。
RAG 的出现本质上是将“智力”与“知识”解耦。
- 智力归大模型:模型不再需要记住所有事实,它只负责理解问题、阅读资料、逻辑推理和组织语言;
- 知识归数据库:所有的原始资料、最新数据、内部文档都存储在外部数据库中;
RAG的意义在于:
- 即时更新:只需要把新文档存入数据库,AI 就能立刻“掌握”新知识,无需任何训练;
- 绝对精确:AI 在回答时会参考数据库中的原文,这大大降低了它信口开河的概率;
1.2 RAG系统的构成
在一个RAG系统中,主要由以下部分构成:
- 知识库:知识库的主要作用是存储外部数据(相对于LLM而言),不仅仅是原始文档,它通常包含向量数据库(存储 Embedding)和原始数据存储(存储文本、表格、图片)。
- 检索器:检索器的主要作用是从外部知识库或文档中检索与用户查询相关的信息。
- 集成层:在RAG架构中,集成层是系统的核心协调部分。它负责管理整个工作流,将检索器找回的相关数据与用户的原始查询进行整合,并将其传递给生成器以生成最终输出。它是确保 RAG 系统各组件同步工作、实现整体功能的关键架构层。
- 生成器:在 RAG 架构中,生成器特指生成式人工智能模型(如大语言模型)。它的核心职能是接收由检索器提供的相关背景信息,并结合用户的原始查询,最终输出答案。
除了以上四个主要的组件,RAG系统中还可能包含以下组件:
- 重排序器 (Reranker):检索器往往会返回前 20 条结果,但 LLM 的上下文窗口有限,且模型存在“迷失在中间(Lost in the Middle)”的缺陷。使用专门的重排序模型(如 BGE-Reranker)对检索结果进行更精细的打分,只选出最相关的 Top 3 或 Top 5 交给生成器。
- 输出处理器(Output Handler):除了格式化(如转为 Markdown 或 JSON),它还承担安全审核和**引用标注(Citations)**的功能。它会确保 AI 生成的每一句话都能对应到知识库的具体出处,增加可信度。
- 查询转换器(Query Transformer):有时候用户提问很模糊,它会先通过 LLM 将问题“改写”得更利于检索器理解(例如把简称补全),这也能极大提升系统表现。
1.3 RAG的工作流程
RAG系统大致由三个流程:
- Ingestion:构建知识库;
- Retrieval:根据用户输入检索知识库,组织Prompt;
- Generation:请求LLM获取输出,并根据需要处理输出;
1.3.1 Ingestion
Ingestion是指将原始数据存进知识库的过程。
TIP
为了简单起见,这里说的原始数据是指文本数据。
Ingestion主要涉及以下步骤:
Chunking(切块):切块是指将原始数据切分为多个小片段。
为什么需要切块?
- 大模型上下文窗口限制:大模型上下文窗口是有限的,为了避免上下文窗口被外部知识撑爆,只塞进最相关的信息,也就是说要控制信息的大小,需要对原始数据进行切分;
- 减少噪声:如果把一万字交给 LLM,其中只有两百字有用,LLM 可能会被剩下的九千多字干扰,切块能确保喂给模型的是最有用的信息;
- 语义聚焦:一个向量只能代表一个语义重心。如果一个分块包含五个主题,它的向量会变得非常模糊,导致检索时“搜什么都像,但搜什么都不准”。
如何切块?不同的数据类型需要不同的切块方式:
- 固定大小切块 (Fixed-size Chunking):
- 设定每块 500 个字符。简单粗暴,但容易把一句话从中间切断。
- 重叠切块 (Sliding Window / Overlap):
- 在块与块之间保留一部分重复内容(比如 10%–20% 的重叠)。
- 作用:确保上下文的连贯性。如果某个知识点恰好在切分点上,重叠部分能保证这个知识点在两个块中都是完整的。
- 基于标记的切块 (Recursive Character Splitting):
- 优先按段落切,段落太长按句子切,句子太长按空格切。这是目前最推荐的通用做法。
- 语义切块 (Semantic Chunking):
- 高级玩法:利用模型监测语义的变化点,只有当话题发生转移时才进行切分。
Embedding(向量化):将切块后的文本转换为向量。
什么是向量?本质是一组有序的数字,比如
[0.1, -0.5, 0.8, ...]。什么是向量维度?就是一个向量里到底包含多少个数字,维度决定了信息的精细程度。
- 低维度(如 2 维):
[0.1, 0.5]。信息量少,只能区分大类(比如:这是动物,那是植物); - 高维度(如 1536 维): 信息量巨大。每一维可能隐晦地代表了颜色、情绪、时态、专业性等极细微的特征;
直观理解: 维度就像是评价一个人的指标。如果只从“身高、体重”两个维度看人,很多人看起来都一样;如果从“身高、体重、性格、学历、爱好...”等 1000 个维度看人,就能极其精准地定位每一个人。
向量化?就是将文本、图片、音频甚至视频等数据,转变为向量的过程。
例如,将“我饿了”这句话转变为向量,结果可能为
[0.1,0.2,-0.1...]。嵌入模型(Embedding Model):负责执行“向量化”任务的计算引擎,例如OpenAI 的
text-embedding-3-small/large,BGE (Beijing General Embedding)等。- 低维度(如 2 维):
Store(存储):存储就是将原始内容和向量结果存在数据库(一般是向量数据库)中,方便后续取回。
向量化和存储可以是分开的步骤,也可以耦合成一个步骤。
- 向量化和存储解耦:先在本地或通过 API 调用 Embedding 模型(如 OpenAI、BGE 等),将文本转换成一个浮点数数组(向量),然后手动将这个向量 + 原始文本发送给向量数据库进行存储。
- 向量化和存储耦合: 直接把纯文本存入数据库。向量数据库内部集成了模型接口(或者配置了模型插件),它会自动调用模型生成向量并完成存储。
推荐将向量化和存储解耦合,这样灵活性高,并且后期可迁移。
推荐的向量数据库有Pinecone、Milvus、Qdrant、pgvector (PostgreSQL)、Chroma等。
1.3.2 Retrieval
Retrieval就是根据用户的提示词和搜索关键词,从向量数据库中找到最相关的数据。
问题的关键是如何找到最相关的数据?使用的方法有语义检索、元数据检索以及父文档检索。
语义检索,可以理解为计算用户的提示词和搜索关键词的向量(需要保证和存储时使用的嵌入模型一致),然后通过计算向量距离/向量相似度,找到向量距离最接近的多个原始数据。
为了衡量用户查询(Query)向量与文档块(Chunk)向量之间的相似度,通常使用以下几种数学计算方法:
余弦相似度 (Cosine Similarity)
这是 RAG 中最常用的方法。它衡量的是两个向量在方向上的夹角,而不关注向量的绝对长度。
公式:
范围: [-1, 1]。在文本嵌入中,结果通常在 [0, 1] 之间。
特点: 适合文本语义匹配,因为无论文档长短,只要语义方向一致,分值就高。
欧氏距离 (Euclidean Distance / L2 Distance)
衡量多维空间中两个点之间的直线距离。
公式:
范围:
。数值越小代表越相似。 特点: 对向量的模(长度)非常敏感。如果两个文档语义相似但长度差异巨大,欧氏距离可能会很大。
点积 (Dot Product / Inner Product)
直接计算两个向量的乘积之和。
公式:
范围:
。 特点: 计算速度极快。如果向量经过了归一化(Normalized)处理,点积在数学上等同于余弦相似度。目前很多向量数据库(如 Milvus, Pinecone)在处理归一化向量时首选此方法。
曼哈顿距离 (Manhattan Distance / L1 Distance)
计算向量在各个坐标轴上的绝对距离之和。
公式:
特点: 在高维空间中比欧氏距离更具鲁棒性,但在 RAG 的主流 Embedding 模型中应用较少。
元数据检索,即根据存储的标签,进行匹配,例如只想找“2025年”的“财务报表”,数据库会先根据这些标签(Metadata)缩小范围,再进行语义检索。
父文档检索 (Parent Document Retrieval):这是一个很聪明的技巧。系统先检索小的文本块(切片),但在发给大模型时,会把这个切片所属的整段话或整个章节(父文档)带上,给大模型更完整的上下文。
当通过以上方式检索到最相关的多个原始文档后,如果直接将其送进LLM,可能会造成上下文窗口资源紧张,因此通常还有一个**重排序(rerank)**阶段。重排序就是将向量检索后得到的文档,与用户的原始 Query 组合成多个“问题-答案”对,将这些“问题-答案”对放进重排序模型,重排序模型会给每一对打一个分数,根据 Rerank 的得分重新排序,取出前 3 或 5 条最优结果,之后再将重排后的精华内容发送给 LLM(大模型)生成回答。
实现重排序通常有三种途径:
调用成熟的 API
Cohere Rerank: 行业公认的效果最佳,支持多语言。
BGE Reranker (via API): 许多国产大模型厂商(如智谱、阿里)也提供了相应的重排 API。
部署开源模型
BGE-Reranker: 由智源研究院出品,中文能力极强,有
v2-m3等多个版本。BAAI/bge-reranker-v2-gemma: 结合了轻量级大语言模型能力的重排器,精度极高。
使用大模型(LLM)直接重排
直接写一个 Prompt,让 GPT-4 或 Qwen 把检索到的内容按相关性排个序。
优点: 不需要额外部署模型。
缺点: 价格贵、速度慢,通常只适合对少量(5-10条)文档进行最终确认。
1.3.3 Generation
Generation阶段就是将Retrieval阶段取回的相关文档,放进提示词中,和用户的提问一起发送给LLM,供LLM参考回答,例如:
txt
你是一个专业的助手。请根据以下参考资料回答用户的问题。如果参考资料中没有相关信息,请诚实回答你不知道,不要胡乱猜测。
参考资料:
[这里就是从向量数据库检索出来的片段]
用户问题:
[用户的原始提问]2. RAG 实战
本小节介绍如何使用BGE-m3模型进行向量化,并且将向量存储在Milvus向量数据库中。
2.1 环境准备
本地python版本为3.14。
首先创建虚拟环境:
bash
# 用指定版本的 Python 创建虚拟环境(谁创建就是谁的版本)
python3.14 -m venv .venv
# 激活虚拟环境
source .venv/bin/activate安装依赖:
bash
pip install "pymilvus[milvus_lite]" # Milvus 向量数据库
pip install sentence-transformers # 加载 BGE-M3 模型问题 1:ModuleNotFoundError: No module named 'pkg_resources'
根因:Python 3.14 的 venv 默认安装了 setuptools 82,该版本移除了 pkg_resources 模块,而 milvus_lite 仍在使用它 解决:pip install "setuptools<81",降级到 80.10.2
问题 2 :模型下载慢 / 超时
表象:从 HuggingFace 下载 BGE-M3(2.27GB)很慢 解决:export HF_ENDPOINT=https://hf-mirror.com 使用国内镜像
2.2 代码案例
python
"""
Milvus + BGE-M3 向量检索 Demo
依赖安装:
pip install "setuptools<81" # Python 3.14 需降级,否则 milvus_lite 无法导入
pip install "pymilvus[milvus_lite]" # Milvus 客户端 + 本地轻量版
pip install sentence-transformers # 用于加载 BGE-M3 embedding 模型
运行前可设置 HuggingFace 镜像加速模型下载:
export HF_ENDPOINT=https://hf-mirror.com
"""
from pymilvus import MilvusClient
from sentence_transformers import SentenceTransformer
# ========== 1. 加载 Embedding 模型 ==========
# BGE-M3: BAAI 开源的多语言向量模型,输出 1024 维向量
# 首次运行会从 HuggingFace 下载模型(约 2.27GB),之后缓存在 ~/.cache/huggingface/
embedding_model = SentenceTransformer("BAAI/bge-m3")
# ========== 2. 连接 Milvus 并创建集合 ==========
# 使用本地文件作为数据库(milvus_lite 模式),无需部署 Milvus 服务端
client = MilvusClient("./milvus_demo.db")
client.create_collection(
collection_name="demo_collection",
dimension=1024, # 必须与 BGE-M3 的输出维度一致
)
# ========== 3. 准备文档并向量化 ==========
docs = [
"检索增强生成(RAG)技术通过结合外部知识库,能显著减少大语言模型在回答专业问题时的\"幻觉\"现象。",
"量子计算机利用量子叠加和量子纠缠的特性,在处理特定复杂计算任务时展现出远超传统计算机的指数级算力。",
"位于南美洲的亚马逊雨林被誉为\"地球之肺\",其生物多样性极高,拥有数百万种动植物物种。",
"珠穆朗玛峰是喜马拉雅山脉的主峰,海拔约 8848.86 米,是世界第一高峰。",
"故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大的木质结构古建筑群之一。",
"《清明上河图》由北宋画家张择端所画,生动记录了十二世纪北宋汴京(今开封)的城市面貌和各阶层人民的生活状况。",
"深度烘焙的咖啡豆通常具有更浓郁的焦糖味和较低的酸度,而浅度烘焙则更能保留咖啡豆本身的原始花果香。",
"人类的血液循环系统由心脏、血管和血液组成,主要功能是向身体各组织输送氧气和营养物质。",
"如果明天下雨,露天音乐会将改在室内体育馆举行。",
"苹果公司总部位于加利福尼亚州的库比蒂诺,其标志性的环形建筑被称为\"Apple Park\"。",
]
# normalize_embeddings=True: 归一化向量,配合余弦相似度使用
vectors = embedding_model.encode(docs, normalize_embeddings=True).tolist()
# ========== 4. 插入数据到 Milvus ==========
data = [{"id": i, "vector": vectors[i], "text": docs[i], "subject": "test"} for i in range(len(docs))]
res = client.insert(collection_name="demo_collection", data=data)
print("插入结果:", res)
# ========== 5. 语义搜索(向量相似度检索) ==========
# 将查询文本向量化,然后在 Milvus 中找最相似的文档
# 返回结果中的 distance 表示余弦相似度,值越大(越接近 1)相关性越高
query = "故宫在哪里"
query_vector = embedding_model.encode([query], normalize_embeddings=True).tolist()
res = client.search(
collection_name="demo_collection",
data=query_vector,
limit=2, # 返回最相似的 2 条
output_fields=["text", "subject"],
)
print("搜索结果:", res)
# ========== 6. 条件查询(标量过滤) ==========
# 不经过向量检索,直接按字段条件过滤
res = client.query(
collection_name="demo_collection",
filter="subject == 'test'",
output_fields=["text", "subject"],
)
print("查询结果:", res)结果如下:
txt
插入结果: {'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
搜索结果: data: [[{'id': 4, 'distance': 0.7463935017585754, 'entity': {'text': '故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大的木质结构古建筑群之一。', 'subject': 'test'}}, {'id': 8, 'distance': 0.38512587547302246, 'entity': {'text': '如果明天下雨,露天音乐会将改在室内体育馆举行。', 'subject': 'test'}}]]
查询结果: data: ['{\'id\': 0, \'text\': \'检索增强生成(RAG)技术通过结合外部知识库,能显著减少大语言模型在回答专业问题时的"幻觉"现象。\', \'subject\': \'test\'}', "{'id': 1, 'text': '量子计算机利用量子叠加和量子纠缠的特性,在处理特定复杂计算任务时展现出远超传统计算机的指数级算力。', 'subject': 'test'}", '{\'id\': 2, \'text\': \'位于南美洲的亚马逊雨林被誉为"地球之肺",其生物多样性极高,拥有数百万种动植物物种。\', \'subject\': \'test\'}', "{'id': 3, 'text': '珠穆朗玛峰是喜马拉雅山脉的主峰,海拔约 8848.86 米,是世界第一高峰。', 'subject': 'test'}", "{'id': 4, 'text': '故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大的木质结构古建筑群之一。', 'subject': 'test'}", "{'id': 5, 'text': '《清明上河图》由北宋画家张择端所画,生动记录了十二世纪北宋汴京(今开封)的城市面貌和各阶层人民的生活状况。', 'subject': 'test'}", "{'id': 6, 'text': '深度烘焙的咖啡豆通常具有更浓郁的焦糖味和较低的酸度,而浅度烘焙则更能保留咖啡豆本身的原始花果香。', 'subject': 'test'}", "{'id': 7, 'text': '人类的血液循环系统由心脏、血管和血液组成,主要功能是向身体各组织输送氧气和营养物质。', 'subject': 'test'}", "{'id': 8, 'text': '如果明天下雨,露天音乐会将改在室内体育馆举行。', 'subject': 'test'}", '{\'id\': 9, \'text\': \'苹果公司总部位于加利福尼亚州的库比蒂诺,其标志性的环形建筑被称为"Apple Park"。\', \'subject\': \'test\'}'], extra_info: {}distance 值越大表示相关性越高。
Milvus 默认使用的是 余弦相似度(Cosine Similarity)(配合 normalize_embeddings=True),范围是 [-1, 1]:
| distance 值 | 含义 |
|---|---|
| 1.0 | 完全相同 |
| 0.7+ | 高度相关 |
| 0.3~0.7 | 有一定相关性 |
| ≈ 0 | 不相关 |
| < 0 | 语义相反 |
2.3 Rerank
当使用向量检索后,我们可以使用Reranker进行重排序,这里演示使用BAAI/bge-reranker-v2-m3模型作为rerank模型:
python
"""
Milvus + BGE-M3 向量检索 Demo
依赖安装:
pip install "setuptools<81" # Python 3.14 需降级,否则 milvus_lite 无法导入
pip install "pymilvus[milvus_lite]" # Milvus 客户端 + 本地轻量版
pip install sentence-transformers # 用于加载 BGE-M3 embedding 模型和 rerank 模型
运行前可设置 HuggingFace 镜像加速模型下载:
export HF_ENDPOINT=https://hf-mirror.com
"""
from pymilvus import MilvusClient
from sentence_transformers import SentenceTransformer, CrossEncoder
# ========== 1. 加载 Embedding 模型 ==========
# BGE-M3: BAAI 开源的多语言向量模型,输出 1024 维向量
# 首次运行会从 HuggingFace 下载模型(约 2.27GB),之后缓存在 ~/.cache/huggingface/
embedding_model = SentenceTransformer("BAAI/bge-m3")
# ========== 1.5 加载 Rerank 模型 ==========
# BGE-Reranker-v2-m3: 交叉编码器,对 query-doc 对做精细相关性打分
# 比向量检索更精确,但速度较慢,适合对召回结果做二次排序
rerank_model = CrossEncoder("BAAI/bge-reranker-v2-m3")
# ========== 2. 连接 Milvus 并创建集合 ==========
# 使用本地文件作为数据库(milvus_lite 模式),无需部署 Milvus 服务端
client = MilvusClient("./milvus_demo.db")
client.create_collection(
collection_name="demo_collection",
dimension=1024, # 必须与 BGE-M3 的输出维度一致
)
# ========== 3. 准备文档并向量化 ==========
docs = [
"检索增强生成(RAG)技术通过结合外部知识库,能显著减少大语言模型在回答专业问题时的\"幻觉\"现象。",
"量子计算机利用量子叠加和量子纠缠的特性,在处理特定复杂计算任务时展现出远超传统计算机的指数级算力。",
"位于南美洲的亚马逊雨林被誉为\"地球之肺\",其生物多样性极高,拥有数百万种动植物物种。",
"珠穆朗玛峰是喜马拉雅山脉的主峰,海拔约 8848.86 米,是世界第一高峰。",
"故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大的木质结构古建筑群之一。",
"《清明上河图》由北宋画家张择端所画,生动记录了十二世纪北宋汴京(今开封)的城市面貌和各阶层人民的生活状况。",
"深度烘焙的咖啡豆通常具有更浓郁的焦糖味和较低的酸度,而浅度烘焙则更能保留咖啡豆本身的原始花果香。",
"人类的血液循环系统由心脏、血管和血液组成,主要功能是向身体各组织输送氧气和营养物质。",
"如果明天下雨,露天音乐会将改在室内体育馆举行。",
"苹果公司总部位于加利福尼亚州的库比蒂诺,其标志性的环形建筑被称为\"Apple Park\"。",
]
# normalize_embeddings=True: 归一化向量,配合余弦相似度使用
vectors = embedding_model.encode(docs, normalize_embeddings=True).tolist()
# ========== 4. 插入数据到 Milvus ==========
data = [{"id": i, "vector": vectors[i], "text": docs[i], "subject": "test"} for i in range(len(docs))]
res = client.insert(collection_name="demo_collection", data=data)
print("插入结果:", res)
# ========== 5. 语义搜索(向量相似度检索) ==========
# 将查询文本向量化,然后在 Milvus 中找最相似的文档
# 返回结果中的 distance 表示余弦相似度,值越大(越接近 1)相关性越高
query = "故宫在哪里"
query_vector = embedding_model.encode([query], normalize_embeddings=True).tolist()
res = client.search(
collection_name="demo_collection",
data=query_vector,
limit=5, # 先召回较多候选(top 5)
output_fields=["text", "subject"],
)
print("向量检索结果:")
for hit in res[0]:
print(f" distance={hit['distance']:.4f} {hit['entity']['text'][:40]}...")
# ========== 6. Rerank 重排序 ==========
# 向量检索是"粗筛",rerank 是"精排"
# CrossEncoder 会将 query 和每个候选文档拼接后做精细的相关性打分
candidate_texts = [hit["entity"]["text"] for hit in res[0]]
pairs = [[query, text] for text in candidate_texts]
rerank_scores = rerank_model.predict(pairs).tolist()
# 按 rerank 分数降序排列
reranked = sorted(
zip(candidate_texts, rerank_scores, res[0]),
key=lambda x: x[1],
reverse=True,
)
print("\nRerank 重排序结果:")
for text, score, hit in reranked:
print(f" rerank_score={score:.4f} (原distance={hit['distance']:.4f}) {text[:40]}...")结果如下:
txt
插入结果: {'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
向量检索结果:
distance=0.7464 故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大...
distance=0.3851 如果明天下雨,露天音乐会将改在室内体育馆举行。...
distance=0.3599 苹果公司总部位于加利福尼亚州的库比蒂诺,其标志性的环形建筑被称为"Apple P...
distance=0.3370 《清明上河图》由北宋画家张择端所画,生动记录了十二世纪北宋汴京(今开封)的城市面...
distance=0.3280 珠穆朗玛峰是喜马拉雅山脉的主峰,海拔约 8848.86 米,是世界第一高峰。...
Rerank 重排序结果:
rerank_score=0.9951 (原distance=0.7464) 故宫博物院位于北京中轴线的中心,是中国明清两代的皇家宫殿,也是世界上现存规模最大...
rerank_score=0.0138 (原distance=0.3370) 《清明上河图》由北宋画家张择端所画,生动记录了十二世纪北宋汴京(今开封)的城市面...
rerank_score=0.0028 (原distance=0.3599) 苹果公司总部位于加利福尼亚州的库比蒂诺,其标志性的环形建筑被称为"Apple P...
rerank_score=0.0002 (原distance=0.3280) 珠穆朗玛峰是喜马拉雅山脉的主峰,海拔约 8848.86 米,是世界第一高峰。...
rerank_score=0.0000 (原distance=0.3851) 如果明天下雨,露天音乐会将改在室内体育馆举行。...参考资料
[1] https://github.com/aishwaryanr/awesome-generative-ai-guide/blob/main/resources/RAG_roadmap.md
[2] https://www.ibm.com/think/topics/retrieval-augmented-generation
[3] milvus:https://milvus.io/docs
[4] BGE:https://bge-model.com/tutorial/1_Embedding/1.2.1.html
附录
上下文窗口
大模型上下文窗口(Context Window) 是指 AI 模型在处理任务时,一次性能够“记住”并处理的最大信息量。
上下文窗口的容量(通常以 Token 为单位,1000 个 Token 约等于 750 个英文单词或 400-500 个汉字)是由以下几部分组成的:
- 提问 (Prompt):发给 AI 的指令;
- 之前的对话记录 (Chat History):为了让对话连贯,系统会自动把之前的聊天记录反复喂给模型;
- 外部检索到的资料 (Retrieved Data):在 RAG 系统中,从知识库搜到的参考片段;
- 模型的回答 (Output):AI 正在生成的文字也会占据窗口位置;
关键规则:以上所有内容的总和,不能超过该模型的上限。
一旦对话内容过长,超过了模型的上下文窗口,通常会发生两种情况:
- 直接拒绝:报错提示“输入过长”;
- 滑动窗口策略:系统会自动删掉最早的对话,这会导致 AI 突然“断片”,忘记五分钟前才告诉它的设定;
随着技术的进步,上下文窗口正变得越来越大:
| 模型级别 | 窗口容量 (Tokens) | 相当于多大信息量 |
|---|---|---|
| 标准型 | 4K - 16K | 几篇长文章 |
| 主流型 | 128K - 272K | 一本 300 页的书 |
| 超长型 (如 Gemini 1.5 Pro) | 1M - 2M | 数小时视频、数万行代码或十几本书 |
虽然窗口越大越好,但也存在两个核心挑战:
- 注意力稀释 (Lost in the Middle):研究表明,当窗口非常长时,模型容易记住开头和结尾,却容易忽略掉中间部分的细节。
- 性能与成本:处理的 Token 越多,计算成本越高,响应速度(延迟)通常也会变慢。