基于Llama 2的文档问答机器人数值数据响应不准确问题问询
文档问答机器人数值类问题准确率优化方案
针对多PDF场景下数值类(如服务费率)问答准确率下降的问题,核心原因是检索结果混入无关文档干扰模型判断,以及prompt未引导模型精准提取数值,结合你的代码,可通过以下步骤解决:
1. 优化检索策略,过滤低相关度文档
多文档插入后,MMR检索可能引入过多无关内容,调整检索参数减少噪音:
- 改用相似度阈值过滤,只保留高相关文档:
self.retriever = db.as_retriever( search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.7, "k": 3} # 阈值可根据实际情况调整 )
- 若坚持用MMR,降低
lambda_mult参数,优先保证相关性:
self.retriever = db.as_retriever( search_type="mmr", search_kwargs={"k": 3, "fetch_k": 10, "lambda_mult": 0.2} )
2. 强化Prompt对数值精准性的要求
修改原prompt,明确引导模型聚焦数值提取,避免混淆多文档中的不同数值:
DEFAULT_TEMPLATE = """ ### Instruction: 你是虚拟助手,仅使用聊天历史和以下{context}中的信息回答问题。 针对涉及数值(如费率、金额)的问题,必须从给定context中提取**精确的数值内容**;如果context中有多个相关数值,请明确对应来源;如果找不到对应数值,直接说不知道。 问候语回复要简短,所有回复需简洁、有帮助。 {chat_history} ### Input: {question} ### Response: """
3. 更换Chain类型,避免长上下文过载
原stuff链在多文档场景下会拼接过长上下文,模型易遗漏关键数值,改用map_reduce链先逐个提取数值再整合:
def _create_chain(self,text_pipeline: HuggingFacePipeline,prompt: PromptTemplate,verbose: bool = False,): memory = ConversationBufferMemory( memory_key = "chat_history", human_prefix = "### Input", ai_prefix = "### Response", input_key = "question", output_key = "output_text", return_messages = False, ) # 定义map阶段的prompt,专注数值提取 map_prompt = PromptTemplate( input_variables=["context", "question"], template="从以下内容中提取与问题'{question}'相关的精确数值:{context},如果没有相关数值,返回'无'" ) # 定义combine阶段的prompt,整合结果 combine_prompt = PromptTemplate( input_variables=["summaries", "question"], template="根据以下提取的信息回答问题'{question}':{summaries},如果有多个数值,说明对应来源;如果都没有,说不知道" ) return load_qa_chain( text_pipeline, chain_type="map_reduce", prompt=prompt, map_prompt=map_prompt, combine_prompt=combine_prompt, memory=memory, verbose=False, )
4. 文档预处理强化数值标记
插入Pinecone前,对PDF中的数值做特殊标记,提升检索和提取精度:
# 文本预处理函数,标记数值 def process_text(raw_text): import re # 匹配百分比、金额等数值,添加加粗标记 raw_text = re.sub(r"(\d+\.?\d*%|\d+\.?\d*(元|美元|欧元))", r"**\1**", raw_text) return raw_text # 分割文档时应用预处理 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) processed_text = process_text(raw_pdf_text) chunks = text_splitter.split_text(processed_text)
5. 调整LLM生成参数,降低随机性
微调生成参数,确保模型输出最确定的结果:
pipe = pipeline( "text-generation", model=model, tokenizer= tokenizer, max_new_tokens = 200, # 数值问题无需长回复,缩小长度 temperature=0, top_p= 1.0, # 只取概率最高的输出 repetition_penalty= 1.15, generation_config=generation_config, streamer = streamer, batch_size = 1, )
建议优先尝试前两步(检索优化+prompt修改),这两个改动最小,见效最快;若仍有问题,再逐步调整chain类型和预处理逻辑。
内容的提问来源于stack exchange,提问作者Faiq Aslam
相关产品推荐
相关产品推荐

