0Pricing
Claude Architect · 강의

API 요청의 구조

model, max_tokens, system, messages, tools, tool_choice를 다룹니다

API 요청의 구조은(는) CoddyKit의 무료 Claude Architect 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Claude Architect 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

The Single Endpoint

Every call to Claude is one request to the Messages API. As an architect, you don't memorize syntax — you reason about six fields that shape the whole interaction: model, max_tokens, system, messages, tools, and tool_choice.

Get these right and everything downstream — agents, tool loops, structured output — falls into place. This lesson walks through each field and the decision it represents.

from anthropic import Anthropic

client = Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system="You are a concise assistant.",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.content[0].text)

model — Which Brain

The model field selects which Claude does the work. It's a single string, and the choice is a real architectural trade-off: capability versus latency versus cost.

  • Opus — most capable, best for long-horizon agentic and hard reasoning.
  • Sonnet — strong balance of speed and intelligence.
  • Haiku — fastest and cheapest for simple, high-volume tasks.

You can change the model per request, so route easy tasks to a cheaper model and hard ones to a stronger one.

# Same request shape, different routing decision
response = client.messages.create(
    model="claude-opus-4-8",  # swap to a cheaper model for simple tasks
    max_tokens=1024,
    messages=[{"role": "user", "content": "Summarize this ticket."}],
)

max_tokens — The Output Ceiling

max_tokens is a hard cap on how many tokens Claude may generate in this response. The model is not told this number — it's an enforced ceiling, not a hint.

If generation hits the cap, the response is cut off and stop_reason comes back as "max_tokens". That means the answer is truncated, not complete. Set it high enough to finish the job; for very long outputs, stream so you don't hit request timeouts.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,  # generous ceiling so the answer isn't cut off
    messages=[{"role": "user", "content": "Write a detailed migration plan."}],
)
if response.stop_reason == "max_tokens":
    print("Truncated — raise max_tokens or stream.")

system — Persona and Rules

The system prompt sets Claude's role, tone, and standing rules — the instructions that apply to the whole conversation rather than to one user turn.

Put durable behavior here: "You are a support agent. Verify the customer's identity before any account action." Keep it stable across requests — a frozen system prompt also caches well, which lowers cost and latency on repeated calls.

SYSTEM = (
    "You are a customer-support agent for an online store. "
    "Always verify the customer's identity before discussing an order. "
    "Be warm, concise, and never invent order details."
)

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=SYSTEM,
    messages=[{"role": "user", "content": "Where is my order?"}],
)

messages — The Whole History

This is the field architects get wrong most often. The Messages API is stateless: the model keeps NO memory between requests. On every turn you resend the full conversation history — every prior user and assistant turn, plus any tool results.

If you only send the latest user message, Claude has amnesia. Conversation state lives in your application; you replay it each call. Messages alternate roles, and the first message must be user.

messages = [
    {"role": "user", "content": "My name is Alice."},
    {"role": "assistant", "content": "Hi Alice!"},
    {"role": "user", "content": "What's my name?"},  # only works because history is resent
]
response = client.messages.create(
    model="claude-opus-4-8", max_tokens=256, messages=messages,
)

tools — Giving Claude Hands

The tools field is a list of actions Claude may call — each with a name, an input_schema (JSON Schema), and most importantly a description.

The description is the primary way Claude decides which tool to use — not the name. A good description states the tool's purpose, its return values, input formats with examples, and when NOT to use it. Vague or overlapping descriptions cause misrouting. Keep the set tight: about 4–5 tools per agent is optimal; piling on 18+ degrades selection reliability.

tools = [{
    "name": "get_customer",
    "description": (
        "Look up a customer by verified email or account ID. "
        "Returns name, tier, and a verified customer_id. "
        "Call this FIRST before any account action; do not guess IDs."
    ),
    "input_schema": {
        "type": "object",
        "properties": {"email": {"type": "string"}},
        "required": ["email"],
    },
}]

tool_choice — Who Decides

tool_choice controls whether and how Claude calls a tool:

  • {"type": "auto"} — Claude decides whether to reply with text or call a tool (the default).
  • {"type": "any"} — Claude MUST call some tool. This is how you guarantee structured output.
  • {"type": "tool", "name": "X"} — force one specific tool.

