Paper & Project Page • About This Repo • Quick Start • Configuration • Web UI • Architecture
This is the open-source implementation of the paper "SCOUT: Active Information Foraging for Long-Text Understanding with Decoupled Epistemic States" (ICML 2026).
The SCOUT Agent in the paper is built on an enterprise-internal agent framework with no current plans for open-source release. To promote community development and reproducibility, we re-implemented SCOUT using the Claude Agent SDK — a free, publicly available agent development framework. This repository is that open-source implementation.
The core methodology remains identical — active information foraging, decoupled epistemic states, three-phase foraging strategy, and gap-diagnosed convergence. Due to differences between agent frameworks, there are some implementation-level distinctions (e.g., behavioral enforcement via SDK Hooks instead of framework-native policies). Through testing, this open-source version achieves performance comparable to the original.
git clone https://github.com/XavierZhang2002/scout-open.git
cd scout-open
conda create -n scout python=3.12 -y
conda activate scout
pip install -r requirements.txtcp config.example.yaml config.yaml
vim config.yaml # Fill in your API credentialsMinimum configuration:
api:
base_url: "http://localhost:3456" # Claude Code Router (see below)
auth_token: "your-token"
model: "venus,deepseek-v3.1-terminus" # "provider,model" formatUnless you are calling Anthropic API directly, you need CCR to translate the API protocol. Configure your LLM providers in proxy/.claude-code-router/config.json (see proxy/README.md), then:
cd proxy && bash deploy.bash && cd ..# Single query mode
python main.py --query "What is the net profit for 2023?" --cwd /path/to/docs
# With Web UI (recommended for interactive use)
cd ui && python start.pyPython API:
import anyio
from scout.config import load_config
from scout.agent import query_agent
config = load_config("config.yaml")
config.cwd = "/path/to/documents"
result, tiktoken_usage, api_usage, num_turns, tool_usage = anyio.run(
query_agent,
"What is the main conclusion of this paper?",
None, None, None,
config,
)
print(f"Answer: {result}")
print(f"Turns: {num_turns}, Tokens: {tiktoken_usage}")All configuration lives in a single config.yaml file at the project root. Copy config.example.yaml to get started.
| Section | Purpose |
|---|---|
api |
LLM connection (base_url, auth_token, model) |
eval |
Evaluation LLM (optional, for workspace_evaluate fallback) |
agent |
Behavior control (max_turns, planner/evaluator toggles) |
tools |
Tool parameters (token thresholds, tokenizer model) |
pricing |
Cost estimation (optional) |
SCOUT communicates via the Anthropic Messages API protocol. Since most LLM providers (DeepSeek, Qwen, GPT, Gemini, etc.) do not natively support this protocol, you need the Claude Code Router (CCR) to act as a translation layer — unless you are calling the Anthropic API directly.
Option A: Claude Code Router (recommended for most users) — A local proxy (included in proxy/) that translates Anthropic Messages API into OpenAI/other formats, enabling use of virtually any LLM provider:
cd proxy && bash deploy.bash # Starts proxy on localhost:3456The model field uses "provider,model_name" format for routing:
"venus,deepseek-v3.1-terminus"— Route to Venus platform"ds,deepseek-chat"— Route to DeepSeek API directly"openrouter,anthropic/claude-sonnet-4.5"— Route via OpenRouter
See proxy/README.md for full setup guide.
Option B: Direct Anthropic API — If you have direct access to the Anthropic API (api.anthropic.com), you can skip CCR entirely and point base_url directly at it. This is the only case where CCR is not needed.
| Flag | Description |
|---|---|
--config PATH |
Path to config.yaml |
--model MODEL |
Override model |
--cwd DIR |
Working directory (where documents live) |
--query TEXT |
Single query (omit for interactive) |
--max-turns N |
Maximum agent turns |
--no-planner |
Disable Planner SubAgent |
--no-evaluator |
Disable Evaluator SubAgent |
SCOUT includes a web interface for interactive document querying with real-time agent visualization. The UI server embeds the SCOUT Agent directly — no separate backend process is needed.
Prerequisites: config.yaml must be configured and CCR must be running (if using non-Anthropic models) before starting the UI.
cd ui
python start.py # http://localhost:8080
python start.py --port 9000 # Custom portFeatures:
- File upload (.txt, .md, .json, .csv, .html, .xml, .log)
- Real-time WebSocket event stream (thinking, tool calls, results)
- Workspace viewer (inspect the agent's epistemic state)
- Configuration panel & metrics dashboard
Note: The Web UI is still under active development and may contain bugs. Contributions and PRs are welcome!
scout-open/
├── main.py # CLI entry point
├── config.example.yaml # Configuration template
├── scout/ # Core agent package
│ ├── agent.py # query_agent() — execution loop
│ ├── config.py # ScoutConfig + load_config()
│ ├── mcp_server.py # 6 MCP tools
│ ├── hooks/ # 4 behavioral hooks
│ │ ├── read_guard.py # Pre-read file safety check
│ │ ├── auto_record_reminder.py
│ │ ├── eval_guard.py # Must-evaluate-before-stop
│ │ └── token_tracker.py
│ ├── prompts/ # 11 modular prompt files
│ ├── agents/ # Planner + Evaluator SubAgents
│ ├── tools/ # Tool implementations
│ ├── sessions/ # Checkpoint/resume (optional)
│ └── permissions/ # Tool access control
├── ui/ # Web UI (FastAPI + Vue 3)
└── proxy/ # Claude Code Router
| Hook | Trigger | Effect |
|---|---|---|
read_guard |
Before Read/Grep | Auto-checks file size; injects warnings for large files |
auto_record_reminder |
After Read/Grep | Reminds agent to record findings to workspace |
eval_guard |
After tools + on Stop | Blocks premature stopping without sufficiency evaluation |
token_tracker |
After all tools | Records call counts and output sizes |
- Planner — Analyzes the query, decomposes into sub-tasks and search strategies
- Evaluator — Reviews the workspace, determines if collected information is sufficient
- Claude Agent SDK — The agent framework powering this open-source implementation
- Claude Code Router — API routing proxy (bundled in
proxy/)
We are experimenting with integrating SCOUT's core capabilities into a Claude Code Skill — a native slash-command plugin that lets Claude Code itself act as the reading agent, without requiring the full SDK runtime.
The skill lives in scout-skill/ and reimplements SCOUT's three-phase strategy (Plan → Gather → Verify) as a set of prompt modules and lightweight Python scripts that Claude Code can invoke directly.
Status: Under active development and testing. The skill is not yet production-ready. Contributions, feedback, and bug reports are welcome.
Built for the long-context reasoning community

