📝 本章学习目标:本章聚焦 RAG 系统性能瓶颈核心 ------Embedding 调优,从底层原理、模型选择、分块策略、参数精调、进阶优化、全链路实战六大维度,手把手带你掌握可落地的 Embedding 调优技巧,彻底解决检索不准、语义偏差、幻觉严重等核心问题。
一、引言:Embedding 为何决定 RAG 成败
1.1 背景与痛点
在 RAG(检索增强生成)系统中,Embedding(文本向量化)是 "灵魂"------ 它直接决定语义匹配精度、检索召回率、答案准确性,甚至影响大模型幻觉概率。
当前开发者普遍面临 4 大 Embedding 痛点:
- 语义偏差:字面相似但语义不同的文本,向量距离过近,导致误召回;
- 精度不足:通用模型适配业务场景差,专业术语、行业语义匹配失效;
- 分块混乱:文本切割不合理,语义断裂,生成向量无实际意义;
- 效率失衡:高维向量存储 / 检索慢,低维向量精度断崖式下跌。
据行业测试数据:Embedding 调优可使 RAG 检索精度提升 30%-80%,幻觉率降低 50% 以上,是投入产出比最高的优化手段。70% 的 RAG 项目上线后效果差,核心原因都是 Embedding 未做针对性调优。
1.2 调优核心价值
Embedding 调优的核心价值,体现在 4 个维度:
- 提升检索精度:精准匹配语义,过滤无关文档,召回率从 60% 提升至 90%+;
- 抑制幻觉:检索结果精准,大模型仅基于真实文档生成,幻觉率大幅降低;
- 平衡性能:合理选择向量维度,兼顾精度与检索速度,适配轻量化部署;
- 适配业务:通用模型→行业定制,解决专业术语、领域语义匹配难题。
1.3 本章结构概览
为帮助读者系统性掌握 Embedding 调优全流程,本章从以下维度展开:
plaintext
📊 原理解析 → 模型选择 → 分块调优 → 参数精调 → 进阶优化 → 实战落地 → 问题排查
二、核心概念解析:彻底读懂 Embedding
2.1 基本定义
Embedding(文本嵌入 / 向量化) :将自然语言文本(词、句子、段落)映射到高维稠密数值向量空间 的过程,核心逻辑是 ------语义相近的文本,向量距离更近;语义无关的文本,向量距离更远。
简单类比:把文字 "翻译" 成 AI 能读懂的 "数字密码",语义越像,密码越接近。
- 示例:"产品售后流程" 与 "售后处理步骤" 向量距离极近;"产品售后流程" 与 "员工考勤制度" 向量距离极远。
2.2 核心工作流程
Embedding 在 RAG 中的核心流程:
- 文档分块:长文档切割成语义完整的短文本(Chunk);
- 向量生成:Embedding 模型将每个 Chunk 转化为固定维度向量;
- 向量存储:向量 + 原文映射,存入 FAISS、Milvus 等向量库;
- 查询向量化:用户问题(Query)用同一模型生成向量;
- 语义检索:计算 Query 向量与文档向量相似度,返回 Top-K 最相关结果。
2.3 关键术语解释
⚠️ 以下术语是调优基础,必须掌握:
- 向量维度(Dimension):向量包含的数值个数,常见 768、1024、512、256,维度越高精度越高、存储 / 计算成本越大;
- 相似度计算 :常用余弦相似度(Cosine Similarity),衡量两向量夹角,值越接近 1,语义越相似;
- Chunk(文本块):长文档切割后的最小语义单元,调优核心变量;
- 召回率(Recall):相关文档被检索到的比例,Embedding 核心评估指标;
- MTEB 榜单 :国际权威 Embedding 评测基准,覆盖检索、聚类等 8 大任务,58 个数据集,优先参考检索任务 NDCG@10指标。
2.4 Embedding 与大模型的区别
很多开发者混淆 Embedding 模型与生成式大模型,核心区别如下:
表格
| 对比维度 | Embedding 模型 | 生成式大模型(GPT/Qwen) |
|---|---|---|
| 核心目标 | 语义理解、向量匹配 | 文本生成、对话问答 |
| 模型结构 | Transformer 编码器(Encoder) | Transformer 解码器(Decoder) |
| 输出结果 | 固定维度数值向量 | 自然语言文本 |
| 适用场景 | 检索、聚类、分类 | 问答、创作、总结 |
| 典型模型 | BGE、all-MiniLM、text-embedding | BGE、Qwen、Llama3、GPT-4 |
三、技术选型:选对模型 = 调优成功一半
3.1 主流 Embedding 模型对比(中文优先)
选型核心:中文场景优先 BGE 系列,轻量场景选 all-MiniLM,通用场景选 m3e,以下是主流模型核心参数与适用场景:
表格
| 模型名称 | 维度 | 大小 | 中文效果 | 速度 | 适用场景 |
|---|---|---|---|---|---|
| BGE-large-zh-v1.5 | 1024 | 1.2G | ⭐⭐⭐⭐⭐ | 中等 | 企业级高精度检索、专业领域 |
| BGE-small-zh-v1.5 | 512 | 120M | ⭐⭐⭐⭐ | 极快 | 轻量化部署、CPU 环境、中小知识库 |
| all-MiniLM-L6-v2 | 384 | 60M | ⭐⭐⭐ | 极快 | 英文为主、轻量 Demo、低资源场景 |
| m3e-small | 512 | 110M | ⭐⭐⭐⭐ | 快 | 中文通用、平衡精度与速度 |
| text-embedding-3-small | 512 | 云端 | ⭐⭐⭐⭐ | 依赖网络 | OpenAI 生态、无隐私需求 |
3.2 选型黄金法则
- 中文优先 BGE :BGE 系列是目前中文 Embedding 最优解,远超 all-MiniLM,优先选BGE-small-zh-v1.5 (平衡精度与速度),高精度场景选BGE-large-zh-v1.5;
- 离线优先开源 :内网 / 私有化场景,禁用云端模型(数据泄露),优先选BGE、m3e等开源离线模型;
- 维度适配场景:中小知识库(<10 万条)选 512 维,大规模知识库选 1024 维,极致轻量可选 256 维(BGE 支持 Matryoshka 降维);
- 参考 MTEB 榜单 :选型前核对 MTEB 检索任务排名,优先选NDCG@10高分模型。
3.3 模型加载实战代码(离线 + 在线)
3.3.1 离线加载 BGE 模型(推荐,私有化场景)
python
运行
python
# 安装依赖
# pip install sentence-transformers==2.5.1
from sentence_transformers import SentenceTransformer
import numpy as np
# ---------------------- 配置区 ----------------------
# 离线模型路径(外网下载后拷贝到内网)
MODEL_PATH = "./models/bge-small-zh-v1.5"
# 向量维度(BGE-small默认512)
EMBED_DIM = 512
# ----------------------------------------------------
def load_embedding_model():
"""
加载离线BGE嵌入模型(全程离线,无外网依赖)
"""
print(f"加载离线Embedding模型:{MODEL_PATH}")
# 加载模型,指定CPU(无GPU也可运行)
model = SentenceTransformer(
model_name_or_path=MODEL_PATH,
device="cpu" # 可选"cuda"加速
)
print("模型加载完成!")
return model
def generate_embedding(model, text):
"""
生成文本向量(单文本)
"""
# 关闭梯度,加速推理
with np.no_grad():
# 生成向量,归一化(提升检索精度)
embedding = model.encode(
text,
normalize_embeddings=True, # 归一化,余弦相似度更准
convert_to_numpy=True
)
# 验证向量维度
assert len(embedding) == EMBED_DIM, f"向量维度错误,预期{EMBED_DIM},实际{len(embedding)}"
return embedding
# 测试
if __name__ == "__main__":
# 加载模型
model = load_embedding_model()
# 测试文本
test_text1 = "产品售后流程是什么"
test_text2 = "售后处理步骤有哪些"
test_text3 = "员工考勤制度"
# 生成向量
emb1 = generate_embedding(model, test_text1)
emb2 = generate_embedding(model, test_text2)
emb3 = generate_embedding(model, test_text3)
# 计算余弦相似度
sim12 = np.dot(emb1, emb2) # 语义相近,相似度高
sim13 = np.dot(emb1, emb3) # 语义无关,相似度低
print(f"「{test_text1}」与「{test_text2}」相似度:{sim12:.4f}")
print(f"「{test_text1}」与「{test_text3}」相似度:{sim13:.4f}")
代码说明:
normalize_embeddings=True:向量归一化,余弦相似度计算更精准,必开;- 全程离线,无外网依赖,适配内网私有化场景;
- 输出结果:语义相近文本相似度 > 0.7,语义无关 < 0.3,符合预期。
3.3.2 在线加载 OpenAI 模型(非私有化场景)
python
运行
python
# 安装依赖
# pip install openai==1.13.3
from openai import OpenAI
import numpy as np
# ---------------------- 配置区 ----------------------
client = OpenAI(api_key="你的OpenAI密钥")
EMBEDDING_MODEL = "text-embedding-3-small" # 512维
# ----------------------------------------------------
def generate_online_embedding(text):
"""
在线生成向量(OpenAI,非私有化场景)
"""
response = client.embeddings.create(
input=text,
model=EMBEDDING_MODEL,
dimensions=512 # 降维,平衡精度与速度
)
embedding = np.array(response.data[0].embedding)
return embedding
# 测试
if __name__ == "__main__":
emb = generate_online_("RAG系统Embedding调优")
print(f"向量维度:{len(emb)}")
四、Chunk 分块调优:决定向量 "语义纯度"
4.1 分块核心痛点
Chunk(文本块)是 Embedding 的输入,分块质量直接决定向量语义纯度,常见问题:
- Chunk 过大:包含多个主题,向量语义混杂,检索时匹配无关内容;
- Chunk 过小:语义不完整,上下文断裂,向量无实际意义;
- 分割不合理:按字数硬切,句子 / 段落被拆分,语义破碎。
4.2 分块黄金参数(中文场景)
经过大量实测,中文分块最优参数:
- Chunk Size(块大小) :512 字符(中文约 250-300 字,1-2 个完整段落,语义完整);
- Chunk Overlap(重叠) :50-100 字符(保证上下文连贯,避免语义断裂);
- 分隔符优先级 :
\n\n(段落)→\n(换行)→。(句号)→,(逗号),优先按语义分割。
4.3 分块实战代码(LangChain + 中文优化)
python
运行
python
# 安装依赖
# pip install langchain==0.1.10
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import TextLoader
import os
# ---------------------- 配置区 ----------------------
CHUNK_SIZE = 512 # 中文最优块大小
CHUNK_OVERLAP = 50 # 重叠字符
# 中文分隔符(优先级从高到低)
SEPARATORS = ["\n\n", "\n", "。", ",", "、", " "]
# ----------------------------------------------------
def create_text_splitter():
"""
创建中文优化文本分割器
"""
splitter = RecursiveCharacterTextSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP,
separators=SEPARATORS,
length_function=len, # 按字符数计算
add_start_index=True # 记录块起始位置(溯源用)
)
return splitter
def split_document(file_path):
"""
加载并分割文档
"""
# 加载文档
loader = TextLoader(file_path, encoding="utf-8")
docs = loader.load()
# 创建分割器
splitter = create_text_splitter()
# 分割文档
chunks = splitter.split_documents(docs)
print(f"文档分割完成,共生成{len(chunks)}个文本块")
# 打印前2个块预览
for i in range(min(2, len(chunks))):
print(f"\n【块{i+1}】:\n{chunks[i].page_content}")
return chunks
# 测试
if __name__ == "__main__":
# 测试文档路径(自建txt文档,内容为产品售后流程)
test_file = "./docs/售后流程.txt"
if os.path.exists(test_file):
chunks = split_document(test_file)
else:
print(f"测试文件不存在:{test_file}")
4.4 分块进阶技巧
- 动态分块:长句多的文档(如法律文书)调大 Chunk Size 至 768;短句多的文档(如新闻)调小至 384;
- 语义分割优先 :禁用按字数硬切,优先按段落、句号分割,保证每个 Chunk 是独立语义单元;
- 过滤无效 Chunk:过滤字数 < 50、全空白、乱码的无效块,避免生成无意义向量;
- 标题绑定:Chunk 前追加文档标题(如 "产品售后流程:xxx"),提升主题相关性,检索更精准。
五、向量生成与参数精调:细节决定精度
5.1 核心参数调优
5.1.1 归一化(Normalization)
必开参数 :normalize_embeddings=True,将向量 L2 归一化,余弦相似度计算更精准,检索精度提升 10%-15%。
- 原理:归一化后,向量模长为 1,余弦相似度 = 向量点积,避免模长干扰。
5.1.2 批量生成(Batch Size)
批量生成向量时,Batch Size 建议8-32:
- 过小:速度慢,效率低;
- 过大:显存占用高,易溢出;
- 实测:BGE-small 推荐 Batch=16,BGE-large 推荐 Batch=8。
5.1.3 向量维度选择
- 512 维:平衡精度与速度,90% 场景最优;
- 1024 维:高精度场景,如法律、医疗专业文档;
- 256 维:极致轻量,如移动端、嵌入式部署(BGE 支持 Matryoshka 降维)。
5.2 批量向量生成实战代码
python
运行
python
from sentence_transformers import SentenceTransformer
import numpy as np
import os
# ---------------------- 配置区 ----------------------
MODEL_PATH = "./models/bge-small-zh-v1.5"
CHUNK_SIZE = 512
BATCH_SIZE = 16 # 批量生成大小
# ----------------------------------------------------
def batch_generate_embeddings(model, chunks):
"""
批量生成文本块向量(高效处理)
"""
print(f"批量生成向量,共{len(chunks)}个文本块,Batch={BATCH_SIZE}")
# 提取文本内容
texts = [chunk.page_content for chunk in chunks]
# 批量生成向量(归一化)
embeddings = model.encode(
texts,
batch_size=BATCH_SIZE,
normalize_embeddings=True,
convert_to_numpy=True,
show_progress_bar=True # 显示进度
)
print(f"向量生成完成,维度:{embeddings.shape}")
return embeddings
# 测试
if __name__ == "__main__":
# 加载模型
model = SentenceTransformer(MODEL_PATH, device="cpu")
# 模拟文本块
test_chunks = [
"产品售后流程:用户反馈问题→客服登记→技术排查→解决方案→回访确认",
"售后处理步骤:优先响应2小时,复杂问题24小时内反馈进展",
"员工考勤制度:早9点晚6点,迟到3次扣绩效"
]
# 批量生成向量
embeddings = batch_generate_embeddings(model, test_chunks)
# 计算相似度
sim01 = np.dot(embeddings[0], embeddings[1])
sim02 = np.dot(embeddings[0], embeddings[2])
print(f"相似度0-1:{sim01:.4f}")
print(f"相似度0-2:{sim02:.4f}")
5.3 向量存储优化(FAISS)
生成向量后,存储方式影响检索速度,FAISS 实战代码:
python
运行
python
from langchain.vectorstores import FAISS
import os
# ---------------------- 配置区 ----------------------
VECTOR_DB_PATH = "./vector_db"
# ----------------------------------------------------
def save_vector_db(chunks, embeddings):
"""
保存向量到FAISS
"""
print("保存向量到FAISS...")
# 创建FAISS向量库
vector_db = FAISS.from_embeddings(
embeddings=embeddings,
text_embeddings=chunks
)
# 保存到本地
os.makedirs(VECTOR_DB_PATH, exist_ok=True)
vector_db.save_local(VECTOR_DB_PATH)
print("向量库保存完成!")
return vector_db
# 加载向量库
def load_vector_db():
"""
加载本地FAISS向量库
"""
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name=MODEL_PATH)
vector_db = FAISS.load_local(
VECTOR_DB_PATH,
embeddings,
allow_dangerous_deserialization=True
)
print("向量库加载完成!")
return vector_db
六、进阶调优:解决行业痛点,精度再上台阶
6.1 领域微调(行业定制)
通用 Embedding 模型适配专业领域(如医疗、法律、金融)效果差,领域微调可提升 20%-40% 精度。
6.1.1 微调数据准备
- 数据量:500-2000 条领域文本对(相似文本对 + 无关文本对);
- 格式:
(文本1, 文本2, 标签),标签 1 = 相似,0 = 无关; - 示例:
("肺癌症状", "肺部癌症表现", 1)、("肺癌症状", "感冒发烧", 0)。
6.1.2 微调实战代码(Sentence-Transformer)
python
运行
python
# 安装依赖
# pip install sentence-transformers datasets
from sentence_transformers import SentenceTransformer, losses, InputExample
from torch.utils.data import DataLoader
# ---------------------- 配置区 ----------------------
MODEL_PATH = "./models/bge-small-zh-v1.5"
FINE_TUNE_MODEL_PATH = "./models/bge-small-zh-medical" # 医疗微调模型
EPOCHS = 2
BATCH_SIZE = 16
# ----------------------------------------------------
def prepare_fine_tune_data():
"""
准备微调数据(医疗领域示例)
"""
train_examples = [
InputExample(texts=["肺癌早期症状", "肺部癌症初期表现"], label=1.0),
InputExample(text=["肺癌早期症状", "普通感冒发烧"], label=0.0),
InputExample(text=["高血压治疗方案", "血压高干预措施"], label=1.0),
InputExample(text=["高血压治疗方案", "糖尿病用药指南"], label=0.0)
]
return train_examples
def fine_tune_embedding():
"""
领域微调Embedding模型
"""
# 加载基础模型
model = SentenceTransformer(MODEL_PATH)
# 准备数据
train_examples = prepare_fine_tune_data()
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=BATCH_SIZE)
# 定义损失函数(对比学习)
train_loss = losses.CosineSimilarityLoss(model)
# 微调模型
print("开始领域微调...")
model.fit(
train_objectives=[(train_dataloader, train_loss)],
epochs=EPOCHS,
warmup_steps=100,
output_path=FINE_TUNE_MODEL_PATH,
show_progress_bar=True
)
print(f"微调完成,模型保存至:{FINE_TUNE_MODEL_PATH}")
return model
# 测试
if __name__ == "__main__":
fine_tune_embedding()
6.2 重排序(Rerank)优化
检索后用Rerank 模型二次排序 ,过滤假阳性结果,精度提升 10%-20%。
- 核心逻辑:先用 Embedding 检索 Top-20,再用 BGE-Reranker 重排,返回 Top-3;
- 模型选择:BGE-reranker-large(与 BGE 嵌入模型黄金搭档)。
6.2.1 Rerank 实战代码
python
运行
python
# 安装依赖
# pip install sentence-transformers
from sentence_transformers import CrossEncoder
# ---------------------- 配置区 ----------------------
RERANK_MODEL_PATH = "./models/bge-reranker-large"
TOP_K = 20 # 检索返回数量
RERANK_TOP = 3 # 重排后返回数量
# ----------------------------------------------------
def rerank_results(query, docs):
"""
Rerank重排序
"""
print("开始重排序...")
# 加载Rerank模型
reranker = CrossEncoder(RERANK_MODEL_PATH)
# 构建查询-文档对
pairs = [[query, doc.page_content] for doc in docs]
# 计算相关性分数
scores = reranker.predict(pairs)
# 按分数排序(降序)
sorted_docs = [doc for _, doc in sorted(zip(scores, docs), key=lambda x: x[0], reverse=True)]
# 返回Top-N
return sorted_docs[:RERANK_TOP]
6.3 混合检索(关键词 + 语义)
单一语义检索易受歧义影响,** 混合检索(语义 + 关键词)** 可互补短板,召回率提升 15%+。
- 逻辑:语义检索(70% 权重)+ BM25 关键词检索(30% 权重),融合结果;
- 适用:专业术语多、歧义文本多的场景。
七、全链路实战:从数据到检索,一站式落地
7.1 项目目录
plaintext
embedding_optimize/
├── docs/ # 原始文档(PDF/Word/TXT)
├── models/ # 离线Embedding/Rerank模型
│ ├── bge-small-zh-v1.5/
│ └── bge-reranker-large/
├── vector_db/ # FAISS向量库
└── app.py # 全链路代码
7.2 全链路代码(文档→分块→向量→检索→重排)
python
运行
python
from langchain.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from sentence_transformers import CrossEncoder
import os
# ---------------------- 全局配置 ----------------------
DOCS_DIR = "./docs"
MODEL_PATH = "./models/bge-small-zh-v1.5"
RERANK_MODEL_PATH = "./models/bge-reranker-large"
VECTOR_DB_PATH = "./vector_db"
CHUNK_SIZE = 512
CHUNK_OVERLAP = 50
TOP_K = 20
RERANK_TOP = 3
# ----------------------------------------------------
# 1. 加载文档
def load_documents():
print("加载文档...")
loader = DirectoryLoader(
DOCS_DIR,
glob="**/*.txt",
loader_cls=TextLoader,
show_progress=True
)
docs = loader.load()
print(f"加载完成,共{len(docs)}个文档")
return docs
# 2. 分割文档
def split_documents(docs):
print("分割文档...")
splitter = RecursiveCharacterTextSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP,
separators=["\n\n", "\n", "。", ","]
)
chunks = splitter.split_documents(docs)
print(f"分割完成,共{len(chunks)}个文本块")
return chunks
# 3. 生成向量并存储
def create_vector_db(chunks):
print("生成向量并存储...")
embeddings = HuggingFaceEmbeddings(
model_name=MODEL_PATH,
model_kwargs={"device": "cpu"},
encode_kwargs={"normalize_embeddings": True}
)
vector_db = FAISS.from_documents(chunks, embeddings)
vector_db.save_local(VECTOR_DB_PATH)
print("向量库创建完成")
return vector_db
# 4. 语义检索+重排
def semantic_search(query):
print(f"检索问题:{query}")
# 加载向量库
embeddings = HuggingFaceEmbeddings(model_name=MODEL_PATH)
vector_db = FAISS.load_local(VECTOR_DB, embeddings, allow_dangerous_deserialization=True)
# 初步检索
retriever = vector_db.as_retriever(search_kwargs={"k": TOP_K})
docs = retriever.get_relevant_documents(query)
# 重排序
reranker = CrossEncoder(RERANK_MODEL_PATH)
pairs = [[query, doc.page_content] for doc in docs]
scores = reranker.predict(pairs)
sorted_docs = [doc for _, doc in sorted(zip(scores, docs), key=lambda x: x[0], reverse=True)]
return sorted_docs[:RERANK_TOP]
# 主函数
if __name__ == "__main__":
# 初始化(首次运行)
if not os.path.exists(os.path.join(VECTOR_DB_PATH, "index.faiss")):
docs = load_documents()
chunks = split_documents(docs)
create_vector_db(chunks)
# 测试检索
results = semantic_search("产品售后流程是什么")
print("\n检索结果:")
for i, doc in enumerate(results):
print(f"\n【结果{i+1}】:\n{doc.page_content}")
八、常见问题排查
Q1:检索结果不相关
- 原因:分块不合理、向量未归一化、模型不匹配;
- 解决:调小 Chunk Size 至 384、开启归一化、换 BGE 模型。
Q2:中文效果差
- 原因:用了英文模型、分隔符不合理;
- 解决:换 BGE-zh、中文分隔符优先句号 / 段落。
Q3:向量生成慢
- 原因:Batch Size 过小、CPU 推理;
- 解决:Batch=16、用 GPU 加速、模型量化。
Q4:内存不足
- 原因:模型过大、向量维度高;
- 解决:用 BGE-small、降维至 512、模型量化。
Q5:领域适配差
- 原因:通用模型、无领域微调;
- 解决:领域微调、用领域预训练模型。
九、总结与扩展
9.1 核心总结
Embedding 调优是 RAG 系统的核心,模型选择 + 分块调优 + 参数精调 + 进阶优化四大步骤,可系统性提升检索精度:
- ✅ 中文优先 BGE-small-zh-v1.5,离线开源;
- ✅ 中文 Chunk Size=512、Overlap=50,优先语义分割;
- ✅ 必开归一化,批量生成 Batch=16;
- ✅ 领域微调 + Rerank 重排,精度再上台阶;
- ✅ 全链路离线,适配内网私有化场景。
9.2 扩展方向
- 多模态 Embedding:支持图片、PDF 截图向量化;
- 动态分块:根据文本内容自动调整 Chunk Size;
- 向量量化:INT8 量化,减少 75% 存储,速度提升 50%;
- 多模型融合:多个 Embedding 模型结果融合,提升鲁棒性。