Use any or a forced tool when you need a machine-readable result every time; use auto for open conversation where a plain answer is sometimes correct.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "any"},  # force SOME tool -> structured result guaranteed
    messages=[{"role": "user", "content": "Find the customer alice@shop.com"}],
)

stop_reason — Reading the Outcome

Every response carries a stop_reason that tells you what to do next. Architects branch on it — they never parse the text looking for words like "done".

  • "end_turn" — Claude finished naturally; the turn is complete.
  • "tool_use" — Claude wants a tool run; execute it, append the result, continue.
  • "max_tokens" — output was truncated by the ceiling.
  • "stop_sequence" — a configured stop string was hit.

This single field is the control signal for the entire agentic loop.

response = client.messages.create(
    model="claude-opus-4-8", max_tokens=1024,
    tools=tools, messages=messages,
)

if response.stop_reason == "tool_use":
    pass   # run the tool, append result, call again
elif response.stop_reason == "end_turn":
    pass   # complete
elif response.stop_reason == "max_tokens":
    pass   # truncated -> raise max_tokens

The Agentic Loop

Tools, messages, and stop_reason combine into the core pattern: request → inspect stop_reason → if tool_use, run the tools and append results to history → repeat until end_turn.

Because the API is stateless, you append the assistant's tool request AND the tool result back into messages before the next call. Termination is driven by stop_reason — decisions are model-driven. Any iteration cap you add is a safety net, never the primary stop mechanism.

while True:
    resp = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024,
        tools=tools, messages=messages,
    )
    messages.append({"role": "assistant", "content": resp.content})
    if resp.stop_reason != "tool_use":
        break  # terminate on stop_reason, NOT on text
    results = run_tools(resp.content)          # execute each tool_use block
    messages.append({"role": "user", "content": results})

Why Statelessness Matters

Statelessness isn't a limitation to work around — it's the design that makes Claude predictable and scalable. Because the model holds no hidden state, the request is the complete truth: same six fields plus the same history produce the same behavior.

This is why context management is its own discipline. As history grows you trim verbose tool output to the relevant fields, summarize old turns, and keep critical transactional facts (IDs, amounts, dates) verbatim in a dedicated block — because the model only knows what you put back in messages.

Putting It Together

A production request is rarely just a model and a prompt. A support-agent turn combines all six fields: a routed model, a safe max_tokens, a rules-bearing system, the full messages history, a tight tools set, and a tool_choice that matches the task.

Read these six fields off any request and you can predict exactly how it will behave — that's the architect's lens.

response = client.messages.create(
    model="claude-opus-4-8",                 # routed by task difficulty
    max_tokens=2048,                          # room to finish
    system="You are a support agent. Verify identity first.",
    messages=conversation_history,            # full replay, stateless
    tools=support_tools,                      # 4-5 well-described tools
    tool_choice={"type": "auto"},             # text or tool, model decides
)

Quick Check

Test your understanding of how request fields drive behavior.

Key Takeaways

You now have the architect's mental model of a Claude request:

  • model — capability vs. cost vs. latency; route per task.
  • max_tokens — enforced output ceiling; stop_reason: "max_tokens" means truncated.
  • system — durable persona and rules; keep it stable.
  • messages — the FULL history, resent every turn, because the model holds no state.
  • tools — descriptions drive selection; keep to ~4–5 well-scoped tools.
  • tool_choice — auto / any / forced; use any to guarantee structured output.

And the loop that ties them together: drive it on stop_reason (end_turn vs tool_use), never by parsing text. Master these and the rest of the certification builds on solid ground.

자주 묻는 질문

“API 요청의 구조” 강의는 무료인가요?

네 — “API 요청의 구조” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Claude Architect 강의 전체를 잠금 해제할 수 있습니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.

“API 요청의 구조”에서 뭘 배우나요?

model, max_tokens, system, messages, tools, tool_choice를 다룹니다 브라우저에서 직접 실행하는 실습 코드로 Claude Architect을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Claude Architect을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Claude Architect은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“API 요청의 구조” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Claude Architect 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Claude Architect 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Claude 모델 제품군
  2. API 요청의 구조
  3. 중지 이유 이해하기
  4. 토큰, 컨텍스트 창 및 비용
← Claude Architect(으)로 돌아가기