> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-merged-1773673439-f47cb10.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Build your first agent in minutes

This quickstart takes you from a simple setup to a fully functional AI agent in just a few minutes. A **deep agent** is a LangChain agent with batteries included—planning, file system tools, and subagents out of the box. Use deep agents when you want maximum capability with minimal setup; choose LangChain agents when you need fine-grained control.

<Tip>
  **LangChain Docs MCP server**

  If you're using an AI coding assistant or IDE (e.g. Claude Code or Cursor), you should install the [LangChain Docs MCP server](/use-these-docs) to get the most out of the docs. This ensures your agent has access to up-to-date LangChain documentation and examples.
</Tip>

## Install dependencies

<Tabs default="Deep agents">
  <Tab title="Deep agents">
    <CodeGroup>
      ```bash pip theme={null}
      pip install deepagents tavily-python
      ```

      ```bash uv theme={null}
      uv init
      uv add deepagents tavily-python
      uv sync
      ```
    </CodeGroup>
  </Tab>

  <Tab title="LangChain">
    <CodeGroup>
      ```bash pip theme={null}
      pip install -U langchain tavily-python
      # Requires Python 3.10+
      ```

      ```bash uv theme={null}
      uv add langchain tavily-python
      # Requires Python 3.10+
      ```
    </CodeGroup>
  </Tab>
</Tabs>

<Note>
  This guide uses [Tavily](https://tavily.com/) as an example search provider, but you can substitute any search API (e.g., DuckDuckGo, SerpAPI, Brave Search).
</Note>

## Set up API keys

Get an API key from [any supported model provider](/oss/python/integrations/providers/overview) (for example, Claude (Anthropic) or OpenAI).
If you are following along with the Tavily example, also get a Tavily API key.

Set the API keys, for example:

<CodeGroup>
  ```bash Claude (Anthropic) theme={null}
  export ANTHROPIC_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash OpenAI theme={null}
  export OPENAI_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash Google Gemini theme={null}
  export GOOGLE_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash OpenRouter theme={null}
  export OPENROUTER_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash Fireworks theme={null}
  export FIREWORKS_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash Baseten theme={null}
  export BASETEN_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash Ollama theme={null}
  # Local: Ollama must be running (https://ollama.com)
  # Cloud: Set your Ollama API key for hosted inference
  export OLLAMA_API_KEY="your-api-key"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash Azure theme={null}
  export AZURE_OPENAI_API_KEY="your-api-key"
  export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
  export AZURE_OPENAI_DEPLOYMENT_NAME="your-deployment"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash AWS Bedrock theme={null}
  export AWS_ACCESS_KEY_ID="your-access-key"
  export AWS_SECRET_ACCESS_KEY="your-secret-key"
  export AWS_REGION="us-east-1"
  export TAVILY_API_KEY="your-tavily-api-key"
  ```

  ```bash HuggingFace theme={null}
  export HUGGINGFACEHUB_API_TOKEN="hf_..."
  export TAVILY_API_KEY="your-tavily-api-key"
  ```
</CodeGroup>

## Build a basic agent

Start by creating a simple agent that can answer questions and call tools. The agent in this example uses the specified language model, a basic weather function as a tool, and a simple prompt to guide its behavior:

<Tabs default="Deep agents">
  <Tab title="Deep agents">
    <CodeGroup>
      ```python Claude (Anthropic) theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="claude-sonnet-4-6",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python OpenAI theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="openai:gpt-5.2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Google Gemini theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="google_genai:gemini-2.5-flash-lite",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python OpenRouter theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="openrouter:anthropic/claude-sonnet-4-6",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Fireworks theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Baseten theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="baseten:zai-org/GLM-5",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Ollama theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="ollama:devstral-2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Azure theme={null}
      import os
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="azure_openai:gpt-5.2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
          azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python AWS Bedrock theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="anthropic.claude-3-5-sonnet-20240620-v1:0",
          model_provider="bedrock_converse",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python HuggingFace theme={null}
      from deepagents import create_deep_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_deep_agent(
          model="microsoft/Phi-3-mini-4k-instruct",
          model_provider="huggingface",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
          temperature=0.7,
          max_tokens=1024,
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```
    </CodeGroup>

    <Tip>
      You can use any model that supports [tool calling](/oss/python/langchain/models#tool-calling) by changing the model name in the code and setting up the appropriate API key.
    </Tip>
  </Tab>

  <Tab title="LangChain">
    <CodeGroup>
      ```python Claude (Anthropic) theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="claude-sonnet-4-6",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python OpenAI theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="openai:gpt-5.2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Google Gemini theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="google_genai:gemini-2.5-flash-lite",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python OpenRouter theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="openrouter:anthropic/claude-sonnet-4-6",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Fireworks theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Baseten theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="baseten:zai-org/GLM-5",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ````python Ollama theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="ollama:devstral-2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```python OpenRouter
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="openrouter:anthropic/claude-sonnet-4-6",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ````

      ```python Fireworks theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Baseten theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="baseten:zai-org/GLM-5",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Ollama theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="ollama:devstral-2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python Azure theme={null}
      import os
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="azure_openai:gpt-5.2",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
          azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python AWS Bedrock theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="anthropic.claude-3-5-sonnet-20240620-v1:0",
          model_provider="bedrock_converse",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```

      ```python HuggingFace theme={null}
      from langchain.agents import create_agent

      def get_weather(city: str) -> str:
          """Get weather for a given city."""
          return f"It's always sunny in {city}!"

      agent = create_agent(
          model="microsoft/Phi-3-mini-4k-instruct",
          model_provider="huggingface",
          tools=[get_weather],
          system_prompt="You are a helpful assistant",
          temperature=0.7,
          max_tokens=1024,
      )

      agent.invoke(
          {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
      )
      ```
    </CodeGroup>

    <Tip>
      You can use [any supported model](/oss/python/integrations/providers/overview) by changing the model name in the code and setting up the appropriate API key.
    </Tip>
  </Tab>
</Tabs>

## Build a real-world agent

When building real-world agents, both LangChain and deep agents provide you with fine-grained control over tools, memory, and structured ouput.
The main difference between both is that deep agents come with a range of commonly useful capabilities already built in.

By following this example you will build a research agent that can conduct research and write reports.
Along the way you will explore the following concepts:

1. **Detailed system prompts** for better agent behavior
2. **Create tools** that integrate with external data
3. **Model configuration** for consistent responses
4. **Structured output** for predictable results
5. **Conversational memory** for chat-like interactions
6. **Testing** your agent and using tracing

<Steps>
  <Step title="Define the system prompt">
    The system prompt defines your agent’s role and behavior. Keep it specific and actionable:

    ```python wrap theme={null}
    SYSTEM_PROMPT = """You are an expert researcher. Your job is to conduct thorough research and then write a polished report.

    You have access to the following tools:

    ## `get_user_location`

    Use this first to retrieve the user's location based on their user ID. Call this before researching so you know where the user is located.

    ## `internet_search`

    Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included.
    """
    ```
  </Step>

  <Step title="Create tools">
    [Tools](/oss/python/langchain/tools) let a model interact with external systems by calling functions you define.
    Tools can depend on [runtime context](/oss/python/langchain/runtime) and also interact with [agent memory](/oss/python/langchain/short-term-memory).

    This example uses two tools, one for internet searches and one for obtaining the user's location based on their user ID.

    ```python theme={null}
    import os
    from typing import Literal
    from tavily import TavilyClient
    from langchain.tools import tool, ToolRuntime


    @dataclass
    class Context:
        """Custom runtime context schema."""
        user_id: str


    @tool
    def get_user_location(runtime: ToolRuntime[Context]) -> str:
        """Retrieve user information based on user ID."""
        user_id = runtime.context.user_id
        return "France" if user_id == "1" else "Netherlands"


    tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])

    def internet_search(
        query: str,
        max_results: int = 5,
        topic: Literal["general", "news", "finance"] = "general",
        include_raw_content: bool = False,
    ):
        """Run a web search"""
        return tavily_client.search(
            query,
            max_results=max_results,
            include_raw_content=include_raw_content,
            topic=topic,
        )

    ```

    <Tip>
      Tools should be well-documented: their name, description, and argument names become part of the model's prompt.
      LangChain's @\[`@tool` decorator]\[@tool] adds metadata and enables runtime injection with the `ToolRuntime` parameter.
    </Tip>
  </Step>

  <Step title="Configure your model">
    Set up your [language model](/oss/python/langchain/models) with the right parameters for your use case:

    ```python theme={null}
    from langchain.chat_models import init_chat_model

    model = init_chat_model(
        "claude-sonnet-4-6",
        temperature=0.5,
        timeout=10,
        max_tokens=1000
    )
    ```

    Depending on the model and provider chosen, initialization parameters may vary; refer to their reference pages for details.
  </Step>

  <Step title="Define response format">
    Optionally, define a structured response format if you need the agent responses to match
    a specific schema.

    ```python theme={null}
    from dataclasses import dataclass

    # We use a dataclass here, but Pydantic models are also supported.
    @dataclass
    class ResponseFormat:
        """Response schema for the agent."""
        # A one paragraph response (always required)
        one_paragraph_response: str
        # Any fun facts from the research report
        fun_facts: str | None = None
    ```
  </Step>

  <Step title="Add memory">
    Add [memory](/oss/python/langchain/short-term-memory) to your agent to maintain state across interactions. This allows
    the agent to remember previous conversations and context.

    ```python theme={null}
    from langgraph.checkpoint.memory import InMemorySaver

    checkpointer = InMemorySaver()
    ```

    <Info>
      In production, use a persistent checkpointer that saves message history to a database.
      See [Add and manage memory](/oss/python/langgraph/add-memory#manage-short-term-memory) for more details.
    </Info>
  </Step>

  <Step title="Create and run the agent">
    Now assemble your agent with all the components and run it:

    <Tabs default="Deep agents">
      <Tab title="Deep agents">
        ```python wrap theme={null}
        agent = create_deep_agent(
            model=model,
            tools=[get_user_location, internet_search],
            system_prompt=SYSTEM_PROMPT,
            response_format=ResponseFormat,
            context_schema=Context,
            checkpointer=checkpointer
        )

        content = "What is the capital of the user's location? First use get_user_location to find where the user is, then write a report in markdown format."

        # `thread_id` is a unique identifier for a given conversation.
        result = agent.invoke(
            {"messages": [{"role": "user", "content": content}]},
            config={"configurable": {"thread_id": "123456"}},
            context=Context(user_id="1"),  # "1" -> France, other -> Netherlands
        )
        print(result["messages"][-1].content)
        print("--------------------------------")
        print(result["structured_response"])
        print("--------------------------------")
        ```
      </Tab>

      <Tab title="LangChain agents">
        ```python wrap theme={null}
        from deepagents import create_deep_agent

        agent = create_deep_agent(
            model=model,
            tools=[get_user_location, internet_search],
            system_prompt=SYSTEM_PROMPT,
            response_format=ResponseFormat,
            context_schema=Context,
            checkpointer=checkpointer
        )

        content = "What is the capital of the user's location? First use get_user_location to find where the user is, then write a report in markdown format."

        # `thread_id` is a unique identifier for a given conversation.
        result = agent.invoke(
            {"messages": [{"role": "user", "content": content}]},
            config={"configurable": {"thread_id": "123456"}},
            context=Context(user_id="1"),  # "1" -> France, other -> Netherlands
        )
        print(result["messages"][-1].content)
        print("--------------------------------")
        print(result["structured_response"])
        print("--------------------------------")
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

<Expandable title="Full example code">
  <Tabs default="Deep agents">
    <Tab title="Deep agents">
      ```python theme={null}
      import os
      from typing import Literal
      from tavily import TavilyClient
      from deepagents import create_deep_agent
      from langchain.chat_models import init_chat_model
      from langchain.tools import tool, ToolRuntime
      from dataclasses import dataclass
      from langgraph.checkpoint.memory import InMemorySaver


      @dataclass
      class Context:
          """Custom runtime context schema."""
          user_id: str


      @tool
      def get_user_location(runtime: ToolRuntime[Context]) -> str:
          """Retrieve user information based on user ID."""
          user_id = runtime.context.user_id
          return "France" if user_id == "1" else "Netherlands"


      SYSTEM_PROMPT = """You are an expert researcher. Your job is to conduct thorough research and then write a polished report.

      You have access to the following tools:

      ## `get_user_location`

      Use this first to retrieve the user's location based on their user ID. Call this before researching so you know where the user is located.

      ## `internet_search`

      Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included."""

      tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])

      def internet_search(
          query: str,
          max_results: int = 5,
          topic: Literal["general", "news", "finance"] = "general",
          include_raw_content: bool = False,
      ):
          """Run a web search"""
          return tavily_client.search(
              query,
              max_results=max_results,
              include_raw_content=include_raw_content,
              topic=topic,
          )


      model = init_chat_model(
          "claude-sonnet-4-6",
          temperature=0.5,
          timeout=300,  # 5 min - agent does search + multiple model calls
          max_retries=0,  # prevents timeout multiplication (default 2 retries = 3x wait)
          max_tokens=1000
      )


      # We use a dataclass here, but Pydantic models are also supported.
      @dataclass
      class ResponseFormat:
          """Response schema for the agent."""
          # A one paragraph response (always required)
          one_paragraph_response: str
          # Any fun facts from the research report
          fun_facts: str | None = None


      checkpointer = InMemorySaver()

      agent = create_deep_agent(
          model=model,
          tools=[get_user_location, internet_search],
          system_prompt=SYSTEM_PROMPT,
          response_format=ResponseFormat,
          context_schema=Context,
          checkpointer=checkpointer
      )

      content = "What is the capital of the user's location? First use get_user_location to find where the user is, then write a report in markdown format."

      # `thread_id` is a unique identifier for a given conversation.
      result = agent.invoke(
          {"messages": [{"role": "user", "content": content}]},
          config={"configurable": {"thread_id": "123456"}},
          context=Context(user_id="1"),  # "1" -> France, other -> Netherlands
      )
      print(result["messages"][-1].content)
      print("--------------------------------")
      print(result["structured_response"])
      print("--------------------------------")
      ```
    </Tab>

    <Tab title="LangChain agents">
      ```python theme={null}
      import os
      from typing import Literal
      from tavily import TavilyClient
      from langchain.agents import create_agent
      from langchain.chat_models import init_chat_model
      from langchain.tools import tool, ToolRuntime
      from dataclasses import dataclass
      from langgraph.checkpoint.memory import InMemorySaver


      @dataclass
      class Context:
          """Custom runtime context schema."""
          user_id: str


      @tool
      def get_user_location(runtime: ToolRuntime[Context]) -> str:
          """Retrieve user information based on user ID."""
          user_id = runtime.context.user_id
          return "France" if user_id == "1" else "Netherlands"


      SYSTEM_PROMPT = """You are an expert researcher. Your job is to conduct thorough research and then write a polished report.

      You have access to the following tools:

      ## `get_user_location`

      Use this first to retrieve the user's location based on their user ID. Call this before researching so you know where the user is located.

      ## `internet_search`

      Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included."""

      tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])

      def internet_search(
          query: str,
          max_results: int = 5,
          topic: Literal["general", "news", "finance"] = "general",
          include_raw_content: bool = False,
      ):
          """Run a web search"""
          return tavily_client.search(
              query,
              max_results=max_results,
              include_raw_content=include_raw_content,
              topic=topic,
          )


      model = init_chat_model(
          "claude-sonnet-4-6",
          temperature=0.5,
          timeout=300,  # 5 min - agent does search + multiple model calls
          max_retries=0,  # prevents timeout multiplication (default 2 retries = 3x wait)
          max_tokens=1000
      )


      # We use a dataclass here, but Pydantic models are also supported.
      @dataclass
      class ResponseFormat:
          """Response schema for the agent."""
          # A one paragraph response (always required)
          one_paragraph_response: str
          # Any fun facts from the research report
          fun_facts: str | None = None


      checkpointer = InMemorySaver()

      agent = create_agent(
          model=model,
          tools=[get_user_location, internet_search],
          system_prompt=SYSTEM_PROMPT,
          response_format=ResponseFormat,
          context_schema=Context,
          checkpointer=checkpointer
      )

      content = "What is the capital of the user's location? First use get_user_location to find where the user is, then write a report in markdown format."

      # `thread_id` is a unique identifier for a given conversation.
      result = agent.invoke(
          {"messages": [{"role": "user", "content": content}]},
          config={"configurable": {"thread_id": "123456"}},
          context=Context(user_id="1"),  # "1" -> France, other -> Netherlands
      )
      print(result["messages"][-1].content)
      print("--------------------------------")
      print(result["structured_response"])
      print("--------------------------------")
      ```
    </Tab>
  </Tabs>
</Expandable>

## Test your agent

Start by running your script.
You may get different output than we did:

<Tabs default="Deep agents">
  <Tab title="Deep agents">
    ```python wrap theme={null}
    largest city in France**, situated in the north-central part of the country along the **Seine River**.\n\n---\n\n## 📍 Key Facts\n\n| Detail | Information |\n|---|---|\n| **Capital City** | Paris |\n| **Country** | France |\n| **Region** | Île-de-France |\n| **Population (City Proper)** | ~2.09 million (2024) |\n| **Area** | ~105 km² |\n| **River** | Seine |\n| **Government** | Mayor of Paris + Regional Council |\n\n---\n\n## 🏛️ Historical Background\n\n- **508 AD** — Paris first became the capital of France under **King Clovis I**, the first king of the Franks.\n- **1180–1223** — Paris solidified its status as the capital under **King Philippe Auguste**.\n- **1328** — Paris was already Europe\'s most populated city, with an estimated **200,000 inhabitants**.\n- **1528** — King Francis I returned the royal residence to Paris, making it the largest city in Western Europe.\n- **19th Century** — Paris underwent massive transformation under **Baron Haussmann**, creating the iconic wide boulevards seen today.\n- **1900s** — Paris reached a peak population of ~2.7 million and was the largest Catholic city in the world.\n\n---\n\n## 🌍 Paris as a World City\n\nParis is widely regarded as one of the world\'s most influential cities across multiple domains:\n\n- **Fashion & Luxury**: Home to iconic brands such as Chanel, Dior, Louis Vuitton, and Yves Saint Laurent.\n- **Culture & Arts**: Hosts world-renowned museums including the **Louvre**, **Musée d\'Orsay**, and the **Centre Pompidou**.\n- **Architecture**: Famous landmarks include the **Eiffel Tower**, **Notre-Dame Cathedral**, and the **Arc de Triomphe**.\n- **Literature**: Paris became the center of French literature as early as the **1600s**.\n- **Green Spaces**: The city boasts over **421 parks and gardens**.\n\n---\n\n## 🚇 Infrastructure\n\nParis is served by one of Europe\'s most comprehensive public transit systems, including the **Paris Métro**, the **RER** (regional express rail), and an extensive bus network — making it a model of urban mobility.\n\n---\n\n## 🏁 Conclusion\n\n**Paris** has served as the heart of France for over **1,500 years**. It is a global hub of culture, politics, fashion, and history — a city that continues to captivate millions of visitors and residents alike.\n\n> *"Paris is always a good idea."* — Audrey Hepburn', fun_facts='Paris is nicknamed "The City of Light" (La Ville Lumière), not just for its role in the Enlightenment, but also because it was one of the first cities in Europe to adopt gas street lighting in the early 19th century!')
    --------------------------------
    ResponseFormat(punny_response='# 🇫🇷 Capital of France: Paris\n\n## Overview\n\nBased on your location in **France**, the capital city is **Paris** — often called *"La Ville Lumière"* (The City of Light). Paris is not only the capital but also the **largest city in France**, situated in the north-central part of the country along the **Seine River**.\n\n---\n\n## 📍 Key Facts\n\n| Detail | Information |\n|---|---|\n| **Capital City** | Paris |\n| **Country** | France |\n| **Region** | Île-de-France |\n| **Population (City Proper)** | ~2.09 million (2024) |\n| **Area** | ~105 km² |\n| **River** | Seine |\n| **Government** | Mayor of Paris + Regional Council |\n\n---\n\n## 🏛️ Historical Background\n\n- **508 AD** — Paris first became the capital of France under **King Clovis I**, the first king of the Franks.\n- **1180–1223** — Paris solidified its status as the capital under **King Philippe Auguste**.\n- **1328** — Paris was already Europe\'s most populated city, with an estimated **200,000 inhabitants**.\n- **1528** — King Francis I returned the royal residence to Paris, making it the largest city in Western Europe.\n- **19th Century** — Paris underwent massive transformation under **Baron Haussmann**, creating the iconic wide boulevards seen today.\n- **1900s** — Paris reached a peak population of ~2.7 million and was the largest Catholic city in the world.\n\n---\n\n## 🌍 Paris as a World City\n\nParis is widely regarded as one of the world\'s most influential cities across multiple domains:\n\n- **Fashion & Luxury**: Home to iconic brands such as Chanel, Dior, Louis Vuitton, and Yves Saint Laurent.\n- **Culture & Arts**: Hosts world-renowned museums including the **Louvre**, **Musée d\'Orsay**, and the **Centre Pompidou**.\n- **Architecture**: Famous landmarks include the **Eiffel Tower**, **Notre-Dame Cathedral**, and the **Arc de Triomphe**.\n- **Literature**: Paris became the center of French literature as early as the **1600s**.\n- **Green Spaces**: The city boasts over **421 parks and gardens**.\n\n---\n\n## 🚇 Infrastructure\n\nParis is served by one of Europe\'s most comprehensive public transit systems, including the **Paris Métro**, the **RER** (regional express rail), and an extensive bus network — making it a model of urban mobility.\n\n---\n\n## 🏁 Conclusion\n\n**Paris** has served as the heart of France for over **1,500 years**. It is a global hub of culture, politics, fashion, and history — a city that continues to captivate millions of visitors and residents alike.\n\n> *"Paris is always a good idea."* — Audrey Hepburn', fun_facts='Paris is nicknamed "The City of Light" (La Ville Lumière), not just for its role in the Enlightenment, but also because it was one of the first cities in Europe to adopt gas street lighting in the early 19th century!')
    ```
  </Tab>

  <Tab title="LangChain agents">
    ```python wrap theme={null}
    Returning structured response: ResponseFormat(one_paragraph_response="Paris is the capital of France, located in the north-central part of the country along the Seine River. It has been the capital since 508 AD under King Clovis I, making it one of the oldest and most historically significant capitals in the world. With a population of over 2.2 million in the city proper and a rich cultural heritage, Paris is a global hub for politics, art, fashion, and tourism. It is home to iconic landmarks such as the Eiffel Tower, the Louvre (the world's largest museum), Notre-Dame Cathedral, and the Arc de Triomphe.", fun_facts='1. Paris was originally called "Lutetia" by the Romans before being renamed in the 4th century. 2. The Louvre in Paris is the largest museum in the world, with nearly 73,000 square metres of exhibition space. 3. Paris has hosted the Summer Olympics three times: in 1900, 1924, and 2024. 4. The Lumière brothers presented the world\'s first projected moving pictures to a paying audience in Paris in December 1895. 5. The Statue of Liberty was gifted to the United States and first presented in Paris on July 4, 1884.')
    --------------------------------
    ResponseFormat(one_paragraph_response="Paris is the capital of France, located in the north-central part of the country along the Seine River. It has been the capital since 508 AD under King Clovis I, making it one of the oldest and most historically significant capitals in the world. With a population of over 2.2 million in the city proper and a rich cultural heritage, Paris is a global hub for politics, art, fashion, and tourism. It is home to iconic landmarks such as the Eiffel Tower, the Louvre (the world's largest museum), Notre-Dame Cathedral, and the Arc de Triomphe.", fun_facts='1. Paris was originally called "Lutetia" by the Romans before being renamed in the 4th century. 2. The Louvre in Paris is the largest museum in the world, with nearly 73,000 square metres of exhibition space. 3. Paris has hosted the Summer Olympics three times: in 1900, 1924, and 2024. 4. The Lumière brothers presented the world\'s first projected moving pictures to a paying audience in Paris in December 1895. 5. The Statue of Liberty was gifted to the United States and first presented in Paris on July 4, 1884.')
    --------------------------------
    ```
  </Tab>
</Tabs>

If you look at the output on both tabs, you notice an immediate difference in the structure and length of the responses.

A deep agent automatically:

1. **Plans its approach** using the built-in [`write_todos`](/oss/python/deepagents/harness#planning-capabilities) tool to break down the research task.
2. **Conducts research** by calling the `internet_search` tool to gather information.
3. **Manages context** by using file system tools ([`write_file`](/oss/python/deepagents/harness#virtual-filesystem-access), [`read_file`](/oss/python/deepagents/harness#virtual-filesystem-access)) to offload large search results.
4. **Spawns subagents** as needed to delegate complex subtasks to specialized subagents.
5. **Synthesizes a report** to compile findings into a coherent response.

For LangChain agents, you must implement more capabilities to get a similar level of service and can customize them along the way as needed.

## Trace agent calls

Most interesting applications you build with LangChain make many calls to LLMs. As these applications get more complex, it becomes important to be able to inspect what exactly is going on inside your agent. The best way to do this is with [LangSmith](https://smith.langchain.com).

Sign up for a [LangSmith](https://smith.langchain.com) account and set these to start logging traces:

```shell theme={null}
export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."
```

Once set, run your script again and then inspect what happened during your agent calls on [LangSmith](https://smith.langchain.com) .

<Tip>
  To learn more about tracing your agent with LangSmith, see the [LangSmith documentation](/langsmith/trace-with-langchain).
</Tip>

## Next steps

You now have agents that can:

* **Understand context** and remember conversations
* **Use tools** intelligently
* **Provide structured responses** in a consistent format
* **Handle user-specific information** through context
* **Maintain conversation state** across interactions
* **Plan, research, and synthesize** (deep agents only)

Continue with:

* **LangChain agents**: [Add and manage memory](/oss/python/langgraph/add-memory#manage-short-term-memory), [deploy to production](/oss/python/langgraph/deploy)
* **Deep agents**: [Customization options](/oss/python/deepagents/customization), [persistent memory](/oss/python/deepagents/long-term-memory), [deploy to production](/oss/python/langgraph/deploy)

***

<div className="source-links">
  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/oss/langchain/quickstart.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>

  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>
</div>
