-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
修复gemini toolcall 的名称导致的循环调用 #4686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
修复gemini toolcall 的名称导致的循环调用 #4686
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - 我发现了 1 个问题
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `astrbot/core/provider/sources/gemini_source.py:385-387` </location>
<code_context>
- ]
+ # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
+ # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
+ func_name = message.get("name", "unknown_tool")
+
+ # 2. 创建 Part,注意 name 参数必须是函数名
</code_context>
<issue_to_address>
**suggestion:** 建议将 `tool_call_id` 用作函数名的回退值,而不是使用泛化的字面量。
使用像 `"unknown_tool"` 这样的通用占位符,会让你在日志中更难将响应与其对应的工具调用关联起来。由于这里可以保证 `tool_call_id` 一定存在,并且之前也被用作函数名,因此使用 `message.get("name", message["tool_call_id"])` 可以在仍然优先使用显式 `name` 的同时,更好地保留可追踪性。
```suggestion
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
func_name = message.get("name", message["tool_call_id"])
```
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审质量。
Original comment in English
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `astrbot/core/provider/sources/gemini_source.py:385-387` </location>
<code_context>
- ]
+ # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
+ # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有
+ func_name = message.get("name", "unknown_tool")
+
+ # 2. 创建 Part,注意 name 参数必须是函数名
</code_context>
<issue_to_address>
**suggestion:** Consider using `tool_call_id` as the fallback function name instead of a generic literal.
A generic placeholder like `"unknown_tool"` makes it harder to correlate responses with their originating tool calls, especially in logs. Since `tool_call_id` is guaranteed here and was previously used as the function name, using `message.get("name", message["tool_call_id"])` preserves traceability while still preferring an explicit `name` when present.
```suggestion
# 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name)
# 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源
func_name = message.get("name", message["tool_call_id"])
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name) | ||
| # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有 | ||
| func_name = message.get("name", "unknown_tool") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: 建议将 tool_call_id 用作函数名的回退值,而不是使用泛化的字面量。
使用像 "unknown_tool" 这样的通用占位符,会让你在日志中更难将响应与其对应的工具调用关联起来。由于这里可以保证 tool_call_id 一定存在,并且之前也被用作函数名,因此使用 message.get("name", message["tool_call_id"]) 可以在仍然优先使用显式 name 的同时,更好地保留可追踪性。
| # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name) | |
| # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有 | |
| func_name = message.get("name", "unknown_tool") | |
| # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name) | |
| # 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源 | |
| func_name = message.get("name", message["tool_call_id"]) |
Original comment in English
suggestion: Consider using tool_call_id as the fallback function name instead of a generic literal.
A generic placeholder like "unknown_tool" makes it harder to correlate responses with their originating tool calls, especially in logs. Since tool_call_id is guaranteed here and was previously used as the function name, using message.get("name", message["tool_call_id"]) preserves traceability while still preferring an explicit name when present.
| # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name) | |
| # 如果 message 中没有 name,说明上游数据丢失,这里可能需要 fallback 逻辑,但通常都会有 | |
| func_name = message.get("name", "unknown_tool") | |
| # 1. 尝试获取真实的函数名称 (AstrBot/OpenAI 格式的消息通常包含 name) | |
| # 如果 message 中没有 name,则回退使用 tool_call_id,便于在日志中追踪来源 | |
| func_name = message.get("name", message["tool_call_id"]) |
Modifications / 改动点
修复了
ProviderGoogleGenAI(Gemini) 适配器中导致工具调用无限循环的 Bug。在构建
role == "tool"的历史消息时,原代码错误地将tool_call_id当作了函数name传入,且没有显式绑定id到function_response中。这导致 Gemini API 无法正确识别工具执行结果,从而让模型认为任务未完成并陷入死循环。主要修改 (
astrbot/core/provider/sources/gemini_source.py):types.Part.from_function_response中使用真实的函数名 (message.get("name")),而不是 ID。part.function_response.id = message["tool_call_id"],确保工具返回结果能正确匹配到对应的调用请求。Screenshots or Test Results / 运行截图或测试结果
Before Fix / 修复前:

(日志显示模型不断重复调用
chip_build,无法识别工具返回结果,陷入死循环。)After Fix / 修复后:

(Gemini 正确识别了工具执行结果,并成功输出了最终总结文本,跳出了循环。)
Checklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.