GEOZ

朴素的 RAG 系统由于不科学的分块、单查询和缺少相关性过滤,常常效果不佳

2026/9/6
朴素的 RAG 系统由于不科学的分块、单查询和缺少相关性过滤,常常效果不佳

AIAI Summary (BLUF)

朴素的 RAG 系统由于不科学的分块、单查询和缺少相关性过滤,常常效果不佳。本文梳理了11个真实可用的 RAG 优化策略,从摄取阶段的上下文感知分块、上下文检索,到查询阶段的查询扩展、多查询以及混合的智能体/自反思策略,并通过组合使用将准确率从60%大幅提升到94%。内容附有代码示例和适用场景,适合对 RAG 已有一定了解的开发者直接实践。

核心洞察

先说结论:RAG 项目的瓶颈大多不在模型,而在数据进入系统那一步。这篇文章把 11 个策略讲得挺清楚,但最值得反复看的是第三部分的组合设计和第四部分的实施顺序。做项目的人容易一上来就追智能体、知识图谱这些新名词,先把分块和重排序做好,收益比什么高级架构都大。

我第一次搭 RAG 系统,把活儿想得太简单了。文档切块、转向量、检索、拼上下文喂给大模型,完事。

实际准确率只有 60% 左右。

用户会看到完全不相干的答案。模型“自信”地输出一堆无关内容,有时候连文档里明摆着的关联都能漏掉。

光排查就花了几个星期。

后来我才知道,那套做法就是论文里说的“朴素 RAG”。这种最基础的实现,基本没法直接上生产。

下面的 11 个策略,是我把准确率从 60% 提到 94% 的过程中真正用过的东西。每个策略拆开讲是什么、解决什么问题,再给代码和合适的使用场景。最后是组合方案和上手顺序。

读这篇之前需要点基础。你要是刚接触这些概念,先补补课:

  • RAG(检索增强生成)是怎么回事
  • 大模型的基本原理
  • 向量、嵌入这些基础概念

核心结论

  1. RAG 系统效果不佳的根源大多不在模型,而在数据处理和检索环节;采用本文的 11 个策略后,准确率从约 60% 提升到了 94%。

  2. 朴素 RAG(固定长度切块 + 向量检索 + 无过滤拼接)的准确率仅约 60%,典型缺陷包括切块截断语义、查询单一、没有相关性过滤、小块上下文缺失。

  3. 上下文检索策略(策略 2)为每个分块用大模型生成一句“上下文说明”再入库,据 Anthropic 研究可使检索失败率降低 35%–49%。

  4. 重排序策略(策略 3)采用“向量检索引召回 20–50 个候选 → 交叉编码器逐一打分 → 取前 N 个”的两阶段方案,能有效修正向量搜索的排序偏差,显著提升最终答案的相关性。

  5. 知识图谱策略(策略 8)通过结合向量检索与实体关系网络,能补上纯向量搜索遗漏的显式关系、减少幻觉,但需额外维护图数据库,建设与计算成本较高。

一、朴素 RAG 的根本问题

要理解这么多补救措施,先得搞明白基础方案怎么翻车的。

# 朴素 RAG 的做法
def naive_rag(query: str) -> str:
    # 1. 把查询转成向量
    query_embedding = embed(query)

    # 2. 去向量库找最接近的 5 个块
    chunks = vector_db.search(query_embedding, top_k=5)

    # 3. 拼成上下文丢给大模型
    context = "\n".join(chunks)
    answer = llm.generate(f"上下文:{context}\n\n问题:{query}")

    return answer

代码看着头头是道,坑全在看不见的地方:

  • 固定长度切块会把句子拦腰截断,前一句和后一句的联系直接断掉。
  • 查询只有一个角度。换个说法写进文档的内容,向量搜索容易搜不到。
  • 没有相关性过滤。向量库返回的是“最接近”的块,不等于“最有用”的块。
  • 块太小,单独拿出来理解不了全貌。

这么一套组合下来,整个系统成了高级猜谜游戏。

下面 11 个策略,就是按着这些失败模式一个坑一个坑填。

二、真正有效的 11 个策略

我把它们分成三类。摄取阶段解决文档怎么切、怎么入库的问题;查询阶段解决怎么搜才更准的问题;混合阶段把多个策略拧在一起,让效果互相放大。

策略 1:上下文感知分块

