基于RAG构建应用,如何阻止AI回答文档范围外的问题?
RAG应用中AI回答超出文档范围问题的原因与解决方法
问题背景
基于RAG流程开发应用,已将私有文档加载至向量数据库,可与OpenAI模型围绕文档内容对话并获得满意响应,也能从向量数据库中检索到正确数据。但当询问完全超出向量数据库文档范围的问题(如“太阳系有多少行星”)时,即使向量数据库未返回任何文档,AI模型仍会给出回答。
原因分析
- 大模型固有特性:OpenAI模型训练了海量通用知识,其“乐于助人”的预设优先级可能高于系统提示词约束,导致即使无可用文档,模型仍会调用自身训练数据生成答案。
- 提示词约束不足:当前系统提示词虽要求“不确定或答案不在文档中就说不知道”,但未针对“无文档返回”场景给出强硬明确的规则,模型对该场景的识别执行力度不够。
- 空文档标识歧义:当传入
No information found作为文档内容时,模型可能未将其解读为“无可用上下文”,而是视为普通文本,仍尝试基于自身知识回答。
解决方案
1. 强化系统提示词的明确性
修改系统提示词,针对无文档场景添加强制规则:
你是一个仅基于指定文档内容回答问题的助手。 严格使用DOCUMENTS部分的信息提供准确答案,**如果DOCUMENTS部分显示为"No information found",或者问题无法从DOCUMENTS中找到答案,请直接回复"抱歉,我无法回答这个问题,它不在我的知识库范围内。"** 禁止使用任何DOCUMENTS以外的信息回答问题。 DOCUMENTS: {documents}
2. 代码层面直接拦截空检索结果
在生成系统消息时,若检索不到文档,直接返回预设的拒绝回答消息,无需将空标识传入提示词模板:
private Message generateSystemMessage(String message) { LOGGER.info("检索文档中"); List<Document> similarDocuments = vectorStore.similaritySearch(SearchRequest.query(message) .withTopK(2).withSimilarityThreshold(0.75)); LOGGER.info("找到{}个相似文档", similarDocuments.size()); // 直接拦截空结果,返回拒绝回答的消息 if(similarDocuments.isEmpty()) { return Message.system("抱歉,我无法回答这个问题,它不在我的知识库范围内。"); } String documentContent = similarDocuments.stream().map(Document::getContent).collect(Collectors.joining("\n")); SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.systemPromptResource); return systemPromptTemplate.createMessage(Map.of("documents", documentContent)); }
3. 优化检索策略
- 适当提高相似度阈值(如调整至0.8或更高),减少低相关文档被返回的概率;
- 增加主题匹配校验:提前对用户问题进行主题判断,若问题明显不属于私有文档的主题范围,直接拒绝回答。
相关代码与日志
原向量相似度搜索代码
private Message generateSystemMessage(String message) { LOGGER.info("检索文档中"); List<Document> similarDocuments = vectorStore.similaritySearch(SearchRequest.query(message) .withTopK(2).withSimilarityThreshold(0.75)); LOGGER.info("找到{}个相似文档", similarDocuments.size()); SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.systemPromptResource); if(similarDocuments.isEmpty()) { return systemPromptTemplate.createMessage(Map.of("documents", "No information found")); } String documentContent = similarDocuments.stream().map(Document::getContent).collect(Collectors.joining("\n")); return systemPromptTemplate.createMessage(Map.of("documents", documentContent)); }
原系统提示词
你是一个乐于助人的助手,与用户围绕一组文档中的主题进行对话。 使用DOCUMENTS部分的信息提供准确答案。如果不确定或答案不在DOCUMENTS部分,只需说明你不知道答案。 并且不要回答任何与DOCUMENTS部分提供的上下文无关的问题。 DOCUMENTS: {documents}
相关日志
2024-03-13T21:26:17.172+11:00 INFO 25298 --- [io-8080-exec-10] c.example.rag.qa.StreamingChatService : 检索文档中 2024-03-13T21:26:17.714+11:00 INFO 25298 --- [io-8080-exec-10] c.example.rag.qa.StreamingChatService : 找到0个相似文档 2024-03-13T21:26:17.716+11:00 INFO 25298 --- [io-8080-exec-10] c.example.rag.qa.StreamingChatService : 系统提示词是 -- 你是一个乐于助人的助手,与用户围绕一组文档中的主题进行对话。 使用DOCUMENTS部分的信息提供准确答案。如果不确定或答案不在DOCUMENTS部分,只需说明你不知道答案。 并且不要回答任何与DOCUMENTS部分提供的上下文无关的问题。 DOCUMENTS: No information found
内容的提问来源于stack exchange,提问作者Sagar
相关产品推荐
相关产品推荐

