基于LangChain + Milvus 实现RAG

使用 LangChain + Milvus(Lite 本地部署),并用 Hugging Face 的 thenlper/gte-large-zh 做 embedding。方案覆盖:环境准备、Milvus Lite 用法、embedding 实现、文本切片(chunking)、向量和文本入库、检索示例,以及常见注意点与扩展建议。


一、总结(要实现的目标)

用户输入一份大文本 → LangChain 把文本切片成多个 chunk → 用 thenlper/gte-large-zh 对每个 chunk 产生 embedding → 把 embedding 与对应 chunk(和元数据)写入 Milvus Lite(本地文件形式) → 支持后续相似检索 / RAG 等。


二、环境与先决条件

  • 操作系统:Ubuntu / macOS(Milvus Lite 支持)。

  • Python:建议 Python 3.10+。

  • 建议有 GPU(可选),否则在 CPU 上也能跑但较慢(亲测真的很慢)。

  • 需要网络以下载 HuggingFace 模型文件。

关键安装包(下面命令在虚拟环境中执行):

python -m venv venv && source venv/bin/activate
pip install -U pip

# 必要包
pip install langchain pymilvus>=2.4.2 transformers torch sentencepiece

# 可选:如果想用 langchain 社区的 Milvus 集成(取决于 langchain 版本)
pip install langchain-milvus langchain-community

说明:pymilvus >= 2.4.2 包含 Milvus Lite;使用本地文件 URI 会自动启用 Milvus Lite。(Milvus)


三、设计要点(简要)

  1. Chunk 切分:因为 gte-large-zh 的最大序列长度是 512 tokens(会截断更长的输入),所以 chunk 的长度要小于或等于 512 tokens。中文中 tokens 与字符近似但不完全等价,建议字符级 chunk_size 约 400–500 字符,并使用例如 50–100 的 overlap。这样能兼顾上下文与不超长截断。(Hugging Face)

  2. Embedding 实现:可直接用 transformersAutoTokenizer + AutoModel,从 outputs.last_hidden_state[:,0](CLS)或 mean-pooling 得到向量。thenlper/gte-large-zh 官方示例使用 outputs.last_hidden_state[:,0](CLS token)并做 L2 归一化作为 embedding。embedding 维度为 1024(gte-large-zh)。(Hugging Face)

  3. 向量库:使用 Milvus Lite(本地文件存储)。Milvus Lite 支持 FLAT 索引(受限),适用于原型 / 本地测试;生产上应使用 Milvus Standalone/Cluster。(Milvus)

  4. LangChain 集成:使用 LangChain 的 Milvus 向量存储适配器(示例使用 Milvus.from_documents 或构造器),把 Embeddings 对象传入。(python.langchain.com)


四、完整可运行示例代码

把下面内容保存为 ingest_and_query.py。它包含:读取文本文件、切分、embedding(基于 transformers + CLS pooling)、写入 Milvus Lite(通过 LangChain),并提供一个查询示例。

"""
ingest_and_query.py
Usage:
  python ingest_and_query.py ingest /path/to/large_text.txt
  python ingest_and_query.py query "你的检索问题"
"""

import sys
import os
from typing import List, Optional
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel
from langchain.text_splitter import CharacterTextSplitter
from langchain_core.documents import Document
# 如果你的 langchain 版本使用不同命名空间,请调整导入(下面两种导入形式二选一)
try:
    # newer: langchain-community / langchain_milvus
    from langchain_milvus import Milvus
except Exception:
    try:
        from langchain_community.vectorstores import Milvus
    except Exception:
        # 最后兜底:从 langchain.vectorstores 导入(视版本可能不可用)
        from langchain.vectorstores import Milvus  # type: ignore

from langchain.embeddings.base import Embeddings

