RAG-检索优化策略

0 阅读16分钟

在RAG系统落地实践中,向量基础检索往往存在语义匹配偏差、上下文碎片化,长文档召回不全、关键词漏匹配等问题。单纯的靠固定分块加向量检索的方案,很难适应复杂的业务场景。为了解决这些问题,有一些经典的高级检索优化策略,如双层检索、混合检索等。接下来本文将分享这些策略的实现思路,方便在座的亦菲、彦祖们有个参考。

索引优化-前.png

父子文档检索

将长文档切分为小的 chunk(子文档)进行向量化索引,但在元数据中记录其所属的父文档 ID。检索时命中子文档,但返回整个父文档或父文档的大段落给 LLM。兼顾了检索的精准性(小块匹配度高)和生成时的完整上下文。

流程图

索引优化-父子文档检索.png

代码示例

import os
import uuid
from dotenv import load_dotenv
from openai import OpenAI
from langchain_core.documents import Document
from langchain_openai import ChatOpenAI
from langchain_classic.chains.retrieval_qa.base import RetrievalQA
from langchain_core.prompts import PromptTemplate
from langchain_classic.retrievers import ParentDocumentRetriever
from langchain_classic.storage import InMemoryStore
​
​
from langchain_community.vectorstores import Milvus
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.embeddings import Embeddings
​
load_dotenv()
​
# ===================== 配置初始化 =====================
OPENAI_API_KEY = os.getenv("GLM_API_KEY")
OPENAI_BASE_URL = os.getenv("GLM_BASE_URL")
EMBEDDING_MODEL = os.getenv("GLM_EMBEDDING_MODEL", "embedding-3")
MILVUS_URI = os.getenv("MILVUS_URI", "http://localhost:19530")
​
​
# 兼容 LangChain 的嵌入适配器
class OpenAIEmbeddingsAdapter(Embeddings):
    def __init__(self, client, model):
        self.client = client
        self.model = model
​
    def embed_documents(self, texts):
        response = self.client.embeddings.create(input=texts, model=self.model)
        return [item.embedding for item in response.data]
​
    def embed_query(self, text):
        return self.embed_documents([text])[0]
​
​
client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_BASE_URL)
embed_model = OpenAIEmbeddingsAdapter(client, EMBEDDING_MODEL)
COLLECTION_NAME = "finance_report_parent_child"
​
​
# ===================== 文档解析 =====================
def parse_finance_document():
    full_text = """
悦享餐饮2020-2023财务综合分析报告
一、短期偿债能力分析:速动比率与流动比率趋势
2020~2023年间,悦享餐饮速动比率分别为2.85、2.07、1.48和1.53,流动比率分别为2.12、2.24、1.61和1.68,整体呈先降后升趋势。2022年受非流动资产增加影响,流动比率大幅回落;2023年加强应付账款管控,流动资产增加,短期偿债能力略有改善。此外2021年会计政策变更对数据有一定影响。
二、长期偿债能力分析:资产负债率与产权比率趋势
2020~2023年,悦享餐饮资产负债率先升后降(21.56%->22.03%->28.15%->26.87%),产权比率同步变动(28.0%->39.9%->36.7%)。2022年受外部冲击,应付账款大增,资产负债率攀升至28.15%;2023年优化资产结构,总资产增至188652.47万元,负债回落,长期偿债能力略有改善。
三、营运能力分析:应收账款与存货周转率
2020~2023年,应收账款周转率从25.12次降至15.34次后回升至18.65次;存货周转率波动较大(10.87->8.23->12.35->11.68)。
四、盈利能力分析:毛利率与净资产收益率
2020~2021年毛利率稳定在60%左右,2022年大幅下滑至-10.23%,2023年回升至8.65%。
五、发展能力分析:营业收入与利润增长趋势
2022年新增5家门店,成本3256.87万元,加剧资金压力;2023年暂停扩张。
"""
    return [Document(page_content=full_text)]
​
​
# ===================== 构建父子检索器=====================
def build_parent_child_retriever(documents):
    parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    child_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=50)
​
    #auto_id=True
    vectorstore = Milvus(
        embedding_function=embed_model,
        collection_name=COLLECTION_NAME,
        connection_args={"uri": MILVUS_URI},
        auto_id=True,
    )
