Gemini Python API函数调用function_response报错求助:CURL可行Python不行
问题解决:Vertex API函数调用报错
ValueError: Protocol message Struct has no "location" field. 错误原因
你的Python代码中函数响应的格式不符合Vertex AI SDK要求。REST API(CURL使用的)和Vertex Python SDK在构造function角色消息时存在格式差异:
- REST API中,
functionResponse的response字段需要嵌套name和content层; - 但Vertex SDK中,
function_response的response字段应直接放置函数返回的结构化数据,不需要额外嵌套name和content。
你的代码中函数响应部分多了一层{"name": "find_theaters", "content": {...}},导致SDK解析Struct时找不到location字段(实际字段嵌套在content内部),从而抛出错误。
修正后的代码示例
1. 修正消息列表(核心修复)
messages = [ { "role": "user", "parts": [{"text": "Which theaters in Mountain View show Barbie movie?"}], }, { "role": "model", "parts": [ { "function_call": { "name": "find_theaters", "args": {"location": "Mountain View, CA", "movie": "Barbie"}, } } ], }, { "role": "function", "parts": [ { "function_response": { "name": "find_theaters", # 直接返回函数结果,去掉name和content嵌套 "response": { "movie": "Barbie", "theaters": [ { "name": "AMC Mountain View 16", "address": "2000 W El Camino Real, Mountain View, CA 94040", }, { "name": "Regal Edwards 14", "address": "245 Castro St, Mountain View, CA 94040", }, ], }, } } ], }, ]
2. 工具定义(保持原结构,确保参数类型小写)
tools = [ { "function_declarations": [ { "name": "find_movies", "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616", }, "description": { "type": "string", "description": "Any kind of description including category or genre, title words, attributes, etc.", }, }, "required": ["description"], }, }, { "name": "find_theaters", "description": "find theaters based on location and optionally movie title which is currently playing in theaters", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616", }, "movie": { "type": "string", "description": "Any movie title", }, }, "required": ["location"], }, }, { "name": "get_showtimes", "description": "Find the start times for movies playing in a specific theater", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616", }, "movie": { "type": "string", "description": "Any movie title", }, "theater": { "type": "string", "description": "Name of the theater", }, "date": { "type": "string", "description": "Date for requested showtime", }, }, "required": ["location", "movie", "theater", "date"], }, }, ] } ]
3. 调用模型(补充tool_config,可选)
from google.cloud import aiplatform aiplatform.init(project="你的项目ID", location="us-central1") model = aiplatform.GenerativeModel("gemini-pro") # 可选:配置工具调用模式 tool_config = {"function_calling_config": {"mode": "AUTO"}} response = model.generate_content(messages, tools=tools, tool_config=tool_config) print(response.text)
额外说明
如果需要更严谨的类型控制,可以使用SDK提供的google.protobuf.Struct和json_format转换字典为protobuf结构,避免格式错误:
from google.protobuf import json_format, struct_pb2 # 将字典转换为Struct response_struct = json_format.ParseDict( { "movie": "Barbie", "theaters": [ {"name": "AMC Mountain View 16", "address": "2000 W El Camino Real, Mountain View, CA 94040"}, {"name": "Regal Edwards 14", "address": "245 Castro St, Mountain View, CA 94040"} ] }, struct_pb2.Struct() ) # 在消息中使用Struct messages[2]["parts"][0]["function_response"]["response"] = response_struct
内容的提问来源于stack exchange,提问作者giulianoBarbosa
相关产品推荐
相关产品推荐

