examples/deep_research/research_agent.ipynb
from dotenv import load_dotenv
load_dotenv(".env", override=True)
%load_ext autoreload
%autoreload 2
We will use the deepagents package to create a research agent. When using the deepagents package, it's important to:
You can see an overview of the native tools in the deepagents package README as well as the quickstarts README. We'll extend this with two task-specific tools.
There are different search tools that we can use. For example, we can use Tavily to search for relevant URLs, then fetches the full webpage content.
We'll supply a think tool, which is a useful way to help audit agent decision making.
from research_agent.tools import tavily_search, think_tool
tools = [tavily_search, think_tool]
Next, let's define task specific instructions using a few prompting techniques for agents:
What instructions would you give a new work colleague?
Use Hard Limits to prevent the research agent from calling tools excessively:
After each search tool calling, use think_tool to analyze the results:
from datetime import datetime
from utils import show_prompt, format_messages
from research_agent.prompts import (
RESEARCHER_INSTRUCTIONS,
RESEARCH_WORKFLOW_INSTRUCTIONS,
SUBAGENT_DELEGATION_INSTRUCTIONS,
)
show_prompt(RESEARCHER_INSTRUCTIONS)
You can specify custom subagents as a means of context isolation.
Here's well define a sub-agent that can search the web for information.
# Get current date
current_date = datetime.now().strftime("%Y-%m-%d")
# Create research sub-agent
research_sub_agent = {
"name": "research-agent",
"description": "Delegate research to the sub-agent researcher. Only give this researcher one topic at a time.",
"system_prompt": RESEARCHER_INSTRUCTIONS.format(date=current_date),
"tools": [tavily_search, think_tool],
}
Now, we can look at all of our instructions together.
# Limits
max_concurrent_research_units = 3
max_researcher_iterations = 3
# Combine orchestrator instructions (RESEARCHER_INSTRUCTIONS only for sub-agents)
INSTRUCTIONS = (
RESEARCH_WORKFLOW_INSTRUCTIONS
+ "\n\n"
+ "=" * 80
+ "\n\n"
+ SUBAGENT_DELEGATION_INSTRUCTIONS.format(
max_concurrent_research_units=max_concurrent_research_units,
max_researcher_iterations=max_researcher_iterations,
)
)
show_prompt(INSTRUCTIONS)
Now, we create our deepagent with these components.
from IPython.display import Image, display
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model
from langchain_google_genai import ChatGoogleGenerativeAI
# Model Gemini 3
model = ChatGoogleGenerativeAI(model="gemini-3-pro-preview")
# Model Claude 4.5
model = init_chat_model(model="anthropic:claude-sonnet-4-5-20250929", temperature=0.0)
# Create the agent
agent = create_deep_agent(
model=model,
tools=tools,
system_prompt=INSTRUCTIONS,
subagents=[research_sub_agent],
)
# Show the agent
display(Image(agent.get_graph().draw_mermaid_png()))
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "research context engineering approaches used to build AI agents",
}
],
},
)
format_messages(result["messages"])
from deepagents.backends.utils import file_data_to_string
# Convert a specific file to string
file_content = file_data_to_string(result["files"]['/final_report.md'])
show_prompt(file_content)
Trace:
https://smith.langchain.com/public/72d23852-4616-4bcc-8d8a-b0d1905c945b/r