Chapter 6 · Part 3

Polish, cost & next steps

You have a working app. Three finishing touches separate a demo from something you'd actually ship: handle errors, watch the cost, and pick the right model.

Handle errors

Network calls fail — rate limits, timeouts, the occasional server hiccup. The SDK raises a typed exception for each kind, so you can react appropriately instead of crashing. Catch the specific ones first, then a general fallback:

robust.py
import anthropic

try:
  message = client.messages.create(
      model="claude-opus-4-8",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello!"}],
  )
  print(message.content[0].text)
except anthropic.RateLimitError:
  print("Slow down — too many requests. Wait a moment and retry.")
except anthropic.APIError as e:
  print(f"Something went wrong: {e}")

(The SDK already retries transient failures a couple of times on its own, so you mostly need to handle the errors that persist.)

Watch the cost

Every response reports how many tokens it used. Since you pay per token — and output tokens cost several times more than input — this is how you keep the bill honest:

cost.py
message = client.messages.create(
  model="claude-opus-4-8",
  max_tokens=1024,
  messages=[{"role": "user", "content": "Explain recursion in one sentence."}],
)
print(message.usage)
# Usage(input_tokens=16, output_tokens=28, ...)

Multiply those token counts by the model's per-token price and you have the cost of the call. The whole economics — why output costs more, how conversation history quietly inflates the bill, and the levers that cut it — is exactly what The Price of a Prompt is about. Set a spending cap now, in the Console billing settings, so a runaway loop can never surprise you.

Pick the right model

You've used claude-opus-4-8, the most capable model, for everything. Real apps right-size: use a small, fast, cheap model for easy work and save the frontier model for the hard parts. It's a one-word change — the model string:

models.py
# Fast and cheap — great for simple chat and for experimenting while you learn
model="claude-haiku-4-5"

# Balanced — strong quality at lower cost than the frontier
model="claude-sonnet-5"

# Most capable — for the hardest reasoning and agentic work
model="claude-opus-4-8"

While you're learning and making lots of test calls, switch your chatbot to claude-haiku-4-5 to keep costs to a rounding error; reach for Opus when a task actually needs the extra intelligence.

Where to go next

In half an hour you went from zero to a streaming, tool-using chatbot on a real AI API — the same foundation every AI product is built on. From here:

  • Build an agent. Loop the tool-use cycle from Chapter 5 with real tools (web search, a database, code execution) and you have an agent. The SDK's tool_runner handles the loop.
  • Ground it in your documents (RAG). Combine this with the retriever from Build a RAG Chatbot to answer from your own data — swap that course's local model for the Claude call you just learned.
  • Get better answers. Everything in How to Talk to an AI applies directly to your system prompt and messages.
  • Force structured output. Ask the API for JSON that matches a schema when you need machine- readable results instead of prose.

You're no longer just using AI products — you're building them.