MongoDB作为Mistral 7B加载器的检索异常问题排查
问题描述
近期在为Mistral 7B大模型搭配MongoDB VectorStore与MongoDB Atlas搜索索引存储数据,此前已成功加载txt、PDF等小型文件,现希望直接以MongoDB数据库作为模型查询数据源。使用LangChain的MongodbLoader加载数据后,出现以下问题:
- 查询Bronx区烘焙餐厅数量(实际共70家)时,模型仅返回4家且每次结果不同
- 查询特定餐厅信息时返回错误或无相关内容
已通过Compass确认数据成功上传,怀疑问题出在检索环节,需解决以下疑问:
- 数据库加载是否正确?
- 是否需要修改搜索索引?
- 是否有其他创建检索器的方法?
加载器代码
client = pymongo.MongoClient("mongodb+srv://xxxxxx:xxxxxx@prueba1.hdlxqaf.mongodb.net/") dbName = "LLM2" collectionName = "Mistral2" collection = client[dbName][collectionName] loader = MongodbLoader( connection_string="mongodb+srv://xxxxxx:xxxxxx@prueba1.hdlxqaf.mongodb.net/", db_name = "sample_restaurants", collection_name="restaurants", filter_criteria={"borough": "Bronx", "cuisine": "Bakery"} ) doc = loader.load() splitter = RecursiveCharacterTextSplitter( chunk_size = 300, chunk_overlap = 50, ) data = splitter.split_documents(doc) embeddings = HuggingFaceBgeEmbeddings( model_name = "sentence-transformers/paraphrase-MiniLM-L6-v2", ) vectorStore = MongoDBAtlasVectorSearch.from_documents( data, embeddings, collection=collection, index_name = "Model" )
搜索索引配置
{ "fields": [ { "numDimensions": 384, "path": "embedding", "similarity": "cosine", "type": "vector" } ] }
RAG架构代码
def query_data(query): docs = vectorStore.similarity_search(query, top_k=1) as_output = docs[0].page_content llm = CTransformers(model = "./mistral-7b-instruct-v0.1.Q4_0.gguf", model_type = "llama", #config = {'max_new_tokens': 400, 'temperature': 0.01} ) retriever = vectorStore.as_retriever() QA_CHAIN_PROMPT = PromptTemplate.from_template(template) qa = RetrievalQA.from_chain_type(llm, chain_type="stuff", retriever=retriever, chain_type_kwargs = {'prompt': QA_CHAIN_PROMPT}) retriever_output = qa.invoke(query) return as_output, retriever_output
解决方案
1. 验证数据库加载正确性
- 检查加载数据量:在
doc = loader.load()后添加print(len(doc)),确认是否加载到70条目标数据。若数量不足,排查filter_criteria的字段匹配问题(如大小写、值的拼写是否与数据库一致)。 - 检查文档序列化效果:打印
doc[0].page_content,确认餐厅数据是否被完整、清晰地转为字符串。可通过MongodbLoader的projection参数只保留核心字段(如name、borough、cuisine),减少冗余信息干扰。 - 确认向量存储写入量:检查
LLM2.Mistral2集合的文档数是否与分割后的data长度一致,确保所有chunk都成功生成embedding并写入。
2. 调整搜索索引配置
- 添加过滤字段到索引:当前索引仅包含向量字段,无法高效利用原始过滤条件。建议新增
borough、cuisine为过滤字段,缩小检索范围,避免无关数据干扰。调整后的索引示例:
{ "fields": [ { "numDimensions": 384, "path": "embedding", "similarity": "cosine", "type": "vector" }, { "path": "borough", "type": "filter" }, { "path": "cuisine", "type": "filter" } ] }
- 确认维度匹配:当前使用的
paraphrase-MiniLM-L6-v2输出维度为384,索引numDimensions设置正确,无需修改。
3. 优化检索器实现
方法一:带过滤条件的检索器
直接在检索器中绑定过滤规则,避免全量向量搜索:
from langchain.retrievers import MongoDBAtlasVectorSearchRetriever retriever = MongoDBAtlasVectorSearchRetriever( collection=collection, embedding=embeddings, index_name="Model", filter={"borough": "Bronx", "cuisine": "Bakery"}, top_k=10 # 根据需求调整返回数量 )
方法二:调整检索参数
- 提高top_k值:当前
similarity_search的top_k=1仅返回1条数据,统计类问题需调高该值(如20),让LLM基于更多数据计算。 - 使用MMR检索模式:平衡相关性与多样性,避免重复结果:
retriever = vectorStore.as_retriever(search_type="mmr", search_kwargs={"k": 10, "fetch_k": 20})
4. 其他优化点
- 开启LLM参数配置:取消
config参数注释,设置temperature=0.01降低模型随机性,避免结果波动。 - 优化Prompt模板:明确指令,如统计数量时要求“基于提供的所有餐厅数据,准确统计符合条件的数量”;查询特定餐厅时要求“仅从给定文档提取信息,无相关数据则明确说明”。
- 调整Chunk分割逻辑:若单条餐厅数据字段少,可增大
chunk_size或不分割,避免信息碎片化。
内容的提问来源于stack exchange,提问作者Víctor Iglesias González
相关产品推荐
相关产品推荐

