Staso Docs
Getting Started

Core Concepts

The vocabulary Staso uses to describe AI agent observability: traces, spans, agents, conversations, environments, workspaces, and organizations.

Organization
└── Workspace
    └── Traces
        └── Spans

Trace

One end-to-end agent run. A trace is the root container for everything that happened during a single invocation — LLM calls, tool calls, intermediate steps, errors. Identified by trace_id. Created automatically when you enter the first span via @st.agent, @st.tool, @st.trace, or st.span(...).

Span

One unit of work inside a trace. Every LLM call, tool call, or chain step is a span. A span has:

FieldDescription
kindWhat type of work — see span kinds below.
statusok, error, or timeout.
inputSerializable dict of inputs captured at start.
outputSerializable dict of outputs captured at end.
metadataFree-form attributes (model, tokens, tags, source loc).

Span kind

The classification Staso uses to render and filter spans. One of:

KindMeaning
llmA call to an LLM provider (Anthropic, OpenAI, ...).
toolA tool or function the agent invoked.
chainA composite step — default for @st.trace.
retrieverA retrieval or search step (vector DB, RAG).
agentAn agent entry point — set by @st.agent.
customAnything else.

See the data model reference for the exact enum and storage layout.

Agent

The logical unit emitting traces — one row in your dashboard's agent list. Most teams run more than one agent in the same process (a chat bot, a refund worker, a report generator), so Staso lets you tag every trace with the agent that produced it and slice metrics, alerts, and guard rules by agent.

The primary way to name an agent is the @st.agent decorator on each entry point:

@st.agent(name="refund-worker")
def handle_refund(req): ...

@st.agent(name="support-bot")
def answer_question(msg): ...

Every span inside a decorated function inherits that agent name, so traces route to the right agent automatically — even when several agents share the same Python process.

st.init(agent_name=...) sets the baseline agent name for code paths that aren't wrapped in @st.agent. It's required by init(), and it's the only name you need if you run a single agent or don't care about per-agent metrics.

Conversation

A set of traces that share a conversation_id — for example, every turn of one chat thread, every step of one multi-turn agent run, or every retry of the same background job. The Staso dashboard shows all traces in a conversation as a single timeline so you can follow how an agent behaved across turns, attribute a failure on turn 7 to a decision made on turn 2, and filter analytics per end user.

Use st.conversation(...) as a context manager to attach a conversation_id (and optionally a user_id) to every trace produced inside the scope.

with st.conversation("conv-42", user_id="user-alice"):
    run_agent(query)

See conversations for details.

Environment

A logical partition for traces — typically prod, staging, dev. Set via environment in st.init(...) or the STASO_ENVIRONMENT env var. Defaults to default. Useful for keeping production data separate from local experiments in dashboards and alerts.

Workspace

A data isolation unit inside an organization. Traces, guards, datasets, and API keys can all be scoped to a workspace. Target a specific workspace from the SDK with workspace_slug in st.init(...) or STASO_WORKSPACE_SLUG. See organizations and workspaces.

Organization

The top-level billing, RBAC, and ownership boundary. An organization contains one or more workspaces and all its members. Every API key belongs to exactly one organization and is either full-org scoped or workspace-scoped. See organizations and workspaces.

Next