mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 14:07:55 +00:00
198 lines
7.3 KiB
Markdown
198 lines
7.3 KiB
Markdown
---
|
|
title: Deep Research Assistant
|
|
description: Build a multi-source research agent with memory-augmented orchestration
|
|
---
|
|
|
|
# Deep Research Assistant
|
|
|
|
This tutorial walks through `examples/deep_research/research.py` — a standalone script that uses an orchestrator agent to research a topic, gather sources across multiple tool-calling turns, and produce a cited report. It demonstrates how to compose web search, memory, and file output into a single coherent research workflow.
|
|
|
|
!!! tip "Prerequisites"
|
|
- Python 3.10 or later
|
|
- OpenJarvis installed: run `uv sync --extra dev` from the repository root
|
|
- An inference engine running — either Ollama locally (see below) or a cloud API key in your `.env` file
|
|
|
|
## Quick Start
|
|
|
|
Run the research script from the repository root, passing your topic as a positional argument:
|
|
|
|
```bash title="Terminal"
|
|
python examples/deep_research/research.py "quantum computing advances 2026"
|
|
```
|
|
|
|
Save the report to a file:
|
|
|
|
```bash title="Terminal"
|
|
python examples/deep_research/research.py "quantum computing advances 2026" \
|
|
--output report.md
|
|
```
|
|
|
|
Use a cloud model instead of a local engine:
|
|
|
|
```bash title="Terminal"
|
|
source .env # load API keys
|
|
python examples/deep_research/research.py "climate policy trends" \
|
|
--model gpt-4o --engine cloud --max-turns 20
|
|
```
|
|
|
|
## How It Works
|
|
|
|
The script creates a `Jarvis` instance and delegates the research task to an `OrchestratorAgent` with five tools wired in. The orchestrator iterates through multiple tool-calling turns, deciding at each step whether to search, store, think, or synthesize.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant U as User
|
|
participant J as Jarvis SDK
|
|
participant O as OrchestratorAgent
|
|
participant W as web_search
|
|
participant T as think
|
|
participant MS as memory_store
|
|
participant MQ as memory_search
|
|
participant F as file_write
|
|
|
|
U->>J: research.py "quantum computing"
|
|
J->>O: ask(prompt, agent="orchestrator", tools=[...])
|
|
loop Up to max_turns iterations
|
|
O->>W: search("quantum computing 2026")
|
|
W-->>O: search results
|
|
O->>T: think(reasoning about findings)
|
|
T-->>O: structured thoughts
|
|
O->>MS: store(key finding)
|
|
MS-->>O: stored
|
|
O->>MQ: search(earlier findings)
|
|
MQ-->>O: related context
|
|
end
|
|
O->>F: file_write(report.md)
|
|
F-->>O: saved
|
|
O-->>J: final report with citations
|
|
J-->>U: print report
|
|
```
|
|
|
|
Each turn the orchestrator decides which tool to call based on what it has learned so far. The `think` tool lets the model reason without side effects, while `memory_store` and `memory_search` provide persistent scratch space across turns — so a finding from turn 3 can still inform the synthesis in turn 12.
|
|
|
|
## The Script
|
|
|
|
```python title="examples/deep_research/research.py" hl_lines="9 10 11 12 13"
|
|
from openjarvis import Jarvis
|
|
|
|
tools = ["web_search", "think", "file_write", "memory_store", "memory_search"]
|
|
|
|
j = Jarvis(model="qwen3:8b", engine_key="ollama") # (1)!
|
|
try:
|
|
response = j.ask(
|
|
"Research the following topic in depth and produce a report:\n\nquantum computing",
|
|
agent="orchestrator", # (2)!
|
|
tools=tools, # (3)!
|
|
system_prompt=..., # (4)!
|
|
max_turns=15, # (5)!
|
|
temperature=0.5,
|
|
)
|
|
finally:
|
|
j.close()
|
|
```
|
|
|
|
1. Creates a `Jarvis` instance targeting the local Ollama engine with `qwen3:8b`. Both parameters are optional — omitting them uses auto-detected defaults from `~/.openjarvis/config.toml`.
|
|
2. Selects the `OrchestratorAgent`, which runs a multi-turn tool-calling loop rather than a single round-trip.
|
|
3. The tool list is passed directly to the agent. All five tools are registered in the tool registry and need no further configuration.
|
|
4. The system prompt instructs the model to cite sources and distinguish facts from emerging claims.
|
|
5. The loop terminates after 15 tool-calling turns or when the agent decides it has enough information.
|
|
|
|
## Engine Configuration
|
|
|
|
=== "Ollama (local)"
|
|
|
|
Start the Ollama daemon and pull the model before running the script:
|
|
|
|
```bash title="Terminal"
|
|
ollama serve
|
|
ollama pull qwen3:8b
|
|
python examples/deep_research/research.py "your topic here"
|
|
```
|
|
|
|
No flags needed — `--engine ollama` and `--model qwen3:8b` are the defaults.
|
|
|
|
=== "Cloud API"
|
|
|
|
Set your API key in `.env`, then pass `--engine cloud` and the appropriate model identifier:
|
|
|
|
```bash title="Terminal"
|
|
# .env (in the repository root, gitignored)
|
|
OPENAI_API_KEY=sk-...
|
|
|
|
source .env
|
|
python examples/deep_research/research.py "your topic" \
|
|
--model gpt-4o --engine cloud
|
|
```
|
|
|
|
=== "vLLM"
|
|
|
|
If you are running a vLLM inference server (e.g., on a multi-GPU node):
|
|
|
|
```bash title="Terminal"
|
|
python examples/deep_research/research.py "your topic" \
|
|
--model meta-llama/Meta-Llama-3-8B-Instruct \
|
|
--engine vllm
|
|
```
|
|
|
|
Make sure `VLLM_BASE_URL` is set in `.env` pointing to your vLLM server.
|
|
|
|
## Configuration Reference
|
|
|
|
| Flag | Default | Description |
|
|
|---|---|---|
|
|
| `--model` | `qwen3:8b` | Model identifier passed to the engine |
|
|
| `--engine` | `ollama` | Engine backend (`ollama`, `cloud`, `vllm`, `llamacpp`, `mlx`) |
|
|
| `--max-turns` | `15` | Maximum orchestrator loop iterations |
|
|
| `--output` | (none) | File path to save the final report; if omitted, prints to stdout |
|
|
|
|
## Recipe-Driven Configuration
|
|
|
|
The companion `research.toml` in `examples/deep_research/` expresses the same setup declaratively. You can load it programmatically with `load_recipe()` and pass the result to `SystemBuilder`:
|
|
|
|
```python title="Using the recipe"
|
|
from openjarvis.recipes import load_recipe
|
|
from openjarvis import SystemBuilder
|
|
|
|
recipe = load_recipe("examples/deep_research/research.toml")
|
|
system = SystemBuilder(**recipe.to_builder_kwargs()).build()
|
|
response = system.ask("quantum computing advances 2026")
|
|
system.close()
|
|
```
|
|
|
|
This is useful when you want to version-control the research configuration, share it with collaborators, or feed it to the `jarvis eval` runner for benchmarking.
|
|
|
|
## Customization
|
|
|
|
### Swap the agent
|
|
|
|
Replace `"orchestrator"` with `"native_react"` for a Thought-Action-Observation loop, or `"native_openhands"` for a CodeAct-style agent that can write and execute code:
|
|
|
|
```python
|
|
response = j.ask(prompt, agent="native_react", tools=tools)
|
|
```
|
|
|
|
### Add more tools
|
|
|
|
Append any registered tool name to the `tools` list. For example, to also query a local knowledge base:
|
|
|
|
```python
|
|
tools = ["web_search", "think", "file_write",
|
|
"memory_store", "memory_search", "knowledge_graph_query"]
|
|
```
|
|
|
|
Run `jarvis agent info orchestrator` to see the full tool catalog.
|
|
|
|
### Adjust temperature
|
|
|
|
Lower values (0.2) produce more focused, factual reports. Higher values (0.7-0.8) encourage broader exploration and more creative synthesis:
|
|
|
|
```bash title="Terminal"
|
|
python examples/deep_research/research.py "your topic" --max-turns 20
|
|
```
|
|
|
|
## See Also
|
|
|
|
- [Architecture: Agents](../architecture/agents.md) — agent hierarchy (`BaseAgent`, `ToolUsingAgent`, `OrchestratorAgent`) and the `accepts_tools` mechanism
|
|
- [Architecture: Tools and Memory](../architecture/memory.md) — tool registry, MCP adapter, and the `ToolExecutor` dispatch pipeline
|
|
- [Getting Started: Configuration](../getting-started/configuration.md) — how to configure engines and models in `~/.openjarvis/config.toml`
|