Structured deep-research CLI with mechanically enforced output. Two-turn architecture: Claude researches, deterministic template renders.
Project description
Research Director CLI
A two-turn research tool that produces structurally-guaranteed research briefs.
┌────────────────────────┐
"Linear vs Jira for 15 ──────│ Turn 1 (Claude API) │
engineers — what should │ research → JSON │
we know before switching?" └───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Turn 2 (Python) │
│ JSON → markdown brief │
└───────────┬────────────┘
│
▼
brief-*.md
brief-*.json
Why this exists
The original Research Director was a single-turn Claude skill — a SKILL.md file uploaded to claude.ai. After three iterations of escalating spec-strictness (v1.2.0 → v1.2.1 → v1.2.2 adding "non-skippable" language, verbatim required headers, even a complete worked example baked into the spec), the produced briefs still ignored the structural contract while doing the underlying research well.
The CLI architecture solves this by separating research (where Claude excels) from rendering (where determinism is required):
- Turn 1 — Claude produces structured JSON. No formatting, no structural decisions. Just data.
- Turn 2 — A Python template renders the JSON into the final markdown. No model. The structural contract IS the template.
The contract is mechanically enforced because Turn 2 has no latitude to "interpret" anything.
Output structure (always)
Every brief contains these five sections, in this exact order, with these exact headers:
## Executive summary
## Key findings
## Open questions / gaps
## Recommended next steps
## Sources
Gap entries always carry the format: statement (Category.) Recommendation: action. Category is always one of: Blind spot, Hallucination, Thin research, Missed consultation, Quality slippage, Drift. Sources are always a consolidated block at the end with name, citation, recency, and reliability note when applicable.
Install
pip install research-director
Set your Anthropic API key:
export ANTHROPIC_API_KEY="sk-ant-..."
(Get one at https://console.anthropic.com/settings/keys)
Use
rd "What's the current state of agent SDK ecosystems for production multi-agent systems?"
Outputs two files in the current directory:
brief-2026-04-30-1842.md ← the rendered markdown brief
brief-2026-04-30-1842.json ← the structured data the brief was rendered from
Cost per run: roughly $0.20–$0.80 in Anthropic API spend depending on how much research happens. Wall-clock time: typically 2–5 minutes.
Common variants
# Specify output filename
rd "your question" -o linear-jira-evaluation.md
# Print to stdout instead of writing files
rd "your question" --print
# Pipe markdown to clipboard (macOS)
rd "your question" --print | pbcopy
# Skip the JSON sidecar
rd "your question" --no-json
# Get only the structured data
rd "your question" --json-only
Full flag reference: rd --help
Three distribution layers
This tool ships in three forms depending on how you work:
1. CLI (this repo) — recommended
pip install research-director. Best for developers, scripts, and pipelines. Works in any terminal. Produces structurally-guaranteed output.
2. Claude Code skill
For Claude Code users. Drop the contents of claude_code_skill/ into ~/.claude/skills/research-director/ (or per-project at .claude/skills/research-director/). Then in any Claude Code session:
/research-director "your question"
Or just describe what you want — Claude Code will auto-invoke the skill when the description matches. Under the hood it runs the same rd CLI, so you get the same structurally-guaranteed output.
3. Claude.ai skill (limited fallback)
The original Research Director skill still exists as a .skill upload for claude.ai users. It produces good research but cannot mechanically enforce the output contract — that's the limitation that motivated this CLI. Documented in that repo's CHANGELOG. Use when you don't have terminal access; the CLI is the recommended path.
How it works (architecture)
Turn 1 — Research
Claude (Opus 4.7) gets a system prompt focused entirely on producing structured JSON. It runs intake-equivalent reasoning, plans research, executes web search, names the cross-cutting synthesis pattern, and switches register to author the gaps adversarially against a six-flag taxonomy. Output is a single JSON object with these top-level fields:
{
"synthesis_pattern": "...",
"executive_summary": "...",
"key_findings": [...],
"gaps": [...],
"next_steps": [...],
"sources": [...]
}
The full schema with field rules and validation is in src/research_director_cli/core.py.
Turn 1 validation
Before rendering, the JSON is validated:
- All six top-level fields present
key_findings[].confidenceis one ofhigh,medium,lowgaps[].categoryis one of the six valid categoriesgapsis non-empty (research without gaps hallucinated its completeness)sourcesis non-empty
If validation fails, the run errors out with specific field-level messages — no malformed brief is rendered.
Turn 2 — Render
A pure Python function takes the validated JSON and emits markdown using a deterministic template. No model involvement. The function is in src/research_director_cli/core.py — read it; it's about 50 lines.
Limitations
- Requires terminal access. The CLI doesn't run in claude.ai chat. Use the .skill upload as a fallback there, with the known structural-enforcement limitations.
- Single-pass research. No multi-step decomposition for very large topics yet. Heavy topics may produce a thinner brief than the same question would in claude.ai's research mode.
- English only. No localization yet.
- No persistent memory across runs. Each invocation is self-contained.
Contributing
Issues and PRs welcome. The simplest contribution is reporting a brief that came out wrong — paste the question, what came out, and what you expected.
License
MIT.
Provenance
Built as part of the Research Director skill family. Companion eval harness: research-director-evals. The full design narrative — including why the original single-turn skill couldn't enforce its own contract — is documented in the build-out-loud notes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file research_director-1.0.1.tar.gz.
File metadata
- Download URL: research_director-1.0.1.tar.gz
- Upload date:
- Size: 21.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aaa110654ece4aa09ffdc8a730d6bb0fa0e2ff347345eb43c088cc82f3dd8471
|
|
| MD5 |
b33d262829c6b9403c5148d56e5f8511
|
|
| BLAKE2b-256 |
affbee9df4ccac51e65b990581612d5750af256c2280e2ad54a9ea42a080888d
|
File details
Details for the file research_director-1.0.1-py3-none-any.whl.
File metadata
- Download URL: research_director-1.0.1-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cffe40517f4d2e7b7f1cc8930a6de42e0742258025c4d6979258ae10b41bb14c
|
|
| MD5 |
58a021dff278eef14bf93192c5245194
|
|
| BLAKE2b-256 |
f3b7f8619738280c7f3f8786ee7b90913bf89da6e15aec255d9663252a9b0d2f
|