Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

Fix stop sequences synchronization for Anthropic, Bedrock, and Gemini providers

Summary

Fixes issue #3836 where stop sequences were not being sent to Anthropic, Bedrock, and Gemini APIs, causing massive token usage (10x higher costs).

Root cause: CrewAgentExecutor sets llm.stop to control when the model should stop generating, but these three providers store stop sequences in a separate stop_sequences attribute that gets sent to the API. Since there was no synchronization between these two attributes, the API never received stop instructions, causing the model to generate entire conversations in a single response instead of stopping at \nObservation: boundaries.

Fix: Added @property getter/setter for stop attribute in AnthropicCompletion, BedrockCompletion, and GeminiCompletion classes to synchronize stop with stop_sequences. When CrewAgentExecutor sets llm.stop, it now properly updates stop_sequences which is what gets sent to the API.

Changes:

  • Added stop property to AnthropicCompletion (lib/crewai/src/crewai/llms/providers/anthropic/completion.py)
  • Added stop property to BedrockCompletion (lib/crewai/src/crewai/llms/providers/bedrock/completion.py)
  • Added stop property to GeminiCompletion (lib/crewai/src/crewai/llms/providers/gemini/completion.py)
  • Added comprehensive test suite (lib/crewai/tests/llms/test_stop_sequences_sync.py)

Review & Testing Checklist for Human

⚠️ IMPORTANT: These tests could not be run locally due to pytest plugin conflicts. CI validation is critical.

  • Verify new tests pass in CI - The test suite test_stop_sequences_sync.py contains 18 tests across 3 providers. Confirm all pass.
  • Test actual bug scenario end-to-end - Create an agent with Anthropic (or Bedrock/Gemini), set up a tool, and verify:
    • Stop sequences are actually sent to the API (check request payload)
    • Model stops generating at \nObservation: instead of inventing full conversations
    • Token usage returns to normal levels (~13K instead of ~138K)
  • Check initialization order - The property is set during BaseLLM.__init__, then the child class also sets stop_sequences. Verify no issues with object construction.
  • Review reference semantics - BedrockCompletion.stop getter returns list(self.stop_sequences) (new list) while Anthropic/Gemini return the same reference. Confirm this doesn't break anything in executor code that might rely on reference equality.
  • Verify with OpenAI/Azure - These providers use self.stop directly (not stop_sequences), so they should be unaffected. Quick sanity check recommended.

Notes

  • Scope expansion: Original issue [BUG] Stop sequences not sent to Anthropic API causing massive token usage #3836 only mentioned Anthropic, but I discovered Bedrock and Gemini had the same bug pattern (separate stop and stop_sequences attributes without synchronization). All three are fixed in this PR.
  • Type safety: Fixed a mypy error in BedrockCompletion where the property return type needed to match the declared type.
  • Testing gap: Could not verify end-to-end that this fixes the actual token usage issue - only verified the synchronization logic works correctly.

Link to Devin run: https://app.devin.ai/sessions/4ba6b0786af24d0a93988371fe403744
Requested by: João (joao@crewai.com)

… providers

- Add stop property getter/setter to AnthropicCompletion to sync stop with stop_sequences
- Add stop property getter/setter to BedrockCompletion to sync stop with stop_sequences
- Add stop property getter/setter to GeminiCompletion to sync stop with stop_sequences
- Add comprehensive tests for all three providers to verify synchronization works correctly

This fixes issue #3836 where CrewAgentExecutor sets llm.stop but the provider-specific
stop_sequences attribute (which is sent to the API) was not synchronized, causing the
model to generate entire conversations instead of stopping at the expected boundaries.

The fix ensures that when CrewAgentExecutor sets llm.stop, the value is properly
synchronized with the provider-specific stop_sequences attribute that gets sent to
the API, preventing massive token usage and cost overruns.

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants