Project: Building a Calculator Agent
Let us build a complete calculator agent that handles complex multi-step math problems by breaking them into primitive operations and chaining the results.
Calculator Tool Suite
import anthropic
import json
import math
client = anthropic.Anthropic()
# ── Tool implementations ──
def add(a: float, b: float) -> float:
return a + b
def subtract(a: float, b: float) -> float:
return a - b
def multiply(a: float, b: float) -> float:
return a * b
def divide(a: float, b: float) -> float:
if b == 0:
raise ValueError("Division by zero")
return a / b
def power(base: float, exponent: float) -> float:
return math.pow(base, exponent)
def sqrt(value: float) -> float:
if value < 0:
raise ValueError("Cannot take square root of negative number")
return math.sqrt(value)
def logarithm(value: float, base: float = math.e) -> float:
if value <= 0:
raise ValueError("Logarithm undefined for non-positive values")
return math.log(value, base)
TOOL_MAP = {
"add": add, "subtract": subtract, "multiply": multiply,
"divide": divide, "power": power, "sqrt": sqrt, "logarithm": logarithm,
}
# ── Tool definitions ──
CALC_TOOLS = [
{
"name": "add",
"description": "Add two numbers: a + b",
"input_schema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]},
},
{
"name": "subtract",
"description": "Subtract b from a: a - b",
"input_schema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]},
},
{
"name": "multiply",
"description": "Multiply two numbers: a * b",
"input_schema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]},
},
{
"name": "divide",
"description": "Divide a by b: a / b. Returns error if b is 0.",
"input_schema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]},
},
{
"name": "power",
"description": "Raise base to exponent: base ** exponent",
"input_schema": {"type": "object", "properties": {"base": {"type": "number"}, "exponent": {"type": "number"}}, "required": ["base", "exponent"]},
},
{
"name": "sqrt",
"description": "Square root of a non-negative number",
"input_schema": {"type": "object", "properties": {"value": {"type": "number"}}, "required": ["value"]},
},
]
# ── Agent loop ──
def calculator_agent(problem: str) -> str:
messages = [{"role": "user", "content": problem}]
for _ in range(20):
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
system="You are a precise calculator. Break problems into atomic operations using the available tools. Show your work step by step.",
tools=CALC_TOOLS,
messages=messages,
)
if response.stop_reason == "end_turn":
return response.content[0].text
if response.stop_reason == "tool_use":
tool_results = []
for block in response.content:
if block.type == "tool_use":
handler = TOOL_MAP[block.name]
try:
result = handler(**block.input)
content = str(result)
except Exception as e:
content = json.dumps({"error": str(e)})
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": content,
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
return "Could not complete calculation."
# ── Test it ──
problems = [
"What is (15.5 * 4) + sqrt(144) - 7?",
"Calculate the compound interest on $10,000 at 5% annual rate for 3 years.",
"If a triangle has legs of 3 and 4, what is the hypotenuse?",
]
for problem in problems:
print(f"Problem: {problem}")
print(f"Answer: {calculator_agent(problem)}\n")
This calculator agent demonstrates the full tool use lifecycle: defining tools, running the agent loop, executing tool calls, and returning results until Claude has a complete answer.