Feature: configurable reasoning effort level for subagents

Status Fixed / completed
Maintainer reply ✓ Yes — bcherny
Activity 27 comments · opened Apr 3, 2026 · closed Aug 17, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Feature Request

Is your feature request related to a problem?

When using the Agent tool to dispatch subagents, the model parameter allows selecting which model the subagent runs on (opus, sonnet, haiku). However, there is no way to configure the reasoning effort level (low/medium/high) for subagents. Effort level only applies to the parent conversation via /model.

Describe the solution you'd like

Add an optional effort parameter to the Agent tool (and/or subagent YAML frontmatter) that controls the reasoning effort level for the spawned subagent:

# In .claude/agents/my-agent.md frontmatter:
---
model: opus
effort: high
---

Or per-invocation:

{
  "subagent_type": "senior-dev",
  "model": "opus",
  "effort": "high",
  "prompt": "..."
}

Use case

I run a 28-agent orchestration system for an algorithmic trading platform:

  • Orchestrator: Opus at low effort (fast routing, summarization)
  • Code-writing agents (10): Should run at high effort (deep reasoning for correctness)
  • Review agents (12): Could run at medium effort (structured analysis)
  • Lookup agents (6): Should run at low effort (fast data queries)

Currently all subagents spawn at default effort regardless of task complexity. Being able to set effort per-agent would optimize both cost and quality across the swarm.

Additional context

  • The model resolution already has a clean priority chain: env var > invocation param > frontmatter > parent. Effort could follow the same pattern.
  • This would pair well with the existing model parameter on the Agent tool.

🤖 Generated with Claude Code

View original on GitHub ↗

27 Comments

jacobcxdev · 4 months ago

+1

mpolomack · 4 months ago

+1

markdiantonio · 3 months ago

+100

GerardoFC8 · 3 months ago

Adding empirical evidence supporting this request. I tested the currently-documented effort frontmatter field on Claude Code 2.1.128 (Linux) and found it produces zero observable signal, which makes it indistinguishable from a no-op.

Setup

Added effort: high to ~/.claude/agents/sdd-explore.md (model: sonnet). Restarted Claude Code. Triggered the sub-agent on a non-trivial codebase exploration task. Repeated with effort: max. No config errors at load time.

Observation surfaces checked — all blind

| Surface | Exposes resolved sub-agent effort? |
|---|---|
| /status | No |
| /doctor | No |
| ~/.claude/projects/<cwd>/<session>/subagents/agent-*.meta.json | No — only agentType and description (80 bytes total) |
| ~/.claude/projects/<cwd>/<session>/subagents/agent-*.jsonl | No — keys are agentId, cwd, entrypoint, gitBranch, isSidechain, message, parentUuid, promptId, requestId, sessionId, timestamp, type, userType, uuid, version. No effort, thinking, or budget_tokens anywhere. |
| Per-turn usage block | No thinking_tokens field. Only input_tokens, cache_creation_input_tokens, cache_read_input_tokens, output_tokens, service_tier, speed, iterations. |

Quantitative scan

Scanned all 835 sub-agent transcripts in my local ~/.claude/projects/:

835 sub-agent JSONL files
  2 with thinking content blocks > 0  (both internal helpers — agent-acompact-*, agent-aside_question-*)
833 user-defined sub-agents with 0 thinking blocks

Claude Code appears to strip thinking content from persisted transcripts for user-defined sub-agents, regardless of model or declared effort. The 2 outliers are internal Claude Code helpers, not user-configurable agents.

Why this matters for this feature request

