From 7dc01fa3f5aae4d44b4e70bd44c391831049373f Mon Sep 17 00:00:00 2001 From: ryaneggz Date: Mon, 4 Aug 2025 17:34:19 -0500 Subject: [PATCH 1/8] Updates the README with steps for altering the research_agent.py --- README.md | 56 ++++++++++++++++++++++++++++ examples/research/research_agent.py | 57 ++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d3e938902..7b02f22ca4 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,62 @@ You can also specify [custom sub agents](#subagents--optional-) with their own i Sub agents are useful for ["context quarantine"](https://www.dbreunig.com/2025/06/26/how-to-fix-your-context.html#context-quarantine) (to help not pollute the overall context of the main agent) as well as custom instructions. +## Passing Custom Model + +The `create_deep_agent` function can be passed a compatible Langchain `BaseChatModel`. To run a local Ollama model via Docker: + +```bash +# Run Ollama and enable all local GPUs +docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama + +# Pull local image +docker exec -it ollama bash +ollama pull qwen3 +exit + +# View Ollama Logs +docker logs -f ollama --tail 2000 + +# Test initial query +curl http://localhost:11434/api/chat -d '{ + "model": "qwen3", + "messages": [ + { "role": "user", "content": "why is the sky blue?" } + ] +}' +``` + +Below are the modifications to the **examples/research/research_agent.py** example. + +(To run the example below, will need to `pip install langchain-ollama`) + +```python +from deepagents import create_deep_agent +from langchain.chat_models import init_chat_model + +# ...examples/research/research_agent.py agent definitions + +# Create agent +agent = create_deep_agent( + tools=[internet_search], + instructions=research_instructions, + subagents=[critique_sub_agent, research_sub_agent], + model=init_chat_model( + model="ollama:qwen3:14b", + temperature=0.0, + max_tokens=40_000, # 📝 See "context" column: https://ollama.com/library/qwen3 + ) +).with_config({"recursion_limit": 1000}) + +# Stream the agent +for chunk in agent.stream( + {"messages": [{"role": "user", "content": "what is langgraph?"}]}, + stream_mode="values" +): + if "messages" in chunk: + chunk["messages"][-1].pretty_print() +``` + ## Roadmap [] Allow users to customize full system prompt [] Code cleanliness (type hinting, docstrings, formating) diff --git a/examples/research/research_agent.py b/examples/research/research_agent.py index 9b3653efa5..79548ff516 100644 --- a/examples/research/research_agent.py +++ b/examples/research/research_agent.py @@ -1,10 +1,43 @@ import os +import logging from typing import Literal +from datetime import datetime +from dotenv import load_dotenv +from langchain.chat_models import init_chat_model +from deepagents import create_deep_agent from tavily import TavilyClient -from deepagents import create_deep_agent, SubAgent +load_dotenv() + +# ─── Prepare logs directory ──────────────────────────────────────────────────── +logs_dir = "logs" +os.makedirs(logs_dir, exist_ok=True) + +# Generate a new filename for this run +timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") +log_filename = os.path.join(logs_dir, f"agent_{timestamp}.log") + +# ─── Configure Logging ───────────────────────────────────────────────────────── +logger = logging.getLogger("agent_logger") +logger.setLevel(logging.INFO) + +formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", + "%Y-%m-%d %H:%M:%S") + +# File handler → writes to a fresh file each run +file_handler = logging.FileHandler(log_filename, mode="w", encoding="utf-8") +file_handler.setLevel(logging.INFO) +file_handler.setFormatter(formatter) + +# Console handler → still prints live to stdout +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.INFO) +console_handler.setFormatter(formatter) + +logger.addHandler(file_handler) +logger.addHandler(console_handler) # Search tool to use to do research @@ -155,9 +188,29 @@ def internet_search( Use this to run an internet search for a given query. You can specify the number of results, the topic, and whether raw content should be included. """ + # Create the agent agent = create_deep_agent( [internet_search], research_instructions, subagents=[critique_sub_agent, research_sub_agent], -).with_config({"recursion_limit": 1000}) + model=init_chat_model( + model="ollama:qwen3:14b", + temperature=0.0, + max_tokens=40000, + ) +).with_config({"recursion_limit": 100}) + + +# Stream the agent +result = agent.stream({"messages": [{"role": "user", "content": "Provide a summary of https://github.com/hwchase17/deepagents. Review the README, Code, and Social Media."}]}) + +for chunk in result: + if "agent" in chunk: + msg = chunk["agent"]["messages"][0].content.strip() + logger.info("=== Agent Message ===\n%s", msg) + if "tools" in chunk: + call = chunk["tools"]["messages"][0].content.strip() + logger.info("+++ Tool Call +++\n%s", call) + +logger.info("Finished streaming. Log saved to %s", log_filename) From 7c3e68b175a5d93c9023e5b01ce23795777d0c8d Mon Sep 17 00:00:00 2001 From: ryaneggz Date: Mon, 4 Aug 2025 19:45:54 -0500 Subject: [PATCH 2/8] Restore research_agent.py to init state, remove changes from https://github.com/hwchase17/deepagents/pull/14 --- examples/research/research_agent.py | 67 ++++------------------------- 1 file changed, 8 insertions(+), 59 deletions(-) diff --git a/examples/research/research_agent.py b/examples/research/research_agent.py index 79548ff516..340ff867e1 100644 --- a/examples/research/research_agent.py +++ b/examples/research/research_agent.py @@ -1,43 +1,10 @@ import os -import logging from typing import Literal -from datetime import datetime -from dotenv import load_dotenv -from langchain.chat_models import init_chat_model -from deepagents import create_deep_agent from tavily import TavilyClient -load_dotenv() - -# ─── Prepare logs directory ──────────────────────────────────────────────────── -logs_dir = "logs" -os.makedirs(logs_dir, exist_ok=True) - -# Generate a new filename for this run -timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") -log_filename = os.path.join(logs_dir, f"agent_{timestamp}.log") - -# ─── Configure Logging ───────────────────────────────────────────────────────── -logger = logging.getLogger("agent_logger") -logger.setLevel(logging.INFO) - -formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", - "%Y-%m-%d %H:%M:%S") - -# File handler → writes to a fresh file each run -file_handler = logging.FileHandler(log_filename, mode="w", encoding="utf-8") -file_handler.setLevel(logging.INFO) -file_handler.setFormatter(formatter) - -# Console handler → still prints live to stdout -console_handler = logging.StreamHandler() -console_handler.setLevel(logging.INFO) -console_handler.setFormatter(formatter) - -logger.addHandler(file_handler) -logger.addHandler(console_handler) +from deepagents import create_deep_agent, SubAgent # Search tool to use to do research @@ -60,12 +27,15 @@ def internet_search( sub_research_prompt = """You are a dedicated researcher. Your job is to conduct research based on the users questions. -Conduct thorough research and then reply to the user with a detailed answer to their question""" +Conduct thorough research and then reply to the user with a detailed answer to their question + +only your FINAL answer will be passed on to the user. They will have NO knowledge of anything expect your final message, so your final report should be your final message!""" research_sub_agent = { "name": "research-agent", "description": "Used to research more in depth questions. Only give this researcher one topic at a time. Do not pass multiple sub questions to this researcher. Instead, you should break down a large topic into the necessary components, and then call multiple research agents in parallel, one for each sub question.", "prompt": sub_research_prompt, + "tools": ["internet_search"] } sub_critique_prompt = """You are a dedicated editor. You are being tasked to critique a report. @@ -115,9 +85,8 @@ def internet_search( -CRITICAL: Make sure the answer is written in the same language as the human messages! -For example, if the user's messages are in English, then MAKE SURE you write your response in English. If the user's messages are in Chinese, then MAKE SURE you write your entire response in Chinese. -This is critical. The user will only understand the answer if it is written in the same language as their input message. +CRITICAL: Make sure the answer is written in the same language as the human messages! If you make a todo plan - you should note in the plan what language the report should be in so you dont forget! +Note: the language the report should be in is the language the QUESTION is in, not the language/country that the question is ABOUT. Please create a detailed answer to the overall research brief that: 1. Is well-organized with proper headings (# for title, ## for sections, ### for subsections) @@ -188,29 +157,9 @@ def internet_search( Use this to run an internet search for a given query. You can specify the number of results, the topic, and whether raw content should be included. """ - # Create the agent agent = create_deep_agent( [internet_search], research_instructions, subagents=[critique_sub_agent, research_sub_agent], - model=init_chat_model( - model="ollama:qwen3:14b", - temperature=0.0, - max_tokens=40000, - ) -).with_config({"recursion_limit": 100}) - - -# Stream the agent -result = agent.stream({"messages": [{"role": "user", "content": "Provide a summary of https://github.com/hwchase17/deepagents. Review the README, Code, and Social Media."}]}) - -for chunk in result: - if "agent" in chunk: - msg = chunk["agent"]["messages"][0].content.strip() - logger.info("=== Agent Message ===\n%s", msg) - if "tools" in chunk: - call = chunk["tools"]["messages"][0].content.strip() - logger.info("+++ Tool Call +++\n%s", call) - -logger.info("Finished streaming. Log saved to %s", log_filename) +).with_config({"recursion_limit": 1000}) \ No newline at end of file From d00262d53e203ad202433ad6390e1071f60e0cef Mon Sep 17 00:00:00 2001 From: ryaneggz Date: Mon, 4 Aug 2025 20:30:00 -0500 Subject: [PATCH 3/8] Add newline to get rid of change --- examples/research/research_agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/research/research_agent.py b/examples/research/research_agent.py index 340ff867e1..82867c2aa8 100644 --- a/examples/research/research_agent.py +++ b/examples/research/research_agent.py @@ -162,4 +162,4 @@ def internet_search( [internet_search], research_instructions, subagents=[critique_sub_agent, research_sub_agent], -).with_config({"recursion_limit": 1000}) \ No newline at end of file +).with_config({"recursion_limit": 1000}) From 5e774fb7aac2f58f638db29f077d40dc94aeccbf Mon Sep 17 00:00:00 2001 From: ryaneggz Date: Mon, 4 Aug 2025 20:36:32 -0500 Subject: [PATCH 4/8] Reorg --- README.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ac59f7360a..3dad666402 100644 --- a/README.md +++ b/README.md @@ -127,17 +127,10 @@ agent = create_deep_agent( ### `model` (Optional) By default, `deepagents` will use `"claude-sonnet-4-20250514"`. If you want to use a different model, -you can pass a [LangChain model object](https://python.langchain.com/docs/integrations/chat/). For more cost effective local testing models like `ollama:qwen3` are availble from [langchain-ollama](https://github.com/langchain-ai/langchain/blob/master/libs/partners/ollama/README.md) due to their tool calling capabilities. - -```bash -# Run Ollama and enable local GPUs -docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama -``` +you can pass a [LangChain model object](https://python.langchain.com/docs/integrations/chat/). Below are the modifications to the **examples/research/research_agent.py** example. -(To run the example below, will need to `pip install langchain-ollama`) - ```python from deepagents import create_deep_agent from langchain.chat_models import init_chat_model @@ -149,14 +142,32 @@ agent = create_deep_agent( tools=[internet_search], instructions=research_instructions, subagents=[critique_sub_agent, research_sub_agent], + # Pass custom model model=init_chat_model( - model="ollama:qwen3:14b", + model="ollama:qwen3:14b", # pip install langchain-ollama temperature=0.0, max_tokens=40_000, # 📝 See "context" column: https://ollama.com/library/qwen3 ) ).with_config({"recursion_limit": 1000}) ``` +For more cost effective local testing, models like `ollama:qwen3` are availble from [langchain-ollama](https://github.com/langchain-ai/langchain/blob/master/libs/partners/ollama/README.md) as it was trained with tool call capabilities. + +```bash +# Run Ollama and enable local GPUs +docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama + +# Pull Model +docker exec -it ollama bash +ollama pull qwen3 +``` + + + + + + + ## Deep Agent Details The below components are built into `deepagents` and helps make it work for deep tasks off-the-shelf. From 65a378f595b930aa200f32ae2117f7cf716a6b68 Mon Sep 17 00:00:00 2001 From: ryaneggz Date: Mon, 4 Aug 2025 20:46:56 -0500 Subject: [PATCH 5/8] Clean up the format --- README.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 3dad666402..0ff84ed211 100644 --- a/README.md +++ b/README.md @@ -126,48 +126,44 @@ agent = create_deep_agent( ### `model` (Optional) -By default, `deepagents` will use `"claude-sonnet-4-20250514"`. If you want to use a different model, -you can pass a [LangChain model object](https://python.langchain.com/docs/integrations/chat/). +By default, `deepagents` uses `"claude-sonnet-4-20250514"`. You can customize this by passing any [LangChain model object](https://python.langchain.com/docs/integrations/chat/). -Below are the modifications to the **examples/research/research_agent.py** example. +#### Example: Using a Custom Model + +Here's how to modify the **examples/research/research_agent.py** example: ```python from deepagents import create_deep_agent from langchain.chat_models import init_chat_model -# ...examples/research/research_agent.py agent definitions +# ... existing agent definitions ... -# Create agent agent = create_deep_agent( tools=[internet_search], instructions=research_instructions, subagents=[critique_sub_agent, research_sub_agent], - # Pass custom model model=init_chat_model( - model="ollama:qwen3:14b", # pip install langchain-ollama + model="ollama:qwen3:14b", # Requires: pip install langchain-ollama temperature=0.0, - max_tokens=40_000, # 📝 See "context" column: https://ollama.com/library/qwen3 + max_tokens=40_000, # 📝 See context limits: https://ollama.com/library/qwen3 ) ).with_config({"recursion_limit": 1000}) ``` -For more cost effective local testing, models like `ollama:qwen3` are availble from [langchain-ollama](https://github.com/langchain-ai/langchain/blob/master/libs/partners/ollama/README.md) as it was trained with tool call capabilities. +#### Local Development with Ollama + +For cost-effective local testing, you can use models like `ollama:qwen3` from [langchain-ollama](https://github.com/langchain-ai/langchain/blob/master/libs/partners/ollama/README.md). These models are trained with tool-calling capabilities. + +**Setup:** ```bash -# Run Ollama and enable local GPUs +# Start Ollama with GPU support docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama -# Pull Model -docker exec -it ollama bash -ollama pull qwen3 +# Pull the model +docker exec -it ollama ollama pull qwen3 ``` - - - - - - ## Deep Agent Details The below components are built into `deepagents` and helps make it work for deep tasks off-the-shelf. From b073754c90e925c68a70937fe1addb6a56c59f6c Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Tue, 5 Aug 2025 10:33:07 -0700 Subject: [PATCH 6/8] Update README.md --- README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/README.md b/README.md index 0ff84ed211..2ff30956b2 100644 --- a/README.md +++ b/README.md @@ -150,19 +150,6 @@ agent = create_deep_agent( ).with_config({"recursion_limit": 1000}) ``` -#### Local Development with Ollama - -For cost-effective local testing, you can use models like `ollama:qwen3` from [langchain-ollama](https://github.com/langchain-ai/langchain/blob/master/libs/partners/ollama/README.md). These models are trained with tool-calling capabilities. - -**Setup:** - -```bash -# Start Ollama with GPU support -docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama - -# Pull the model -docker exec -it ollama ollama pull qwen3 -``` ## Deep Agent Details From e52aeedc869d84020203af4329cfe3f74646b4b7 Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Tue, 5 Aug 2025 10:33:30 -0700 Subject: [PATCH 7/8] Update README.md --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2ff30956b2..5fea130058 100644 --- a/README.md +++ b/README.md @@ -130,25 +130,24 @@ By default, `deepagents` uses `"claude-sonnet-4-20250514"`. You can customize th #### Example: Using a Custom Model -Here's how to modify the **examples/research/research_agent.py** example: +Here's how to use a custom model (like OpenAI's `gpt-oss` model via Ollama): + +(Requires `pip install langchain` and then `pip install langchain-ollama` for Ollama models) ```python from deepagents import create_deep_agent -from langchain.chat_models import init_chat_model # ... existing agent definitions ... +model = model=init_chat_model( + model="ollama:gpt-oss:20b", +) agent = create_deep_agent( - tools=[internet_search], - instructions=research_instructions, - subagents=[critique_sub_agent, research_sub_agent], - model=init_chat_model( - model="ollama:qwen3:14b", # Requires: pip install langchain-ollama - temperature=0.0, - max_tokens=40_000, # 📝 See context limits: https://ollama.com/library/qwen3 - ) -).with_config({"recursion_limit": 1000}) -``` + tools=tools, + instructions=instructions, + model=model, + ... +) ## Deep Agent Details From 524279d6f5a6b54d3bb7ea2303f00dc621568797 Mon Sep 17 00:00:00 2001 From: Harrison Chase Date: Tue, 5 Aug 2025 10:36:20 -0700 Subject: [PATCH 8/8] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 5fea130058..2ef9a4865c 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,6 @@ agent = create_deep_agent( ... ) - ## Deep Agent Details The below components are built into `deepagents` and helps make it work for deep tasks off-the-shelf.