使用Langchain与HuggingFacePipeline构建RAG问答模型遇类型错误求助
问题分析与解决方案
错误原因
你使用的是Hugging Face的question-answering类型Pipeline,但存在两个核心格式不兼容问题:
- 该Pipeline要求输入必须是包含
question和context的字典(如{"question": "xxx", "context": "xxx"}),直接传入字符串会触发格式错误argument needs to be of type (SquadExample, dict)。 - LangChain的
RetrievalQA组件默认适配的是文本生成(text-generation)类型的模型,而非专门的QA模型,直接用QA模型作为llm参数会导致逻辑不匹配。
解决方案
方案1:直接用QA Pipeline适配检索流程
不需要将QA Pipeline包装成LLM,直接用LangChain的load_qa_chain对接检索文档与QA模型:
from langchain.chains.question_answering import load_qa_chain # 保持原有QA Pipeline初始化 model_name = "Intel/dynamic_tinybert" tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir="../assets") question_answerer = pipeline( "question-answering", model=model_name, tokenizer=tokenizer ) # 1. 用检索器获取相关文档 docs = retriever.get_relevant_documents("What is the mass of the sun?") # 2. 加载QA链并绑定Pipeline chain = load_qa_chain(question_answerer, chain_type="stuff") # 3. 执行问答 result = chain.run(input_documents=docs, question="What is the mass of the sun?") print(result)
方案2:将QA Pipeline适配为LangChain LLM接口(适配RetrievalQA)
自定义LLM包装类,让输入格式符合QA Pipeline要求,再结合RetrievalQA使用:
from langchain.llms.base import LLM from typing import Optional, List from langchain.prompts import PromptTemplate # 自定义LLM类,适配QA Pipeline的输入格式 class QAPipelineLLM(LLM): pipeline: any @property def _llm_type(self) -> str: return "custom_qa" def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: # 从prompt中拆分question和context(需与后续模板匹配) parts = prompt.split("\nContext: ") question = parts[0].replace("Question: ", "") context = parts[1] # 调用QA Pipeline qa_result = self.pipeline({"question": question, "context": context}) return qa_result["answer"] # 初始化自定义LLM model_name = "Intel/dynamic_tinybert" tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir="../assets") question_answerer = pipeline( "question-answering", model=model_name, tokenizer=tokenizer ) llm = QAPipelineLLM(pipeline=question_answerer) # 定义匹配拆分逻辑的prompt模板 prompt_template = """Question: {question} Context: {context} Answer:""" PROMPT = PromptTemplate(template=prompt_template, input_variables=["question", "context"]) # 构建RetrievalQA链 qa = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True, chain_type_kwargs={"prompt": PROMPT} ) # 测试调用 result = qa("What is the mass of the sun?") print(result["result"])
方案3:换用文本生成模型(更推荐)
通用RAG场景下,使用支持文本生成的开源模型(如distilgpt2、mistral-7b-instruct-v0.2等)更适配RetrievalQA原生逻辑:
from langchain.prompts import PromptTemplate model_name = "distilgpt2" tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir="../assets") # 生成模型需设置pad_token(默认用eos_token替代) tokenizer.pad_token = tokenizer.eos_token # 初始化文本生成Pipeline generator = pipeline( "text-generation", model=model_name, tokenizer=tokenizer, max_new_tokens=100, temperature=0.1 ) # 包装为LangChain LLM llm = HuggingFacePipeline(pipeline=generator) # 定义RAG专用prompt模板 prompt_template = """使用以下上下文回答问题。如果不知道答案,请直接说不知道,不要编造。 {context} 问题:{question} 回答:""" PROMPT = PromptTemplate(template=prompt_template, input_variables=["context", "question"]) # 构建RetrievalQA链 qa = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True, chain_type_kwargs={"prompt": PROMPT} ) # 测试调用 result = qa("What is the mass of the sun?") print(result["result"])
内容的提问来源于stack exchange,提问作者Amit Kharel
相关产品推荐
相关产品推荐

