What happened / 发生了什么
在使用 Gemini 模型(如 gemini-3.1-pro-preview)配合第三方中转站调用 AstrBot 的内置知识库或其他工具时,如果工具返回的结果是纯文本,大模型会直接抛出 400 错误并拒绝回复。
根本原因是 Gemini 的 API 接口极其严格,其 function_response 强制要求传入标准的 JSON 对象(google.protobuf.Struct),而框架原生逻辑直接将纯文本字符串传递了过去。
【建议的修复方案】
在 astrbot/core/provider/sources/openai_source.py 的 _query 和 _query_stream 发送请求前,对 role == "tool" 且返回内容非 JSON 格式的消息进行一层包装处理。例如:
import json
for msg in payloads.get("messages", []):
if msg.get("role") == "tool":
content = msg.get("content", "")
if isinstance(content, str) and not content.strip().startswith("{"):
msg["content"] = json.dumps({"result": content}, ensure_ascii=False)
本地修改后实测已完美解决该 400 报错。
Reproduce / 如何复现?
- 配置大模型为
gemini-3.1-pro-preview 等严格校验格式的模型接口。
- 开启并配置内置知识库或任意会返回纯文本的工具。
- 在聊天中提问,触发大模型调用该工具(如
astr_kb_search)。
- 框架获取结果后,将包含纯文本的 payload 发送给大模型,立刻触发 400 Invalid argument 报错崩溃。
AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
AstrBot 版本:v4.22.2
部署方式:Windows 一键启动包 (.astrbot_launcher)
使用的提供商:openai_chat_completion (gg/gemini-3.1-pro-preview)
使用的消息平台适配器:aiocqhttp (NapCatQQ)
OS
Windows
Logs / 报错日志
[Core] [WARN] [v4.22.2] [runners.tool_loop_agent_runner:350]: Chat Model gg/gemini-3.1-pro-preview request error: Error code: 400 - {'error': {'message': 'upstream status 400: {\n "error": {\n "code": 400,\n "message": "Invalid value at 'request.contents[49].parts[0].function_response.response' (type.googleapis.com/google.protobuf.Struct), \"以下是相关的知识库内容,请参考这些信息回答用户的问题:\n\n【知识 1】\n来源: astrbot文档 / AstrBot_Manual_Merged.txt\n...', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_argument'}}
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct
What happened / 发生了什么
在使用 Gemini 模型(如 gemini-3.1-pro-preview)配合第三方中转站调用 AstrBot 的内置知识库或其他工具时,如果工具返回的结果是纯文本,大模型会直接抛出 400 错误并拒绝回复。
根本原因是 Gemini 的 API 接口极其严格,其
function_response强制要求传入标准的 JSON 对象(google.protobuf.Struct),而框架原生逻辑直接将纯文本字符串传递了过去。【建议的修复方案】
在
astrbot/core/provider/sources/openai_source.py的_query和_query_stream发送请求前,对role == "tool"且返回内容非 JSON 格式的消息进行一层包装处理。例如:import json
for msg in payloads.get("messages", []):
if msg.get("role") == "tool":
content = msg.get("content", "")
if isinstance(content, str) and not content.strip().startswith("{"):
msg["content"] = json.dumps({"result": content}, ensure_ascii=False)
本地修改后实测已完美解决该 400 报错。
Reproduce / 如何复现?
gemini-3.1-pro-preview等严格校验格式的模型接口。astr_kb_search)。AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
AstrBot 版本:v4.22.2
部署方式:Windows 一键启动包 (.astrbot_launcher)
使用的提供商:openai_chat_completion (gg/gemini-3.1-pro-preview)
使用的消息平台适配器:aiocqhttp (NapCatQQ)
OS
Windows
Logs / 报错日志
[Core] [WARN] [v4.22.2] [runners.tool_loop_agent_runner:350]: Chat Model gg/gemini-3.1-pro-preview request error: Error code: 400 - {'error': {'message': 'upstream status 400: {\n "error": {\n "code": 400,\n "message": "Invalid value at 'request.contents[49].parts[0].function_response.response' (type.googleapis.com/google.protobuf.Struct), \"以下是相关的知识库内容,请参考这些信息回答用户的问题:\n\n【知识 1】\n来源: astrbot文档 / AstrBot_Manual_Merged.txt\n...', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_argument'}}
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct