어드바이저 도구

어드바이저 도구 (Advisor Tool)

더 빠른 실행(executor) 모델을 더 높은 지능의 어드바이저(advisor) 모델과 짝지어, 생성 중간에 전략적 지침을 제공받게 해요.

어드바이저 도구를 사용하면 빠르고 저렴한 실행 모델(Sonnet 또는 Haiku)이 생성 중간에 고지능 어드바이저 모델(Opus 4.6)과 상의할 수 있어요. 어드바이저는 전체 대화를 읽고 보통 400~700 텍스트 토큰의 계획이나 과정 수정을 만들며, 실행 모델은 작업을 계속합니다.

이 패턴은 대부분의 턴이 기계적이지만 훌륭한 계획이 중요한 장기 에이전틱 워크로드(코딩 에이전트, 컴퓨터 사용, 멀티스텝 리서치)에 잘 맞아요. 어드바이저 단독 품질에 가까우면서도 토큰 생성의 대부분은 실행 모델 요율로 이뤄집니다.

어드바이저 도구는 베타입니다. 요청에 anthropic-beta: advisor-tool-2026-03-01 을 포함하세요. LiteLLM은 tools 배열에서 어드바이저 도구를 감지하면 이 헤더를 자동으로 추가합니다.

지원 프로바이더

프로바이더 Chat Completions API Messages API 비고
Anthropic API 네이티브 — 서버측에서 실행
OpenAI / Azure OpenAI LiteLLM 오케스트레이션 루프
Amazon Bedrock LiteLLM 오케스트레이션 루프
Google Vertex AI LiteLLM 오케스트레이션 루프
Groq / Mistral / others LiteLLM 오케스트레이션 루프

동작 방식 (LiteLLM 네이티브 오케스트레이션)

비-Anthropic 프로바이더의 경우 LiteLLM이 어드바이저 루프를 직접 구현합니다. 호출하는 API는 동일하며, LiteLLM이 루프를 대신 실행해 줘요.

advisor_20260301 도구와 비-Anthropic 프로바이더로 요청이 도착하면 AdvisorOrchestrationHandler 가 그것을 가로챕니다. 어드바이저 도구를 프로바이더가 이해하는 일반 함수 도구로 변환한 뒤 오케스트레이션 루프를 실행합니다.

LiteLLM이 당신을 위해 하는 일:

  • 아웃바운드 요청에서 advisor_20260301 을 제거하여, 프로바이더가 advisor 라는 표준 함수 도구만 보게 함
  • 실행 모델이 호출하면, 결과가 당신에게 도달하기 전에 가로채 어드바이저 하위 호출을 실행하고 조언을 주입
  • 재전송 시 메시지 히스토리에서 advisor_tool_result / server_tool_use 블록을 제거하여 비-Anthropic 프로바이더가 Anthropic 전용 타입을 보지 않게 함
  • stream=True 를 요청하면 최종 응답을 SSE 스트림으로 래핑
  • max_uses 를 하드 상한으로 강제 — 초과하면 AdvisorMaxIterationsError 발생, max_uses=0 이면 어드바이저를 완전히 비활성화

모델 호환성

실행 모델과 어드바이저 모델은 유효한 짝을 이뤄야 해요. 어드바이저는 Opus 모델(claude-opus-5)이고, 실행 모델은 Opus 4.6 이상, Sonnet 4.6 이상, 또는 Haiku 4.5일 수 있습니다.

Executor Advisor
claude-haiku-4-5-20251001 claude-opus-5
claude-sonnet-5 claude-opus-5
claude-opus-5 claude-opus-5

출처: 문서

본문

Chat Completions API

SDK 사용법

기본 예시

import litellm

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {"role": "user", "content": "Build a concurrent worker pool in Go with graceful shutdown."}
    ],
    tools=[
        {
            "type": "advisor_20260301",
            "name": "advisor",
            "model": "claude-opus-5",
        }
    ],
    max_tokens=4096,
)

print(response.choices[0].message.content)

선택 파라미터와 함께

