Skip to main content
deepagents is an open-source agent framework built on top of LangGraph, designed for complex, multi-step tasks that require planning, tool usage, and sub-agent delegation. Deep agents supports native LangSmith tracing. This guide shows you how to enable LangSmith tracing for deep agents, view traces in the LangSmith UI, and (optionally) customize trace configuration for more advanced use cases.

Installation

Install deepagents in your Python environment:
pip install deepagents
deepagents requires:
  • Python 3.11+.
  • An LLM that supports tool calling (for example, OpenAI or Anthropic models).
  • For tracing, a LangSmith account and API key (free to sign up).
You do not need to install the langsmith Python package to trace deep agents. deepagents is built on LangGraph, which includes native LangSmith tracing support. As long as the LangSmith environment variables are set, traces are sent automatically.The langsmith package is only required if you want programmatic control over tracing (for example, using tracing_context, adding custom metadata, or querying runs from Python).

Setup

You can find your LangSmith API key and project name in the LangSmith UI under Settings:
export LANGSMITH_API_KEY=<your-langsmith-api-key>
export LANGSMITH_TRACING=true
export LANGSMITH_PROJECT=<your-project-name>

Create a trace

Once tracing is enabled via environment variables, Deep Agents will automatically emit traces to LangSmith. For example:
from typing import Dict, Any, List

from deepagents import create_deep_agent


def compute_compound_interest(
    principal: float,
    annual_rate: float,
    years: int,
    compounds_per_year: int,
) -> Dict[str, Any]:
    """Compute compound interest and return ending balance and interest earned."""
    r = annual_rate
    n = compounds_per_year
    t = years
    amount = principal * (1 + r / n) ** (n * t)
    interest = amount - principal
    return {
        "principal": principal,
        "annual_rate": annual_rate,
        "years": years,
        "compounds_per_year": n,
        "ending_balance": round(amount, 2),
        "interest_earned": round(interest, 2),
    }


def yearly_balance_schedule(
    principal: float,
    annual_rate: float,
    years: int,
    compounds_per_year: int,
) -> List[Dict[str, Any]]:
    """Return a year-by-year balance schedule for the investment."""
    r = annual_rate
    n = compounds_per_year
    schedule: List[Dict[str, Any]] = []

    for year in range(1, years + 1):
        amount = principal * (1 + r / n) ** (n * year)
        schedule.append(
            {
                "year": year,
                "ending_balance": round(amount, 2),
                "interest_earned": round(amount - principal, 2),
            }
        )

    return schedule


agent = create_deep_agent(
    tools=[compute_compound_interest, yearly_balance_schedule],
    system_prompt=(
        "You are a careful assistant. "
        "Use tools for calculations and structured outputs. "
        "Return a concise final answer."
    ),
)

result = agent.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": (
                    "I have $2,500 invested at 6% annual interest compounded monthly for 5 years.\n"
                    "1) Compute the ending balance and total interest earned.\n"
                    "2) Generate a year-by-year ending balance schedule.\n"
                    "Then summarize the key takeaways in 3 bullets.\n\n"
                    "Use compounds_per_year=12."
                ),
            }
        ]
    }
)

print(result)
Your trace tree in the LangSmith UI will show the following structure:
  • Agent run (top level) representing the full Deep Agents invocation.
  • LLM call where the agent analyzes the user request and decides which tools to use.
  • Tool run: compute_compound_interest:
    • Displays the tool inputs (for example, principal, annual_rate, years, and compounds_per_year).
    • Displays the structured output, including the ending balance and total interest earned.
  • LLM call that interprets the calculation results and determines the next step.
  • Tool run: yearly_balance_schedule:
    • Shows the inputs used to generate the schedule.
    • Returns a year-by-year breakdown of ending balances and interest earned.
  • Final LLM response that summarizes the results for the user.
The resulting trace contains multiple nested spans, which allows you to follow the agent’s planning, calculation steps, and interpretation flow in the LangSmith UI.

Customize LangSmith tracing

By default, Deep Agents traces are emitted automatically when LangSmith tracing is enabled via environment variables. You can use the LangSmith SDK directly to customize your tracing, such as scoping traces to part of your code, attaching tags or metadata, or overriding the project name. Install and use langsmith if you want to:
  • Trace only specific agent invocations.
  • Add custom tags or metadata for filtering in the UI.
  • Override the project name at runtime.
pip install langsmith
This example invokes the same deep agent twice:
  • The first invocation is untraced, because it runs outside of tracing_context.
  • The second invocation is traced, because it runs inside tracing_context(enabled=True, ...).
You can selectively trace only part of your workflow, without enabling global tracing for your entire process with LANGSMITH_TRACING=true:
from typing import Dict, Any, List

import langsmith as ls
from deepagents import create_deep_agent


def compute_compound_interest(
    principal: float,
    annual_rate: float,
    years: int,
    compounds_per_year: int,
) -> Dict[str, Any]:
    """Compute compound interest and return ending balance and interest earned."""
    r = annual_rate
    n = compounds_per_year
    t = years
    amount = principal * (1 + r / n) ** (n * t)
    interest = amount - principal
    return {
        "principal": principal,
        "annual_rate": annual_rate,
        "years": years,
        "compounds_per_year": n,
        "ending_balance": round(amount, 2),
        "interest_earned": round(interest, 2),
    }


def yearly_balance_schedule(
    principal: float,
    annual_rate: float,
    years: int,
    compounds_per_year: int,
) -> List[Dict[str, Any]]:
    """Return a year-by-year balance schedule for the investment."""
    r = annual_rate
    n = compounds_per_year
    schedule: List[Dict[str, Any]] = []

    for year in range(1, years + 1):
        amount = principal * (1 + r / n) ** (n * year)
        schedule.append(
            {
                "year": year,
                "ending_balance": round(amount, 2),
                "interest_earned": round(amount - principal, 2),
            }
        )

    return schedule


agent = create_deep_agent(
    tools=[compute_compound_interest, yearly_balance_schedule],
    system_prompt=(
        "You are a careful assistant. "
        "Use tools for calculations and structured outputs. "
        "Return a concise final answer."
    ),
)

# ----------------------------
# Untraced invocation
# ----------------------------
agent.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": (
                    "I have $2,500 invested at 6% annual interest compounded monthly for 5 years. "
                    "Compute the ending balance and total interest earned. "
                    "Use compounds_per_year=12."
                ),
            }
        ]
    }
)

# ----------------------------
# Traced invocation
# ----------------------------
with ls.tracing_context(
    enabled=True,
    project_name="deepagents-demo",
    tags=["deepagents", "scoped-tracing"],
    metadata={"example": "partial-workflow"},
):
    agent.invoke(
        {
            "messages": [
                {
                    "role": "user",
                    "content": (
                        "I have $2,500 invested at 6% annual interest compounded monthly for 5 years.\n"
                        "1) Compute the ending balance and total interest earned.\n"
                        "2) Generate a year-by-year ending balance schedule.\n"
                        "Then summarize the key takeaways in 3 bullets.\n\n"
                        "Use compounds_per_year=12."
                    ),
                }
            ]
        }
    )
The tracing_context block enables tracing and also configures how the trace is recorded and organized in LangSmith:
  • enabled=True explicitly enables tracing for the duration of the block, even if LANGSMITH_TRACING is unset or set to false.
  • project_name="deepagents-demo" routes traces from this block to the specified LangSmith project. This overrides LANGSMITH_PROJECT for runs created within the context.
  • tags=[...] attaches tags to the traced runs. Tags appear in the LangSmith UI, which you can use to filter and group traces.
  • metadata={...} attaches arbitrary structured metadata (for example, environment, experiment name, or feature flag).
In this example, the agent is invoked twice, but only the invocation inside tracing_context is recorded. This demonstrates how you can selectively trace specific parts of a Deep Agents workflow without enabling global tracing for the entire process.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.