pypi-anthropic

Description
The official Python library for the anthropic API
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/pypi-anthropic@0.66.0

tools.md docs/

1
# Tool Use (Function Calling)
2
3
Tool use enables Claude to interact with external functions, APIs, and systems by calling predefined tools with structured inputs. This capability allows Claude to perform actions beyond text generation, such as calculations, data retrieval, and system interactions.
4
5
## Capabilities
6
7
### Tool Definition
8
9
Tools are defined using JSON Schema to specify function signatures, parameters, and descriptions that Claude can understand and use.
10
11
```python { .api }
12
class ToolParam(TypedDict):
13
name: str
14
description: str
15
input_schema: Dict[str, Any]
16
17
class ToolUnionParam(TypedDict, total=False):
18
type: Literal["function"]
19
function: ToolParam
20
21
class ToolChoiceParam(TypedDict, total=False):
22
type: Literal["auto", "any", "none", "tool"]
23
name: Optional[str]
24
25
class ToolChoiceAnyParam(TypedDict):
26
type: Literal["any"]
27
28
class ToolChoiceAutoParam(TypedDict):
29
type: Literal["auto"]
30
31
class ToolChoiceNoneParam(TypedDict):
32
type: Literal["none"]
33
34
class ToolChoiceToolParam(TypedDict):
35
type: Literal["tool"]
36
name: str
37
```
38
39
### Tool Use Blocks
40
41
Claude's responses when using tools include structured tool use blocks that specify which tool to call and with what parameters.
42
43
```python { .api }
44
class ToolUseBlock(TypedDict):
45
type: Literal["tool_use"]
46
id: str
47
name: str
48
input: Dict[str, Any]
49
50
class ToolUseBlockParam(TypedDict):
51
type: Literal["tool_use"]
52
id: str
53
name: str
54
input: Dict[str, Any]
55
cache_control: Optional[CacheControlEphemeralParam]
56
57
class ToolResultBlockParam(TypedDict):
58
type: Literal["tool_result"]
59
tool_use_id: str
60
content: Union[str, List[ContentBlockParam]]
61
is_error: Optional[bool]
62
cache_control: Optional[CacheControlEphemeralParam]
63
```
64
65
### Built-in Tool Types
66
67
The SDK includes predefined tool types for common use cases.
68
69
```python { .api }
70
class ToolBash20250124Param(TypedDict):
71
type: Literal["bash_20250124"]
72
name: str
73
74
class ToolTextEditor20250124Param(TypedDict):
75
type: Literal["text_editor_20250124"]
76
name: str
77
78
class ToolTextEditor20250429Param(TypedDict):
79
type: Literal["text_editor_20250429"]
80
name: str
81
82
class ToolTextEditor20250728Param(TypedDict):
83
type: Literal["text_editor_20250728"]
84
name: str
85
86
class WebSearchTool20250305Param(TypedDict):
87
type: Literal["web_search_20250305"]
88
name: str
89
```
90
91
### Server-side Tool Usage
92
93
For server-side tool implementations, the SDK provides additional types for tool usage tracking and results.
94
95
```python { .api }
96
class ServerToolUsage(TypedDict):
97
type: str
98
99
class ServerToolUseBlock(TypedDict):
100
type: Literal["tool_use"]
101
id: str
102
name: str
103
input: Dict[str, Any]
104
105
class ServerToolUseBlockParam(TypedDict):
106
type: Literal["tool_use"]
107
id: str
108
name: str
109
input: Dict[str, Any]
110
```
111
112
## Usage Examples
113
114
### Basic Tool Definition
115
116
```python
117
from anthropic import Anthropic
118
119
client = Anthropic()
120
121
# Define a simple calculator tool
122
calculator_tool = {
123
"name": "calculate",
124
"description": "Perform basic arithmetic calculations",
125
"input_schema": {
126
"type": "object",
127
"properties": {
128
"operation": {
129
"type": "string",
130
"enum": ["add", "subtract", "multiply", "divide"],
131
"description": "The arithmetic operation to perform"
132
},
133
"a": {
134
"type": "number",
135
"description": "First number"
136
},
137
"b": {
138
"type": "number",
139
"description": "Second number"
140
}
141
},
142
"required": ["operation", "a", "b"]
143
}
144
}
145
146
message = client.messages.create(
147
model="claude-sonnet-4-20250514",
148
max_tokens=1024,
149
tools=[calculator_tool],
150
messages=[
151
{"role": "user", "content": "What is 15 * 7?"}
152
]
153
)
154
155
# Claude will respond with a tool use block
156
for content in message.content:
157
if content.type == "tool_use":
158
print(f"Tool: {content.name}")
159
print(f"Input: {content.input}")
160
# Output: Tool: calculate, Input: {"operation": "multiply", "a": 15, "b": 7}
161
```
162
163
### Tool Execution and Response
164
165
```python
166
def execute_tool(tool_name: str, tool_input: dict) -> str:
167
"""Execute a tool and return the result"""
168
if tool_name == "calculate":
169
operation = tool_input["operation"]
170
a = tool_input["a"]
171
b = tool_input["b"]
172
173
if operation == "add":
174
result = a + b
175
elif operation == "subtract":
176
result = a - b
177
elif operation == "multiply":
178
result = a * b
179
elif operation == "divide":
180
if b == 0:
181
return "Error: Division by zero"
182
result = a / b
183
else:
184
return f"Error: Unknown operation {operation}"
185
186
return str(result)
187
188
return f"Error: Unknown tool {tool_name}"
189
190
# First message with tool use
191
message = client.messages.create(
192
model="claude-sonnet-4-20250514",
193
max_tokens=1024,
194
tools=[calculator_tool],
195
messages=[
196
{"role": "user", "content": "Calculate 25 + 17"}
197
]
198
)
199
200
# Process tool use and prepare response
201
tool_results = []
202
for content in message.content:
203
if content.type == "tool_use":
204
result = execute_tool(content.name, content.input)
205
tool_results.append({
206
"type": "tool_result",
207
"tool_use_id": content.id,
208
"content": result
209
})
210
211
# Send tool results back to Claude
212
response = client.messages.create(
213
model="claude-sonnet-4-20250514",
214
max_tokens=1024,
215
tools=[calculator_tool],
216
messages=[
217
{"role": "user", "content": "Calculate 25 + 17"},
218
{"role": "assistant", "content": message.content},
219
{"role": "user", "content": tool_results}
220
]
221
)
222
223
print(response.content[0].text)
224
# Output: "25 + 17 = 42"
225
```
226
227
### Multiple Tools
228
229
```python
230
# Define multiple tools
231
weather_tool = {
232
"name": "get_weather",
233
"description": "Get current weather for a location",
234
"input_schema": {
235
"type": "object",
236
"properties": {
237
"location": {
238
"type": "string",
239
"description": "City name or coordinates"
240
},
241
"units": {
242
"type": "string",
243
"enum": ["celsius", "fahrenheit"],
244
"default": "celsius"
245
}
246
},
247
"required": ["location"]
248
}
249
}
250
251
time_tool = {
252
"name": "get_time",
253
"description": "Get current time for a timezone",
254
"input_schema": {
255
"type": "object",
256
"properties": {
257
"timezone": {
258
"type": "string",
259
"description": "Timezone (e.g., 'America/New_York', 'UTC')"
260
}
261
},
262
"required": ["timezone"]
263
}
264
}
265
266
tools = [calculator_tool, weather_tool, time_tool]
267
268
message = client.messages.create(
269
model="claude-sonnet-4-20250514",
270
max_tokens=1024,
271
tools=tools,
272
messages=[
273
{"role": "user", "content": "What's the weather in London and what time is it there?"}
274
]
275
)
276
277
# Claude may use multiple tools in one response
278
for content in message.content:
279
if content.type == "tool_use":
280
print(f"Using tool: {content.name} with {content.input}")
281
```
282
283
### Tool Choice Control
284
285
```python
286
# Force Claude to use a specific tool
287
message = client.messages.create(
288
model="claude-sonnet-4-20250514",
289
max_tokens=1024,
290
tools=[calculator_tool, weather_tool],
291
tool_choice={"type": "tool", "name": "calculate"},
292
messages=[
293
{"role": "user", "content": "It's sunny today and 2 + 2 equals what?"}
294
]
295
)
296
# Claude will use the calculator tool even though weather was mentioned
297
298
# Allow any tool
299
message = client.messages.create(
300
model="claude-sonnet-4-20250514",
301
max_tokens=1024,
302
tools=[calculator_tool, weather_tool],
303
tool_choice={"type": "any"},
304
messages=[
305
{"role": "user", "content": "Hello"}
306
]
307
)
308
# Claude must use one of the available tools
309
310
# Disable tool use
311
message = client.messages.create(
312
model="claude-sonnet-4-20250514",
313
max_tokens=1024,
314
tools=[calculator_tool, weather_tool],
315
tool_choice={"type": "none"},
316
messages=[
317
{"role": "user", "content": "What is 5 + 3?"}
318
]
319
)
320
# Claude will respond in text without using tools
321
```
322
323
### Complex Tool with Nested Objects
324
325
```python
326
database_tool = {
327
"name": "query_database",
328
"description": "Query a database with filters and options",
329
"input_schema": {
330
"type": "object",
331
"properties": {
332
"table": {
333
"type": "string",
334
"description": "Table name to query"
335
},
336
"filters": {
337
"type": "object",
338
"properties": {
339
"column": {"type": "string"},
340
"operator": {"type": "string", "enum": ["=", "!=", ">", "<", ">=", "<=", "LIKE"]},
341
"value": {"type": ["string", "number", "boolean"]}
342
},
343
"required": ["column", "operator", "value"]
344
},
345
"limit": {
346
"type": "integer",
347
"minimum": 1,
348
"maximum": 1000,
349
"default": 10
350
},
351
"order_by": {
352
"type": "object",
353
"properties": {
354
"column": {"type": "string"},
355
"direction": {"type": "string", "enum": ["ASC", "DESC"]}
356
}
357
}
358
},
359
"required": ["table"]
360
}
361
}
362
363
message = client.messages.create(
364
model="claude-sonnet-4-20250514",
365
max_tokens=1024,
366
tools=[database_tool],
367
messages=[
368
{"role": "user", "content": "Find all users with age greater than 25, ordered by name, limit 5"}
369
]
370
)
371
372
for content in message.content:
373
if content.type == "tool_use":
374
print(f"Query: {content.input}")
375
# Expected: {
376
# "table": "users",
377
# "filters": {"column": "age", "operator": ">", "value": 25},
378
# "limit": 5,
379
# "order_by": {"column": "name", "direction": "ASC"}
380
# }
381
```
382
383
### Error Handling in Tools
384
385
```python
386
def safe_execute_tool(tool_name: str, tool_input: dict) -> tuple[str, bool]:
387
"""Execute tool and return (result, is_error)"""
388
try:
389
if tool_name == "divide":
390
a = tool_input["a"]
391
b = tool_input["b"]
392
if b == 0:
393
return "Cannot divide by zero", True
394
return str(a / b), False
395
else:
396
return f"Unknown tool: {tool_name}", True
397
except Exception as e:
398
return f"Tool execution error: {str(e)}", True
399
400
# Process with error handling
401
message = client.messages.create(
402
model="claude-sonnet-4-20250514",
403
max_tokens=1024,
404
tools=[calculator_tool],
405
messages=[
406
{"role": "user", "content": "What is 10 divided by 0?"}
407
]
408
)
409
410
tool_results = []
411
for content in message.content:
412
if content.type == "tool_use":
413
result, is_error = safe_execute_tool(content.name, content.input)
414
tool_results.append({
415
"type": "tool_result",
416
"tool_use_id": content.id,
417
"content": result,
418
"is_error": is_error
419
})
420
421
# Claude will handle the error appropriately
422
response = client.messages.create(
423
model="claude-sonnet-4-20250514",
424
max_tokens=1024,
425
tools=[calculator_tool],
426
messages=[
427
{"role": "user", "content": "What is 10 divided by 0?"},
428
{"role": "assistant", "content": message.content},
429
{"role": "user", "content": tool_results}
430
]
431
)
432
```
433
434
### Streaming with Tools
435
436
```python
437
with client.messages.stream(
438
model="claude-sonnet-4-20250514",
439
max_tokens=1024,
440
tools=[calculator_tool],
441
messages=[
442
{"role": "user", "content": "Calculate 15 * 23 and explain the process"}
443
]
444
) as stream:
445
for event in stream:
446
if event.type == "content_block_start":
447
if event.content_block.type == "tool_use":
448
print(f"Starting tool: {event.content_block.name}")
449
elif event.type == "content_block_delta":
450
if hasattr(event.delta, 'partial_json'):
451
print(f"Tool input building: {event.delta.partial_json}")
452
elif event.type == "content_block_stop":
453
print("Tool definition complete")
454
```
455
456
### Async Tool Usage
457
458
```python
459
import asyncio
460
from anthropic import AsyncAnthropic
461
462
async def async_tool_example():
463
client = AsyncAnthropic()
464
465
message = await client.messages.create(
466
model="claude-sonnet-4-20250514",
467
max_tokens=1024,
468
tools=[calculator_tool],
469
messages=[
470
{"role": "user", "content": "What's 42 * 1.5?"}
471
]
472
)
473
474
# Process tool use
475
for content in message.content:
476
if content.type == "tool_use":
477
result = execute_tool(content.name, content.input)
478
479
response = await client.messages.create(
480
model="claude-sonnet-4-20250514",
481
max_tokens=1024,
482
tools=[calculator_tool],
483
messages=[
484
{"role": "user", "content": "What's 42 * 1.5?"},
485
{"role": "assistant", "content": message.content},
486
{"role": "user", "content": [
487
{
488
"type": "tool_result",
489
"tool_use_id": content.id,
490
"content": result
491
}
492
]}
493
]
494
)
495
496
return response.content[0].text
497
498
result = asyncio.run(async_tool_example())
499
```