import litellm

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {"role": "user", "content": "Build a REST API with authentication in Python."}
    ],
    tools=[
        {
            "type": "advisor_20260301",
            "name": "advisor",
            "model": "claude-opus-5",
            "max_uses": 3,                             # cap advisor calls per request
            "caching": {"type": "ephemeral", "ttl": "5m"},  # enable for 3+ calls per conversation
        }
    ],
    max_tokens=4096,
)

스트리밍

import litellm

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {"role": "user", "content": "Implement a distributed rate limiter."}
    ],
    tools=[
        {
            "type": "advisor_20260301",
            "name": "advisor",
            "model": "claude-opus-5",
        }
    ],
    max_tokens=4096,
    stream=True,
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

어드바이저 하위 추론은 스트리밍되지 않습니다. 어드바이저가 실행되는 동안 실행 모델의 스트림은 멈추고, 전체 어드바이저 결과가 단일 이벤트로 도착합니다. 그 후 실행 모델 출력이 스트리밍을 재개해요.

멀티 턴 대화

import litellm

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 = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages,
    tools=tools,
    max_tokens=4096,
)

# Append the full response (includes server_tool_use + advisor_tool_result blocks)
messages.append({"role": "assistant", "content": response.choices[0].message.content})

# Continue the conversation — keep the same tools array
messages.append({"role": "user", "content": "Now add a max-in-flight limit of 10."})

response2 = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages,
    tools=tools,
    max_tokens=4096,
)

LiteLLM은 현재 요청에 어드바이저 도구가 없을 때 메시지 히스토리에서 advisor_tool_result 블록을 자동으로 제거합니다. 이렇게 하면 그렇지 않으면 발생할 Anthropic 400 오류를 방지합니다.

AI Gateway 사용법

Proxy 구성

model_list:
  - model_name: claude-sonnet
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY

Proxy를 통한 클라이언트 요청

from openai import OpenAI

client = OpenAI(
    api_key="your-litellm-proxy-key",
    base_url="http://0.0.0.0:4000/v1"
)

response = client.chat.completions.create(
    model="claude-sonnet",
    messages=[
        {"role": "user", "content": "Implement a distributed rate limiter in Python."}
    ],
    tools=[
        {
            "type": "advisor_20260301",
            "name": "advisor",
            "model": "claude-opus-5",
        }
    ],
    max_tokens=4096,
)

Messages API

SDK 사용법

기본 예시

import asyncio
import litellm

async def main():
    response = await litellm.anthropic.messages.acreate(
        model="anthropic/claude-sonnet-5",
        messages=[
            {"role": "user", "content": "Build a concurrent worker pool in Go with graceful shutdown."}
        ],
        tools=[
            {
                "type": "advisor_20260301",
                "name": "advisor",
                "model": "claude-opus-5",
            }
        ],
        max_tokens=4096,
    )
    print(response)

asyncio.run(main())

스트리밍

import asyncio
import json
import litellm

async def main():
    response = await litellm.anthropic.messages.acreate(
        model="anthropic/claude-sonnet-5",
        messages=[
            {"role": "user", "content": "Implement a distributed rate limiter."}
        ],
        tools=[
            {
                "type": "advisor_20260301",
                "name": "advisor",
                "model": "claude-opus-5",
            }
        ],
        max_tokens=4096,
        stream=True,
    )

    async for chunk in response:
        if isinstance(chunk, bytes):
            for line in chunk.decode("utf-8").split("\n"):
                if line.startswith("data: "):
                    try:
                        print(json.loads(line[6:]))
                    except json.JSONDecodeError:
                        pass

asyncio.run(main())

AI Gateway 사용법

Proxy 구성

model_list:
  - model_name: claude-sonnet
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY

Proxy를 통한 클라이언트 요청 (Anthropic SDK)

import anthropic

client = anthropic.Anthropic(
    api_key="your-litellm-proxy-key",
    base_url="http://0.0.0.0:4000"
)

