diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 7bbdb9a43fd..022fce01ded 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -1935,10 +1935,15 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): output_key="top_k", ) + # ``messages`` must be the last key in the serialized request body: Anthropic's + # prompt cache (observed on the Vertex AI global endpoint) keys off the raw + # request bytes, and a stable ``system``/``tools`` prefix only hits the cache + # on repeat turns when ``messages`` (the part that changes every turn) is + # ordered after them, not before. data: Final = { "model": model, - "messages": anthropic_messages, **optional_params, + "messages": anthropic_messages, } self._apply_output_config(data=data, model=model, optional_params=optional_params) diff --git a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py index 231d3b48754..17c28245e5b 100644 --- a/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/test_litellm/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -916,6 +916,35 @@ def test_anthropic_chat_transform_request_includes_context_management(): assert result["context_management"] == _sample_context_management_payload() +def test_anthropic_chat_transform_request_orders_messages_last(): + config = AnthropicConfig() + result = config.transform_request( + model="claude-sonnet-4-20250514", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Hello"}, + ], + optional_params={ + "tools": [ + { + "name": "get_weather", + "input_schema": {"type": "object", "properties": {}}, + } + ], + "max_tokens": 256, + }, + litellm_params={}, + headers={}, + ) + + keys = list(result.keys()) + assert "system" in keys + assert "tools" in keys + assert keys.index("messages") > keys.index("system") + assert keys.index("messages") > keys.index("tools") + assert keys[-1] == "messages" + + def test_anthropic_structured_output_beta_header(): from litellm.types.utils import CallTypes from litellm.utils import return_raw_request