Skip to main content
The Agents view in Netra provides a centralized dashboard of all AI agents used in your project. It shows when each agent was first and last active, how many traces it has generated, and which tools it uses.

Viewing Agents

Access the Agents view from Observability → Agents in the Netra dashboard. For each agent, Netra displays:
FieldDescription
Agent NameThe name assigned via the @agent decorator or manual span
Total TracesNumber of traces where this agent was invoked
First EventTimestamp of the agent’s first recorded invocation
Last EventTimestamp of the agent’s most recent activity

Agent Actions

Each agent card provides two actions:
  • View Traces - Opens the Traces view filtered to this agent, showing all executions, inputs, outputs, latency, and cost
  • Tools - Opens a modal listing tools invoked by the agent and their call counts

Configuring Agents

Agents are automatically tracked when you use the @agent decorator or create spans with SpanType.AGENT.

Using the Agent Decorator

The @agent decorator is the recommended way to define agents. It automatically creates spans with the correct type and tracks agent activity.
from netra.decorators import agent

# Basic usage - agent name derived from function name
@agent
def research_agent(query: str):
    # Agent logic here
    return perform_research(query)

# With custom name
@agent(name="customer-support-agent")
def handle_support_request(request: dict):
    intent = classify_intent(request)
    response = generate_response(intent)
    return response
import { agent } from "netra-sdk/decorators";

// Basic usage - agent name derived from function name
@agent
async function researchAgent(query: string) {
  // Agent logic here
  return await performResearch(query);
}

// With custom name
@agent({ name: "customer-support-agent" })
async function handleSupportRequest(request: SupportRequest) {
  const intent = await classifyIntent(request);
  const response = await generateResponse(intent);
  return response;
}

Decorating Agent Classes

You can also decorate entire classes. All public methods will be instrumented as part of the agent.
from netra.decorators import agent, task

@agent(name="data-analysis-agent")
class DataAnalyzer:
    @task
    def analyze_data(self, data: list):
        # Analysis logic
        pass

    @task
    def generate_report(self, analysis: dict):
        # Report generation
        pass
import { agent, task } from "netra-sdk/decorators";

@agent({ name: "data-analysis-agent" })
class DataAnalyzer {
  @task
  async analyzeData(data: any[]) {
    // Analysis logic
  }

  @task
  async generateReport(analysis: any) {
    // Report generation
  }
}

Manual Agent Spans

For more control, create agent spans manually:
from netra import Netra, SpanType

def run_agent(input: str):
    with Netra.start_span("planning-agent", as_type=SpanType.AGENT) as span:
        span.set_attribute("agent.input", input)

        result = execute_agent_logic(input)
        span.set_attribute("agent.output", result)
        span.set_success()

        return result
import { Netra, SpanType } from "netra-sdk";

async function runAgent(input: string) {
  const span = Netra.startSpan("planning-agent", {}, undefined, SpanType.AGENT);

  span.setAttribute("agent.input", input);

  try {
    const result = await executeAgentLogic(input);
    span.setAttribute("agent.output", result);
    span.setSuccess();
    return result;
  } catch (error) {
    span.setError(error.message);
    throw error;
  } finally {
    span.end();
  }
}

Agent with Tools

Track which tools your agent uses by nesting @task or SpanType.TOOL spans within agent spans:
from netra.decorators import agent, task

@agent(name="research-agent")
class ResearchAgent:
    @task(name="web-search")
    def search_web(self, query: str):
        return web_search_api.search(query)

    @task(name="summarize-results")
    def summarize(self, results: list):
        return llm.summarize(results)

    def research(self, topic: str):
        results = self.search_web(topic)
        return self.summarize(results)
import { agent, task } from "netra-sdk/decorators";

@agent({ name: "research-agent" })
class ResearchAgent {
  @task({ name: "web-search" })
  async searchWeb(query: string) {
    return await webSearchAPI.search(query);
  }

  @task({ name: "summarize-results" })
  async summarize(results: any[]) {
    return await llm.summarize(results);
  }

  async research(topic: string) {
    const results = await this.searchWeb(topic);
    return await this.summarize(results);
  }
}
The Tools modal in the Agents view will show call counts for web-search and summarize-results.

Best Practices

  1. Use descriptive agent names - Names like customer-support-agent or code-review-agent are more useful than agent1
  2. Nest tools within agents - Use @task for tools to track which tools each agent uses
  3. Add custom attributes - Include relevant context like input queries, user intent, or decision outcomes
  4. Use classes for stateful agents - The class decorator tracks all methods as part of the agent

Next Steps

Last modified on March 17, 2026