# -------------------------
# Embeddings wrapper using thenlper/gte-large-zh
# -------------------------
class GTEEmbeddings(Embeddings):
    def __init__(self, model_name: str = "thenlper/gte-large-zh", device: Optional[str] = None, batch_size: int = 8):
        self.model_name = model_name
        self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
        self.batch_size = batch_size

        # load tokenizer + model
        self.tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
        self.model = AutoModel.from_pretrained(model_name).to(self.device)
        self.model.eval()

        # model dimension: checked on HF model card (gte-large-zh -> 1024)
        # self.dim = 1024  # optional

    def _embed_batch(self, texts: List[str]) -> List[List[float]]:
        all_embs = []
        with torch.no_grad():
            for i in range(0, len(texts), self.batch_size):
                batch = texts[i:i + self.batch_size]
                batch_inputs = self.tokenizer(batch, padding=True, truncation=True, max_length=512, return_tensors="pt").to(self.device)
                outputs = self.model(**batch_inputs)
                # official example uses CLS token as embedding:
                embs = outputs.last_hidden_state[:, 0, :]  # shape (B, D)
                # L2 normalize
                embs = F.normalize(embs, p=2, dim=1).cpu()
                all_embs.extend(embs.tolist())
        return all_embs

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return self._embed_batch(texts)

    def embed_query(self, text: str) -> List[float]:
        return self._embed_batch([text])[0]

# -------------------------
# Helper: chunk text -> documents
# -------------------------
def chunk_text_to_documents(text: str, chunk_size: int = 400, chunk_overlap: int = 50, source: str = "input") -> List[Document]:
    splitter = CharacterTextSplitter(separator="\n", chunk_size=chunk_size, chunk_overlap=chunk_overlap)
    chunks = splitter.split_text(text)
    docs = []
    for i, c in enumerate(chunks):
        docs.append(Document(page_content=c, metadata={"source": source, "chunk": i}))
    return docs

# -------------------------
# Ingest pipeline: read, chunk, embed, write to Milvus Lite via LangChain
# -------------------------
def ingest_file_to_milvus(txt_path: str, collection_name: str = "docs_collection", uri: str = "./milvus_demo.db"):
    assert os.path.exists(txt_path), f"{txt_path} not found"
    with open(txt_path, "r", encoding="utf-8") as f:
        text = f.read()

    print("Splitting text...")
    docs = chunk_text_to_documents(text, chunk_size=400, chunk_overlap=80, source=os.path.basename(txt_path))
    print(f"Created {len(docs)} chunks.")

    print("Loading embedding model (this may take a while)...")
    embeddings = GTEEmbeddings(model_name="thenlper/gte-large-zh")

    print("Writing to Milvus Lite (via LangChain)...")
    # from_documents 会对 documents 使用 embedding 计算向量并写入 Milvus
    vectorstore = Milvus.from_documents(
        documents=docs,
        embeddings=embeddings,
        collection_name=collection_name,
        connection_args={"uri": uri},
        drop_old=True,  # 如果希望覆盖旧 collection,设为 True
    )
    print("Ingest finished.")
    return vectorstore

# -------------------------
# Query demo
# -------------------------
def query_milvus(query: str, k: int = 3, collection_name: str = "docs_collection", uri: str = "./milvus_demo.db"):
    print("Loading embeddings and vectorstore handle...")
    embeddings = GTEEmbeddings(model_name="thenlper/gte-large-zh")
    vs = Milvus(embeddings=embeddings, collection_name=collection_name, connection_args={"uri": uri})
    print("Searching...")
    docs = vs.similarity_search(query, k=k)
    for i, d in enumerate(docs):
        print(f"=== Result {i+1} ===")
        print("Score/metadata:", d.metadata)
        print(d.page_content[:600].rstrip())
        print()

# -------------------------
# CLI
# -------------------------
def main():
    if len(sys.argv) < 2:
        print(__doc__)
        return
    cmd = sys.argv[1]
    if cmd == "ingest":
        if len(sys.argv) < 3:
            print("Usage: ingest /path/to/large_text.txt")
            return
        ingest_file_to_milvus(sys.argv[2])
    elif cmd == "query":
        if len(sys.argv) < 3:
            print('Usage: query "你的检索问题"')
            return
        query = sys.argv[2]
        query_milvus(query)
    else:
        print("Unknown command:", cmd)

if __name__ == "__main__":
    main()

五、如何运行(示例)

  1. 启动虚拟环境并安装依赖(见上文)。

  2. 保存上面的脚本 ingest_and_query.py

  3. 准备一个大文本文件 large_text.txt(UTF-8)。

  4. 执行入库:

python ingest_and_query.py ingest ./large_text.txt
# 这会创建本地 Milvus Lite 文件: ./milvus_demo.db
  1. 运行检索示例:

python ingest_and_query.py query "中国的首都是哪里?"

