Deep AgentsDeep Agents 0.7 · Python 3.11+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →

create_deep_agent: your first deep agent

create_deep_agent is the function that builds a deep agent: it takes a model, your tools and a system prompt, adds the built-in file and subagent tools, and returns an agent you run with invoke.

Last updated: 29 Sep, 2026 · Deep Agents 0.7

Creating a deep agent with create_deep_agent · from the Complete Deep Agents Course With LangChain · 31:27 to 35:52
The video loads groq:qwen/qwen3-32b, which Groq has since retired. The page runs the same code on groq:openai/gpt-oss-120b, with temperature=0 and max_retries=6 as in every lesson.

The video's first deep agent

The video imports create_deep_agent from deepagents and passes three things: tools=[web_search], a system prompt, "Act as a researcher", and a model. The model comes from init_chat_model, which loads any provider's chat model from a provider:model string; the video uses Groq's qwen3-32b. A first try fails with an unexpected keyword models; the argument is model.

Start research.py with web_search, the Tavily tool from Tools: a travel search the agent can call. It needs tavily-python and a TAVILY_API_KEY, both set up there. The agent below also needs GROQ_API_KEY from Installation and setup.

python
import os
from tavily import TavilyClient
from typing import Literal

tavily_client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))

def web_search(query: str, max_results: int = 5,
               topic: Literal["general", "sports", "news", "finance"] = "general"):
    """Run a web search"""
    return tavily_client.search(query, max_results=min(max_results, 5), topic=topic)

Then the video's agent, on the course model:

python
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)

deepagent = create_deep_agent(
    model=model,
    tools=[web_search],
    system_prompt="Act as a researcher",
)
Invoking the agent and reading the result · from the Complete Deep Agents Course With LangChain · 38:15 to 41:10
The video says the agent first makes a to-do list for this question. On 0.7 there is no write_todos tool unless you add TodoListMiddleware, which write_todos: planning with TodoListMiddleware does.

It runs the agent with invoke and a dictionary whose messages key holds the conversation, one message with "role": "user" and the question "What is deepagent?". The run takes a while because the agent searches the web. result["messages"][-1].content is the answer; in the saved notebook it describes DeepAgent, a 2025 research paper found through the search.

The same agent runs below on Groq. Add the call to the end of research.py. The loop prints each step shortened, then the answer in full, as the video prints it, then the files in the agent's state.

ExampleAPI keyFrom the video, run on Groq
result = deepagent.invoke({"messages": [{"role": "user", "content": "What is deepagent?"}]})

for message in result["messages"][:-1]:     # the steps, shortened
    print(f"{message.type:<5}", message.text[:120] or [(c["name"], c["args"]) for c in message.tool_calls])
print(result["messages"][-1].content)       # the answer, as the video prints it
print("files:", list(result["files"]))

What the research agent did

  • One search: the model called web_search with a query it wrote itself, "DeepAgent framework deep reinforcement learning". Its extra topn argument is not one the function takes, and the call ran with the defaults.
  • The tool message is Tavily's JSON: the query, then a list of results, each with a URL, a title and an extract.
  • The answer describes DeepAgent, the research paper arXiv 2510.21618, which is also what the video's run found. It is long, and not every detail in it can be traced to the results; the prompt "Act as a researcher" does not ask the model to stay with its sources, as the course's own prompts do.
  • files is empty: the results were small enough to stay in the conversation, so nothing was offloaded to a file.
  • Search results change from day to day, so your run will find other pages and word its answer differently.

The rest of this lesson builds the same shape on the travel catalog, whose answers can be checked line by line.

The create_deep_agent call

python
agent = create_deep_agent(model=model, tools=[my_tool], system_prompt="...")
result = agent.invoke({"messages": [{"role": "user", "content": "..."}]})
result["messages"][-1].text   # the final answer

The model

Start trip.py with search_travel, the catalog tool from Tools: a travel search the agent can call. Everything below goes in the same file, under it. Then create the model. temperature=0 keeps the replies steady from run to run.

python
from langchain.tools import tool

CATALOG = {
    "paris": {
        "flight": ["Return flight Delhi to Paris: 42,000 rupees"],
        "hotel": ["Seine Budget Inn, Latin Quarter: 5,200 rupees a night",
                  "Hotel Lumiere, Montmartre: 7,500 rupees a night",
                  "Le Grand Opera Hotel: 16,000 rupees a night"],
        "sight": ["Eiffel Tower summit: 3,100 rupees", "Louvre Museum: 2,000 rupees",
                  "Seine river cruise: 1,500 rupees", "Versailles day trip: 2,600 rupees",
                  "Montmartre walking tour: free"],
        "food": ["Cafe breakfast and bistro dinner: 3,000 rupees a day"],
    },
}


@tool
def search_travel(city: str, kind: str) -> str:
    """Search the travel catalog. kind is "flight", "hotel", "sight" or "food". Prices are in rupees."""
    entries = CATALOG.get(city.lower(), {}).get(kind)
    return "\n".join(entries) if entries else f"The catalog has no {kind} entries for {city}."
python
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)

The agent

The system prompt makes this agent a travel planner and tells it to use only what the catalog returns, so the answer cannot drift into prices the model remembers from training.

python
agent = create_deep_agent(
    model=model,
    tools=[search_travel],
    system_prompt="You are a travel planner. Look up every price with search_travel and use only "
                  "what it returns. Answer in two short sentences.",
)

Running the agent on a hotel question

Add the call and a loop that prints every message of the run: its type, then its text, or the tool it asked for.

ExampleAPI keytrip.py, continued
result = agent.invoke({"messages": [{"role": "user", "content": "What is the cheapest hotel in Paris?"}]})

for message in result["messages"]:
    print(f"{message.type:<5}", message.text or [(c["name"], c["args"]) for c in message.tool_calls])

Reading the four messages

  • human: the question you sent.
  • ai with a tool call: the model did not answer yet. It asked for search_travel with city Paris and kind hotel, arguments it chose from the docstring.
  • tool: the agent ran the function and added its result to the conversation.
  • ai with text: the model read the result and answered. A reply with no tool call ends the run.
  • The loop that ran is the same one create_agent, LangChain's plain agent builder compared in the next lesson, runs. What makes the agent "deep" is what create_deep_agent adds around it, the subject of the next lesson.

create_deep_agent vs calling the model yourself

model.invokecreate_deep_agent
ToolsThe model can only ask for themThe agent runs them and loops
InputA string or a list of messagesA dictionary with a messages key
OutputOne AI messageThe whole conversation, plus files and other state

When to reach for create_deep_agent

  • A job that needs more than one tool call, such as comparing hotels and sights before answering.
  • Work that should leave files behind: notes, a plan, a report.
  • Tasks you may later split between subagents or put behind approval.
Watch out. Pass the conversation as {"messages": [...]}. Passing the question string on its own fails, because the agent's input is its whole state, not one message.
Try it yourself
  • Ask "Which Paris sight is free?" and read the tool call's kind argument.
  • Ask about Tokyo and check that the answer says the catalog has nothing.
  • Remove "Answer in two short sentences" from the prompt and compare the length of the reply.

Slow is fine. Stopping is the only problem.