如何让大语言模型仅使用向量数据库中的数据生成回答
兄弟,我太懂你这种烦躁了——明明设置了分数过滤,还在prompt里反复强调只用向量库的内容,结果模型还是我行我素输出它自己的“库存知识”,完全不按要求来!别着急,咱们一步步解决这个问题:
把Prompt的约束写死,不给模型留“自由发挥”的空间
很多时候模糊的提示会让模型钻空子,你得把规则写得绝对明确,比如用这样的prompt模板:prompt_template = """ 你是一个严格依赖提供文档内容的问答助手,**绝对不能使用你自身的任何知识回答问题**。 如果提供的文档中没有与问题相关的信息,必须一字不差地回复:“我无法在知识库中找到相关答案”。 现在根据以下文档内容回答问题: {context} 问题:{question} """重点是明确指定无信息时的固定回复,并且强调绝对不能用自身知识,不给模型任何模糊的空间。
在链的逻辑里加一道“门禁”:无文档直接返回预设回复
你说分数过滤后没有返回源文档,但还是调用了LLM?那问题出在这儿——就算context是空的,LLM也会硬着头皮用自己的知识瞎答!所以要在检索之后加判断:如果没有检索到符合阈值的文档,直接返回预设回复,根本不把空context传给LLM。
举个示例代码:def get_answer(question): # 检索符合分数要求的文档 relevant_docs = retriever.get_relevant_documents(question) # 检查是否有有效文档 if not relevant_docs: return "我无法在知识库中找到相关答案" # 拼接文档内容作为context context = "\n".join([doc.page_content for doc in relevant_docs]) # 生成prompt并调用LLM prompt = prompt_template.format(context=context, question=question) return llm.predict(prompt)这一步从根源上切断了LLM“瞎编”的机会。
验证你的分数过滤是否真的生效
有时候可能过滤逻辑有漏洞,比如阈值设置不对,或者分数判断的代码写错了?你可以打印一下检索结果的分数,确认低于阈值时确实没有文档被返回:# 注意不同检索器的返回格式可能不同,比如有的返回(doc, score)元组 docs_with_scores = retriever.get_relevant_documents(question, return_scores=True) print("检索到的文档及分数:", docs_with_scores)确保没有低分数的文档偷偷混进context里,让LLM有可乘之机。
降低LLM的随机性,让它更听话
如果用的是支持temperature参数的模型,可以把temperature设为0,这样模型会更严格遵循指令,减少“自由发挥”的概率。比如:from langchain.llms import OpenAI llm = OpenAI(temperature=0, model_name="gpt-3.5-turbo-instruct")(如果是Chat模型,同样可以在初始化时设置temperature=0)
用专门的RAG链强化约束
比如LangChain的RetrievalQAWithSourcesChain,它会强制模型绑定检索到的源文档,同时你可以在prompt里要求回答必须完全来自这些源文档,并且无文档时拒绝回答。设置return_source_documents=True还能方便你验证回答是否真的来自向量库。
按照这些步骤调整下来,应该就能让模型乖乖只使用向量数据库里的内容了!
备注:内容来源于stack exchange,提问作者m1ch4

