基于LangChain与ChromaDB的本地RAG聊天机器人幻觉问题及优化问询
基于LangChain+ChromaDB的RAG自校正与检索优化方案
一、获取ChromaDB检索结果的相关性评分
ChromaDB的similarity_search_with_score方法会直接返回检索到的文档及其对应的余弦相似度分数(分数越高相关性越强,范围通常在0-1之间,具体取决于嵌入模型),可直接用该方法获取评分作为后续判断依据。
示例代码:
from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings # 替换为你使用的本地嵌入模型 from chromadb.config import Settings # 初始化ChromaDB持久化客户端 chroma_client = Chroma( persist_directory="./chroma_db", embedding_function=OpenAIEmbeddings(), client_settings=Settings( persist_directory="./chroma_db", anonymized_telemetry=False ) ) # 带评分的相似性检索 query = "你的问题内容" docs_with_scores = chroma_client.similarity_search_with_score(query, k=3) # 遍历输出文档与对应分数 for doc, score in docs_with_scores: print(f"文档片段: {doc.page_content[:100]}...") print(f"相关性分数: {score}\n")
二、实现自校正循环(阈值判断+降级逻辑)
根据业务场景设定相关性阈值(比如0.6,需结合嵌入模型效果调整),当检索到的最高分数低于阈值时,触发降级方案或返回兜底响应。
1. 阈值判断与兜底响应
# 设定相关性阈值 RELEVANCE_THRESHOLD = 0.6 # 获取最高相关性分数 highest_score = max([score for _, score in docs_with_scores]) if docs_with_scores else 0 if highest_score < RELEVANCE_THRESHOLD: # 返回兜底响应避免幻觉 print("我不知道你问的问题,请换个方式提问或补充更多信息。") else: # 使用检索到的文档生成回答(示例用RetrievalQA链) from langchain.chains import RetrievalQA from langchain.llms import OpenAI qa_chain = RetrievalQA.from_chain_type( llm=OpenAI(), chain_type="stuff", retriever=chroma_client.as_retriever(search_kwargs={"k":3}) ) response = qa_chain.run(query) print(response)
2. 触发网页搜索作为降级方案
若需要补充外部信息,可使用LangChain的搜索工具(需配置对应API密钥):
from langchain.tools import SerpAPIWrapper from langchain.llms import OpenAI from langchain.prompts import PromptTemplate # 初始化网页搜索工具 search = SerpAPIWrapper(serpapi_api_key="你的API密钥") if highest_score < RELEVANCE_THRESHOLD: # 调用网页搜索获取外部信息 search_results = search.run(query) # 基于搜索结果生成回答 prompt = PromptTemplate( input_variables=["query", "search_results"], template="根据以下搜索结果回答问题:{query}\n搜索结果:{search_results}" ) llm = OpenAI() response = llm(prompt.format(query=query, search_results=search_results)) print(response)
三、ChromaDB元数据过滤提升检索准确率
在文档入库时添加丰富元数据,检索时通过where参数过滤,可大幅减少低相关文档被返回的概率,从源头提升检索精准度。
1. 入库时添加元数据
# 带元数据的示例文档 documents = [ { "page_content": "文档内容1", "metadata": { "source": "产品手册V2.0", "category": "技术规范", "created_at": "2024-01-01", "language": "zh" } }, { "page_content": "文档内容2", "metadata": { "source": "用户指南V1.5", "category": "使用教程", "created_at": "2023-10-05", "language": "zh" } } ] # 将文档添加到ChromaDB chroma_client.add_documents( documents=[doc["page_content"] for doc in documents], metadatas=[doc["metadata"] for doc in documents] ) chroma_client.persist()
2. 检索时过滤元数据
比如只检索2024年之后的技术规范类文档:
# 带元数据过滤的检索 filtered_docs_with_scores = chroma_client.similarity_search_with_score( query=query, k=3, where={ "category": "技术规范", "created_at": {"$gte": "2024-01-01"} } )
也可结合where_document参数对文档内容做关键词过滤,比如只包含特定术语的文档:
filtered_docs_with_scores = chroma_client.similarity_search_with_score( query=query, k=3, where_document={"$contains": "API接口"} )
内容的提问来源于stack exchange,提问作者grace h
相关产品推荐
相关产品推荐