六、设计与工程注意点(重要)

  1. Chunk 大小与模型截断:gte-large-zh 最大 512 tokens,会截断更长文本,所以请确保每个 chunk 在这个长度内(示例用 400 字符 + overlap)。若你想在 chunk 中保留更多语义,可做层次切分(先大段拆为若干段,再在需要时再二次细拆)。(Hugging Face)

  2. 向量维度 & 集合 schema:gte-large-zh 输出维度 1024。Milvus collection 的 dimension 要与之对应(LangChain 会处理此细节,但如果你用 pymilvus 原生接口建 collection,要设置 dimension=1024)。(Hugging Face)

  3. Milvus Lite 限制:Milvus Lite 只适合原型/本地测试,只支持 FLAT 索引、不支持 partition 的一些高级特性(比如用于多租户的 partition_key)。若数据量大或需要 partition、高级索引,请部署 Milvus Standalone/Cluster。(Milvus)

  4. 持久化:Milvus Lite 使用本地文件(e.g. ./milvus_demo.db),数据会持久化到该文件。你可以用 milvus-lite dump 导出数据迁移到集群。(Milvus)

  5. 性能 / 批量:对大量文本要批量计算 embedding 并批量 insert(脚本里用 LangChain.from_documents,内部会分批),如果数据量很大,考虑使用 pymilvus[bulk_writer] 的 bulk 插入或把 embedding 计算分布到多台机器上。(Milvus)


七、常见坑与排查

  • 如果 huggingface 下载模型太慢,可先预先 transformers 下载并缓存,或使用镜像/代理。

  • 若模型加载报错 trust_remote_code,可在 from_pretrained 中传 trust_remote_code=True(若模型包含自定义架构)。但 gte-large-zh 通常可以直接加载。(Hugging Face)

  • 若 LangChain 的 Milvus 类导入失败,请检查你安装的包名(langchain-milvus / langchain-community / langchain_milvus 的 API 随版本变动)。如果出问题,可直接使用 pymilvus 的原生 API:MilvusClient("./milvus_demo.db") 创建、create_collectioninsert 等操作(官方文档给有示例)。(Milvus, python.langchain.com)


八、扩展建议(当你准备从本地原型走向生产)

  1. 切换到 Milvus Standalone/Distributed:支持更高级索引(IVF_PQ、HNSW 等)、partition、并发等。(python.langchain.com)

  2. 索引类型调优:FLAT 适用于小规模,数据变多后换更快的近似索引并调参(nlist / nprobe 等)。

  3. 多租户 / 权限:Milvus Lite 不支持用户/角色;生产环境通过 Milvus 服务或 Zilliz Cloud 管理。(Milvus)

  4. Embedding 服务化:若多人并发或需要降低模型部署成本,可把 embedding 模型放到一个推理服务(如 xinference、TorchServe、HF Inference、ONNX或自建 FastAPI 服务),LangChain 侧只调用该服务拿 embedding。

  5. 缓存 & 重用:对重复 chunk 做去重/缓存,避免重复计算 embedding。可以基于 chunk 的 hash 来判断是否已存在。


九、参考(关键文档)

  • Milvus Lite 文档(如何本地运行、API 示例):官方 Run Milvus Lite。(Milvus)

  • Milvus + LangChain 集成文档(示例、from_documents、connection_args 用法):Milvus 与 LangChain 集成。(python.langchain.com)

  • thenlper/gte-large-zh 模型页(max seq len=512, dimension=1024,示例用 CLS token):Hugging Face 模型页面。(Hugging Face)

