Function calling (tool use) premieňa LLM z textového generátora na agenta, ktorý dokáže konať.
Ako to funguje
1. Definujete dostupné funkcie (tools)
2. LLM dostane user query
3. LLM rozhodne, či potrebuje tool
4. LLM vráti štruktúrovaný call
5. Vy vykonáte funkciu
6. Výsledok vrátite LLM
7. LLM formuluje odpoveď
OpenAI Function Calling
Definícia tools
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Získa aktuálne počasie pre danú lokalitu",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Mesto, napr. 'Bratislava'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Jednotka teploty"
}
},
"required": ["location"]
}
}
}
]
Volanie API
from openai import OpenAI
import json
client = OpenAI()
def get_weather(location: str, unit: str = "celsius") -> dict:
# Skutočná implementácia
return {"temperature": 22, "condition": "sunny"}
messages = [{"role": "user", "content": "Aké je počasie v Bratislave?"}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
# Spracovanie tool calls
message = response.choices[0].message
if message.tool_calls:
for tool_call in message.tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
# Vykonanie funkcie
if function_name == "get_weather":
result = get_weather(**arguments)
# Pridanie výsledku do konverzácie
messages.append(message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
# Finálna odpoveď
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)
Claude Tool Use
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "get_stock_price",
"description": "Získa aktuálnu cenu akcie",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol"
}
},
"required": ["ticker"]
}
}
]
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "Aká je cena Apple akcií?"}]
)
# Spracovanie
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
tool_use_id = block.id
# Vykonať tool a pokračovať
Praktické príklady
Database Query Tool
{
"name": "query_database",
"description": "Vykoná SQL query nad databázou produktov",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "SQL SELECT query"
}
},
"required": ["query"]
}
}
def query_database(query: str) -> list:
# Validácia - len SELECT
if not query.strip().upper().startswith("SELECT"):
raise ValueError("Only SELECT queries allowed")
return db.execute(query).fetchall()
Email Tool
{
"name": "send_email",
"description": "Pošle email zákazníkovi",
"parameters": {
"type": "object",
"properties": {
"to": {"type": "string"},
"subject": {"type": "string"},
"body": {"type": "string"}
},
"required": ["to", "subject", "body"]
}
}
Best Practices
1. Jasné popisy
# Zlé
"description": "Počasie"
# Dobré
"description": "Získa aktuálne počasie vrátane teploty, vlhkosti a predpovede na najbližšie hodiny pre zadané mesto"
2. Validácia vstupov
def safe_execute(function_name: str, arguments: dict):
# Whitelist povolených funkcií
allowed = {"get_weather", "search_products"}
if function_name not in allowed:
raise ValueError(f"Unknown function: {function_name}")
# Sanitizácia argumentov
sanitized = sanitize_arguments(arguments)
return functions[function_name](**sanitized)
3. Error Handling
try:
result = execute_tool(tool_call)
except Exception as e:
result = {"error": str(e)}
# LLM môže gracefully handlovať chyby
Záver
Function calling je most medzi LLM a reálnym svetom. Správne implementované tools premenia chatbota na užitočného asistenta.