/docs/first-trace

Send your first trace

A walkthrough of a real, instrumented agent — from the first trace to the first cluster.

We'll instrument a tiny support agent. The agent classifies a user message, retrieves a few docs, and drafts a reply. The same pattern scales to any agent.

1. Wire the client

import os
from theta_observability import TraceClient

client = TraceClient(
    api_key=os.environ["THETA_API_KEY"],
)

2. Trace the run

def run(user_message: str):
    trace_id = None
    with client.trace(name="support-agent", run_type="prod") as t:
        trace_id = t.model.trace_id
        t.set_metadata(release=os.environ.get("RELEASE", "dev"))

        with t.step(name="classify_intent", type="llm", model="claude-sonnet-4-6") as s:
            s.log_message(role="user", text=user_message)
            intent = classify(user_message)
            s.log_message(role="assistant", text=intent)
            s.set_token_usage(input=300, output=12)

        with t.step(name="kb.search", type="retrieval") as s:
            docs = search(intent)
            s.set_metadata(doc_count=len(docs))

        with t.step(name="draft_reply", type="llm", model="claude-sonnet-4-6") as s:
            reply = draft(user_message, docs)
            s.log_message(role="assistant", text=reply)

        return trace_id, reply

3. Record an outcome

client.record_metric(
    "user_helpfulness",
    trace_id,
    passed=user_thumbed_up,
)

What happens next

The trace lands in the obsrv ingest API, gets persisted to object storage, indexed in the warehouse, and embedded for cluster discovery — usually within seconds. Click into the trace to see the full step tree, attached messages, token usage, and metadata.

From here, the dashboard is your inspector. Filter by release, save the view, set a monitor on the helpfulness metric, and let cluster discovery surface emerging issues without waiting for a user to complain.