You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Langchain与Gemini Pro实现文档问答系统时遇消息类型错误求助

解决Gemini Pro与Langchain RetrievalQA的system消息不兼容问题

你遇到的错误核心原因是Gemini Pro不支持system类型的对话消息,而Langchain默认的map_reduce链会向LLM发送带system角色的指令,这与Gemini仅接受Human/AI(user/assistant)消息的要求冲突。以下是两种可行的解决方法:


方案1:更换链类型(简单直接)

将chain_type改为stuff或refine,这两种链默认不会生成system消息,完美适配Gemini的格式要求。

修正后的完整代码

from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_google_genai.embeddings import GoogleGenerativeAIEmbeddings
from PyPDF2 import PdfReader
import google.generativeai as genai

genai.configure(api_key='api_key')

# 读取PDF文档,过滤空文本
reader = PdfReader('Document Path') 
file_data = []
for page in reader.pages:
    text = page.extract_text()
    if text:
        file_data.append(text)
file_data = " ".join(file_data)

# 文本分割
text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n","\n","\t"],chunk_size=8000,chunk_overlap=500)
docs = text_splitter.create_documents([file_data])

# 初始化嵌入模型与向量库
embeddings = GoogleGenerativeAIEmbeddings(google_api_key='api_key',model='models/embedding-001')
vectorstore = Chroma.from_documents(docs, embeddings)

# 初始化Gemini LLM
llm = ChatGoogleGenerativeAI(google_api_key='api_key',model='gemini-pro',temperature=0)

# 关键改动:更换chain_type为'stuff'(或'refine')
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=vectorstore.as_retriever())

# 执行查询(直接传字符串格式的问题即可)
question = "What is the main argument of this document?"
response = qa({'query': question})
print(response)

关键改动说明

  • 移除了未使用的load_summarize_chain导入
  • 增加空文本过滤,避免无效内容干扰
  • 将chain_type从map_reduce改为stuff(该链会把检索到的所有文档内容一次性传入LLM,适合文档总长度不超过模型上下文窗口的场景)
  • 查询时直接传字符串问题,无需额外指定role参数(RetrievalQA内部会自动处理消息格式)

方案2:自定义map_reduce的Prompt(保留map_reduce链)

如果必须使用map_reduce链,可通过自定义prompt模板,强制所有消息使用Human角色,避开system角色限制。

示例代码

from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_google_genai.embeddings import GoogleGenerativeAIEmbeddings
from PyPDF2 import PdfReader
from langchain.prompts import PromptTemplate
from langchain.chains import MapReduceDocumentsChain, ReduceDocumentsChain
from langchain.chains.llm import LLMChain
from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains import RetrievalQA
import google.generativeai as genai

genai.configure(api_key='api_key')

# 读取PDF、文本分割、向量库初始化步骤同方案1
# (此处省略重复代码,直接从初始化LLM开始)

llm = ChatGoogleGenerativeAI(google_api_key='api_key',model='gemini-pro',temperature=0)

# 自定义Map阶段Prompt(仅用Human角色)
map_template = """以下是一段文档内容:
{docs}
请总结这段文档的核心内容。"""
map_prompt = PromptTemplate.from_template(map_template)
map_chain = LLMChain(llm=llm, prompt=map_prompt)

# 自定义Reduce阶段Prompt(仅用Human角色)
reduce_template = """以下是多个文档片段的总结:
{docs}
请将这些总结合并,给出整个文档的核心论点。"""
reduce_prompt = PromptTemplate.from_template(reduce_template)
reduce_chain = LLMChain(llm=llm, prompt=reduce_prompt)

# 构建Reduce链
combine_documents_chain = StuffDocumentsChain(
    llm_chain=reduce_chain, document_variable_name="docs"
)
reduce_documents_chain = ReduceDocumentsChain(
    combine_documents_chain=combine_documents_chain,
    collapse_documents_chain=combine_documents_chain,
    token_max=8000,
)

# 构建自定义MapReduce链
map_reduce_chain = MapReduceDocumentsChain(
    llm_chain=map_chain,
    reduce_documents_chain=reduce_documents_chain,
    document_variable_name="docs",
    return_intermediate_steps=False,
)

# 包装为RetrievalQA
qa = RetrievalQA(
    retriever=vectorstore.as_retriever(),
    combine_documents_chain=map_reduce_chain
)

# 执行查询
question = "What is the main argument of this document?"
response = qa({'query': question})
print(response)

关键改动说明

通过自定义map和reduce阶段的prompt模板,确保所有指令都以Human消息的形式发送给Gemini,完全避开了system角色的限制,同时保留了map_reduce链的分块处理能力。


内容的提问来源于stack exchange,提问作者Ronak Nandanwar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:53:09