快速结论:该报错发生在 CrewAI 使用原生 Gemini provider(模型字符串以 gemini/ 或 google/ 开头)且启用了 guardrail 重试或触发 handle_max_iterations_exceeded 时,消息历史以模型回合结束导致 Gemini API 返回 400。优先排查消息格式化逻辑是否在历史末尾补上用户回合,临时规避可设置 guardrail_max_retries=0 并调高 max_iterations。
适用环境:CrewAI 1.6.0(含 crewAI Tools 1.6.0)、Python 3.11、Venv 虚拟环境、Google Gemini API(AI Studio 和 Vertex 均受影响)、已安装 google-genai 扩展以启用原生 provider。
最快修复方案:暂无确认的一步修复方案(Issue 关闭时 PR 尚未合入)。可优先尝试以下两个已验证的规避方法:① 提高 max_iterations 并设置 guardrail_max_retries=0 以避开重入路径;② 卸载 google-genai,让 gemini/* 回退到 LiteLLM 路径(该路径已有尾随用户回合防护)。
注意事项:上述规避方法仅绕过问题,不解决根因;卸载 google-genai 后原生 provider 不可用,模型请求将走 LiteLLM 替代路径,可能影响其他依赖原生 provider 的功能。Issue 中提出的正式修复(在 _format_messages_for_gemini 末尾补齐用户回合)尚在 PR 审查阶段,未发布到正式版本。
问题场景
用户在 CrewAI 中使用 LLM(model="gemini/gemini-flash-latest") 或任何 google/.../gemini/... 模型字符串,并安装了 google-genai 扩展(此时 CrewAI 会走原生 Google Gen AI provider 而非 LiteLLM 回退路径)。当任务配置了 guardrail 且设置 guardrail_max_retries 大于 0,或代理循环触发了 handle_max_iterations_exceeded 时,执行器会在已经追加了 assistant/tool-call 回合且没有插入用户回合的情况下重新调用 LLM,导致发送给 Gemini generateContent API 的消息历史以模型回合结尾而被拒绝。
Issue 作者在单代理 Crew 中配置 Task 的 guardrail=<completeness_check> 且 guardrail_max_retries=2 时稳定复现该问题;短任务、无 guardrail 的 Crew(如 Google 官方 CrewAI+Gemini 示例)不会触发。
报错原文
[BUG] Gemini native provider never appends trailing user turn -> 400 'Requests ending with a model turn are not supported'
400 INVALID_ARGUMENT. {'error': {'code': 400, 'message': 'Requests ending with a model turn are not supported.', 'status': 'INVALID_ARGUMENT'}}
原因分析
可能原因:CrewAI 的原生 Gemini/Google provider(crewai/llms/providers/gemini/completion.py)中的 GeminiCompletion._format_messages_for_gemini 方法在将 assistant 消息映射为 Gemini 的 model 角色时(包括纯文本分支和工具调用分支),没有检查格式化后的 contents 列表是否以 model 回合结尾。CrewAI 自己的代理循环可以产生这种历史——例如 handle_max_iterations_exceeded 追加一条 assistant 消息后重新调用 LLM,或任务 guardrail/guardrail 重试次数耗尽后的再次调用——这种畸形历史被原样发送到 Gemini API,被其拒绝。
值得注意的是,CrewAI 的 LLM 回退路径(LLM._format_messages_for_provider)中已经有针对 Mistral 和 Ollama 的同类防护(在最后一条消息是 assistant 时追加合成用户消息),但原生 Gemini provider 没有这一防护,导致两条路径行为不一致。
环境排查
- CrewAI 版本:1.6.0(issue 作者确认在 release 版本和当前 main 分支均存在此问题)
- crewAI Tools 版本:1.6.0
- Python 版本:3.11
- 虚拟环境:Venv
- 依赖:确认已安装
google-genai扩展(未安装时走 LiteLLM 回退路径,不会触发此问题) - 操作系统:其他(issue 未指明具体系统)
- Gemini API 端点:AI Studio 和 Vertex 均执行相同的 contents 契约
解决步骤
- 临时规避(已验证):提高
max_iterations并设置guardrail_max_retries=0,避免代理循环在 assistant/tool-call 回合后重新调用 LLM。 - 替代规避(已验证):卸载
google-genai扩展,使gemini/*模型字符串回退到 LiteLLM 路径——该路径的_format_messages_for_provider已包含尾随用户回合防护。 - 正式修复(待合入):Issue 作者已提交 PR,计划在
_format_messages_for_gemini末尾镜像 Mistral 的防护逻辑:当最后一条 content 是 model 回合时,追加一条合成用户消息(文本为 “Please continue.”,与 Mistral 路径一致),使代理循环在 guardrail 重试或handle_max_iterations_exceeded后可以安全地重新调用 LLM。回归测试覆盖尾随 assistant 场景以及无需补丁的场景(已用户回合结尾、工具响应结尾、仅系统消息)。 - 直接复现脚本(用于验证):直接调用
GeminiCompletion._format_messages_for_gemini,传入以 assistant 回合结束的历史,观察返回的 contents 角色列表是否以model结尾。
验证方法
修复后,直接调用 _format_messages_for_gemini 并传入以 assistant 回合结束的历史(例如 [{"role": "user", "content": "hi"}, {"role": "assistant", "content": "partial"}]),确认返回的 contents 列表最后一个角色是 user 而不是 model。在真实代理运行中,配置 guardrail 且 guardrail_max_retries 大于 0,确认触发重试后不再收到 400 INVALID_ARGUMENT 且任务能正常完成。当前 Issue 关闭时 PR 尚未合入,需自行应用补丁或等待后续版本。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Bug]: minimum_should_match fraction is truncated, not rounded, in every full-text doc-store connector](https://www.chat-gpts.plus/wp-content/uploads/2026/09/19027-c05031a9-768x403.jpg)
