[BUG] Stop sequences not sent to Anthropic API causing massive token usage

用户在使用 CrewAI 框架时,配置 Anthropic(Claude)模型(如 claude-sonnet-4-5、claude-3-5-sonnet-20241022)作为 Agent 的 LLM 后端,并启用工具调用。在运行 Crew 时,模型未在 \nObservation: 边界处停止,

[BUG] Stop sequences not sent to Anthropic API causing massive token usage

[BUG] Stop sequences not sent to Anthropic API causing massive token usage

快速结论:该问题发生在 CrewAI 使用 Anthropic(Claude)模型时,由于 llm.stop_sequences 属性未被正确同步,导致 API 未收到停止序列参数 stop_sequences,模型持续生成至 max_tokens 上限,造成 10 倍以上的 token 消耗和费用超支。优先排查 crewai/llms/providers/anthropic/completion.pyself.stop_sequences 是否为空。

问题场景

用户在使用 CrewAI 框架时,配置 Anthropic(Claude)模型(如 claude-sonnet-4-5、claude-3-5-sonnet-20241022)作为 Agent 的 LLM 后端,并启用工具调用。在运行 Crew 时,模型未在 \nObservation: 边界处停止,而是生成完整的多轮对话,导致单次调用 token 消耗从预期的约 13K 飙升到约 138K,费用从约 $0.10 增至 $1+。

报错原文

# 实际输出(单次 API 调用,模型自行编造 Observation):
Action: sample_tool
Action Input: {"query": "test"}
Observation: Tool result                    ← INVENTED by model!
Thought: Now I'll continue...
Action: another_tool
Action Input: {...}
Observation: More invented output           ← INVENTED by model!
...continues until max_tokens...

# 调试打印:
print(f"llm.stop: {agent.llm.stop}")           # ['\nObservation:']
print(f"llm.stop_sequences: {agent.llm.stop_sequences}")  # [] ← BUG!

原因分析

根本原因在于 crewai/agents/crew_agent_executor.py 中设置了 self.llm.stop,但 crewai/llms/providers/anthropic/completion.py 中存在两个分离的属性:self.stop(由 CrewAgentExecutor 设置)和 self.stop_sequences(实际发送到 API 的参数)。两者之间没有同步逻辑,导致 stop_sequences 始终为空,API 无法接收到停止指令。在 completion.py 第 197-198 行中,仅当 self.stop_sequences 非空时才将其加入 API 参数。

环境排查

  • CrewAI 版本:1.2.0(Issue 中使用的版本)
  • Python 版本:3.12.8
  • Anthropic 模型:claude-sonnet-4-5、claude-3-5-sonnet-20241022 等所有 Claude 模型
  • 操作系统:macOS(Darwin 24.6.0)
  • 依赖:Anthropic Python SDK 版本(需确认)

解决步骤

  1. 确认问题:在触发 Agent 前,打印 agent.llm.stopagent.llm.stop_sequences 检查同步状态。
  2. 更新代码(优先尝试):根据 Issue 中提到的修复(#3853),在 crewai/llms/providers/anthropic/completion.py 中增加同步逻辑,使得设置 self.stop 时自动更新 self.stop_sequences。例如在 __init__ 或 setter 方法中同步两属性。
  3. 手动修复(临时方案):在创建 AnthropicCompletion 实例后,手动将 llm.stop 赋值给 llm.stop_sequences
    llm = AnthropicCompletion(model="claude-sonnet-4-5", max_tokens=2000)
    # 在使用前手动同步
    llm.stop_sequences = llm.stop if isinstance(llm.stop, list) else []
  4. 验证修复:运行 Issue 中的测试代码,确认 llm.stop_sequences 不再为空。

验证方法

运行以下检查代码,确认 stop_sequences 已正确同步:

print(f"llm.stop: {agent.llm.stop}")            # 应显示 ['\nObservation:']
print(f"llm.stop_sequences: {agent.llm.stop_sequences}")  # 应显示 ['\nObservation:']

此外,可通过 LangSmith 或 API 调用日志确认停止序列是否随请求发送,并观察 token 消耗是否回归到正常水平(从 ~138K 降至 ~13K)。

参考来源

crewAIInc/crewAI #3836

相关修复提交:#3853

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 13015

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注