​
    store = InMemoryStore()
​
    retriever = ParentDocumentRetriever(
        vectorstore=vectorstore,
        docstore=store,
        child_splitter=child_splitter,
        parent_splitter=parent_splitter,
    )
​
    #传入ID
    retriever.add_documents(documents, ids=[str(uuid.uuid4())])
    return retriever
​
​
# ===================== RAG 问答链 =====================
def create_qa_chain(retriever):
    llm = ChatOpenAI(
        model="glm-4", temperature=0.1, api_key=OPENAI_API_KEY, base_url=OPENAI_BASE_URL
    )
    prompt = PromptTemplate(
        template="""基于以下上下文回答问题,不知道就说找不到信息。
上下文:{context}
问题:{question}
回答:""",
        input_variables=["context", "question"],
    )
    return RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=retriever,
        return_source_documents=True,
        chain_type_kwargs={"prompt": prompt},
    )
​
​
# ===================== 运行 =====================
if __name__ == "__main__":
    docs = parse_finance_document()
    retriever = build_parent_child_retriever(docs)
    qa = create_qa_chain(retriever)
​
    questions = [
        "2022年悦享餐饮毛利率为什么下滑?",
        "短期还债能力怎么样?",
        "2022年开店策略有什么影响?",
    ]
​
    for q in questions:
        print("\n问题:", q)
        res = qa.invoke({"query": q})
        print("回答:", res["result"])
双层检索

把知识分类分为两层:摘要和详情,并在向量库中建立这两层的数据集合。那么查询的时候是先查询摘要层的数据,然后通过摘要层的数据去定位详情层的数据。

比如我代码示例中对财务数据进行了分层:{summary:“摘要信息”,"detail": "详情数据", "category": "类型"},每一类知识都会有摘要和详情,对每一类知识都构建了双层 Milvus 集合。

从专业的角度来描述,分为两个阶段:

建库阶段

  • 摘要层:提取知识的简短概括(如“偿债能力分析”、“查询净利润”),将其向量化存入。目的是用轻量级、高密度的语义去快速匹配用户意图,并定位到具体的知识实体。
  • 详情层:存储完整的知识内容(如完整的财务详情数据),将其向量化存入,并将摘要层的 title 作为关联键。

检索阶段

  • 第一层(粗排+分类) :将用户问题向量化,在三个知识分类的摘要层中分别检索,比对相似度得分,选出分数最高的分类和对应的 title。这一步同时完成了“知识分类”和“目标定位”。
  • 第二层(精排+过滤) :拿着第一层得到的 title,到对应分类的详情层中,利用标量过滤(filter='title == "xxx"')+ 向量相似度检索,精准捞出最相关的详细知识内容。

流程图

索引优化-双层检索.png

代码示例

