Skip to main content

Waxell Observe

You already have agents -- add observability in 2 lines of code.

Waxell Observe is a lightweight Python package that brings LLM call tracking, cost management, and policy enforcement to any AI agent. It works with any Python agent framework -- LangChain, LlamaIndex, CrewAI, custom code, or anything else. No vendor lock-in, no runtime changes, no migration required.

Fastest Path: Auto-Instrumentation

Two lines to automatically trace all OpenAI and Anthropic calls:

import waxell_observe
waxell_observe.init(api_key="wax_sk_...", api_url="https://waxell.dev")

# Import LLM SDKs AFTER init() -- they're now auto-instrumented
from openai import OpenAI

client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
# Automatically traced with model, tokens, cost, latency
Recommended Path

Most users should start here: waxell.init() auto-instruments all LLM calls with zero code changes. Add @observe decorators when you want named traces and enrichment. Only reach for WaxellContext if you need explicit lifecycle control (session IDs, user tracking, multi-function workflows).

Integration Patterns

Patterns listed from simplest to most control:

1. Decorator -- Function-Level Tracing

Wrap any function with @observe and get automatic run tracking, IO capture, and policy enforcement:

from waxell_observe import observe

@observe(agent_name="support-bot")
async def handle_ticket(query: str, waxell_ctx=None) -> str:
result = await my_llm_call(query)
if waxell_ctx:
waxell_ctx.record_llm_call(model="gpt-4o", tokens_in=150, tokens_out=80)
return result

2. Context Manager -- Advanced Control

Use WaxellContext when you need explicit control over what gets recorded:

from waxell_observe import WaxellContext, generate_session_id

async with WaxellContext(
agent_name="research-agent",
session_id=generate_session_id(),
user_id="user_123",
) as ctx:
result = await run_research_pipeline(query)
ctx.record_llm_call(model="claude-sonnet-4", tokens_in=500, tokens_out=200)
ctx.record_step("summarize", output={"summary": result})
ctx.set_result({"answer": result})

3. LangChain Callback -- Drop-in Integration

Three lines to observe any LangChain chain or agent:

from waxell_observe.integrations.langchain import WaxellLangChainHandler

handler = WaxellLangChainHandler(agent_name="langchain-agent")
result = chain.invoke(input, config={"callbacks": [handler]})
handler.flush_sync(result={"output": result})

What You Get

FeatureDescription
LLM Call TrackingModel, token counts, cost, prompt/response previews for every LLM call
LLM Call ExplorerBrowse, filter, and inspect every LLM call with prompt/response viewer
Session TrackingGroup related runs by session for conversation-level analytics
User TrackingPer-user cost attribution, usage patterns, and analytics
ScoringCapture quality scores via SDK or UI annotations
Annotation QueuesHuman review workflows for manual quality assessment
Prompt ManagementVersion-controlled prompts with labels, playground, and SDK retrieval
Cost AnalyticsModel usage breakdown, per-user costs, custom pricing overrides
Policy EnforcementPre-execution and mid-execution checks with allow/block/warn/throttle actions
Step RecordingOrdered execution steps with outputs for debugging and audit
Run LifecycleStart, track, and complete execution runs with inputs, outputs, and status
Event RecordingArbitrary governance events for audit trails

Framework Compatibility

Waxell Observe works with any Python agent framework:

  • OpenAI -- auto-instrumentation or manual recording
  • Anthropic -- auto-instrumentation or manual recording
  • LangChain / LangGraph -- first-class callback handler
  • LiteLLM -- unified API for 100+ providers
  • LlamaIndex -- decorator or context manager
  • CrewAI -- decorator or context manager
  • Custom frameworks -- decorator, context manager, or raw client
  • Any Python code -- if it runs Python, you can observe it

Next Steps