AISquare
Govern

Agent identity

Every trace routes by agent name. How identity is set on each integration path, how to run more than one agent, and what failure looks like when a name is missing.

Every trace that reaches AISquare carries an agent name. The gateway routes each trace by the pair (workspace, agent name) to a studio and its Rule Book, and the dashboard groups runs, verdicts, and cost by the same name. A trace without a name has nowhere to go. This page is the contract: where the name lives, how each integration path sets it, and what breaks when it is missing.

Why identity exists

Identity is written to the trace as attributes["agent.name"] on the trace's root span. The gateway reads it once per trace and uses it three ways:

  • Routing. Each trace routes by (workspace, agent name) to a studio. This is how a run ends up on the right dashboard.
  • Rule Book binding. The name decides which Rule Book judges the run. Bind a Rule Book to support-bot and every run named support-bot is evaluated against it.
  • Grouping. Runs, policy verdicts, and cost aggregate per agent. The name is the axis.

Two channels, one name

The SDK carries identity on two channels. They answer different questions, and you should keep them equal.

  • Span identity (agent.name on the root span) routes the trace and groups your dashboards.
  • Policy identity (AISQUARE_AGENT_NAME) tells policy checks which Rule Book judges the agent.

From SDK 1.0.6 the two are unified: AISQUARE_AGENT_NAME also serves as the fallback trace identity. When a span batch arrives with no explicit name on its root span, the SDK stamps it with AISQUARE_AGENT_NAME. Explicit naming in code always wins; the env var is the safety net. Keep it equal to your agent_name so both channels agree.

How identity is set, per path

Explicit naming is the contract. Each integration path has exactly one place to put the name.

PathWhere the name goes
Raw pipeline / custom spansAgentRunTracer(agent_name=...)
AgnoAgent(name=...) — required
LangChainmetadata={"agent_name": ...} in the invoke config
Custom or OpenAI-wrapped via GovernedAgentagent_name= on the wrapper; tracing is automatic (SDK 1.0.6)
ProxyX-Agent-Name header

Raw pipelines. Open an AgentRunTracer around the run. Its agent_name lands on the root span and every child inherits the route.

# .env: EXPLAINABILITY_GATEWAY_URL, EXPLAINABILITY_API_KEY,
# EXPLAINABILITY_AGENTS=support-bot   <- pre-registers; must equal agent_name below
import aisquare.explainability as sdk

sdk.init_from_env()

with sdk.AgentRunTracer(agent_name="support-bot"):
    with sdk.LLMCallTracer(model="gpt-4o", provider="openai") as llm:
        ...
sdk.flush()

Agno. The agent must be named. The SDK reads Agent(name=...) and uses it as the trace identity; an unnamed Agno agent has no identity to send.

my_agent = Agent(name="support-bot", ...)

LangChain. Pass the name in the invoke config's metadata. The callback handler picks it up per call.

chain.invoke(inputs, config={"metadata": {"agent_name": "support-bot"}})

Custom and OpenAI-wrapped agents. From SDK 1.0.6, GovernedAgent auto-opens an AgentRunTracer around .run() and .arun(), so the wrapped agent is traced and named in one move.

agent = GovernedAgent.wrap(my_agent, agent_name="support-bot")
agent.run("...")   # traced automatically, routed as support-bot

Streaming run methods are not auto-traced

The automatic tracer wraps .run() and .arun(). If your run method is generator-shaped (it streams or yields), the run outlives the call and the wrapper cannot see its end. Open an AgentRunTracer(agent_name=...) around the code that consumes the stream instead.

Proxy. Identity comes from the X-Agent-Name header on each request. If the header is absent, the proxy falls back to the pipeline id (X-Pipeline-Id), then to claude-code. Set the header if you want the name to mean something.

Running more than one agent

Name each agent in code. AISQUARE_AGENT_NAME holds one name; it is a single-agent convenience, not a naming scheme.

The env var cannot name a fleet

If several agents run in one process and rely on the env-var fallback, they all inherit the same identity. Their traces collapse into one agent — one shared Rule Book, merged dashboards, blended cost — and nothing warns you. The runs still arrive; they are just indistinguishable. With multiple agents, set agent_name explicitly on every one.

Pre-register your roster

EXPLAINABILITY_AGENTS takes a comma-separated list of agent names and registers them at init_from_env(), so the first trace from each agent routes immediately instead of waiting on registration.

export EXPLAINABILITY_AGENTS="support-bot,billing-bot"

The names must equal the agent_name values used in code, character for character. A roster entry that matches nothing registers an agent that never runs; a coded name missing from the roster still needs registration before its first trace routes.

Naming rules

  • Unique per workspace. The name is the routing key; two agents sharing a name are one agent as far as AISquare is concerned.
  • Stable across deploys. Rule Book bindings key off the name. Rename the agent and its bindings, history, and dashboards do not follow.
  • Allowed characters: letters, digits, ., _, -, and spaces.

What failure looks like

When identity is missing or unknown, trace ingest answers 409 Conflict with a machine-readable code in detail.code:

CodeMeaningWhat to do
no_agent_identityA root span arrived with no identity on it.Fix the integration — name the agent. Retrying will not succeed.
awaiting_trace_routeA child-only batch arrived before its root span.Transient. The SDK retries it automatically.
agent_not_registeredThe name is set but not registered in the workspace.Register the agent, or enable auto-discovery on the workspace.

Full remediation for each code is in the error reference. If you are not sure which case you are in, run explainability-doctor: its agent_identity check flags naming gaps in your integration, and its delivery_backlog check reads the local delivery queue and reports exactly which of these failures is holding traces back.

Next steps

On this page