LangChain+ChatVertexAI调用Gemini时示例消息组织报错咨询
问题描述
使用LangChain结合ChatVertexAI调用Gemini模型做信息提取时,构建包含HumanMessage-AIMessage-ToolMessage循环的示例消息序列,运行extractor.invoke({"text": text, "examples": example_messages})时报错:
InvalidArgument: 400 Please ensure that function call turn comes immediately after a user turn or after a function response turn
不带示例调用、或切换为ChatOpenAI带示例调用均能正常运行。已知Gemini要求对话角色必须在user和ai间严格交替,当前示例结构不符合该规则。
解决方案
1. 正确的示例消息结构
Gemini对多轮示例的角色规则极为严格:必须遵循**HumanMessage(用户输入)与AIMessage(模型输出)严格交替**的轮次结构,不支持在示例序列中插入ToolMessage角色。
对于信息提取任务,示例只需直接展示「输入文本→提取结果」的映射关系即可,无需模拟工具调用的中间环节。
2. 仅移除ToolMessage是合适的解决方案
LangChain针对OpenAI设计的示例结构(包含ToolMessage)适配OpenAI的函数调用流程,但Gemini不认可这种额外的角色类型。直接移除示例中的ToolMessage,保留HumanMessage+AIMessage的成对结构,即可完全符合Gemini的角色交替要求,解决报错问题。
3. 无需在Tool与Human消息间添加AIMessage
这种方案不仅冗余,还会破坏示例的简洁性。提取任务的核心是让模型学习输入与输出的对应关系,直接用HumanMessage-AIMessage的成对示例已足够,不需要额外模拟工具调用的中间步骤。
示例代码
# 符合Gemini要求的示例消息结构 example_messages = [ # 示例1 HumanMessage(content="张三的邮箱是zhangsan@example.com,电话13812345678"), AIMessage(content='{"姓名": "张三", "邮箱": "zhangsan@example.com", "电话": "13812345678"}'), # 示例2 HumanMessage(content="李四住在北京市朝阳区,公司是XX科技"), AIMessage(content='{"姓名": "李四", "地址": "北京市朝阳区", "公司": "XX科技"}') ] # 调用提取器 result = extractor.invoke({"text": target_text, "examples": example_messages})
内容的提问来源于stack exchange,提问作者A. Bollans