import os
import json
from dotenv import load_dotenv
from pymilvus import MilvusClient, DataType
from openai import OpenAI
load_dotenv()
# ===================== 配置初始化 =====================OPENAI_API_KEY = os.getenv("GLM_API_KEY")
OPENAI_BASE_URL = os.getenv("GLM_BASE_URL")
EMBEDDING_MODEL = os.getenv("GLM_EMBEDDING_MODEL", "embedding-3")
MILVUS_URI = os.getenv("MILVUS_URI", "http://localhost:19530")
client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_BASE_URL)
milvus_client = MilvusClient(uri=MILVUS_URI)
VEC_DIM = 2048  # embedding-3 维度
COLLECTION_SUMMARY = "finance_report_summary"
COLLECTION_DETAILS = "finance_report_details"# ===================== 1. 模拟数据解析 (展示数据结构) =====================
def parse_finance_document():
    """
    将财务文档拆解为摘要和详情双层结构。
    摘要:提取核心分析维度与指标名称,用于精准语义路由。
    详情:保留完整的前因后果、历年数据对比与评价,用于大模型生成。
    """
    knowledge_nodes = [
        {
            "summary": "悦享餐饮短期偿债能力分析:速动比率与流动比率趋势",
            "detail": "2020~2023年间,悦享餐饮速动比率分别为2.85、2.07、1.48和1.53,流动比率分别为2.12、2.24、1.61和1.68,整体呈先降后升趋势。2022年受非流动资产增加影响,流动比率大幅回落;2023年加强应付账款管控,流动资产增加,短期偿债能力略有改善。此外2021年会计政策变更对数据有一定影响。",
            "category": "偿债能力"
        },
        {
            "summary": "悦享餐饮长期偿债能力分析:资产负债率与产权比率趋势",
            "detail": "2020~2023年,悦享餐饮资产负债率先升后降(21.56%->22.03%->28.15%->26.87%),产权比率同步变动(28.0%->39.9%->36.7%)。2022年受外部冲击,应付账款大增,资产负债率攀升至28.15%;2023年通过优化资产结构,总资产增至188652.47万元,负债回落,长期偿债能力略有改善,但风险仍需警惕。",
            "category": "偿债能力"
        },
        {
            "summary": "悦享餐饮营运能力分析:应收账款与存货周转率",
            "detail": "2020~2023年,应收账款周转率从25.12次降至15.34次后回升至18.65次;存货周转率波动较大(10.87->8.23->12.35->11.68)。2022年受外部冲击,应收账款拖欠时间延长,但公司及时清理滞销存货使存货周转率提升;2023年建立专项催收机制,资金回收效率有所改善,存货周转保持较高水平。",
            "category": "营运能力"
        },
        {
            "summary": "悦享餐饮盈利能力分析:毛利率与净资产收益率",
            "detail": "2020~2021年毛利率稳定在60%左右,2022年大幅下滑至-10.23%,2023年回升至8.65%。2022年下滑原因:客户流失率达18.65%、收入降48%、存货跌价损失1256.87万,叠加房租与人工等固定成本刚性及防疫物资支出。净资产收益率持续落后于行业平均水平,盈利稳定性与抗风险机制存在明显缺陷。",
            "category": "盈利能力"
        },
        {
            "summary": "悦享餐饮发展能力分析:营业收入与利润增长趋势",
            "detail": "2020~2022年各项增长率均为负,2022年降幅峰值(营业利润增长率-523.68%)。2023年营业收入增长率(10.82%)与总资产增长率(3.07%)转正,发展能力现转机。但值得注意的是,2022年在外部环境严峻下仍新增5家门店(扩张成本3256.87万元)加剧资金压力;2023年暂停扩张,集中提升单店效率。",
            "category": "发展能力"
        }
    ]
    return knowledge_nodes
​
# ===================== 2. 创建双层集合 =====================
def create_collections():
    for name in [COLLECTION_SUMMARY, COLLECTION_DETAILS]:
        if milvus_client.has_collection(name):
            milvus_client.drop_collection(name)
    # 摘要层 Schema
    s_schema = milvus_client.create_schema(auto_id=True)
    s_schema.add_field("id", DataType.INT64, is_primary=True, auto_id=True)
    s_schema.add_field("vector", DataType.FLOAT_VECTOR, dim=VEC_DIM)
    s_schema.add_field("title", DataType.VARCHAR, max_length=500)
    s_schema.add_field("category", DataType.VARCHAR, max_length=100) # 增加分类字段,支持过滤
    milvus_client.create_collection(COLLECTION_SUMMARY, schema=s_schema)
    # 详情层 Schema
    d_schema = milvus_client.create_schema(auto_id=True)
    d_schema.add_field("id", DataType.INT64, is_primary=True, auto_id=True)
    d_schema.add_field("vector", DataType.FLOAT_VECTOR, dim=VEC_DIM)
    d_schema.add_field("title", DataType.VARCHAR, max_length=500)
    d_schema.add_field("content", DataType.VARCHAR, max_length=8192) # 存放完整分析逻辑
    milvus_client.create_collection(COLLECTION_DETAILS, schema=d_schema)
​
# ===================== 3. 数据入库 =====================
def build_knowledge_base(nodes):
    for node in nodes:
        summary_text = node["summary"]
        detail_text = node["detail"]
        # 入库摘要层
        s_vec = client.embeddings.create(input=summary_text, model=EMBEDDING_MODEL).data[0].embedding
        milvus_client.insert(COLLECTION_SUMMARY, {
            "vector": s_vec,
            "title": summary_text,
            "category": node["category"]
        })
        # 入库详情层
        d_vec = client.embeddings.create(input=detail_text, model=EMBEDDING_MODEL).data[0].embedding
        milvus_client.insert(COLLECTION_DETAILS, {
            "vector": d_vec,
            "title": summary_text, # 使用相同的 title 作为跨表关联的钥匙
            "content": detail_text
        })