response = client.beta.messages.create(
    model="claude-sonnet",
    max_tokens=4096,
    betas=["advisor-tool-2026-03-01"],
    messages=[
        {"role": "user", "content": "Build a concurrent worker pool in Go with graceful shutdown."}
    ],
    tools=[
        {
            "type": "advisor_20260301",
            "name": "advisor",
            "model": "claude-opus-5",
        }
    ],
)
print(response)

비-Anthropic 프로바이더 (LiteLLM 오케스트레이션 루프)

import asyncio
import litellm

async def main():
    # executor: openai/gpt-5.6-luna  |  advisor: claude-opus-5
    # LiteLLM runs the orchestration loop automatically
    response = await litellm.anthropic.messages.acreate(
        model="openai/gpt-5.6-luna",
        messages=[
            {"role": "user", "content": "Implement a Python LRU cache with O(1) get and put."}
        ],
        tools=[
            {
                "type": "advisor_20260301",
                "name": "advisor",
                "model": "claude-opus-5",
                "max_uses": 3,
            }
        ],
        max_tokens=1024,
        custom_llm_provider="openai",
    )
    # Final response is clean — no advisor tool_use blocks
    print(response["content"][0]["text"])

asyncio.run(main())

응답 구조

성공적인 어드바이저 호출은 assistant 콘텐츠에 server_tool_useadvisor_tool_result 블록을 반환합니다:

{
  "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 using a channel-based coordination pattern..."
    }
  ]
}

어드바이저 블록을 포함한 전체 assistant 콘텐츠를 이후 턴에 다시 전달하세요. LiteLLM은 provider_specific_fields 를 통해 이를 자동으로 처리합니다.

비용 제어

어드바이저 호출은 어드바이저 모델 요율로 청구되는 별도의 하위 추론으로 실행됩니다. 사용량은 usage.iterations[] 에 보고됩니다:

{
  "usage": {
    "input_tokens": 412,
    "output_tokens": 531,
    "iterations": [
      {
        "type": "message",
        "input_tokens": 412,
        "output_tokens": 89
      },
      {
        "type": "advisor_message",
        "model": "claude-opus-5",
        "input_tokens": 823,
        "output_tokens": 1612
      },
      {
        "type": "message",
        "input_tokens": 1348,
        "output_tokens": 442
      }
    ]
  }
}

Top-level 사용량은 실행 모델 토큰만 반영합니다. 어드바이저 토큰은 type: "advisor_message" 를 가진 iterations 항목에 나타나며 Opus 요율로 청구됩니다.

팁:

  • 대화당 어드바이저 호출이 3회 이상 기대될 때만 도구 정의에 캐싱을 활성화하세요. 그 임계값 아래에서는 저장하는 것보다 비용이 더 들어요.
  • max_uses 로 요청당 어드바이저 호출을 제한하세요. 한도에 도달하면 실행 모델은 추가 조언 없이 계속합니다.
  • 대화 수준 상한은 클라이언트 측에서 어드바이저 호출을 세세요. 한도에 도달하면 tools에서 어드바이저 도구를 제거하세요.

권장 시스템 프롬프트

코딩 및 에이전트 작업에서 Anthropic은 일관된 어드바이저 타이밍과 최적의 비용/품질을 위해 시스템 프롬프트 앞에 다음 블록을 붙이는 것을 권장합니다:

You have access to an `advisor` tool backed by a stronger reviewer model. It takes NO parameters — when you call advisor(), your entire conversation history is automatically forwarded. They see the task, every tool call you've made, every result you've seen.

Call advisor BEFORE substantive work — before writing, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, fetching a source, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.

Also call advisor:
- When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, save the result, commit the change.
- When stuck — errors recurring, approach not converging, results that don't fit.
- When considering a change of approach.

On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling.
Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim, adapt. A passing self-test is not evidence the advice is wrong.

If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call — "I found X, you suggest Y, which constraint breaks the tie?"

품질을 잃지 않고 어드바이저 출력 길이를 35~45% 줄이려면 다음을 추가하세요:

The advisor should respond in under 100 words and use enumerated steps, not explanations.

추가 자료

더 알아보기 (Learn more)