The advisor tool lets a faster, lower-cost executor model consult a higher-intelligence advisor model mid-generation for strategic guidance. The advisor reads the full conversation, produces a plan or course correction, and the executor continues with the task.
This pattern fits long-horizon agentic workloads (coding agents, computer use, multistep research pipelines) where most turns are mechanical but having an excellent plan is crucial. You get close to advisor-solo quality while the bulk of token generation happens at executor-model rates. For measured results, including how the benefit shrinks as the executor's own capability approaches the advisor's, see Optimizing for cost and intelligence.
The advisor fits these configurations:
Results are task-dependent. Evaluate on your own workload.
The advisor is a weaker fit for single-turn Q&A (nothing to plan), pure pass-through model pickers where your users already choose their own cost and quality tradeoff, or workloads where every turn genuinely requires the advisor model's full capability.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-sonnet-5",
max_tokens=4096,
betas=["advisor-tool-2026-03-01"],
tools=[
{
"type": "advisor_20260301",
"name": "advisor",
"model": "claude-opus-5",
}
],
messages=[
{
"role": "user",
"content": "Build a concurrent worker pool in Go with graceful shutdown.",
}
],
)
print(response)The response content includes an advisor_tool_result block carrying the advisor's guidance. With claude-opus-5 as the advisor, as in this quick start, the block's content field is an advisor_redacted_result variant (encrypted; the executor reads it server-side, but your client does not). To see the advice text directly in your response, use claude-opus-4-8 as the advisor model instead, which returns the plaintext advisor_result variant. See Result variants for both shapes side by side and which advisor models return which, and Model compatibility for the full list of valid pairs.
When you add the advisor tool to your tools array, the executor model determines when to call it, like any other tool. When the executor calls the advisor:
server_tool_use block with name: "advisor" and an empty input. The executor signals timing, and the server supplies context.advisor_tool_result block.All of this occurs inside a single /v1/messages request, with no extra round trips on your side. The exception is a turn that pauses mid-call, which you resume with a follow-up request (see Resuming a paused turn).
The advisor itself runs without tools and without context management. Its thinking blocks are dropped before the result returns. Only the advice text reaches the executor.
| Parameter | Type | Default | Description |
|---|---|---|---|
type | string | required | Must be "advisor_20260301". |
name | string | required | Must be "advisor". |
model | string | required | The advisor model ID, such as . Billed at this model's rates for the sub-inference. |
max_uses | integer | unlimited | Maximum number of advisor calls allowed in a single request. Once the executor reaches this cap, further advisor calls return an advisor_tool_result_error with error_code: "max_uses_exceeded" and the executor continues without further advice. This is a per-request cap, not a per-conversation cap. See Cost control for conversation-level limits. |
max_tokens | integer | advisor model's output cap | Caps the advisor's total output (thinking plus text) per call. Minimum 1024. See Capping advisor output. |
caching | object | null | null (off) | Enables prompt caching for the advisor's own transcript across calls within a conversation. See Advisor prompt caching. |
The caching object has the shape {"type": "ephemeral", "ttl": "5m" | "1h"}. Unlike cache_control on content blocks, this is not a breakpoint marker. It is an on/off switch. The server determines where cache boundaries go.
The advisor tool also accepts the generic properties available on any tool definition: cache_control, allowed_callers, defer_loading, and strict (covered in structured outputs). See the Tool reference for their semantics.
When the advisor is called, a server_tool_use block is followed by an advisor_tool_result block in the assistant's content. The following example shows the plaintext advisor_result variant returned by a Claude Opus 4.8 advisor. The Quick start uses Claude Opus 5, which returns the encrypted advisor_redacted_result variant instead; see Result variants for both shapes side by side.
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Let me consult the advisor on this."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "advisor",
"input": {}
},
{
"type": "advisor_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "advisor_result",
"text": "Use a channel-based coordination pattern. The tricky part is draining in-flight work during shutdown: close the input channel first, then wait on a WaitGroup..."
}
},
{
"type": "text",
"text": "Here's the implementation. I'm using a channel-based coordination pattern to avoid writer starvation..."
}
]
}The server_tool_use.input is always empty. The server constructs the advisor's view from the full transcript automatically. Nothing the executor puts in input reaches the advisor.
The advisor_tool_result.content field is a discriminated union. For successful calls, the variant depends on the advisor model:
| Variant | Fields | Returned when |
|---|---|---|
advisor_result | text, stop_reason | The advisor model returns plaintext (for example, Claude Opus 4.8). |
advisor_redacted_result | encrypted_content, stop_reason | The advisor model returns encrypted output. |
Here is the same request sent twice, identical except for the advisor model in the tool definition, showing both variants.
With "model": "claude-opus-4-8", the advice is plaintext:
{
"type": "advisor_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "advisor_result",
"text": "Use a channel-based coordination pattern. The tricky part is draining in-flight work during shutdown: close the input channel first, then wait on a WaitGroup..."
}
}With "model": "claude-opus-5", the advice is encrypted:
{
"type": "advisor_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "advisor_redacted_result",
"encrypted_content": "EqQBCkYIBRgCIiQ5ZjE0N2M2OC0yYWIxLTRkZTktYjA3ZC1hZTUyMzkxYjhkMmU..."
}
}Both result variants carry a stop_reason field when you set max_tokens on the tool definition, and omit it when you do not. It holds the advisor sub-call's stop reason, typically "end_turn", or "max_tokens" when the cap is hit. The values match the top-level Messages API stop_reason.
With advisor_result, the text field contains human-readable advice. With advisor_redacted_result, the encrypted_content field contains an opaque blob that you cannot read. On the next turn, the server decrypts it and renders the plaintext into the executor's prompt.
In both cases, round-trip the content verbatim on subsequent turns. If you switch advisor models mid-conversation, branch on content.type to handle both shapes.
If the advisor call fails, the result carries an error:
{
"type": "advisor_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "advisor_tool_result_error",
"error_code": "overloaded"
}
}The executor sees the error and continues without further advice. The request itself does not fail.
error_code | Meaning |
|---|---|
max_uses_exceeded | The request reached the max_uses cap set on the tool definition. Further advisor calls in the same request return this error. |
too_many_requests | The advisor sub-inference was rate-limited. |
overloaded | The advisor sub-inference hit capacity limits. |
prompt_too_long | The transcript exceeded the advisor model's context window. |
execution_time_exceeded | The advisor sub-inference timed out. |
model_not_found | The configured advisor model is not available. |
unavailable | Any other advisor failure. |
Advisor rate limits draw from the same per-model bucket as direct calls to the advisor model. A rate limit on the advisor appears as too_many_requests inside the tool result. A rate limit on the executor fails the whole request with HTTP 429.
Pass the full assistant content, including advisor_tool_result blocks, back to the API on subsequent turns. Round-trip the result blocks verbatim: with a Claude Opus 5 advisor the result block's content is the encrypted advisor_redacted_result variant, and the server decrypts it and renders the advice into the executor's prompt on the next turn (see Result variants). The mechanics are identical for any advisor model.
client = anthropic.Anthropic()
tools = [
{
"type": "advisor_20260301",
"name": "advisor",
"model": "claude-opus-5",
}
]
messages = [
{
"role": "user",
"content": "Build a concurrent worker pool in Go with graceful shutdown.",
}
]
response = client.beta.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
betas=["advisor-tool-2026-03-01"],
tools=tools,
messages=messages,
)
# Append the full response content, including any advisor_tool_result blocks
messages.append({"role": "assistant", "content": response.content})
# Continue the conversation
messages.append({"role": "user", "content": "Now add a max-in-flight limit of 10."})
response = client.beta.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
betas=["advisor-tool-2026-03-01"],
tools=tools,
messages=messages,
)You can drop the advisor tool from tools on a follow-up turn while the message history still contains advisor_tool_result blocks. The request is accepted and the historical blocks are preserved; the model cannot call the advisor on that turn. You must still send the advisor-tool-2026-03-01 beta header for those history blocks to be accepted.
A response can end with stop_reason: "pause_turn" while an advisor call is still pending. When that occurs, the response contains the advisor's server_tool_use block with no advisor_tool_result for it. To resume, append that assistant message to messages with its content unchanged, keeping the server_tool_use block, and send the request again with the same advisor tool and beta header. You do not need to add a user message or a tool_result block. The API runs the pending advisor call and continues the executor's turn in the new response. A resumed turn can pause again. If it does, repeat the same step. Omitting the advisor tool from the resume request returns a 400 invalid_request_error, because the pending server_tool_use block has no tool definition to run against; include the tool whenever a call is pending. If instead the executor called one of your tools in the same turn, the response ends with stop_reason: "tool_use" while the advisor call is still pending. Send the tool_result blocks as usual, and the pending advisor call runs at the start of that next request. See Mixing server tools and client tools in one turn.
If a Haiku executor has not called the advisor in its first assistant turn, append a short reminder as an additional user message before the second assistant turn. In Anthropic's internal behavioral evaluation this raised task pass rates by roughly 7 percentage points on Haiku executors. On Sonnet executors, the plain-text nudge had no measurable effect in Anthropic's testing. The call-timing considerations that follow are especially relevant for Sonnet. Do not apply the nudge to Opus executors: On Opus it slightly lowered pass rates.
With the default NUDGE_TURN of 2, the reminder typically arrives after the model has oriented on the task but before it has committed to an approach.
client = anthropic.Anthropic()
NUDGE_TURN = 2 # inject before this assistant turn if no advisor call yet
NUDGE_TEXT = (
"You have not consulted the advisor yet. If the task has a non-obvious "
"design decision or a failure mode you haven't ruled out, call advisor "
"now before committing to an approach."
)
MAX_TURNS = 10 # agent loop cap
def run_your_tools(content):
# Replace with your tool dispatch. Returns one tool_result block per tool_use block.
return [
{
"type": "tool_result",
"tool_use_id": block.id,
"content": "Replace with your tool output.",
}
for block in content
if block.type == "tool_use"
]
tools = [
{"type": "advisor_20260301", "name": "advisor", "model": "claude-opus-5"},
# ... your other tools
]
task = "Build a concurrent worker pool in Go with graceful shutdown."
messages = [{"role": "user", "content": task}]
advisor_called = False
for turn in range(1, MAX_TURNS + 1):
response = client.beta.messages.create(
model="claude-haiku-4-5",
max_tokens=4096,
betas=["advisor-tool-2026-03-01"],
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
advisor_called = advisor_called or any(
block.type == "server_tool_use" and block.name == "advisor"
for block in response.content
)
if response.stop_reason == "end_turn":
break
if response.stop_reason == "pause_turn":
continue # server tool pending; re-send to let the API complete it
results = run_your_tools(response.content) # list of tool_result blocks
if results:
messages.append({"role": "user",