​
# ===================== 4. 双层检索 =====================
def search_finance(question):
    query_vec = client.embeddings.create(input=question, model=EMBEDDING_MODEL).data[0].embedding
    # 第一层:在摘要层快速寻找最相关的知识节点
    res = milvus_client.search(
        collection_name=COLLECTION_SUMMARY,
        data=[query_vec],
        limit=1,
        output_fields=["title", "category"],
        search_params={"params": {"nprobe": 10}}
    )
    if not res or not res[0]:
        return None, None
    best_match = res[0][0]
    best_title = best_match["entity"]["title"]
    best_category = best_match["entity"]["category"]
    # 第二层:用 title 精确过滤,在详情层捞出完整上下文
    detail_res = milvus_client.search(
        collection_name=COLLECTION_DETAILS,
        data=[query_vec],
        filter=f'title == "{best_title}"', # 标量过滤,精准路由
        limit=1,
        output_fields=["content"]
    )
    if detail_res and detail_res[0]:
        return best_category, detail_res[0][0]["entity"]["content"]
    return None, None
​
​
# ===================== 创建索引并加载集合 =====================
def load_collections():
    for name in [COLLECTION_SUMMARY, COLLECTION_DETAILS]:
        # 1. 准备索引参数 (使用 HNSW 算法,性能远优于 IVF_FLAT)
        index_params = milvus_client.prepare_index_params()
        index_params.add_index(
            field_name="vector", 
            index_type="HNSW", 
            metric_type="COSINE",
            params={"M": 16, "efConstruction": 256} # HNSW 的核心参数
        )
        # 2. 创建索引
        milvus_client.create_index(
            collection_name=name, 
            index_params=index_params
        )
        # 3. 将集合加载到内存
        milvus_client.load_collection(name)
    print("索引创建完成,集合已加载至内存")
​
# ===================== 5. 运行测试 =====================
if __name__ == "__main__":
    print("正在构建双层索引...")
    create_collections()
    nodes = parse_finance_document()
    build_knowledge_base(nodes)
​
    load_collections()
​
    # 模拟真实业务中的模糊提问
    test_questions = [
        "2022年悦享餐饮毛利率为什么下滑这么厉害?",
        "公司短期还债能力这两年怎么样?",
        "2022年开店策略对公司有什么影响?"
    ]
    for q in test_questions:
        print(f"\n问题: {q}")
        category, content = search_finance(q)
        print(f"命中分类: {category}")
        print(f"召回详情: {content}\n")
        print("-" * 50)
混合检索

混合检索是使用向量检索和关键词检索,这样做的好处就是取长补短,实现好的召回效果。

打个比方,问: “2022年公司毛利率下滑的原因是什么?”

只用向量检索,它会关注的是“盈利能力下降的原因”这个语义方向,而容易忽略了“2022年”这个时间限制,可能也会把“2023”年的文档也捞出来,产生事实性幻觉。

只用关键词检索,它会对问题进行分词:["2022年", "公司", "毛利率", "下滑", "原因"],然后去文档里找这些词的词频。谁包含的查询词多,谁就是最相关的。只会关键词匹配,如果换个方式提问,换成“近期盈利表现不佳的原因是什么”的提问方式。那么没有一个词对上,结果为空,召回失败。

用向量检索加关键词匹配的混合检索,关键词会匹配“2022年”时间和“毛利率”等关键词,向量检索语义相关文档,综合评分,更能精确检索出相关文档。

总的来说混合检索是:关键词检索负责句子专有名词的匹配,向量检索负责句子的语义理解,两者结合选出相关性最高的回答。

流程图

索引优化-混合检索.png

代码示例

