How do I trace the Anthropic API in Python?
Rius traces the Anthropic API in Python with one install command and one init call, and every messages.create call then shows up in the trace with its model, token counts and cost. You do not change your call sites. Install the Anthropic extra of the Rius SDK, call rius.init once, and use your Anthropic client as before.
How it works
The Rius SDK for Python is published as glassflow-rius and imported as rius. It needs Python 3.10 or newer. The anthropic extra installs the instrumentation for the Anthropic client library. It does not install anthropic itself, so a fresh environment needs both names in the install line. A project that already calls Anthropic has the library, and pip leaves it untouched.
When you call rius.init(), every installed integration turns on, including Anthropic. From then on, each messages.create call is recorded automatically, process-wide. If you install the extra without the anthropic library, init() logs a DependencyConflict and the Anthropic integration stays off. That is the one failure worth recognizing.
Cost is not something you send. Rius computes it from the model and the token counts, as a list-price estimate in US dollars.
The full list of init arguments and environment variables is on Installation and configuration. The Anthropic specifics are on the Anthropic integration page.
Set it up
- Install the SDK with the Anthropic extra, and the
anthropiclibrary if your environment does not have it yet:
pip install "glassflow-rius[anthropic]" anthropic- Call
rius.initonce, as early as possible in your process, before you make Anthropic calls. Setservice_nameexplicitly. It is how you find your agent in trace filters and cost breakdowns, and it defaults tounknown_service. This example puts the init call and a minimal traced call together. The@rius.observedecorator wraps your function so the model call appears nested inside the run:
import anthropic
import rius
rius.init(api_key="ri_...", service_name="my-agent")
claude = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
@rius.observe
def handle(query: str) -> str:
response = claude.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=200,
messages=[{"role": "user", "content": query}],
)
return response.content[0].text
handle("What should I check when a collector drops spans?")-
Replace
ri_...with your Rius API key. You can also supply it through theRIUS_API_KEYenvironment variable, and the service name throughRIUS_SERVICE_NAME. Explicit arguments win over environment variables. -
Run the script, then open the trace in the Rius console. The span for the model call shows the model, the token counts and a cost.
If you want to trace only Anthropic and nothing else that is installed, pass instruments=["anthropic"] to rius.init. Passing instruments=[] turns all integrations off.
What you get
Each messages.create call becomes its own span in the trace. It carries:
- The model, for example
claude-haiku-4-5-20251001. - Token usage from the response, including cache reads and cache writes, so prompt caching is reflected in cost.
- A cost for the call, computed by Rius from the model and tokens. Costs are list-price estimates, not billed amounts.
- The messages, request and response. Text blocks become text parts and tool calls become tool call parts. Any other block, such as an image or a reasoning block, is kept as a text part holding the block serialized, so nothing is lost.
- The system prompt. Anthropic takes it as a separate
systemparameter, and Rius places it as the leading system message in the input messages. - Errors. A failed call records
error.typeas the error class, such asanthropic.NotFoundError.
With @rius.observe around your function, the model call nests inside your agent’s run, so you see the step and the call together.
Streamed calls also carry token usage, because Anthropic reports it in the message lifecycle events. One gap: auto-instrumented Anthropic streams carry no time to first token. If that number matters for a call, trace it as a manual generation and use record_first_token().
Prompt and response content follows your privacy controls. Setting RIUS_CAPTURE_CONTENT to false strips content at export while the metadata still flows.
When something else fits
- If your service is written in TypeScript, the Anthropic integration uses a different package. The Anthropic integration page covers it.
- If you call Claude through the Claude Agent SDK, it is the one manual integration, so follow its own page, which you can reach from Integrations.
- If you call Anthropic through a framework or router such as LangChain or LiteLLM, use that integration’s page from the same list.