Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ cover/
*.pot

# Django stuff:
*.log
# *.log
local_settings.py
db.sqlite3
db.sqlite3-journal
Expand Down Expand Up @@ -208,3 +208,4 @@ __marimo__/

# LangGraph
.langgraph_api
**/logs/agent_*.log
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,15 @@ as well as custom instructions.
[] Create an example of a deep coding agent built on top of this
[] Benchmark the example of [deep research agent](examples/research/research_agent.py)
[] Add human-in-the-loop support for tools

## Added InitChatModel [Ollama Qwen3](https://ollama.com/library/qwen3)

Initial runs of out-of-box setup was took $1+, made mistake on first running `.invoke` instead of `.stream`

```py
init_chat_model(
model="ollama:qwen3:14b",
temperature=0.0,
max_tokens=40000,
)
```
31 changes: 31 additions & 0 deletions examples/research/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Research Agent",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/research_agent.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"env": {
"PYTHONPATH": "${workspaceFolder}"
},
"justMyCode": false,
"python": "${workspaceFolder}/.venv/bin/python"
},
{
"name": "Debug Research Agent (External Terminal)",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/research_agent.py",
"console": "externalTerminal",
"cwd": "${workspaceFolder}",
"env": {
"PYTHONPATH": "${workspaceFolder}"
},
"justMyCode": false,
"python": "${workspaceFolder}/.venv/bin/python"
}
]
}
166 changes: 166 additions & 0 deletions examples/research/logs/ollama-deepagents-summary.log

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions examples/research/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
deepagents
langgraph-cli[inmem]
tavily-python
langchain-openai
langchain-ollama
langchain-mcp-adapters
57 changes: 55 additions & 2 deletions examples/research/research_agent.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)