import os
from dotenv import load_dotenv
from openai import OpenAI
from langchain_community.retrievers import BM25Retriever
from langchain_community.vectorstores import Milvus
from langchain_classic.retrievers import EnsembleRetriever
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_classic.schema import Document
from langchain_classic.chains import RetrievalQA
​
load_dotenv()
# ===================== 配置初始化 =====================
OPENAI_API_KEY = os.getenv("GLM_API_KEY")
OPENAI_BASE_URL = os.getenv("GLM_BASE_URL")
EMBEDDING_MODEL = os.getenv("GLM_EMBEDDING_MODEL", "embedding-3")
MILVUS_URI = os.getenv("MILVUS_URI", "http://localhost:19530")
​
​
# ===================== 1. 模拟数据解析 =====================
def parse_finance_document():
    knowledge_nodes = [
        {
            "summary": "悦享餐饮短期偿债能力分析:速动比率与流动比率趋势",
            "detail": "2020~2023年间,悦享餐饮速动比率分别为2.85、2.07、1.48和1.53,流动比率分别为2.12、2.24、1.61和1.68,整体呈先降后升趋势。2022年受非流动资产增加影响,流动比率大幅回落;2023年加强应付账款管控,流动资产增加,短期偿债能力略有改善。此外2021年会计政策变更对数据有一定影响。",
            "category": "偿债能力",
        },
        {
            "summary": "悦享餐饮长期偿债能力分析:资产负债率与产权比率趋势",
            "detail": "2020~2023年,悦享餐饮资产负债率先升后降(21.56%->22.03%->28.15%->26.87%),产权比率同步变动(28.0%->39.9%->36.7%)。2022年受外部冲击,应付账款大增,资产负债率攀升至28.15%;2023年通过优化资产结构,总资产增至188652.47万元,负债回落,长期偿债能力略有改善,但风险仍需警惕。",
            "category": "偿债能力",
        },
        {
            "summary": "悦享餐饮营运能力分析:应收账款与存货周转率",
            "detail": "2020~2023年,应收账款周转率从25.12次降至15.34次后回升至18.65次;存货周转率波动较大(10.87->8.23->12.35->11.68)。2022年受外部冲击,应收账款拖欠时间延长,但公司及时清理滞销存货使存货周转率提升;2023年建立专项催收机制,资金回收效率有所改善,存货周转保持较高水平。",
            "category": "营运能力",
        },
        {
            "summary": "悦享餐饮盈利能力分析:毛利率与净资产收益率",
            "detail": "2020~2021年毛利率稳定在60%左右,2022年大幅下滑至-10.23%,2023年回升至8.65%。2022年下滑原因:客户流失率达18.65%、收入降48%、存货跌价损失1256.87万,叠加房租与人工等固定成本刚性及防疫物资支出。净资产收益率持续落后于行业平均水平,盈利稳定性与抗风险机制存在明显缺陷。",
            "category": "盈利能力",
        },
        {
            "summary": "悦享餐饮发展能力分析:营业收入与利润增长趋势",
            "detail": "2020~2022年各项增长率均为负,2022年降幅峰值(营业利润增长率-523.68%)。2023年营业收入增长率(10.82%)与总资产增长率(3.07%)转正,发展能力现转机。但值得注意的是,2022年在外部环境严峻下仍新增5家门店(扩张成本3256.87万元)加剧资金压力;2023年暂停扩张,集中提升单店效率。",
            "category": "发展能力",
        },
    ]
    return knowledge_nodes
​
​
# ===================== 2. 构建LangChain文档 =====================
def build_langchain_documents(nodes):
    docs = []
    for node in nodes:
        # 将摘要和详情融合,构建具备完整上下文的文档
        content = f"摘要:{node['summary']}\n详情:{node['detail']}"
        docs.append(
            Document(
                page_content=content,
                metadata={"category": node["category"], "title": node["summary"]},
            )
        )
    return docs
​
​
# ===================== 3. 创建混合检索器(BM25 + Milvus向量) =====================
def create_hybrid_retriever(docs):
    # 1. BM25 关键词检索器 (基于内存,适合中小规模文档)
    bm25_retriever = BM25Retriever.from_documents(docs)
    bm25_retriever.k = 2
    # 2. Milvus 向量检索器 (使用LangChain原生集成,自动处理Embedding入库和检索)
    embedding = OpenAIEmbeddings(
        model=EMBEDDING_MODEL,
        openai_api_key=OPENAI_API_KEY,
        openai_api_base=OPENAI_BASE_URL,
    )
    #向量计算 + 连接Milvus + 入库 + 索引创建
    vectorstore = Milvus.from_documents(
        docs,
        embedding,
        connection_args={"uri": MILVUS_URI},
        collection_name="finance_report_hybrid",  # 混合检索专用集合
        drop_old=True,  # 每次运行重建集合,保证数据最新
    )
    milvus_retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
    # 3. 混合检索 (EnsembleRetriever)
    # BM25负责专有名词/关键词的精准匹配(如: "2022年", "毛利率"),向量负责语义深层召回(如: "还债能力"->"偿债能力")
    hybrid_retriever = EnsembleRetriever(
        retrievers=[bm25_retriever, milvus_retriever],
        weights=[0.4, 0.6],  # 向量语义检索权重略高
    )
    return hybrid_retriever
