Skip to main content
AgentScope provides observability so you can monitor and debug the execution of your agent applications. Built on OpenTelemetry, it gives you tracing across LLM calls, tool invocations, agent replies, and formatters—with optional visualization in AgentScope Studio or export to third-party platforms.

Tracing

Built-in spans for LLM, tool, agent reply, and formatter with error and exception tracking.

AgentScope Studio

Native visualization of traces and token usage when you connect your run to Studio.

Third-Party Export

Send traces to OTLP-compatible backends (e.g. Arize-Phoenix, Langfuse, Alibaba Cloud).
Connecting to AgentScope Studio or a third-party tracing endpoint is done at application startup via agentscope.init. See Settings for other init options.

Overview

Observability in AgentScope is implemented with OpenTelemetry. The framework instruments:
  • LLM calls — each model __call__ (chat, streaming, tools)
  • Agent replies — each agent reply (reasoning and acting)
  • Formatters — message formatting before sending to the model
  • Tools — toolkit call_tool_function invocations
  • Embeddings — embedding model calls
Spans are emitted in OTLP format, so you can view them in AgentScope Studio or any OTLP-compatible backend. Your own OpenTelemetry instrumentation is compatible with AgentScope and will appear in the same trace context.

Setting Up Tracing

AgentScope Studio

When you run agents with AgentScope Studio, you get built-in trace visualization and token usage views. Configure the connection at the start of your application:
import agentscope

# Connect to your Studio instance; traces and token usage will appear in the Studio UI
agentscope.init(studio_url="http://localhost:port")
Once connected, Studio receives traces and run metadata so you can inspect spans, latency, and token consumption per run.

Third-Party Platforms

To send traces to an OpenTelemetry-compatible backend (or your own OTLP collector), set tracing_url in agentscope.init. The URL must be the OTLP trace endpoint.
import agentscope

# Generic OTLP endpoint
agentscope.init(tracing_url="https://your-backend:4318/v1/traces")
If you pass both studio_url and tracing_url, traces are sent to tracing_url; if you pass only studio_url, traces are sent to Studio’s tracing endpoint.
Use either Studio (studio_url) or a third-party (tracing_url) for trace export, or both when you want Studio for UI and a separate backend for storage/analysis.

Connecting to Third-Party Backends

The following examples show how to point AgentScope at popular OTLP-compatible backends.

Alibaba Cloud CloudMonitor

Alibaba Cloud CloudMonitor supports OTLP. Use the public endpoint for your region from the ARMS console (Access Center > OpenTelemetry). You can set the service name with the OTEL_SERVICE_NAME environment variable.
import agentscope

agentscope.init(tracing_url="https://tracing-cn-hangzhou.arms.aliyuncs.com/adapt_xxx/api/otlp/traces")

Arize Phoenix

Arize Phoenix accepts OTLP. Set PHOENIX_API_KEY in your environment and pass Phoenix’s trace endpoint:
import os
import agentscope

os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={os.environ.get('PHOENIX_API_KEY')}"
agentscope.init(tracing_url="https://app.phoenix.arize.com/v1/traces")

Langfuse

Langfuse supports OTLP. Configure LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY, then set the Authorization=Basic ... header for the OTLP exporter:
import os
import base64
import agentscope

LANGFUSE_PUBLIC_KEY = os.environ["LANGFUSE_PUBLIC_KEY"]
LANGFUSE_SECRET_KEY = os.environ["LANGFUSE_SECRET_KEY"]
auth_string = f"{LANGFUSE_PUBLIC_KEY}:{LANGFUSE_SECRET_KEY}"
auth_b64 = base64.b64encode(auth_string.encode("utf-8")).decode("ascii")
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {auth_b64}"

# EU region
agentscope.init(tracing_url="https://cloud.langfuse.com/api/public/otel/v1/traces")
# US region: https://us.cloud.langfuse.com/api/public/otel/v1/traces
For more on run identity and logging, see the project, name, run_id, and logging_path arguments of agentscope.init. run_id is especially useful in Studio to distinguish different runs.

Customizing Tracing

AgentScope’s tracing is implemented with OpenTelemetry; custom spans you create with the OpenTelemetry SDK will appear in the same trace tree. In addition, the following decorators are available to trace framework components:
DecoratorTargetDescription
@trace_llmChatModelBase.__call__Traces LLM invocations (chat, stream, tools).
@trace_replyAgentBase.replyTraces agent reply (reasoning and acting).
@trace_formatFormatterBase.formatTraces message formatting.
@trace_toolkitToolkit.call_tool_functionTraces tool calls.
@trace_embeddingEmbedding model __call__Traces embedding API calls.
@trace(name="...")Any functionGeneral-purpose tracer for sync/async and generators.
These decorators are already applied to the built-in model, agent, formatter, and toolkit classes. You only need to use them when defining your own model, agent, or formatter classes.

Tracing a Custom Chat Model

Your custom model must inherit from ChatModelBase. Apply @trace_llm to __call__ so its calls appear in traces:
from agentscope.model import ChatModelBase
from agentscope.tracing import trace_llm

class MyChatModel(ChatModelBase):
    @trace_llm
    async def __call__(self, messages, **kwargs):
        # Your implementation
        ...

Tracing a Custom Agent

Your custom agent must inherit from AgentBase. Apply @trace_reply to reply:
from agentscope.agent import AgentBase
from agentscope.tracing import trace_reply

class MyAgent(AgentBase):
    @trace_reply
    async def reply(self, *args, **kwargs):
        # Your implementation
        ...

Tracing a Custom Formatter

Your custom formatter must inherit from FormatterBase. Apply @trace_format to format:
from agentscope.formatter import FormatterBase
from agentscope.tracing import trace_format

class MyFormatter(FormatterBase):
    @trace_format
    async def format(self, *args, **kwargs):
        # Your implementation
        ...

General-Purpose Tracing

Use @trace(name="...") on any function—sync or async, including generators—to add a span with the given name:
from agentscope.tracing import trace

@trace(name="my_step")
async def my_async_step(data: dict) -> dict:
    return {"processed": data}

@trace(name="my_sync_fn")
def my_sync_fn(x: int) -> int:
    return x + 1

Token Usage

Token usage is tracked by the model layer and is included in trace metadata where supported. When you connect to AgentScope Studio, token consumption is visualized in the Studio UI so you can monitor cost and usage per run. For third-party backends, token-related attributes are exported with the LLM spans according to the OpenTelemetry semantic conventions used by AgentScope. For programmatic access to usage after a model call, use the usage field on the ChatResponse returned by the model.

Summary

  • Call agentscope.init(studio_url=…) for Studio tracing and token visualization, or agentscope.init(tracing_url=…) for an OTLP backend (or both).
  • Use AgentScope Studio for built-in trace and token usage views.
  • Use tracing_url to send traces to Arize-Phoenix, Langfuse, Alibaba Cloud CloudMonitor, or any OTLP endpoint.
  • Use @trace_llm, @trace_reply, @trace_format, @trace_toolkit, @trace_embedding, and @trace when implementing custom models, agents, or formatters so they appear in the same trace tree.
For evaluation of agent behavior and benchmarks, see Evaluation.