Skip to main content
Applies to:
  • Plan -
  • Deployment -

Summary

Issue: Traces are not created when calling litellm.anthropic_messages() or routing through the /anthropic/v1/messages passthrough. Calls to litellm.completion(model="anthropic/claude-...") are traced correctly. Cause: patch_litellm wraps litellm.completion, acompletion, responses, embedding, and related entrypoints — it does not wrap litellm.anthropic_messages or the /anthropic/v1/messages passthrough route. Resolution: Use litellm.completion for standard Claude tracing, or use the Anthropic SDK directly with wrap_anthropic if you need native Anthropic Messages API features.

Resolution steps

If you are calling litellm.completion with a Claude model and seeing no spans

Step 1: Verify setup order

patch_litellm() must be called before importing or using litellm. Confirm the following are also in place:
  • init_logger(project="...") is called
  • BRAINTRUST_API_KEY is set in your environment

Step 2: Confirm the call pattern

from braintrust import init_logger, patch_litellm

init_logger(project="my-project")
patch_litellm()

import litellm

response = litellm.completion(
    model="anthropic/claude-3-5-sonnet-20241022",
    messages=[{"role": "user", "content": "Hello"}]
)
This path is fully traced. LiteLLM translates the call to Anthropic’s /messages API internally, and the Braintrust wrapper operates at the litellm.completion layer.

If you need native Anthropic Messages API features (extended thinking, prompt caching, etc.)

Step 1: Use wrap_anthropic with the Anthropic SDK directly

litellm.anthropic_messages is not wrapped by patch_litellm. Use this path instead:
import anthropic
from braintrust.wrappers.anthropic import wrap_anthropic

client = wrap_anthropic(anthropic.Anthropic())

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}]
)

If you are building a gate pattern on top of patch_litellm

Step 1: Save original function references before wrapping

patch_litellm patches the litellm module in-place. If you save references after calling patch_litellm, both your original and traced refs point to the already-wrapped function, and the gate has no effect. Save refs first:
from braintrust import patch_litellm

import litellm
original_completion = litellm.completion
original_acompletion = litellm.acompletion

patch_litellm()

litellm.completion = _gate_sync(original_completion, litellm.completion)
litellm.acompletion = _gate_async(original_acompletion, litellm.acompletion)

Notes

  • Native anthropic_messages wrapper support in patch_litellm is not currently available. If this is a requirement, submit a feature request.
  • Do not use LiteLLM’s BraintrustLogger callback for tracing. Use patch_litellm() or braintrust.auto_instrument() instead — only function-wrapping preserves span context.