​
​
# ===================== 4. 创建RAG问答链 =====================
def create_rag_chain(retriever):
    llm = ChatOpenAI(
        model="glm-4",
        temperature=0,
        openai_api_key=OPENAI_API_KEY,
        openai_api_base=OPENAI_BASE_URL,
    )
    qa_chain = RetrievalQA.from_chain_type(
        llm=llm, retriever=retriever, return_source_documents=True
    )
    return qa_chain
​
​
# ===================== 5. 测试对比效果 =====================
def test_finance_rag(hybrid_retriever, bm25_retriever, milvus_retriever):
    # 使用同一个LLM创建不同的QA链用于对比
    llm = ChatOpenAI(
        model="glm-4",
        temperature=0,
        openai_api_key=OPENAI_API_KEY,
        openai_api_base=OPENAI_BASE_URL,
    )
    hybrid_qa = RetrievalQA.from_chain_type(
        llm=llm, retriever=hybrid_retriever, return_source_documents=True
    )
    bm25_qa = RetrievalQA.from_chain_type(
        llm=llm, retriever=bm25_retriever, return_source_documents=True
    )
    vector_qa = RetrievalQA.from_chain_type(
        llm=llm, retriever=milvus_retriever, return_source_documents=True
    )
    test_questions = [
        "2022年悦享餐饮毛利率为什么下滑这么厉害?",  # 包含明确的时间关键词
        "公司短期还债能力怎么样?",  # 纯语义查询(还债->偿债)
    ]
    print("\n===== 财务知识库 RAG 测试(对比检索效果)=====\n")
    for q in test_questions:
        print(f"问题:{q}")
        print("\n1. 混合检索结果 (BM25 + 向量):")
        h_res = hybrid_qa.invoke({"query": q})
        print(f"回答:{h_res['result']}")
        print("\n2. 纯BM25检索结果 (对比):")
        b_res = bm25_qa.invoke({"query": q})
        print(f"回答:{b_res['result']}")
        print("\n3. 纯向量检索结果 (对比):")
        v_res = vector_qa.invoke({"query": q})
        print(f"回答:{v_res['result']}")
        print("=" * 80)
​
​
# ===================== 主入口 =====================
if __name__ == "__main__":
    # 1. 解析财务数据并构建文档
    nodes = parse_finance_document()
    lc_docs = build_langchain_documents(nodes)
    # 2. 创建混合检索器
    # 注意:这里会连接Milvus并自动入库,请确保Milvus服务已启动
    hybrid_retriever = create_hybrid_retriever(lc_docs)
    # 获取单独的检索器用于对比测试
    bm25_only = BM25Retriever.from_documents(lc_docs)
    bm25_only.k = 2
    embedding = OpenAIEmbeddings(
        model=EMBEDDING_MODEL,
        openai_api_key=OPENAI_API_KEY,
        openai_api_base=OPENAI_BASE_URL,
    )
    vs = Milvus.from_documents(
        lc_docs,
        embedding,
        connection_args={"uri": MILVUS_URI},
        collection_name="finance_report_hybrid_vs",
        drop_old=True,
    )
    milvus_only = vs.as_retriever(search_kwargs={"k": 2})
    # 3. 运行对比测试
    test_finance_rag(hybrid_retriever, bm25_only, milvus_only)
总结

索引优化-后.png

技术方案设计思路
父子文档检索小块检索保证精准,大块返回保证上下文完整
双层检索知识层级拆分、先粗后精检索
混合检索关键词精准匹配 + 语义相似召回双路互补

RAG系统的索引优化策略就分享到这儿,在座的亦菲、彦祖们有想要讨论的,欢迎到评论区留言哦!