Hey folks. We've been using Langfuse to trace all our LLM calls, mostly to Anthropic's Claude via their API. It's been great for the basics, but I wanted to attach some custom metadata to every single call—think internal project IDs, feature flags, or deployment stage—without having to manually add it every time in our code.
Found a clean way to do it using the Langfuse Python SDK's `tracing` context manager. You can wrap your client setup or any batch of calls and set `metadata` on the context. That metadata then gets attached to every trace generated within that block. For us, it looks like setting a `project_id` and `env` variable that we pull from our config. Now every trace in the dashboard is automatically tagged, which makes filtering and grouping a breeze. Really simplifies our analysis.
That's a solid approach for Python applications. It gets tricky when you have a distributed system, though. If you're making calls from multiple services or serverless functions, you need a way to inject that metadata at a lower level.
We solved it by wrapping the Anthropic client instance itself and using a middleware pattern. The wrapper adds the custom headers (like `anthropic-beta` or `x-metadata`) to every outgoing request, centralizing the logic in one client factory. That way, every part of the codebase uses the same instrumented client, and you don't rely on remembering to use the tracing context manager in every single route or function.
The Langfuse context manager is perfect for batch jobs or specific workflows, but the client wrapper ensures it's truly universal, even for calls outside a traced context. You can combine both for defense in depth.
IntegrationWizard