Even if Anthropic implements per-sub-agent effort tomorrow (which #43083 and #39220 are asking for), users will still have no way to verify the resolved configuration is being applied. Two distinct gaps:

  1. Functional (this issue + #39220): per-sub-agent effort needs to actually propagate to the API request.
  2. Observability (complementary): the resolved sub-agent config (effort, model, tools) needs to be inspectable somewhere — /agents inspect <name>, /status per sub-agent, or restored thinking blocks / thinking_tokens in saved usage stats.

Without (2), (1) becomes undebuggable in practice — exactly the situation today with the documented-but-unverifiable effort frontmatter field.

Related observations

  • Docs at https://docs.claude.com/en/docs/claude-code/sub-agents currently list effort as a supported frontmatter field ("Overrides the session effort level"). The docs and the observed behavior disagree, or the application is silent.
  • #47175 confirms CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 exists as an undocumented escape hatch that forces effort on sub-agents — implying the default behavior is to NOT propagate frontmatter effort. This matches the empirical scan above.
  • Naming inconsistency worth flagging while the team is in this code: settings.json uses effortLevel, sub-agent frontmatter uses effort, env vars use CLAUDE_CODE_EFFORT_LEVEL and CLAUDE_CODE_ALWAYS_ENABLE_EFFORT. Four different names for the same concept across four surfaces.

Happy to provide the scan script or run mitmproxy capture against api.anthropic.com/v1/messages to confirm whether thinking.budget_tokens is being included or omitted at the network layer if that would help triage.

qqzlqqzlqqzl · 3 months ago

Status update from v2.1.129: docs already promise this, implementation is broken

Hi @AndrewGoodson — I verified on Claude Code v2.1.129 that this feature is already documented but does not work.

Docs say it exists

The official subagents docs list:

effort | No | Effort level when this subagent is active. Overrides the session effort level. Default: inherits from session. Options: low, medium, high, xhigh, max

Both behaviors asked for in this issue — explicit YAML override AND session inheritance — are documented as supported.

Implementation: neither path works

Captured outbound HTTP request bodies via ANTHROPIC_LOG=debug claude --print "..." and compared the thinking field:

| Test | Setup | Subagent's thinking field |
|---|---|---|
| A | Built-in general-purpose, parent has "effortLevel": "xhigh" in settings.json (should inherit) | undefined |
| B | Custom agent in ~/.claude/agents/think-test.md with frontmatter effort: xhigh (should override) | undefined |
| C (control) | Same parent session running the prompt itself (no Task dispatch) | [Object ...] (set, works) |

When thinking is undefined, the SDK strips it during JSON.stringify, so the API receives a body with no thinking field at all → no extended thinking server-side. The parent session sets it correctly; the moment it dispatches via Task tool, it's dropped.

The frontmatter IS parsed (the binary contains let Y=H.effort,w=Y!==void 0?Ta(Y):void 0 in the YAML loader), but the parsed value never reaches the subagent's API request thinking config.

Token-level corroboration

Same prompt ("smallest n such that n!/(n-3)! > 2^n, show step by step"), captured via --output-format=stream-json --verbose:

  • Parent session solving it: 839 output_tokens
  • Subagent solving it: 303 output_tokens (≈ 36%)
  • Subagent solve duration: 10.7s vs full session 24.85s

Both consistent with thinking being completely disabled in the subagent.

Note on related tickets

#25669 was auto-closed by github-actions as duplicate of #25591 (which was also closed as duplicate). Neither was actually shipped. This (#43083) appears to be the only open ticket. Not just a missing feature — a documentation/implementation contradiction.

jaredthirsk · 3 months ago

My Opus 4.7 was looking into this for me and concluded it's a bug: either missing implementation, or docs that overpromise. It wanted me to post this:

Subagent effort: frontmatter ignored on Task-tool spawn but honored on claude -p --agent

Adding empirical evidence to issue #43083. The same subagent .md file actuates extended thinking via the CLI path but not via the in-session Task tool spawn — quantified below.

Environment: Claude Code 2.1.146, Linux WSL2, parent session Opus 4.7.

Repro: Create ~/.claude/agents/sonnet-low.md and ~/.claude/agents/sonnet-high.md differing only in the effort: value:

---
name: sonnet-low      # or sonnet-high
model: sonnet
effort: low           # or high
---
Execute the assigned work with [light/careful, deliberate] reasoning.

Run the same prompt four ways. I used a 12-step combinatorics problem (lattice paths (0,0)→(7,5) avoiding two interior points, inclusion-exclusion; answer 286), designed so deep reasoning shows up as more output tokens, not just better quality.

| Dispatch path | low | high | Δ output_tokens |
|---|---|---|---|
| Task tool subagent_type: sonnet-{low,high} (in-session) | 18,437 total | 18,343 total | −0.5% (noise) |
| Task tool subagent_type: opus-{high,xhigh} (intra-model effort) | 27,013 | 27,072 | +0.2% (noise) |
| claude -p --model sonnet --effort {low,high} | 1,451 | 2,181 | +50.3% |
| claude -p --agent sonnet-{low,high} (same .md files) | 1,746 | 2,529 | +44.8% |

Run-to-run variance on the in-session path measured 3.6% on tokens / 26% on wall time across same-effort repeats — both Task-tool deltas sit inside that noise band; both claude -p deltas are two orders of magnitude beyond it.

Confirmed it's not just JSONL stripping. Inspected ~/.claude/projects/{slug}/{sid}/subagents/agent-{id}.jsonl directly:

  • Zero type:"thinking" content blocks in the assistant message
  • Zero thinking_* fields in the usage block
  • service_tier: "standard" and speed: "standard" identical across all runs
  • Total wall time also identical across same-prompt different-effort Task spawns

If thinking were actuated server-side and stripped client-side, billed output_tokens and wall time would still differ — they don't.

What works: claude -p --agent <name> honors the frontmatter and actuates ~45% more output tokens with ~42% longer wall time on the same prompt. So the wiring exists in the CLI; the Task tool just isn't using it.

Docs reference: code.claude.com/docs/en/sub-agents.md § Supported frontmatter fields lists effort: as overriding the session effort level. Either the docs should scope the actuation claim to the --agent CLI path, or the Task tool should be wired to honor the same frontmatter on spawn.

privacyguy123 · 3 months ago

+1 - waiting too long for this simple feature.

aac · 3 months ago

Adding a use case the thread hasn't covered: parallel-fanout orchestration. I run an orchestrator that dispatches many implementation subagents at once via the Agent tool, each in its own worktree. The Agent tool already lets me right-size model per dispatch (opus/sonnet/haiku), and that's valuable — but effort is the finer cost/quality lever on the same model, and it's exactly where per-unit control pays off most: in one wave I want Max effort on an ambiguous multi-file refactor and Low on a mechanical single-file edit. Today I can size the model per unit but not the effort.

An optional effort param on the Agent tool, defaulting to the parent session's effort when omitted (precisely how model already behaves), would close the gap.

Confirming the frontmatter workaround others reported: effort: in an agent .md is a no-op on the Task-tool spawn path, so there's no usable per-subagent lever right now. +1.

mlevkov · 2 months ago

+1 with a concrete protocol-level use case, plus the symmetry argument.

Setup: a Rust workspace whose session protocol runs an 8-subagent double review (8 reviewer lenses → remediate → 8 again) on every plan and every code change. The Agent tool already accepts a per-call model override, so we can vary which model a reviewer runs on — but effort is session-global, so we cannot express the thing the workflow actually wants:

  • the 8 breadth lenses at high (they each have a tight scope; deep effort is wasted), and
  • one or two adversarial verifiers at xhigh (e.g. "re-derive this beacon-multiset oracle from the spec and try to refute it" — the only fires where extra reasoning depth measurably pays).

Today the only lever is raising the whole session's effort, which prices every mechanical fire at the verifier's tier. We measured this within our own protocol and ended up retiring max effort entirely (review fan-out substitutes for marginal solo effort at lower cost) — but that conclusion was forced partly because effort is all-or-nothing per session. Role-scoped effort would let cost track where reasoning depth actually matters.

Ask (matching this issue): an effort parameter on the Agent tool call, symmetric with the existing model parameter, plus an effort: field in custom-agent frontmatter with the same precedence rule (call-site param > frontmatter > inherit session).

elvisripley · 2 months ago

Adding controlled measurements from a multi-agent orchestration setup (one coordinator dispatching ~17 specialist subagents), on Claude Code 2.1.170 (subscription / OAuth). Short version: model: per-agent works; effort: per-agent does not, and the only dependable lever is session-level.

Method: headless claude -p A/B on one fixed hard reasoning prompt, tools disabled so output tokens ≈ reasoning, and subagent tokens isolated via modelUsage (parent and subagent run different models).

1. The --effort flag works, so the plumbing exists. Same prompt, Sonnet low→max: 616→5,556 output tokens (9×); Opus 471→2,694 (5.7×). Same model, same correct answer, so the delta is reasoning. Effort is real; it just isn't exposed on the per-agent surfaces.

2. Frontmatter effort: is not honored (run-as --agent). 3 trials/cell, the --effort flag as in-experiment goalposts:

| path | model | low→max out_tok | ratio |
|---|---|---|---|
| flag | opus | 337 → 1984 | 5.9× |
| flag | sonnet | 797 → 3002 | 3.8× |
| frontmatter | opus | 808 → 596 | 0.7× |
| frontmatter | sonnet | 1668 → 1676 | 1.0× |

The flag spreads low→max cleanly; the same effort set in the agent file produces no spread and never reaches the flag's max. The file's model: was honored on every run — only effort: is dropped.

3. On Task-tool spawns, session effort dominates (controlled 2×2). A real agent, varied session effort × file effort, 4 trials/cell, subagent tokens isolated (parent opus / subagent sonnet):

| session | file effort | subagent out_tok |
|---|---|---|
| low | low | 8 |
| low | max | 8 |
| max | low | 229 |
| max | max | 569 |

Main effects: session 391 tok vs file 170. At session=low the file effort did nothing (8 vs 8); it only mattered when the session was already max — i.e. no independent per-agent control. Consistent with #64706.

Why this matters (the cost is task-dependent). Max vs low is ~5–9× output tokens on pure reasoning but only ~1.6× on I/O-bound web research (gated by fetches, not thinking). With one session knob, a mixed pipeline is always mis-budgeted: run it high and you overpay 5–9× on mechanical/research steps; run it low and you starve the high-leverage reasoning roles. Per-agent effort — an Agent-tool param plus honored frontmatter, with the same per-model fallback semantics as /effort — would let orchestrators spend reasoning only where it pays off. +1.

Djentinga · 2 months ago

Yes please!

wrteam-jay · 2 months ago

+1. Use case: skills that dispatch subagents for different roles in the same workflow — some mechanical (checklist marking), some judgment-heavy (tradeoff classification). Both inherit session effort today; there's no way to encode "this role needs depth, that one doesn't" in the skill itself. An effort param on Agent tool, same precedence as model, would close this.

trudslev · 1 month ago

+1

ariccio · 1 month ago

Every time I come back to Claude code, I run into some silly oversight like this. It's honestly kinda odd how often Claude code feels like a beta product - is anthropic understaffed?

arthurauffray · 1 month ago

+1

creativecreatorormaybenot · 1 month ago

This is still an issue as of Claude Code 2.1.211.

archneon · 1 month ago

Claude code CLI: I was using Fable medium in one terminal. I opened another terminal (new session), set model to Opus with high reasoning. Then after several hours, i switched back to 'fable' terminal and it switched it to opus and to high reasoning. Guys, this needs to be per session, not overriding each session with model and effort changes. And add frontmatter for model and effort to frontmatter for subagents. No wonder you are out of compute, nothing is optimized :)

creativecreatorormaybenot · 1 month ago

I verified that the following workaround works in Claude Code v2.1.212:

Spawn sub-agents via CLI using claude --bg and supply the desired reasoning effort level via --effort. The full command looks like this:

claude --bg "Sample prompt" --agent <agent_name> --effort max --permission-mode auto

You can add an instruction to use this command format instead of the Agent Tool call to spawn sub-agents from the .claude/agents/ definitions in CLAUDE.md and the main agent will spawn all sub-agents like this.

Then, you can view all sub-agents working in claude agents.

ofekron · 1 month ago

Subagent effort should be part of the child runtime profile, not inherited accidentally from the parent conversation.

The clean model is: parent selects or references a child profile containing model, effort, tool scope, MCP scope, context budget, and max spend/turn limits. The spawn record should persist the resolved profile so a resumed or background subagent keeps the same effort even if the parent later switches models. Per-invocation overrides are useful, but they should resolve into that same durable child profile before launch.

I maintain Better Agent (https://github.com/ofekron/better-agent), where provider/model/reasoning-effort selections are explicit runtime profiles across Claude, Codex, and Gemini sessions. If useful, a star helps other multi-agent workflow builders find it.

tom-murray-dev · 1 month ago

It's really disappointing that this is still a bug 3 months later, for such a critical and important part of the subagent process, with no official communication or response at all.

The ability to optimise our token expenditure should be a constant and ongoing priority for Anthropic. Not only does it benefit each user who wants to use your product more than they're able to, but it directly benefits you as a company when you're constantly struggling with compute.

interestingcodelol · 1 month ago

Hitting this too, and I want to add a detail that I think upgrades this from "missing feature" to "silent footgun", because it cost us a few hours today.

The shape of our workflow

A lead session does implementation at high effort. It then spawns independent review subagents that re-derive the lead's load-bearing claims against the real artifact before anything merges. Those reviewers want a strong model at low effort: the reasoning is mostly "read this, reproduce that claim, say whether it holds", not deep multi-step planning. That is exactly the model: opus + effort: low combination this issue asks for.

Why the current behaviour is worse than a plain gap

Effort inherits from the parent session, and there is no signal anywhere that it did. So pinning a reviewer to a stronger model does not give you "stronger model, cheap reasoning" — it gives you "stronger model at whatever the parent happened to be", which for us was high. That is the single most expensive combination available, and nothing in the output, the transcript, or the UI says so.

I verified it rather than assuming. Spawning a subagent whose definition carried both:

model: opus
effort: low

then reading the recorded spawn metadata at
~/.claude/projects/<project>/<session>/subagents/agent-<name>-<hash>.meta.json:

{"agentType":"...","model":"sonnet","customAgentType":"...","permissionMode":"auto"}

model is captured. There is no effort key at all — the field is not ignored downstream, it is never captured in the first place. So there is currently no way to confirm what effort a subagent actually ran at, which makes the inheritance invisible to anyone trying to audit their own setup. (Claude Code 2.1.220.)

Worth flagging separately: several third-party guides currently document effort: in subagent frontmatter as if it were supported. People are adding that line, believing it works, and getting a no-op. A warning on an unrecognised frontmatter key would catch that on its own.

What it forced us to do

We wanted stronger-model reviewers at low effort. Since we could not get the effort half, our options were:

  1. keep the stronger model and accept it silently running at the parent's high effort — unpredictable cost, and not what we were choosing; or
  2. drop back to the smaller model so that inheriting high lands somewhere we can at least reason about.

We picked (2) and reverted the change. So the practical outcome of this gap is that we are running a weaker reviewer than we want, purely because the cost dimension is not controllable independently of the capability dimension.

Asks, roughly in order of usefulness to us

  1. Honour effort: in .claude/agents/*.md frontmatter (matching how model: already resolves).
  2. Record the effective effort in the subagent spawn metadata, so a configuration can actually be verified instead of trusted.
  3. Optionally, an effort parameter on the Agent tool for per-call overrides, mirroring the existing model parameter.

(1) and (2) together would be enough for us — (2) matters almost as much as (1), because without it there is no way to tell a working config from a no-op one.

One adjacent thing I ran into while testing, in case it saves someone else the confusion: agent definitions appear to be read once at session start. Editing a persona file mid-session does not affect subagents spawned later in that same session — the old values are still used, which makes a frontmatter change look broken when it may only be stale.

jordanmiguel · 23 days ago

It's insane this is not implemented and working yet, such an important thing.

gianpaolodn · 19 days ago

+1

bcherny collaborator · 14 days ago

Good news: subagents can now set their own reasoning effort. Add effort: high (or low, medium, xhigh, max, depending on the model) to the agent's frontmatter in .claude/agents/<name>.md, and it overrides the session's effort whenever that subagent runs. The same field works in the JSON passed to --agents.

Docs: https://code.claude.com/docs/en/sub-agents (see the supported frontmatter fields) and the changelog: https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md

There isn't a per-call effort parameter on the Agent tool itself, but per-agent frontmatter covers the orchestrator/coder/reviewer split you describe. Closing as shipped.

🤖 Generated with Claude Code

archneon · 9 days ago

@bcherny Hi! This issue is not solved at all and it shouldn't be closed.

The whole point was that an orchestrator model can choose effort when he launches subagent. Otherwise we need to create multiple subagents such as opus-low.md ,opus-medium.md, opus-high.md, opus-xhigh.md and so on... and then write a skill that orchestrator understands to use effort level based on the task complexity. And the problem is that every .md file is EXACTLY the same, except effort is changed in the frontmatter. This is horrible. It goes totally against SSOT and DRY principles. And now imagine, if you want to add sonnet subagents as well? soonet-low.md, sonnet-medium.md, sonnet-high.md ... and then also for haiku? it's a nightmare!

There should be something like default effort level or perhaps that u can specify multiple effort levels or something and then a description when orchestrator should use which effort level when it calls subagent.

Once this issue is fixed i will be able to simplify my 'agents' files a lot. It will be much easier to maintain.

There isn't a per-call effort parameter on the Agent tool itself

EXACTLY! We know that already! :) And that is the whole point! It is NOT yet available as per-call effort parameter. Add task on TODO please instead of closing it as shipped please :)

ariccio · 9 days ago

I suspect the fix was landed but hasn't released yet

Sincerely,
Alexander Riccio
--
"Change the world or go home."
about.me/ariccio

<http://about.me/ariccio>
If left to my own devices, I will build more.

On Fri, Aug 21, 2026, 3:07 AM archneon @.***> wrote:

archneon left a comment (anthropics/claude-code#43083) <https://github.com/anthropics/claude-code/issues/43083#issuecomment-5366380965> @bcherny <https://github.com/bcherny> Hi! This issue is not solved at all and it shouldn't be closed. The whole point was that an orchestrator model can choose effort when he launches subagent. Otherwise we need to create multiple subagents such as opus-low.md ,opus-medium.md, opus-high.md, opus-xhigh.md and so on... and then write a skill that orchestrator understands to use effort level based on the task complexity. And the problem is that every .md file is EXACTLY the same, except effort is changed in the frontmatter. This is horrible. It goes totally against SSOT and DRY principles. And now imagine, if you want to add sonnet subagents as well? soonet-low.md, sonnet-medium.md, sonnet-high.md ... and then also for haiku? it's a nightmare! There should be something like default effort level or perhaps that u can specify multiple effort levels or something and then a description when orchestrator should use which effort level when it calls subagent. Once this issue is fixed i will be able to simplify my 'agents' files a lot. It will be much easier to maintain. — Reply to this email directly, view it on GitHub <https://github.com/anthropics/claude-code/issues/43083?email_source=notifications&email_token=AAQLAZBSNAAFFL5IMMIRMNT5K7YLNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZWGYZTQMBZGY22M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5366380965>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAQLAZBY7JEDFA2GJW236ND5K7YLNAVCNFSNUABFKJSXA33TNF2G64TZHM4TGNZSGUZTINZVHNEXG43VMU5TIMRQGA2DAOBRHAZKC5QC> . You are receiving this because you commented.Message ID: @.***>
fschutt · 9 days ago

Issue is not solved in CC v2.1.239

Subagent default to "low" reasoning, even if parent is set to "max"