<think>我们正在构建一个RAG系统,使用LangChain作为框架,Milvus作为向量数据库,bge-m3作为嵌入模型。以下是实现步骤:1.**环境准备**:-安装必要的库:langchain,pymilvus,transformers等。-下载bge-m3模型(可以从ModelScope或HuggingFace下载)。2.**文档加载与处理**:-使用LangChain的文档加载器(如`TextLoader`、`DirectoryLoader`)加载文档。-对文档进行拆分(使用`RecursiveCharacterTextSplitter`等),注意设置合适的块大小和重叠。3.**嵌入模型**:-初始化bge-m3模型,该模型能够生成稠密向量(denseembeddings)和稀疏向量(sparseembeddings)。-由于Milvus支持混合搜索(hybridsearch),我们将同时使用这两种向量。4.**向量数据库(Milvus)**:-在Milvus中创建两个集合(collections)或一个支持多向量的集合,分别存储稠密向量和稀疏向量(或者使用一个集合包含两个向量字段)。-注意:Milvus2.4及以上版本支持多向量字段,因此可以创建一个集合,包含两个向量字段:一个稠密向量字段和一个稀疏向量字段(注意Milvus对稀疏向量的支持情况,目前Milvus支持稀疏向量SPARSE_FLOAT_VECTOR)。5.**文档向量化与存储**:-将拆分后的文档通过bge-m3模型生成稠密向量和稀疏向量。-将文档块内容、元数据以及对应的两种向量存储到Milvus中。6.**检索**:-用户输入查询问题,同样使用bge-m3生成查询的稠密向量和稀疏向量。-使用Milvus的混合搜索(hybridsearch)功能,同时利用两种向量进行检索,并融合结果(例如使用RRF(ReciprocalRankFusion)或其他方法)。-返回最相关的文档块。7.**生成**:-将检索到的文档块作为上下文,与用户问题一起输入到大语言模型(LLM)中,生成回答。下面我们详细说明每一步,并给出代码示例。###步骤1:环境准备首先,安装必要的库:```bashpipinstalllangchainpymilvustransformers```然后,下载bge-m3模型。由于模型较大,建议使用ModelScope(国内更快)或HuggingFace。这里使用ModelScope:```bashgitlfsinstallgitclonehttps://www.modelscope.cn/Xorbits/bge-m3.git```###步骤2:文档加载与处理假设我们有一个文档目录,里面存放着多个文本文件。```pythonfromlangchain.document_loadersimportDirectoryLoaderfromlangchain.text_splitterimportRecursiveCharacterTextSplitter#加载文档loader=DirectoryLoader('./docs',glob="**/*.txt")documents=loader.load()#拆分文档text_splitter=RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50)texts=text_splitter.split_documents(documents)```###步骤3:初始化嵌入模型我们使用`transformers`库加载bge-m3模型。注意,bge-m3可以同时生成稠密向量和稀疏向量(稀疏向量是SPLADE表示)。```pythonfromtransformersimportAutoModel,AutoTokenizermodel_path="path/to/bge-m3"#替换为实际路径tokenizer=AutoTokenizer.from_pretrained(model_path)model=AutoModel.from_pretrained(model_path)```###步骤4:设置Milvus向量数据库确保Milvus服务已经启动。然后,我们使用`pymilvus`连接Milvus,并创建集合。```pythonfrompymilvusimportconnections,FieldSchema,CollectionSchema,DataType,Collection,utility#连接Milvusconnections.connect("default",host="localhost",port="19530")#定义集合的字段fields=[FieldSchema(name="id",dtype=DataType.INT64,is_primary=True,auto_id=True),FieldSchema(name="text",dtype=DataType.VARCHAR,max_length=1000),FieldSchema(name="dense_vector",dtype=DataType.FLOAT_VECTOR,dim=1024),#bge-m3稠密向量维度为1024FieldSchema(name="sparse_vector",dtype=DataType.SPARSE_FLOAT_VECTOR)#稀疏向量]#创建集合schema=CollectionSchema(fields,"RAGusingbge-m3andMilvus")collection_name="bge_m3_docs"ifutility.has_collection(collection_name):utility.drop_collection(collection_name)collection=Collection(collection_name,schema)#创建索引(稠密向量使用IVF_FLAT,稀疏向量使用SPARSE_INVERTED_INDEX)index_params_dense={"index_type":"IVF_FLAT","metric_type":"L2","params":{"nlist":1024}}index_params_sparse={"index_type":"SPARSE_INVERTED_INDEX","metric_type":"IP"#内积}collection.create_index("dense_vector",index_params_dense)collection.create_index("sparse_vector",index_params_sparse)```###步骤5:文档向量化与存储对每个文本块,使用bge-m3生成稠密向量和稀疏向量,然后插入Milvus。```pythonimporttorchimportnumpyasnpfrompymilvusimportMilvusClient#初始化Milvus客户端client=MilvusClient(uri="http://localhost:19530",db_name="default")#准备批量插入的数据data=[]fortextintexts:#使用bge-m3生成向量inputs=tokenizer(text.page_content,return_tensors="pt")withtorch.no_grad():outputs=model(**inputs)#获取稠密向量dense_embedding=outputs.last_hidden_state.mean(dim=1).squeeze().numpy()#获取稀疏向量(SPLADE)sparse_embedding=outputs.logits.max(dim=1)[0].squeeze().numpy()#将稀疏向量转换为字典格式(索引:值)sparse_dict={idx:valueforidx,valueinenumerate(sparse_embedding)ifvalue!=0}data.append({"text":text.page_content,"dense_vector":dense_embedding.tolist(),"sparse_vector":sparse_dict})#插入数据client.insert(collection_name,data)```###步骤6:检索用户查询时,同样生成两种向量,然后进行混合搜索。```pythondefhybrid_search(query,top_k=5):#生成查询向量inputs=tokenizer(query,return_tensors="pt")withtorch.no_grad():outputs=model(**inputs)dense_embedding=outputs.last_hidden_state.mean(dim=1).squeeze().numpy()sparse_embedding=outputs.logits.max(dim=1)[0].squeeze().numpy()sparse_dict={idx:valueforidx,valueinenumerate(sparse_embedding)ifvalue!=0}#分别进行稠密搜索和稀疏搜索#稠密搜索dense_results=client.search(collection_name=collection_name,data=[dense_embedding.tolist()],anns_field="dense_vector",param={"metric_type":"L2","params":{"nprobe":10}},limit=top_k,output_fields=["text"])#稀疏搜索(注意:Milvus的稀疏向量搜索使用内积,且返回的分数是内积值)sparse_results=client.search(collection_name=collection_name,data=[sparse_dict],anns_field="sparse_vector",param={"metric_type":"IP"},limit=top_k,output_fields=["text"])#融合结果(简单示例:使用RRF)#为每个文档分配一个融合后的分数scores={}#处理稠密结果foridx,hitinenumerate(dense_results[0]):doc_id=hit.id#RRF:1/(rank+k)这里k设为60(常用值)rrf_score=1.0/(idx+60)scores[doc_id]=scores.get(doc_id,0)+rrf_score#处理稀疏结果foridx,hitinenumerate(sparse_results[0]):doc_id=hit.idrrf_score=1.0/(idx+60)scores[doc_id]=scores.get(doc_id,0)+rrf_score#按融合分数排序sorted_scores=sorted(scores.items(),key=lambdax:x[1],reverse=True)top_doc_ids=[doc_idfordoc_id,scoreinsorted_scores[:top_k]]#获取文档内容results=client.get(collection_name,ids=top_doc_ids,output_fields=["text"])return[res['text']forresinresults]```###步骤7:生成使用LangChain的LCEL(LangChainExpressionLanguage)或简单的链式调用,将检索到的文档作为上下文,输入到LLM中。```pythonfromlangchain.llmsimportOpenAIfromlangchain.promptsimportPromptTemplatefromlangchain.schema.runnableimportRunnablePassthrough#初始化LLMllm=OpenAI(api_key="your-openai-key")#定义提示模板template="""基于以下上下文,回答用户问题:{context}问题:{question}"""prompt=PromptTemplate.from_template(template)#定义RAG链defretrieve(question):returnhybrid_search(question)chain=({"context":retrieve,"question":RunnablePassthrough()}|prompt|llm)#调用链response=chain.invoke("用户的问题")print(response)```###注意事项1.**性能考虑**:bge-m3模型较大,推理速度较慢,可以考虑使用GPU加速。2.**混合搜索的融合策略**:这里使用了简单的RRF,也可以尝试其他融合方法,如加权分数等。3.**Milvus的稀疏向量支持**:确保Milvus版本支持稀疏向量(2.4及以上)。4.**文档分块大小**:根据实际文档调整分块大小和重叠。以上是一个完整的RAG系统实现方案,结合了LangChainMilvus和bge-m3的优势。###相关问题1.如何优化bge-m3模型的推理速度?2.在Milvus中,如何调整索引参数以提高搜索性能?3.除了RRF,还有哪些融合检索结果的方法?4.如何处理大文档的嵌入,避免内存溢出?</think>### 使用 LangChain + Milvus + BGE-M3 实现 RAG 方案 以下是完整的实现方案,分为 6 个关键步骤: #### 1. **环境准备** ```python # 安装核心库 pip install langchain pymilvus sentence-transformers git clone https://www.modelscope.cn/Xorbits/bge-m3.git # 下载模型[^1] ``` #### 2. **初始化组件** ```python from langchain.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from pymilvus import connections, Collection from transformers import AutoModel, AutoTokenizer # 连接 Milvus connections.connect(host="localhost", port="19530") # 加载 BGE-M3 模型[^3] model = AutoModel.from_pretrained("./bge-m3") tokenizer = AutoTokenizer.from_pretrained("./bge-m3") ``` #### 3. **文档处理与向量化** ```python # 加载文档 loader = TextLoader("data.txt") documents = loader.load() # 文档分块(关键步骤)[^2] text_splitter = RecursiveCharacterTextSplitter( chunk_size=512, chunk_overlap=50 ) chunks = text_splitter.split_documents(documents) # 生成混合向量 def get_embeddings(text): inputs = tokenizer(text, return_tensors="pt") outputs = model(**inputs) dense_embed = outputs.last_hidden_state.mean(dim=1).squeeze().tolist() sparse_embed = outputs.logits.max(dim=1)[0].squeeze().numpy() return dense_embed, sparse_embed ``` #### 4. **Milvus 向量库配置** ```python # 创建集合(支持混合向量)[^4] collection = Collection.create( "rag_collection", fields=[ {"name": "id", "type": "INT64", "is_primary": True}, {"name": "text", "type": "VARCHAR", "max_length": 1000}, {"name": "dense_vector", "type": "FLOAT_VECTOR", "dim": 1024}, {"name": "sparse_vector", "type": "SPARSE_FLOAT_VECTOR"} ] ) # 创建双索引 collection.create_index( field_name="dense_vector", index_params={"index_type": "IVF_FLAT", "metric_type": "L2"} ) collection.create_index( field_name="sparse_vector", index_params={"index_type": "SPARSE_INVERTED_INDEX"} ) ``` #### 5. **检索增强流程** ```python from langchain.chains import RetrievalQA from langchain.llms import OpenAI # 混合检索函数 def hybrid_search(query, top_k=5): dense_emb, sparse_emb = get_embeddings(query) # 并行执行双向量检索 dense_results = collection.search( data=[dense_emb], anns_field="dense_vector", limit=top_k ) sparse_results = collection.search( data=[sparse_emb], anns_field="sparse_vector", limit=top_k ) # 结果融合 (RRF 算法) return reciprocal_rank_fusion(dense_results, sparse_results) # 构建 RAG 链 qa_chain = RetrievalQA.from_chain_type( llm=OpenAI(temperature=0), chain_type="stuff", retriever=hybrid_search, return_source_documents=True ) ``` #### 6. **运行与优化** ```python # 插入文档向量 for chunk in chunks: dense_vec, sparse_vec = get_embeddings(chunk.page_content) collection.insert([ {"text": chunk.page_content}, {"dense_vector": dense_vec}, {"sparse_vector": sparse_vec} ]) # 执行查询 response = qa_chain("什么是量子纠缠?") print(f"答案: {response['result']}") print(f"来源: {response['source_documents'][0].page_content}") ``` ### 关键优势说明 1. **多粒度检索**:BGE-M3 支持词级/句级/段落级嵌入[^3],提升语义捕获能力 2. **混合搜索**:同时利用稠密向量的语义信息和稀疏向量的关键词信息[^4] 3. **性能优化**: - 分块大小建议 256-512 字符[^2] - 使用 `IVF_FLAT` + `SPARSE_INVERTED_INDEX` 组合索引 - 批处理文档插入(每次 500-1000 条) ### 常见问题解决 - **OOM 错误**:减小分块尺寸或启用 `model.half()` 半精度 - **低召回率**:调整分块重叠(建议 10-15%)或尝试不同分块策略 - **延迟过高**:在 Milvus 中启用 GPU 加速或增加 `nprobe` 参数 ### 相关问题 1. 如何评估 RAG 系统中检索结果的质量? 2. BGE-M3 与其他嵌入模型(如 OpenAI Embeddings)相比有何优势? 3. 在资源受限环境中如何优化 Milvus 的性能? 4. 如何处理 RAG 中的长文档上下文溢出问题? 5. 如何实现基于 RAG 的多轮对话系统? [^1]: 从 huggingface 或国内的 modelscope 下载 BGE-M3 模型 [^2]: 文档拆分的注意点,embedding model, chat model区别 [^3]: BGE-M3:Multi-Functionality Multi-Linguisticity Multi-Granularity [^4]: 混合搜索同时使用稠密向量和稀疏向量增强准确性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值