Claude Research Agent
Build a Claude Code research agent that searches primary sources, keeps an evidence ledger, writes a cited report, and fails its quality gate when claims lack support.
Arrête de tout configurer. Place à la construction.
Des templates SaaS avec orchestration IA.
A Claude Code research agent can turn one question into a cited report while keeping search results out of your main coding context. The reliable version is not "search the web and summarize." It has a source policy, an evidence ledger, a fixed report shape, and a gate that rejects unsupported work.
This tutorial builds that version. It searches and fetches sources, writes one Markdown report, and cannot edit application code or run shell commands.
What makes research reliable
A research agent is a custom subagent with a narrow job. Anthropic's subagent documentation says each subagent gets its own context window, system prompt, tools, and permissions, then returns a summary to the main conversation.
The separate context is useful. Ten search pages can fill a normal coding session with details you never need again. A research subagent does the messy reading elsewhere and returns the report path plus its strongest findings.
The hard part is evidence discipline. A model can produce a polished paragraph before it has checked whether the supporting page is official, current, or even relevant. The workflow below makes evidence collection happen before synthesis.
| Weak research prompt | Bounded research workflow |
|---|---|
| "Research this topic" | Defines the exact decision |
| Any search result | Primary-source hierarchy |
| Sources listed at the end | URL attached to each factual claim |
| No record of rejected evidence | Evidence ledger with exclusions |
| Confident prose fills gaps | Unknowns stay explicit |
| Agent decides when done | File validator enforces a minimum contract |
Final file tree
The setup lives inside the repository, so the team can review and version it. The generated report goes in research/, separate from product code.
your-project/
├── .claude/
│ ├── agents/
│ │ └── researcher.md
│ ├── hooks/
│ │ └── validate-research.mjs
│ └── settings.json
├── research/
│ └── report.md
└── CLAUDE.mdDefine the research contract
Before writing an agent, decide what a valid report must contain. This prevents the final answer from quietly changing shape around whatever the search happened to find.
The contract below works for product, API, library, and market questions:
- State the decision the research should inform.
- Prefer official documentation, first-party announcements, standards, filings, and original papers.
- Record the publication or update date when available.
- Attach a direct URL to every material current claim.
- Separate verified facts from interpretation.
- Record conflicts and missing evidence.
- End with a recommendation that follows from the ledger.
This is stricter than a normal reading list. Good. Research that cannot survive a source check should not steer a build.
Create the custom subagent
Save the following file as .claude/agents/researcher.md. Its description tells Claude when to delegate, while the tool list keeps the worker away from Bash and source-code editing.
The agent can write because it owns research/report.md. Its body explicitly limits that permission to one output file and requires primary sources for facts that change over time.
---
name: researcher
description: Research a technical, product, or market question using current primary sources and write a cited evidence report. Use for comparisons, API decisions, pricing checks, and implementation research.
tools: WebSearch, WebFetch, Read, Write
disallowedTools: Bash, Edit, NotebookEdit
model: sonnet
permissionMode: dontAsk
maxTurns: 20
---
You are a skeptical research analyst.
Write the final report to `research/report.md`. Do not write or modify any
other file.
## Source policy
Use primary sources whenever they exist:
- Official product and API documentation
- First-party release notes and announcements
- Standards bodies and government publications
- Original research papers and their supplementary material
- Company filings or directly published datasets
Search results and secondary articles may help you discover a source. Do not
use them as final evidence for product behavior, pricing, benchmark results,
legal requirements, or a current technical fact when a primary source exists.
## Research process
1. Restate the decision this report must support.
2. Break the question into factual subquestions.
3. Search for the primary source for each subquestion.
4. Open and read the relevant source, not just the search snippet.
5. Record the URL, page title, publisher, date, and supported claim.
6. Look for evidence that would disprove the emerging conclusion.
7. Mark unresolved points as unknown. Never fill a gap with a guess.
8. Write the report using the required structure below.
## Required report structure
# Research report
## Decision
## Short answer
## Verified findings
## Evidence ledger
Use a Markdown table with these columns:
| Claim | Primary source | Publisher | Date checked | Confidence |
## Conflicts and unknowns
## Recommendation
## Sources
Use direct links to the exact supporting pages.
## Output rules
- Put a source link in the same paragraph as each evolving factual claim.
- Distinguish source facts from your interpretation.
- Use exact dates rather than "recently."
- Do not invent numbers, quotes, benchmarks, or prices.
- Keep excerpts short and paraphrase unless exact wording is necessary.
- End your response with the report path and three strongest findings.Claude Code loads custom agents at session start. If you add the file during an active session, use the agent-management command documented by your installed version or start a fresh session.
Add a deterministic report gate
The prompt asks for the right structure, but a prompt is still a request to a model. A hook gives the repository a deterministic check that runs every time the researcher stops.
The validator below reads hook input from standard input, checks the report file, and returns a block decision when required sections or source links are missing. Save it as .claude/hooks/validate-research.mjs.
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
let input = "";
for await (const chunk of process.stdin) {
input += chunk;
}
const event = input ? JSON.parse(input) : {};
const projectDir = event.cwd || process.cwd();
const reportPath = resolve(projectDir, "research/report.md");
const requiredHeadings = [
"# Research report",
"## Decision",
"## Short answer",
"## Verified findings",
"## Evidence ledger",
"## Conflicts and unknowns",
"## Recommendation",
"## Sources",
];
let report = "";
try {
report = await readFile(reportPath, "utf8");
} catch {
process.stdout.write(
JSON.stringify({
decision: "block",
reason:
"The research report is missing. Write the complete report to research/report.md before stopping.",
}),
);
process.exit(0);
}
const missingHeadings = requiredHeadings.filter(
(heading) => !report.includes(heading),
);
const links = report.match(/https?:\/\/[^\s)]+/g) ?? [];
const hasLedgerHeader =
report.includes("| Claim |") &&
report.includes("| Primary source |") &&
report.includes("| Confidence |");
const problems = [];
if (missingHeadings.length > 0) {
problems.push(`missing headings: ${missingHeadings.join(", ")}`);
}
if (links.length < 3) {
problems.push("fewer than three direct source links");
}
if (!hasLedgerHeader) {
problems.push("evidence ledger table is missing or malformed");
}
if (problems.length > 0) {
process.stdout.write(
JSON.stringify({
decision: "block",
reason: `Research gate failed: ${problems.join(
"; ",
)}. Fix research/report.md, then finish again.`,
}),
);
}This gate cannot prove that a source supports a claim. It catches structural shortcuts: no report, missing evidence table, or a source section with no usable links. Human review still decides whether the evidence is relevant and strong.
Register the hook
Claude Code's hooks guide documents SubagentStop as the event fired when a subagent finishes. A block decision sends the reason back to the subagent so it can continue.
Register the validator in .claude/settings.json. The matcher limits it to the researcher agent, so other subagents are unaffected.
{
"hooks": {
"SubagentStop": [
{
"matcher": "researcher",
"hooks": [
{
"type": "command",
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/validate-research.mjs\"",
"timeout": 30
}
]
}
]
}
}Run the hook against a harmless research question before trusting it. Hook schemas and supported fields change, so compare the example with Anthropic's current hooks reference if your installed Claude Code version reports a configuration error.
Run the first research job
Start a fresh Claude Code session from the repository root. Explicitly name the researcher for the first few runs so you can inspect its behavior before relying on automatic delegation.
The prompt below asks for a decision, defines the deployment context, and names the sources that count. That is enough direction without pre-writing the conclusion.
Use the researcher agent.
Decision: Should this Next.js 16 SaaS use Inngest or Vercel Cron for a daily
job that may retry failed API calls and must expose run history?
Constraints:
- The app deploys on Vercel.
- Jobs may run for several minutes.
- We need retries and an audit trail.
- Use current official Inngest, Vercel, and Next.js documentation.
- Do not use affiliate comparisons or SEO listicles as evidence.
Write the result to research/report.md and include unknowns that require a
prototype.Do not ask for "everything about background jobs." A decision-focused question gives the agent a stopping condition and makes the report easier to evaluate.
Review the evidence, not the prose
A clean report can still be wrong. Open every source behind the recommendation and check three things:
- Does the linked page say what the report claims?
- Is the page current for the version you will deploy?
- Is the claim a documented guarantee or the agent's interpretation?
Pay special attention to pricing, plan availability, quotas, beta features, and benchmark numbers. Those facts change quickly and are often repeated long after the source changed.
The report should make uncertainty visible. "The official page does not document this behavior" is a useful finding. A made-up answer is not.
Add an independent review pass
For a consequential decision, ask a second agent to challenge the report without seeing the researcher's hidden process. Give it the report and the same source policy, then ask it to identify unsupported leaps, stale pages, and ignored alternatives.
This review prompt is intentionally adversarial. It tries to falsify the recommendation instead of polishing it.
Review research/report.md as a skeptical technical editor.
Open every linked primary source.
For each material claim, classify it as supported, partially supported, or
unsupported.
Check dates, version scope, plan restrictions, and whether the report turned
an interpretation into a fact.
List required corrections before giving a final verdict.
Do not rewrite the report until the evidence audit is complete.The extra pass costs more usage. Reserve it for architecture, security, vendor selection, and published claims where a wrong answer is expensive.
Keep research out of permanent context
Do not paste a twenty-page report into CLAUDE.md. Permanent project instructions should contain the decision and the durable constraint, not the entire search trail.
After approval, record the outcome in an architecture decision record and link back to the report:
# ADR 004: Background job provider
## Status
Accepted
## Decision
Use the selected provider for retryable background workflows.
## Constraints
- Jobs must expose run history.
- Failed external calls need bounded retries.
- Deployment must work with the current Vercel setup.
## Evidence
See `research/report.md` for the primary-source ledger and unresolved limits.That keeps normal coding sessions focused while preserving why the decision was made. If the provider changes its limits later, rerun the research and update the record deliberately.
Frequently asked questions
Can Claude Code search the web for research?
Yes, when WebSearch and WebFetch are available in your environment and granted to the subagent. Tool access should still be narrow, and the agent should open supporting pages rather than trust search snippets.
How do I make a Claude research agent cite sources?
Require a direct URL beside every evolving factual claim, keep an evidence ledger, and reject reports without the required sections. Then manually verify that each source supports the attached claim.
Should a research agent use primary sources only?
Use primary sources for the final evidence whenever they exist. Secondary coverage is useful for finding a paper, release note, filing, or official documentation page, but it should not replace that source.
The $29 Code Kit includes a one-time Claude Code harness with a broader discovery and build pipeline: research informs specs, specialist builders implement them, evaluators challenge the result, tests run, and quality gates require zero type errors, zero lint errors, and a clean build. Claude Code itself still requires a paid Anthropic plan, and the Code Kit does not include that plan.
Posted by @speedy_devv
Arrête de tout configurer. Place à la construction.
Des templates SaaS avec orchestration IA.
Kiro Migration Guide
Migrate Kiro to Claude Code without losing steering files, feature specs, hooks, or MCP servers. This guide maps each Kiro artifact to a working Claude Code equivalent.
Leave Grok Build
Move from Grok Build to Claude Code without losing instructions, skills, agents, MCP servers, hooks, or project safety rules.