Skip to content

[Bug] Gemini 模型工具调用报错 400: Unknown name "id" at 'function_response' #7357

@Yuki-yao

Description

@Yuki-yao

What happened / 发生了什么

问题描述
使用 Gemini 模型触发工具调用时发生异常。原因是框架在提交工具执行结果时,向 function_response 中赋予了 id 字段。而最新的 Gemini API 存在严格的 Schema 校验,其 FunctionResponse 结构中不存在也不允许传入 id 字段,导致请求被 Google 服务器 400 拒绝。
参考google提供的文档:https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference?hl=zh-cn#parameters

Image

报错日志

Chat Model gemini-3.1-pro-preview-customtools request error: 400 None. {'error': {'message': 'Invalid JSON payload received. Unknown name "id" at \'contents[4].parts[0].function_response\': Cannot find field.', 'type': 'upstream_error', 'param': '', 'code': 400}}

原因分析与修复建议
问题出在 /AstrBot/astrbot/core/provider/sources/gemini_source.py 中的 _prepare_conversation 方法处理 role == "tool" 的逻辑处(大约在第 403 行):

            elif role == "tool" and not native_tool_enabled:
                func_name = message.get("name", message["tool_call_id"])
                part = types.Part.from_function_response(
                    name=func_name,
                    response={
                        "name": func_name,
                        "content": message["content"],
                    },
                )
                # 下面这两行给 id 赋值的代码导致了 400 报错,建议直接删除或注释掉
                if part.function_response:
                    part.function_response.id = message["tool_call_id"]

Reproduce / 如何复现?

使用Gemini模型,与AstrBot对话,要求调用网络搜索功能总结任意话题即可复现

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

  • AstrBot 版本: v4.22.2
  • 部署方式:服务器Docker Compose部署
  • 模型提供商: Google Gemini (NewAPI转接)
  • 使用的消息平台适配器:QQ官方机器人

OS

Linux

Logs / 报错日志

[2026-04-04 14:27:11.921] [Core] [WARN] [v4.22.2] [runners.tool_loop_agent_runner:350]: Chat Model Vertex/gemini-3.1-pro-preview-customtools request error: 400 None. {'error': {'message': 'Invalid JSON payload received. Unknown name "id" at 'contents[4].parts[0].function_response': Cannot find field.', 'type': 'upstream_error', 'param': '', 'code': 400}}
Traceback (most recent call last):
File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 305, in _iter_llm_responses_with_fallback
async for attempt in retrying:
File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/init.py", line 170, in anext
do = await self.iter(retry_state=self._retry_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/init.py", line 157, in iter
result = await action(retry_state)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/_utils.py", line 111, in inner
return call(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/init.py", line 393, in
self._add_action_func(lambda rs: rs.outcome.result())
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 449, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 309, in _iter_llm_responses_with_fallback
async for resp in self._iter_llm_responses(
File "/AstrBot/astrbot/core/agent/runners/tool_loop_agent_runner.py", line 272, in _iter_llm_responses
yield await self.provider.text_chat(**payload)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/AstrBot/astrbot/core/provider/sources/gemini_source.py", line 822, in text_chat
if await self._handle_api_error(e, keys):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/AstrBot/astrbot/core/provider/sources/gemini_source.py", line 129, in _handle_api_error
raise e
File "/AstrBot/astrbot/core/provider/sources/gemini_source.py", line 820, in text_chat
return await self._query(payloads, func_tool)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/AstrBot/astrbot/core/provider/sources/gemini_source.py", line 588, in _query
result = await self.client.models.generate_content(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/google/genai/models.py", line 7854, in generate_content
return await self._generate_content(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/google/genai/models.py", line 6642, in _generate_content
response = await self._api_client.async_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/google/genai/_api_client.py", line 1578, in async_request
result = await self._async_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/google/genai/_api_client.py", line 1511, in _async_request
return await self._async_retry( # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/init.py", line 112, in call
do = await self.iter(retry_state=retry_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/init.py", line 157, in iter
result = await action(retry_state)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/_utils.py", line 111, in inner
return call(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/init.py", line 413, in exc_check
raise retry_exc.reraise()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/tenacity/init.py", line 184, in reraise
raise self.last_attempt.result()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 449, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/usr/local/lib/python3.12/site-packages/tenacity/asyncio/init.py", line 116, in call
result = await fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/google/genai/_api_client.py", line 1443, in _async_request_once
await errors.APIError.raise_for_async_response(response)
File "/usr/local/lib/python3.12/site-packages/google/genai/errors.py", line 247, in raise_for_async_response
await cls.raise_error_async(status_code, response_json, response)
File "/usr/local/lib/python3.12/site-packages/google/genai/errors.py", line 269, in raise_error_async
raise ClientError(status_code, response_json, response)
google.genai.errors.ClientError: 400 None. {'error': {'message': 'Invalid JSON payload received. Unknown name "id" at 'contents[4].parts[0].function_response': Cannot find field.', 'type': 'upstream_error', 'param': '', 'code': 400}}

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:providerThe bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner.bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions