基于LangChain、GPT与Chainlit的RAG系统提取相似度搜索分数方法
解决LangChain map_rerank链提取相似度分数的方案
核心思路
similarity_score_threshold检索器本身会返回带分数的文档对象,无需依赖链的intermediate_steps,可以直接在检索环节提取分数,再传递到后续UI展示流程中。
具体实现步骤
单独提取检索结果中的分数:
调用检索器时,先获取完整的带分数文档对象,再拆分出文档内容和对应分数。示例代码:# 假设你的检索器实例为retriever retrieved_docs_with_scores = retriever.get_relevant_documents(query) # 提取文档和分数(不同向量库的分数存储位置可能有差异,需根据实际调整) target_docs = [] similarity_scores = [] for doc in retrieved_docs_with_scores: target_docs.append(doc) # 以FAISS为例,分数通常存在metadata的score字段中 similarity_scores.append(doc.metadata.get('score', 0.0))在Chainlit UI中集成分数展示:
在消息处理逻辑里,把分数和答案、源文档一起渲染输出。示例代码:import chainlit as cl @cl.on_message async def handle_message(message: cl.Message): # 执行检索操作 retrieved_docs_with_scores = retriever.get_relevant_documents(message.content) docs = [doc.page_content for doc in retrieved_docs_with_scores] scores = [doc.metadata['score'] for doc in retrieved_docs_with_scores] # 调用map_rerank链生成答案 answer = chain.run(input_documents=docs, question=message.content) # 构建带分数的源文档展示文本 sources_info = "" for idx, (doc, score) in enumerate(zip(retrieved_docs_with_scores, scores), 1): sources_info += f"**源文档 {idx}**\n相似度分数: *{score:.4f}*\n内容片段: {doc.page_content[:300]}...\n\n" # 发送包含答案和分数的消息 await cl.Message( content=f"**回答**: {answer}\n\n**相关源文档及相似度分数**:\n{sources_info}" ).send()自定义Prompt的兼容方案:
如果需要通过链输出分数,可修改map_rerank的Prompt模板,强制模型输出可解析的结构化内容(如JSON),包含答案、分数和源文档信息。示例Prompt片段:请基于提供的文档回答问题,同时返回该文档的相似度分数,输出必须为JSON格式: { "answer": "你的答案内容", "score": 相似度分数数值, "source": "文档关键内容" }之后在代码中用
json.loads解析输出结果,提取分数字段。
注意事项
- 确认向量存储的分数返回逻辑:部分向量库需要显式配置返回分数,比如FAISS的
similarity_search_with_score方法会直接返回(doc, score)元组,基于此实现的similarity_score_threshold检索器才能拿到分数。 - 分数渲染时用强调格式,提升UI中分数的辨识度。
内容的提问来源于stack exchange,提问作者Guilherme Giuliano Nicolau
相关产品推荐
相关产品推荐