分块是整条链路的地基,一个句子断成两截,后面所有环节都找补不回来。这个策略不按固定字符数硬切,而是让程序先理解文档的标题、段落、表格结构,在完整的语义边界处落刀。

from docling.chunking import HybridChunker
from transformers import AutoTokenizer


class SmartChunker:
    def __init__(self, max_tokens=512):
        # 用分词器数 token,而不是按字符长度数
        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_chunks.append(
                self.chunker.contextualize(chunk=chunk)
            )

        return contextualized_chunks

优点:免费、快,不用换嵌入模型,文档结构也会被保留下来。

缺点:比固定切块多一点计算量,而且文档解析得先做对,后面才谈得上“语义”。

用在哪:默认方案。没有特殊理由就优先用它,别一上来固定长度硬切。

策略 2:上下文检索

向量化之前,大模型先给每个分块写一两句“自我介绍”,说清楚它在这份文档里的位置。这样即使块很小,单独拿出来信息也是完整的。

“收入增长 40%”这种句子,脱离上下文谁知道是哪家公司、哪一年。加上来源信息之后,块自己就能说清自己是谁。

async def enrich_chunk(chunk: str, document: str, title: str) -> str:
    # 让大模型生成一段一两句话的上下文说明
    prompt = f"""文档标题:{title}
{document[:4000]}

下面是一个分块:
{chunk}

用一两句话说明这个分块与完整文档的关系,开头用「此分块来自...」。"""

    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 亿美元,利润率提高。”

加了上下文之后:

“此分块来自某公司 2024 年第二季度财报,讲的是当季业绩和第一季度的对比。收入增长 40% 至 3.14 亿美元,利润率提高。”

优点:

  • Anthropic 的研究里提到,这个方法能让检索失败率降低 35% 到 49%。
  • 分块变成自包含的内容,向量搜索和关键词搜索都受益。
  • 不挑嵌入模型。

缺点:

  • 每个分块都要一次大模型调用,摄取成本高。
  • 入库变慢,索引体积变大。

用在哪:法律、医疗、财务这类文档,准确性比成本重要的时候。

策略 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:
    # 第一步:向量检索多取一些候选
    candidate_limit = min(limit * 4, 20)
    query_embedding = await embedder.embed_query(query)

    candidates = await vector_db.search(query_embedding, top_k=candidate_limit)

    # 第二步:交叉编码器逐对打分
    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, _ in reranked]

同一个查询跑出来的对比:

查询:“第二季度收入增长因素是什么?”

纯向量搜索按相似度排序:

  1. “第二季度收入为 3.14 亿美元”(0.82)
  2. “增长因素包括……”(0.78)
  3. “第一季度,收入为……”(0.76)

重排序后按相关性排序:

  1. “增长因素包括……”(0.94)
  2. “第二季度收入为 3.14 亿美元”(0.89)
  3. “第二季度表现的关键驱动因素……”(0.85)

优点:精度提升明显;候选多一点也没关系,反正不会全塞给大模型;能修正向量搜索的偏差。

缺点:比纯向量搜索慢,需要更多算力,成本高一点。

用在哪:答错代价高的问答场景,准确率优先于速度的时候。

策略 4:查询扩展

用户输入往往很模糊。一句“什么是 RAG”,到底想要架构细节、应用案例还是实现指南,根本说不清。

查询扩展就是用大模型把短查询改写成更具体、更完整的版本。

async def expand_query(query: str) -> str:
    system_prompt = """你是一个查询扩展助手。把用户输入的短查询改写成更详细的版本:
1. 补充上下文和必要的澄清
2. 带上相关术语
3. 范围保持集中
4. 仍然是一个完整的问题
把长度控制在原来的 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?”

输出:“什么是检索增强生成?它如何把信息检索和语言生成结合起来?关键组件和架构是什么?它给问答系统带来了哪些优势?”

优点:检索精度提高,模糊查询的处理效果好,只额外调用一次大模型。

缺点:多一次调用就多一点延迟和成本。太简单的查询可能被扩过头。

用在哪:聊天机器人、搜索框这类用户习惯只输入几个词的场景。

策略 5:多查询 RAG

一种问法只有一种召回角度。原文里写的是“如何部署机器学习模型”,用户问的是“模型训练完了怎么上线”,两边可能都对不上。

多查询 RAG 的做法是:让大模型把同一个问题改写成三到四个不同说法,并行去搜,结果按块去重。

async def search_multi_query(query: str, limit: int = 5) -> list:
    # 生成另外 3 种问法
    prompt = f"""把这个问题改写成 3 个不同的问法,只输出 3 行:
{query}"""

    resp = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
    )

    queries = [query] + resp.choices[0].message.content.strip().splitlines()

    # 并行搜索,最后按分块去重
    results = await asyncio.gather(*[
        semantic_search(q, limit) for q in queries
    ])

    seen = {}
    for rows in results:
        for row in rows:
            chunk_id = row["chunk_id"]
            if chunk_id not in seen or row["score"] > seen[chunk_id]["score"]:
                seen[chunk_id] = row

    return sorted(seen.values(),
                  key=lambda x: x["score"], reverse=True)[:limit]

原始问题:“怎么部署机器学习模型?”

变体 1:“把机器学习模型部署到生产环境的步骤是什么?”
变体 2:“机器学习模型部署基础设施有哪些最佳实践?”
变体 3:“训练完的模型有哪些生产部署方式?”

优点:模糊查询的召回率更高,能覆盖不同表述。查询之间是并行的,不会拖慢太多。

缺点:数据库查询次数变成原来的几倍,API 成本也上去了,还可能搜回一堆重复内容。

用在哪:问题可能有多种理解方式的场景,适合比较开放的探索性问题。

策略 6:智能体 RAG

不是每个问题都该走同一条检索路径。有些需要向量搜索,有些要翻完整份文档,有些得去查结构化数据。

智能体 RAG 的思路是给模型配好几个检索工具,让它自己判断该用哪个、按什么顺序用。

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:
    """在知识库分块里做语义搜索"""
    rows = await vector_db.search(
        await embedder.embed_query(query), top_k=limit
    )
    return format_results(rows)


@agent.tool
async def retrieve_full_document(title: str) -> str:
    """分块缺上下文时,取整份文档"""
    doc = await documents.find_by_title(title)
    return f"{doc.title}\n\n{doc.content}"

看一个实际决策过程。

用户问:“完整的退款政策是什么?”

智能体的处理路径:

  1. 先用知识库搜索找到“退款政策”相关的分块。
  2. 发现分块里没有完整政策。
  3. 调用取整份文档的工具。
  4. 基于完整文档回答。

优点:灵活,能处理多种数据源,还能把不同检索策略组合起来。

缺点:实现复杂,行为不太可预测,多步推理会让延迟变高。

用在哪:文档、数据库、API 混着用,查询复杂度差别很大的时候。

策略 7:自反思 RAG

普通 RAG 搜到什么就用什么,第一次结果差也只能认了。

自反思 RAG 会在检索完之后,让大模型给结果打分。分数太低就改写查询重新搜,直到结果过关或者达到循环上限。

async def reflective_search(
    query: str, limit: int = 5, max_iterations: int = 2
):
    for i in range(max_iterations):
        results = await semantic_search(query, limit)
        score = await grade_results(query, results)  # 按 1-5 打分

        if score >= 3:
            return {"results": results, "query": query, "rounds": i + 1}

        # 分数不够,下一轮用改写后的查询再搜
        if i < max_iterations - 1:
            query = await refine_query(query, results)

    return {"results": results, "query": query, "rounds": max_iterations}

迭代过程看起来是这样:

第一轮搜“部署”,相关性只得了 2 分,太模糊。
改写查询,变成“把机器学习模型部署到生产环境”,第二轮得分 4。

优点:有自校正能力,能从很差的初始结果里爬出来。

缺点:延迟最高,每轮都要大模型参与,也是最贵的方案。真正困难的查询,循环几次也可能救不回来。

用在哪:研究类应用、复杂查询,答案准确性远重要于响应速度的场景。

策略 8:知识图谱

向量搜索能发现“文本像”,但发现不了“谁管谁”“什么在哪”“哪个季度报了多少钱”这种明确关系。

知识图谱策略把向量检索和图数据库结合起来,检索时既看语义相似度,也顺着实体关系走。Graphiti 这类工具把实体和关系抽取都封装好了,直接往里塞文档就行。

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 graph_search(query: str) -> str:
    # 内部会同时用语义向量、BM25 关键词和图关系
    results = await graphiti.search(query=query, num_results=5)
    return format_entities_and_relations(results)

查询示例:“谁在管星辰科技,第二季度有什么变化?”

纯向量搜索拿到的是两段互不相干的文本:“星辰科技 CEO 信息……”和“第二季度变化包括……”。

知识图谱返回的是一张关系网:

星辰科技(公司)

  • 首席执行官:王芳(人物)
  • 营收:3.14 亿美元(财务数据)
  • 期间:2024 年第二季度
  • 所在地:上海

模型可以直接回答:“王芳是星辰科技的首席执行官,公司第二季度营收增长到 3.14 亿美元。”

优点:能补上向量检索漏掉的关系信息,减少幻觉。

缺点:要多维护一套图数据库,建设和维护成本都高。设置复杂,检索也慢一些。

用在哪:实体关系很重要的领域,比如医疗网络、财务系统、研究数据库。

策略 9:分层 RAG

小块命中准,但上下文少;大块上下文全,但匹配精度差。

分层 RAG 做一个父子结构:检索时命中小的子块,返回时带上它所属的父块。这样精度和上下文都保住了。

async def hierarchical_search(query: str, limit: int = 3) -> str:
    # 子块承担匹配,父块负责提供上下文
    matches = await child_vectors.search(
        await embedder.embed_query(query), top_k=limit
    )

    parents = [
        await parent_store.get(m["parent_id"]) for m in matches
    ]

    return "\n\n".join(
        f"[{p['heading']}]\n{p['content']}" for p in parents
    )

优点:匹配精度和上下文含量之间的平衡很好,索引里的噪音也少。

缺点:要多维护一层父子关系,索引结构更复杂。

用在哪:技术手册、法律文书、研究论文这类自带层级结构的文档。

策略 10:延迟分块

大多数分块都是先切文档,再对每一块单独做嵌入。这样做的问题是:每个块只能看到自己这点内容,长距离的上下文关系全丢了。

延迟分块的思路反过来。整篇文档先过一遍模型,得到每个位置的向量表示,然后再定分块边界,把每个块对应的向量拿出来做平均池化。

def late_chunk(text: str, chunk_size=512):
    # 整篇文档先编码,获得每个位置的向量
    position_embeddings = transformer_embed(text)

    # 再确定分块边界
    positions = tokenize(text)
    boundaries = list(range(0, len(positions), chunk_size))

    # 每个块用它那一小段的向量做平均池化
    return [
        (
            detokenize(positions[start:end]),
            mean_pool(position_embeddings[start:end]),
        )
        for start, end in zip(boundaries[:-1], boundaries[1:])
    ]

优点:分块向量里保留了全文上下文,对长依赖关系的理解更好。

缺点:嵌入模型得能处理足够长的输入,实现也更复杂,还要受模型最大长度限制。

用在哪:技术合同、密集文档这类“不看全文就理解不了单块”的场景。

策略 11:微调嵌入

通用嵌入模型不懂行业黑话。医学术语、法律措辞、财务缩写,这些在通用向量空间里经常被匹配到错误的位置。

微调嵌入的做法是:拿一批领域内的问题和对应文档,继续训练嵌入模型,让它重新学习这些专业表达之间的距离。

from sentence_transformers import SentenceTransformer, losses
from torch.utils.data import DataLoader

# 领域数据:一批「问题-文档」对
pairs = [
    ("什么是税息折旧及摊销前利润?", "税息折旧及摊销前利润指的是……"),
    ("解释一下资本支出", "资本支出指的是……"),
]

model = SentenceTransformer("all-MiniLM-L6-v2")
loader = DataLoader(pairs, shuffle=True, batch_size=16)
loss = losses.MultipleNegativesRankingLoss(model)

model.fit(train_objectives=[(loader, loss)], epochs=3, warmup_steps=100)
model.save("./fine_tuned_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 美元,前期还有一笔训练投入。
适合:专业术语密集,且实体关系同样重要的领域。

四、实施路线图:从简单开始,智能扩展

别想着一口气把 11 个策略全上。系统复杂到一定程度,出了问题都定位不了。

按阶段来。

阶段 1:基础(第 1 周)

  • 用上下文感知分块替换固定长度分块。
  • 配好基础向量检索。
  • 把当前准确率测出来,作为基线。

阶段 2:快速获胜(第 2-3 周)

  • 加重量排序。这是全篇性价比最高的一步。
  • 加上查询扩展,解决模糊问题。
  • 再测一次改进幅度。

阶段 3:高级(第 4-6 周)

  • 多查询和智能体 RAG 里选一个,看业务更偏哪种。
  • 给关键查询加自反思。
  • 开始做微调和细节优化。

阶段 4:专业化(第二个月以后)

  • 给高价值文档加上下文检索。
  • 关系很重要的话,引入知识图谱。
  • 准备领域数据,微调嵌入模型。

这套顺序的用意很直接:先做投入产出比最高的事,后面每加一层,都得有数据支撑。

五、实际应用结果

下面记录的是这三套组合在真实项目里的表现。

电商客服机器人

  • 之前:58% 的回答准确,35% 的问题转人工。
  • 之后(组合 1):准确率 91%,转人工率降到 12%。
  • 附带收益:客服工单量减少 70%,一年省下约 18 万美元。

医疗文档系统

  • 之前:准确率 62%,低到不敢上生产。
  • 之后(组合 2):准确率 96%,通过审核,允许在临床场景使用。
  • 附带收益:医生每天少花大约 4 小时翻文档。

律师事务所的合同分析

  • 之前:准确率 65%,大量依赖人工复核。
  • 之后(组合 3):合同条款识别准确率 94%。
  • 附带收益:合同审查速度提升 60%,漏条款的情况明显变少。

六、常见错误避免

帮不少团队看过这类系统,反复出现的错误就这几个。

错误 1:一次使用所有策略

结果就是系统复杂到没法排查,钱也花了,最后说不清哪个环节起的作用。

正确做法:从组合 1 开始,跑出基线数据,按需往上加。

错误 2:不测基线性能

没有基线,改完什么都证明不了。

先做一个评估数据集,每次改动前后都测一遍准确率和延迟。

错误 3:固定分块大小

这是最常见的问题。固定长度切块把语义结构切得稀碎,后面用什么高级检索都难补救。

一上来就该用上下文感知分块。

错误 4:忽略重排序

向量相似度和语义相关性是两回事。重排序是整个链路里投入产出比最高的环节,能早加就早加。

错误 5:不做查询预处理

真实用户不会按照你文档的写法提问。他们只会给几个模糊的关键词。

至少做一层查询扩展。

错误 6:只用一种检索策略

一套检索方式应付不了所有类型的查询。

有条件的直接上智能体 RAG,让系统自己切换检索策略。

七、RAG 的未来趋势

RAG 这一两年变化特别快,我主要盯着这几个方向。

新的嵌入模型越来越小、越来越快。有些新模型推理速度快上十倍,准确率能保持在老一代模型的九成以上。

多模态 RAG 也在起来。图片、表格、图表进入检索范围之后,模型拿到的上下文比纯文本丰富得多。

还有一类是“学习的稀疏检索”。SPLADE 这类模型把神经网络和倒排索引的优点合到一起,在有精确关键词需求的场景里表现不错。

这几个方向都值得留意,但目前还没到大规模替代现有方案的时候。

八、写在最后

生产可用的 RAG 系统,往往不是靠多花哨的技术撑起来的。多数时候,只是把朴素 RAG 的失败模式一个一个补齐。

先做对基础:上下文感知分块加质量排序。后续按需加复杂度,每一步都用量化结果说话。

我自己在这套方法里,把系统准确率从 60% 提到了 94%。换一个领域、换一批文档,最终数字肯定不一样,但踩坑的顺序是通的。

九、参考资料

[1] GitHub 仓库:高级 RAG 策略合集

[2] Anthropic 关于上下文检索的研究

[3] Pinecone 的重排序指南

[4] Docling:上下文感知分块工具

[5] Graphiti:面向 RAG 的知识图谱工具

常见问题(FAQ)

为什么我的 RAG 系统效果不好?

朴素 RAG 分块不科学、单查询、无相关性过滤,常导致上下文断裂或检索不准。文档切块、向量检索、拼上下文看似简单,实际准确率仅 60% 左右。

RAG 优化有哪些实用策略?

核心策略有:上下文感知分块、上下文检索、重排序、查询扩展、多查询 RAG。分阶段实施:摄取阶段做好分块与上下文,查询阶段优化检索与重排,组合策略可显著提升。

如何将 RAG 准确率从 60% 提升到 94%?

组合使用策略:先上下文感知分块,再用上下文检索让块自包含,查询时多查询+扩展,最后重排序。按顺序实施,代码示例已验证效果。

晓婷深圳
本文由 晓婷 审核,最后更新于 2026年9月6日
联系编辑 →
← 返回文章列表
分享到:微博

版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。

文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。

若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。