Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
IT Security NachrichtenShinyHunters claims to have breached the FBI.(23.09.2026 um 18:00 Uhr)
IT Security NachrichtenSo bringen Sie Produktivität, Kosten und Governance für KI in Einklang(23.09.2026 um 18:07 Uhr)
IT Security NachrichtenNASA X-Plane: Geheimflugzeug erinnert an legendäre SR-71 Blackbird(23.09.2026 um 18:20 Uhr)
IT Security NachrichtenCould AI really destroy us all, or are humans still the bigger threat?(23.09.2026 um 17:50 Uhr)
IT Security NachrichtenShinyHunters claims to have breached the FBI.(23.09.2026 um 18:00 Uhr)
IT Security NachrichtenSo bringen Sie Produktivität, Kosten und Governance für KI in Einklang(23.09.2026 um 18:07 Uhr)
IT Security NachrichtenNASA X-Plane: Geheimflugzeug erinnert an legendäre SR-71 Blackbird(23.09.2026 um 18:20 Uhr)
IT Security NachrichtenCould AI really destroy us all, or are humans still the bigger threat?(23.09.2026 um 17:50 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Claude API Function Calling: Complete Guide to Tool Use (2026)

Originally published at kalyna.pro Function calling — what Anthropic calls tool use — lets Claude call code you write: query a database, hit an internal API, run a calculation, or check today's date. Claude never executes anything its…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Originally published at kalyna.pro




Function calling — what Anthropic calls tool use — lets Claude call code you write: query a database, hit an internal API, run a calculation, or check today's date. Claude never executes anything itself. It returns a structured request to call a specific tool with specific arguments, your code runs that tool, and you send the result back so Claude can continue. The Claude API Tutorial covers a single-tool example — this guide goes further: multi-step tool loops, parallel tool calls, forcing a specific tool, streaming tool inputs, and error handling, finishing with a complete multi-tool agent you can extend.






Prerequisites






pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-..."









Defining a Tool



A tool definition has three parts: a name, a description, and an input_schema written as JSON Schema. Claude relies entirely on these three fields to decide whether to call the tool and how to fill in its arguments.




tools = [
{
"name": "get_stock_price",
"description": "Get the current price of a stock by its ticker symbol.",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol, e.g. 'AAPL' or 'GOOGL'",
},
"currency": {
"type": "string",
"enum": ["USD", "EUR", "GBP"],
"description": "Currency to return the price in. Defaults to USD.",
},
},
"required": ["ticker"],
},
}
]






If Claude decides the tool is needed, the response has stop_reason == "tool_use" and response.content includes a tool_use block with name, input (already parsed as a dict), and a unique id.






The Tool-Use Loop



Tool use is a loop:




  1. Call messages.create() with tools and the conversation so far

  2. If stop_reason != "tool_use", Claude is done — return its text

  3. Otherwise, execute every tool_use block in response.content and collect the results

  4. Append Claude's response and a new user message containing tool_result blocks, then repeat




from anthropic import Anthropic

client = Anthropic()


def get_stock_price(ticker: str, currency: str = "USD") -> str:
prices = {"AAPL": 230.15, "GOOGL": 178.32, "MSFT": 415.50}
price = prices.get(ticker.upper())
if price is None:
return f"No data for ticker '{ticker}'"
return f"{ticker.upper()}: {price} {currency}"


tools = [...] # tool definition from above

messages = [{"role": "user", "content": "What's Apple's stock price?"}]

while True:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages,
)

if response.stop_reason != "tool_use":
print(response.content[0].text)
break

messages.append({"role": "assistant", "content": response.content})

tool_results = []
for block in response.content:
if block.type == "tool_use" and block.name == "get_stock_price":
result = get_stock_price(**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})

messages.append({"role": "user", "content": tool_results})









Parallel Tool Calls



Claude can request several tools in a single response — for example, a stock price and an exchange rate together. In that case response.content contains more than one tool_use block, each with its own id.




def get_exchange_rate(from_currency: str, to_currency: str) -> str:
rates = {("USD", "EUR"): 0.92, ("EUR", "USD"): 1.09}
rate = rates.get((from_currency.upper(), to_currency.upper()))
if rate is None:
return f"No rate for {from_currency} -> {to_currency}"
return f"1 {from_currency.upper()} = {rate} {to_currency.upper()}"


tools.append({
"name": "get_exchange_rate",
"description": "Get the exchange rate between two currencies.",
"input_schema": {
"type": "object",
"properties": {
"from_currency": {"type": "string", "description": "3-letter code, e.g. 'USD'"},
"to_currency": {"type": "string", "description": "3-letter code, e.g. 'EUR'"},
},
"required": ["from_currency", "to_currency"],
},
})






The loop from the previous section already handles parallel calls — it iterates over every block and replies with one tool_result per tool_use_id. Order doesn't matter; Claude matches results to calls by tool_use_id.






Controlling Tool Choice





  • {"type": "auto"} — default. Claude decides whether a tool is needed.


  • {"type": "any"} — Claude must call one of the provided tools.


  • {"type": "tool", "name": "..."} — Claude must call this specific tool.


  • {"type": "none"} — Claude must not call any tool.



Forcing a specific tool is a clean way to get structured JSON output:




