构建RAG系统的核心策略:从60%到94%准确率
我第一次构建RAG系统时,以为一切都很简单:把文档切块、创建向量、检索相似内容,然后喂给大模型。
结果准确率只有60%左右。
用户得到的是完全不相关的答案。系统会“自信满满”地返回毫无关联的信息,有时甚至错过文档间显而易见的联系。
我花了数周时间排查问题。
后来发现,我使用的正是研究人员所称的“朴素RAG”——这种最基础的实现方案,几乎从不在生产环境中奏效。
本文需要对RAG和大模型底层算法有一定了解,如果还没接触算法,对大模型不太了解,建议先学习以下知识:
一、朴素RAG的根本问题
我们先看看为什么基础RAG经常失败。

传统RAG遵循这个简单流程:
# 朴素RAG方法
def naive_rag(query: str) -> str:
# 1. 对查询进行向量化
query_embedding = embed(query)
# 2. 查找相似片段
chunks = vector_db.search(query_embedding, top_k=5)
# 3. 生成答案
context = "\n".join(chunks)
answer = llm.generate(f"Context: {context}\n\nQuestion: {query}")
return answer看起来合理,对吧?
但问题出在哪里:
固定大小的分块会在思路中间切断句子,丢失上下文
单一查询视角会错过表述不同的文档
没有相关性过滤——你得到的是“最接近”的匹配,而不是最相关的
有限的上下文——小片段缺乏完整画面
结果就是?你的RAG系统变成了一个高级猜谜游戏。
下面展示如何修复这些问题。
二、真正有效的11个策略
我将这些策略分为三类:摄取策略(如何准备文档)、查询策略(如何搜索)和混合方法(组合策略以放大效果)。
策略1:上下文感知分块
作用:不是在固定字符数处分割文档,而是分析语义边界和文档结构。
解决的问题:当你分割“CEO宣布……[分块断开]……收入增长40%”时,上下文就丢失了。上下文感知分块将相关内容保持在一起。
代码示例:
from docling.chunking import HybridChunker
from transformers import AutoTokenizer
class SmartChunker:
def __init__(self, max_tokens=512):
# 使用实际的分词器,而不是字符计数
self.tokenizer = AutoTokenizer.from_pretrained(
"sentence-transformers/all-MiniLM-L6-v2"
)
self.chunker = HybridChunker(
tokenizer=self.tokenizer,
max_tokens=max_tokens,
merge_peers=True# 合并相邻的小分块
)
def chunk_document(self, document):
# 分析文档结构(标题、段落、表格)
chunks = list(self.chunker.chunk(dl_doc=document))
# 每个分块包含标题上下文
contextualized_chunks = []
for chunk in chunks:
# 添加分层标题信息
contextualized_text = self.chunker.contextualize(chunk=chunk)
contextualized_chunks.append(contextualized_text)
return contextualized_chunks优点:
免费且快速
自然地保持文档结构
适用于任何嵌入模型
缺点:
比朴素分割稍慢
需要正确的文档解析
使用时机:这应该是你的默认策略。始终优先选择语义分块而不是固定大小分割。
策略2:上下文检索
作用:在嵌入之前为每个分块添加文档级上下文。LLM生成1-2句话解释每个分块与整个文档的关系。
解决的问题:像“收入增长40%”这样的分块如果没有上下文(哪个公司、哪个季度、哪个文档)就没有意义。
代码示例:
async def enrich_chunk(chunk: str, document: str, title: str) -> str:
"""使用LLM添加上下文前缀"""
prompt = f"""
标题:{title}
{document[:4000]}
{chunk}
提供简要上下文(1-2句话)解释此分块
与完整文档的关系。格式:"此分块来自[标题],讨论[解释]。" """
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0,
max_tokens=150
)
context = response.choices[0].message.content.strip()
# 嵌入带上下文的版本
return f"{context}\n\n{chunk}"前后对比:
之前:
"收入增长40%至3.14亿美元,利润率提高。"
之后:
"此分块来自ACME公司2024年第二季度SEC文件,讨论季度
财务表现与2024年第一季度的比较。
收入增长40%至3.14亿美元,利润率提高。"
优点**:
减少35-49%的检索失败(根据Anthropic研究)
分块变得自包含
适用于向量和关键词搜索
缺点:
昂贵(摄取时每个分块需要1次LLM调用)
摄取时间更慢
索引大小更大
使用时机:用于准确性比成本更重要的关键文档(法律、医疗、财务文档)。
策略3:重排序
作用:两阶段检索,快速向量搜索找到20-50个候选,然后交叉编码器模型重新评分以提高精度。
解决的问题:向量相似度并不总是匹配语义相关性。文档可能在嵌入空间中“接近”,但实际上并不回答问题。
代码示例:
from sentence_transformers import CrossEncoder
# 初始化一次
reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
async def search_with_reranking(query: str, limit: int = 5) -> list:
# 阶段1:快速向量检索(获取4倍候选)
candidate_limit = min(limit * 4, 20)
query_embedding = await embedder.embed_query(query)
candidates = await db.query(
"SELECT content, metadata FROM chunks ORDER BY embedding $1 LIMIT $2",
query_embedding, candidate_limit
)
# 阶段2:使用交叉编码器重新排序
pairs = [[query, row['content']] for row in candidates]
scores = reranker.predict(pairs)
# 按重排序分数排序并返回前N个
reranked = sorted(
zip(candidates, scores),
key=lambda x: x[1],
reverse=True
)[:limit]
return [doc for doc, score in reranked]性能比较:
查询:"第二季度收入增长因素是什么?"
纯向量(相似度分数):
1. "第二季度收入为3.14亿美元" (0.82)
2. "增长因素包括..." (0.78)
3. "第一季度,收入为..." (0.76)
重排序后(相关性分数):
1. "增长因素包括..." (0.94)
2. "第二季度收入为3.14亿美元" (0.89)
3. "第二季度表现的关键驱动因素..." (0.85)
优点:
显著提高精度
考虑更多候选而不压倒LLM
可以修复向量搜索错误
缺点:
比纯向量搜索慢
需要更多计算资源
成本稍高
使用时机:当精度比速度更重要时。非常适合错误答案成本高的问题回答系统。
策略4:查询扩展
作用:使用LLM将简短查询扩展为更详细、全面的版本。
解决的问题:用户查询通常很模糊。“什么是RAG?”并不能捕捉他们想要的是架构细节、使用案例还是实施指南。
代码示例:
async def expand_query(query: str) -> str:
"""将简短查询扩展为详细版本"""
system_prompt = """你是查询扩展助手。
接受简短的用户查询并将其扩展为更详细的版本:
1. 添加相关上下文和澄清
2. 包含相关术语和概念
3. 指定应涵盖的方面
4. 保持原始意图
5. 保持为单个连贯问题
将查询扩展为详细2-3倍,同时保持专注。"""
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"扩展此查询:{query}"}
],
temperature=0.3
)
return response.choices[0].message.content.strip()转换示例:
输入:"什么是RAG?"
输出:"什么是检索增强生成(RAG),它如何将 信息检索与语言生成相结合,其关键组件和架构是什么, 以及它为问答系统提供了哪些优势?"
优点**:
提高检索精度
更好地处理模糊查询
单一增强查询(快速)
缺点:
额外的LLM调用增加延迟
可能过度指定简单查询
成本稍高
使用时机:当用户通常询问简短、模糊问题时。非常适合聊天机器人和搜索界面。
策略5:多查询RAG
作用:生成相同问题的3-4种不同表述,并行搜索所有表述,并去重结果。
解决的问题:一种表述可能错过与不同表述匹配的相关文档。
代码示例:
async def search_with_multi_query(query: str, limit: int = 5) -> list:
# 生成查询变体
variations_prompt = f"""生成此查询的3种不同表述:
"{query}"
仅返回3个查询,每行一个。"""
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": variations_prompt}],
temperature=0.7
)
queries = [query] + response.choices[0].message.content.strip().split('\n')
# 并行执行所有搜索
search_tasks = []
for q in queries:
query_embedding = await embedder.embed_query(q)
task = db.fetch(
"SELECT * FROM match_chunks($1::vector, $2)",
query_embedding, limit
)
search_tasks.append(task)
results_lists = await asyncio.gather(*search_tasks)
# 按分块ID去重,保留最高相似度
seen = {}
for results in results_lists:
for row in results:
chunk_id = row['chunk_id']
if chunk_id notin seen or row['similarity'] > seen[chunk_id]['similarity']:
seen[chunk_id] = row
# 返回前N个唯一结果
return sorted(
seen.values(),
key=lambda x: x['similarity'],
reverse=True
)[:limit]变体示例:
原始:"如何部署ML模型?"
变体1:"将机器学习模型部署到生产环境的步骤是什么?"
变体2:"ML模型部署基础设施的最佳实践"
变体3:"训练模型的生产部署选项"
优点:
对模糊查询有更好的召回率
捕捉不同视角
并行执行保持快速
缺点:
4倍数据库查询(尽管并行化)
更高的API成本
可能检索冗余内容
使用时机:当查询可能有多种有效解释时。非常适合广泛的探索性问题。
策略6:智能体RAG
作用:为AI智能体提供多个检索工具,让它根据查询自主选择使用哪个。
解决的问题:并非所有问题都需要相同的检索策略。有时需要语义搜索,有时需要完整文档,有时需要结构化数据。
代码示例:
from pydantic_ai import Agent
agent = Agent(
'openai:gpt-4o',
system_prompt='你是具有多个检索工具的RAG助手。为每个查询选择合适的工具。'
)
@agent.tool
async def search_knowledge_base(query: str, limit: int = 5) -> str:
"""文档分块的语义搜索"""
query_embedding = await embedder.embed_query(query)
results = await db.match_chunks(query_embedding, limit)
return format_results(results)
@agent.tool
async def retrieve_full_document(document_title: str) -> str:
"""当分块缺乏上下文时检索完整文档"""
result = await db.query(
"SELECT title, content FROM documents WHERE title ILIKE %s",
f"%{document_title}%"
)
return f"**{result['title']}**\n\n{result['content']}"
@agent.tool
async def sql_query(question: str) -> str:
"""查询结构化数据库获取特定数据"""
# 智能体可以为结构化数据编写SQL查询
# (在生产环境中,使用具有安全检查的适当SQL生成)
return execute_safe_sql(question)示例流程:
用户:"完整的退款政策是什么?"
智能体推理:
调用search_knowledge_base("退款政策") → 找到提及"refund_policy.pdf"的分块
意识到分块没有完整政策
调用retrieve_full_document("退款政策") → 返回完整文档
从完整文档生成全面答案
优点:
高度灵活和自适应
处理多样化的数据源
可以组合多种检索策略
缺点:
实现更复杂
行为不太可预测
由于多步推理,延迟更高
使用时机:当你有异构数据源(文档、数据库、API)且查询复杂度差异很大时。
策略7:自反思RAG
作用:检索文档后,系统评估其相关性,如果需要则优化查询,并重新搜索直到满意为止。
解决的问题:初始搜索通常返回差的结果,但传统RAG只是使用它得到的任何结果。
代码示例:
async def search_with_self_reflection(query: str, limit: int = 5, max_iterations: int = 2) -> dict:
"""自校正搜索循环"""
for iteration in range(max_iterations):
# 执行搜索
results = await vector_search(query, limit)
# 评分相关性
grade_prompt = f"""查询:{query}
检索到的文档:
{format_docs_for_grading(results)}
按1-5分评估这些文档与查询的相关性。
仅用数字回答。"""
grade_response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": grade_prompt}],
temperature=0
)
grade = int(grade_response.choices[0].message.content.strip().split()[0])
# 如果结果好,返回它们
if grade >= 3:
return {
"results": results,
"iterations": iteration + 1,
"final_query": query
}
# 如果结果差且不是最后一次迭代,优化查询
if iteration < max_iterations - 1:
refine_prompt = f"""查询"{query}"返回了低相关性结果。
建议一个可能找到更好文档的改进查询。
仅用改进后的查询回答。"""
refined_response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": refine_prompt}],
temperature=0.5
)
query = refined_response.choices[0].message.content.strip()
# 返回最佳尝试
return {
"results": results,
"iterations": max_iterations,
"final_query": query
}迭代示例:
迭代1:
查询:"部署"
评分:2/5(太模糊)
迭代2:
优化查询:"机器学习模型部署到生产环境"
评分:4/5(良好结果)
优点:
自校正
在迭代中改进
可以从差的初始结果中恢复
缺点:
最高延迟(2-3次LLM调用)
最昂贵的策略
对于真正困难的查询可能仍然失败
使用时机:当答案准确性至关重要且延迟可接受时。非常适合研究应用和复杂查询。
策略8:知识图谱
作用:将向量搜索与图数据库结合以捕捉实体间的关系。
解决的问题:向量搜索找到相似的文本但错过了明确的关系,如“CEO of”、“located in”、“reported revenue”。
使用Graphiti的概念示例:
from graphiti_core import Graphiti
from graphiti_core.nodes import EpisodeType
# 初始化Graphiti(连接到Neo4j)
graphiti = Graphiti("neo4j://localhost:7687", "neo4j", "password")
async def ingest_document(text: str, source: str):
"""摄取到知识图谱"""
# Graphiti自动提取实体和关系
await graphiti.add_episode(
name=source,
episode_body=text,
source=EpisodeType.text,
source_description=f"文档:{source}"
)
async def search_knowledge_graph(query: str) -> str:
"""混合搜索:语义 + 关键词 + 图"""
# Graphiti结合:
# - 语义相似性(嵌入)
# - BM25关键词搜索
# - 图结构遍历
# - 时间上下文
results = await graphiti.search(query=query, num_results=5)
# 格式化图结果
formatted = []
for result in results:
formatted.append(
f"实体:{result.node.name}\n"
f"类型:{result.node.type}\n"
f"关系:{result.relationships}"
)
return "\n---\n".join(formatted)查询流程示例:
查询:"谁运营ACME公司,第二季度发生了什么变化?"
纯向量搜索:
- "ACME公司CEO信息..."
- "第二季度变化包括..."
知识图谱搜索:
ACME公司(公司)
├─ HAS_CEO → Jane Smith(人物)
├─ REPORTED_REVENUE → $314M(财务)
│ └─ PERIOD → Q2 2024
└─ LOCATED_IN → California(地点)
结果:可以回答 "Jane Smith运营ACME公司,收入在第二季度增加到3.14亿美元"
优点:
捕捉向量错过的关系
减少幻觉
非常适合互连数据
缺点:
需要Neo4j基础设施
设置和维护复杂
更慢且更昂贵
需要实体提取
使用时机:当实体间关系至关重要时(医疗网络、财务系统、研究数据库)。
策略9:分层RAG
作用:创建父-子分块关系。搜索小子分块以提高精度,返回大父分块以获取上下文。
解决的问题:小子分块精确匹配查询但缺乏上下文。大分块有上下文但匹配不佳。
代码示例:
def ingest_hierarchical(document: str, title: str):
"""创建父-子结构"""
# 父级:大部分(2000字符)
parent_chunks = [document[i:i+2000] for i in range(0, len(document), 2000)]
for parent_id, parent in enumerate(parent_chunks):
# 存储父级
metadata = {"heading": f"{title} - 部分 {parent_id}"}
db.execute(
"INSERT INTO parent_chunks (id, content, metadata) VALUES (%s, %s, %s)",
(parent_id, parent, json.dumps(metadata))
)
# 子级:小子分块(500字符)
child_chunks = [parent[j:j+500] for j in range(0, len(parent), 500)]
for child in child_chunks:
embedding = get_embedding(child)
db.execute(
"INSERT INTO child_chunks (content, embedding, parent_id) VALUES (%s, %s, %s)",
(child, embedding, parent_id)
)
async def hierarchical_search(query: str) -> str:
"""搜索子级,返回父级"""
query_emb = get_embedding(query)
# 搜索小子级以提高精度
results = await db.query(
"""SELECT p.content, p.metadata
FROM child_chunks c
JOIN parent_chunks p ON c.parent_id = p.id
ORDER BY c.embedding %s LIMIT 3""",
query_emb
)
# 返回大父级以获取上下文
formatted = []
for content, metadata in results:
meta = json.loads(metadata)
formatted.append(f"[{meta['heading']}]\n{content}")
return "\n\n".join(formatted)优点:
平衡精度与上下文
减少搜索中的噪音
对于结构化文档很自然
缺点:
需要父-子模式
更复杂的索引
需要仔细的层次设计
使用时机:当文档具有清晰的层次结构时(技术手册、法律文件、研究论文)。
策略10:延迟分块
作用:在分块标记嵌入之前通过转换器处理整个文档(而不是文本)。
解决的问题:传统分块丢失长距离上下文。延迟分块在每个分块的嵌入中保留完整的文档上下文。
概念示例:
def late_chunk(text: str, chunk_size=512) -> list:
"""分块前嵌入完整文档"""
# 步骤1:嵌入整个文档(最多8192个标记)
full_doc_token_embeddings = transformer_embed(text) # 标记级别
# 步骤2:定义分块边界
tokens = tokenize(text)
chunk_boundaries = range(0, len(tokens), chunk_size)
# 步骤3:为每个分块池化标记嵌入
chunks_with_embeddings = []
for start in chunk_boundaries:
end = start + chunk_size
chunk_text = detokenize(tokens[start:end])
# 平均池化标记嵌入(保留完整文档上下文!)
chunk_embedding = mean_pool(full_doc_token_embeddings[start:end])
chunks_with_embeddings.append((chunk_text, chunk_embedding))
return chunks_with_embeddings优点:
保持完整文档上下文
有效利用长上下文模型
更好的语义理解
缺点:
需要长上下文嵌入模型
实现更复杂
受模型最大标记数限制
使用时机:当文档上下文对于理解分块至关重要时(密集技术文档、法律合同)。
策略11:微调嵌入
作用:在特定领域的查询-文档对上训练嵌入模型。
解决的问题:通用嵌入不理解专业术语(医学术语、法律行话、技术缩写)。
代码示例:
from sentence_transformers import SentenceTransformer, losses
from torch.utils.data import DataLoader
def prepare_training_data():
"""领域特定的查询-文档对"""
return [
("什么是EBITDA?", "EBITDA(利息、税项、折旧及摊销前利润..."),
("解释资本支出", "资本支出(CapEx)指的是..."),
# ... 数千对更多
]
def fine_tune_model():
"""在领域数据上微调"""
# 加载基础模型
model = SentenceTransformer('all-MiniLM-L6-v2')
# 准备训练数据
train_examples = prepare_training_data()
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
# 定义损失函数
train_loss = losses.MultipleNegativesRankingLoss(model)
# 训练
model.fit(
train_objectives=[(train_dataloader, train_loss)],
epochs=3,
warmup_steps=100
)
model.save('./fine_tuned_financial_model')
return model
# 使用微调模型
embedding_model = SentenceTransformer('./fine_tuned_financial_model')性能比较:
查询:"什么是营运资金?"
通用嵌入:
1. "营运资金包括..." (0.72)
2. "资本市场提供..." (0.68) ← 错误!
3. "工作条件在..." (0.65) ← 错误!
微调嵌入:
1. "营运资金包括..." (0.89)
2. "营运资金比率计算..." (0.84)
3. "有效管理营运资金..." (0.81)
优点:
通常提高5-10%的准确性
更好地理解领域术语
较小模型可以胜过较大的通用模型
缺点:
需要训练数据
训练时间和资源
需要定期重新训练
使用时机:用于通用嵌入表现不佳的专业领域(医疗、法律、财务、技术)。
三、组合策略的力量:实现94%准确率的关键
以下是关键见解:单个策略是好的。组合策略是变革性的。
在测试了数十种组合后,我发现了三种对不同用例特别有效的强力组合。
组合1:生产就绪堆栈(最佳整体)
策略:上下文感知分块 + 重排序 + 查询扩展 + 智能体RAG
为什么有效:每个策略解决不同的失败模式:
上下文感知分块确保连贯的分块
查询扩展处理模糊查询
重排序修复向量搜索错误
智能体方法适应查询复杂度
性能:92%准确率,1.2秒平均延迟
成本:约 $0.003每次查询
最适合:通用生产系统、客户支持、内部知识库
组合2:高准确率堆栈(最适合关键应用)
策略:上下文检索 + 多查询 + 重排序 + 自反思RAG
为什么有效:最大冗余和自校正:
上下文检索确保分块自包含
多查询捕捉所有角度
重排序过滤噪音
自反思捕捉并修复错误
性能:96%准确率,2.5秒平均延迟
成本:约 $0.008每次查询
最适合:医疗、法律、财务应用,其中错误成本高
组合3:领域专家堆栈(最适合专业领域)
策略:微调嵌入 + 上下文检索 + 知识图谱 + 重排序
为什么有效:每层的深度领域知识:
微调嵌入理解专业术语
上下文检索添加上下文领域
知识图谱捕捉领域关系
重排序应用领域感知相关性
性能:领域查询94%准确率,1.8秒延迟
成本:约 $0.005每次查询(初始训练投资后)
最适合:具有专业术语的医疗、法律、财务、技术领域
四、实施路线图:从简单开始,智能扩展
不要一次尝试实施所有策略。以下是一个实用的路线图:
阶段1:基础(第1周)
上下文感知分块(替换固定大小分割)
具有适当嵌入的基本向量搜索
测量基准准确率
阶段2:快速获胜(第2-3周)
添加重排序(效果最大的准确率提升)
实现查询扩展(处理模糊查询)
测量改进
阶段3:高级(第4-6周)
添加多查询或智能体RAG(根据用例选择)
为关键查询实现自反思
微调和优化
阶段4:专业化(第2个月以上)
为高价值文档添加上下文检索
如果关系重要,考虑知识图谱
微调嵌入以提高领域特定准确率
五、实际应用结果
以下是我将这些组合应用于实际生产系统时发生的情况:
客户支持聊天机器人(电子商务)
之前:58%准确答案,35%升级率
之后(组合1):91%准确,12%升级率
策略:上下文感知分块 + 重排序 + 查询扩展 + 智能体RAG
影响:支持工单减少70%,每年节省 $180K
医疗文档系统(医疗保健)
之前:62%准确率,太冒险无法生产使用
之后(组合2):96%准确率,批准用于临床使用
策略:上下文检索 + 多查询 + 重排序 + 自反思
影响:临床医生每天节省4小时文档查找时间
法律合同分析(律师事务所)
之前:65%准确率,需要大量人工审查
之后(组合3):合同条款94%准确率
策略:微调嵌入 + 上下文检索 + 知识图谱
影响:合同审查速度提高60%,减少遗漏条款
六、常见错误避免
在帮助数十个团队实施这些策略后,以下是我最常见到的错误:
错误1:一次使用所有策略
问题:系统过于复杂,难以调试,昂贵 解决方案:从组合1开始,测量结果,仅在需要时添加复杂性
错误2:不测量基准性能
问题:无法证明改进,不知道什么有效 解决方案:创建评估数据集,测量每次更改前后的准确率/延迟
错误3:固定分块大小
问题:破坏语义连贯性,丢失上下文 解决方案:始终使用上下文感知分块或灵活分块方法作为基础
错误4:忽略重排序
问题:向量相似度 ≠ 相关性,得到平庸结果 解决方案:重排序是最高ROI策略——尽早实施
错误5:没有查询预处理
问题:用户查询模糊,搜索失败 解决方案:至少实现查询扩展
错误6:单一检索策略
问题:一种尺寸不适合所有查询 解决方案:使用智能体RAG为系统提供灵活性
七、RAG的未来趋势
该领域正在快速发展。以下是我关注的新兴趋势:
1. 更小、更快的模型 新嵌入模型以10倍速度实现90%的准确率。
2. 多模态RAG 检索图像、表格和图表以及文本以获取更丰富的上下文。
3. 学习的稀疏检索 像SPLADE这样的模型,将神经网络与稀疏表示结合。
八、写在最后
构建生产就绪的RAG系统不是使用最花哨的技术。而是理解朴素RAG的失败模式并系统地解决它们。
从基础开始(上下文感知分块 + 重排序),仅在需要时添加复杂性,并始终测量你的改进。
我分享的组合使我的准确率从60%提升到了94%。但根据你的领域、数据和使用案例,效果会有所不同。
关键是简单开始,测量一切,并根据真实的性能数据进行迭代。
现在我想知道:你已经在使用哪些策略?哪些组合最适合你的使用案例?
九.参考资料
[1] GitHub仓库:高级RAG策略: https://github.com/coleam00/ottomator-agents/tree/main/all-rag-strategies
[2] Anthropic的上下文检索研究: https://www.anthropic.com/news/contextual-retrieval
[3] Pinecone:重排序指南: https://www.pinecone.io/learn/series/rag/rerankers/
[4] Docling:上下文感知分块: https://github.com/DS4SD/docling
[5] Graphiti:RAG知识图谱: https://github.com/graphiti-ai/graphiti
转载来源:https://mp.weixin.qq.com/s/xrexs6OUn7-5YNxzt5-r5A