Tool Use in Claude: Official Course · Lesson 2
Your First Simple Tool
Build a calculator tool, define it with JSON Schema, pass it to Claude, and handle the ToolUseBlock response to get accurate arithmetic results.
The Problem: Claude Gets Math Wrong
response = client.messages.create(
model="claude-3-haiku-20240307",
messages=[{"role": "user", "content": "Multiply 1984135 by 9343116. Only respond with the result"}],
max_tokens=400
)
# Claude replied: 18593367726060
# Correct answer: 18538003464660
# Off by 55,364,261,400!
Solution: Give Claude a Calculator
def calculator(operation, operand1, operand2):
if operation == "add":
return operand1 + operand2
elif operation == "subtract":
return operand1 - operand2
elif operation == "multiply":
return operand1 * operand2
elif operation == "divide":
if operand2 == 0:
raise ValueError("Cannot divide by zero.")
return operand1 / operand2
calculator_tool = {
"name": "calculator",
"description": "A simple calculator that performs basic arithmetic operations.",
"input_schema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "The arithmetic operation to perform."
},
"operand1": {"type": "number", "description": "The first operand."},
"operand2": {"type": "number", "description": "The second operand."}
},
"required": ["operation", "operand1", "operand2"]
}
}
Full Cycle: Extract Inputs and Call the Function
response = client.messages.create(
model="claude-3-haiku-20240307",
messages=[{"role": "user", "content": "Multiply 1984135 by 9343116. Only respond with the result"}],
max_tokens=300,
tools=[calculator_tool]
)
# response.stop_reason == "tool_use"
tool_name = response.content[0].name # "calculator"
tool_inputs = response.content[0].input # {"operation": "multiply", "operand1": 1984135, "operand2": 9343116}
result = calculator(tool_inputs["operation"], tool_inputs["operand1"], tool_inputs["operand2"])
# RESULT: 18538003464660 — correct!
System Prompt Against Tool-Hungry Claude
If you ask "What color are emeralds?" with a calculator attached, Claude might try to call it. Fix:
system="You have access to tools, but only use them when necessary."
Practical exercise
What to do after this lesson
Write a temperature_converter tool with parameters value (number) and unit ('celsius'|'fahrenheit'). Implement the conversion function and a complete call cycle via Claude.
Ready-to-use prompt
Template for this lesson
Copy and adapt to your context. Text in angle brackets should be replaced.
I want to give Claude a tool for <task>.
The function is already written:
def my_tool(<params>):
# ...
Write the correct tool definition in JSON Schema format
with name, description, and input_schema fields.
Explain each parameter and whether it's required or optional.Common mistakes
What people get wrong
- Forgetting enum for string parameters with a fixed set of valid values.
- Confusing response.content[0].text (text) with response.content[0].input (tool inputs).
- Not checking stop_reason before processing — Claude might respond with text.
Pro tips
What works but no one documents
- Use enum in input_schema — Claude picks values more accurately.
- Always verify tool_name before calling the function — Claude may have chosen a different tool.
- response.content[-1] is more reliable for the tool_use block when the response contains both text and tool_use.
When to use
Precise calculations, data formatting, any deterministic operation where Claude might be unreliable.
When not to use
Simple facts Claude knows accurately — adding a tool unnecessarily slows down the response.
Official sources
Квиз — 3 вопроса
1.You defined a tool with operation enum: ['add', 'subtract', 'multiply', 'divide']. Claude sent input with operation='modulo'. What should you do?
2.Which field of a tool definition most influences whether Claude decides to call the tool?
3.After calling client.messages.create with tools=[calculator_tool], how do you get the name of the tool Claude wants to call?
Отвечено: 0 из 3