save_contact_tool = {
"name": "save_contact",
"description": "Save extracted contact information.",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Full name of the contact"},
"email": {"type": "string", "description": "Email address"},
"phone": {"type": "string", "description": "Phone number, with country code if present"},
},
"required": ["name", "email"],
},
}

response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=[save_contact_tool],
tool_choice={"type": "tool", "name": "save_contact"},
messages=[{
"role": "user",
"content": "Reach out to John Doe at [email protected], phone +1 555-1234.",
}],
)

contact = response.content[0].input
print(contact)
# {'name': 'John Doe', 'email': '[email protected]', 'phone': '+1 555-1234'}






You can also pass "disable_parallel_tool_use": True inside tool_choice to guarantee exactly one tool call back.






Streaming Tool Inputs






with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages,
) as stream:
for event in stream:
if event.type == "content_block_delta" and event.delta.type == "input_json_delta":
print(event.delta.partial_json, end="", flush=True)

final = stream.get_final_message()

for block in final.content:
if block.type == "tool_use":
print(block.name, block.input)






get_final_message() gives you fully-parsed tool_use blocks once the stream ends — you rarely need to assemble partial_json fragments yourself.






Error Handling in Tool Results






try:
result = get_stock_price(**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
except Exception as e:
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": f"Error: {e}",
"is_error": True,
})






Claude sees the error and adapts — retries with different arguments, tries another tool, or explains the failure.






Best Practices for Tool Definitions




  • Write descriptions like API docs for a new teammate

  • Use enum to constrain free-text values

  • Keep required minimal

  • One tool = one job — avoid mega-tools

  • Return concise, structured results — large blobs cost input tokens on every following call

  • Name tools with verbs (get_, search_, create_)






Complete Example: A Multi-Tool Agent






from anthropic import Anthropic
from datetime import datetime, timezone

client = Anthropic()

def get_stock_price(ticker: str, currency: str = "USD") -> str:
prices = {"AAPL": 230.15, "GOOGL": 178.32, "MSFT": 415.50}
price = prices.get(ticker.upper())
if price is None:
return f"No data for ticker '{ticker}'"
return f"{ticker.upper()}: {price} {currency}"


def get_exchange_rate(from_currency: str, to_currency: str) -> str:
rates = {("USD", "EUR"): 0.92, ("EUR", "USD"): 1.09}
rate = rates.get((from_currency.upper(), to_currency.upper()))
if rate is None:
return f"No rate for {from_currency} -> {to_currency}"
return f"1 {from_currency.upper()} = {rate} {to_currency.upper()}"


def get_current_time() -> str:
return datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")


TOOL_FUNCTIONS = {
"get_stock_price": get_stock_price,
"get_exchange_rate": get_exchange_rate,
"get_current_time": get_current_time,
}

TOOLS = [
{
"name": "get_stock_price",
"description": "Get the current price of a stock by its ticker symbol.",
"input_schema": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "Stock ticker, e.g. 'AAPL'"},
"currency": {"type": "string", "enum": ["USD", "EUR", "GBP"], "description": "Defaults to USD"},
},
"required": ["ticker"],
},
},
{
"name": "get_exchange_rate",
"description": "Get the exchange rate between two currencies.",
"input_schema": {
"type": "object",
"properties": {
"from_currency": {"type": "string", "description": "3-letter currency code, e.g. 'USD'"},
"to_currency": {"type": "string", "description": "3-letter currency code, e.g. 'EUR'"},
},
"required": ["from_currency", "to_currency"],
},
},
{
"name": "get_current_time",
"description": "Get the current date and time in UTC.",
"input_schema": {"type": "object", "properties": {}},
},
]

def run_agent(user_message: str, max_steps: int = 5) -> str:
messages = [{"role": "user", "content": user_message}]

for _ in range(max_steps):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=TOOLS,
messages=messages,
)

if response.stop_reason != "tool_use":
return response.content[0].text

messages.append({"role": "assistant", "content": response.content})

tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
func = TOOL_FUNCTIONS[block.name]
try:
result = func(**block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
except Exception as e:
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(e),
"is_error": True,
})

messages.append({"role": "user", "content": tool_results})

return "Reached max steps without a final answer."


if __name__ == "__main__":
print(run_agent("What time is it, and how much is AAPL worth in EUR right now?"))






A single call here can trigger Claude to request get_current_time, get_stock_price, and get_exchange_rate — possibly in one parallel batch — then combine all three results into a final answer.






Summary




  • A tool is name + description + input_schema (JSON Schema)

  • Tool use is a loop: call → check stop_reason == "tool_use" → execute every tool_use block → send tool_result blocks → repeat

  • Claude can request multiple tools in one turn — match by tool_use_id, not order


  • tool_choice: auto, any, a specific tool, or none — forcing a tool is a clean way to get structured output


  • get_final_message() gives parsed tool_use blocks even when streaming

  • Set is_error: true on failed tool results

  • Write clear descriptions, use enums, keep required fields minimal, cap agent loops with a step limit



Further reading:



Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Claude API Function Calling: Complete Guide to Tool Use (2026)

Thematisch verwandte Begriffe: Claude, Function, Calling, Complete · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-92164 | Streamlink is a CLI utility which pipes video streams from various servi…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick