Přeskočit na obsah
LLM & Agenti

Function Calling tutorial

8 min čtení
Function CallingTool UseAPI

Function Calling je klíčová technologie, která umožňuje LLM modelům a AI agentům vykonávat konkrétní funkce a interagovat s externími systémy. Tento tutoriál vás provede od základů až po pokročilé techniky implementace.

Úvod do Function Calling v Large Language Models

Function Calling (také známé jako Tool Use) představuje revoluční přístup k rozšíření schopností velkých jazykových modelů. Místo pouhého generování textu mohou LLM modely nyní aktivně volat externí funkce, API nebo nástroje, což jim umožňuje provádět konkrétní akce a získávat real-time data.

Tato technologie transformuje statické chatboty na dynamické agenty schopné interagovat s externím světem - od získávání aktuálních informací z databází po ovládání IoT zařízení.

Jak Function Calling funguje

Proces Function Calling probíhá v několika krocích:

  • Definice funkcí - Specifikujeme dostupné funkce včetně jejich parametrů
  • Požadavek uživatele - LLM analyzuje dotaz a rozhodne, zda potřebuje zavolat funkci
  • Výběr a volání - Model vybere vhodnou funkci a vygeneruje správné parametry
  • Zpracování výsledku - Aplikace provede funkci a vrátí výsledek modelu
  • Finální odpověď - LLM formuluje odpověď na základě získaných dat

Praktická implementace s OpenAI API

Podívejme se na konkrétní příklad implementace Function Calling pomocí OpenAI API v Pythonu:

import openai
import json
import requests

# Definice funkcí, které může LLM volat
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Získá aktuální počasí pro zadané město",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "Název města"
                    },
                    "units": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Teplotní jednotky"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

def get_weather(city, units="celsius"):
    """Simulace API call pro počasí"""
    # V reálné aplikaci by zde byl call na weather API
    return {
        "city": city,
        "temperature": "22°C" if units == "celsius" else "72°F",
        "condition": "slunečno",
        "humidity": "65%"
    }

Hlavní komunikační loop

def chat_with_functions(user_message):
    # Inicializace konverzace
    messages = [
        {"role": "system", "content": "Jsi užitečný asistent s přístupem k funkcím."},
        {"role": "user", "content": user_message}
    ]
    
    # První request s definicí funkcí
    response = openai.chat.completions.create(
        model="gpt-4-1106-preview",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )
    
    response_message = response.choices[0].message
    messages.append(response_message)
    
    # Kontrola, zda model chce volat funkci
    if response_message.tool_calls:
        for tool_call in response_message.tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)
            
            # Volání příslušné funkce
            if function_name == "get_weather":
                function_response = get_weather(**function_args)
            
            # Přidání výsledku do konverzace
            messages.append({
                "tool_call_id": tool_call.id,
                "role": "tool",
                "name": function_name,
                "content": json.dumps(function_response)
            })
        
        # Druhý request s výsledky funkcí
        final_response = openai.chat.completions.create(
            model="gpt-4-1106-preview",
            messages=messages
        )
        
        return final_response.choices[0].message.content
    
    return response_message.content

# Použití
result = chat_with_functions("Jaké je počasí v Praze?")
print(result)

Pokročilé techniky a best practices

Validace parametrů

Klíčové je implementovat robustní validaci parametrů, protože LLM může někdy generovat neplatné hodnoty:

from pydantic import BaseModel, ValidationError
from typing import Literal

class WeatherRequest(BaseModel):
    city: str
    units: Literal["celsius", "fahrenheit"] = "celsius"
    
    def validate_city(cls, v):
        if len(v.strip()) < 2:
            raise ValueError("Město musí mít alespoň 2 znaky")
        return v.strip().title()

def safe_get_weather(tool_call):
    try:
        args = json.loads(tool_call.function.arguments)
        validated_args = WeatherRequest(**args)
        return get_weather(validated_args.city, validated_args.units)
    except (ValidationError, json.JSONDecodeError) as e:
        return {"error": f"Neplatné parametry: {str(e)}"}

Error handling a fallbacks

def robust_function_call(tool_call, max_retries=3):
    for attempt in range(max_retries):
        try:
            function_name = tool_call.function.name
            
            if function_name == "get_weather":
                return safe_get_weather(tool_call)
            
            return {"error": f"Neznámá funkce: {function_name}"}
            
        except Exception as e:
            if attempt == max_retries - 1:
                return {"error": f"Funkce selhala po {max_retries} pokusech: {str(e)}"}
            continue

Konkrétní use case: Database agent

Praktický příklad agenta pro práci s databází:

database_tools = [
    {
        "type": "function",
        "function": {
            "name": "execute_query",
            "description": "Provede SQL SELECT dotaz na databázi",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "SQL SELECT dotaz"
                    },
                    "table": {
                        "type": "string",
                        "description": "Název tabulky pro validaci"
                    }
                },
                "required": ["query", "table"]
            }
        }
    }
]

def execute_query(query, table):
    """Bezpečné provedení SQL dotazu s validací"""
    # Základní SQL injection prevence
    forbidden_keywords = ["DROP", "DELETE", "UPDATE", "INSERT", "ALTER"]
    
    if any(keyword in query.upper() for keyword in forbidden_keywords):
        return {"error": "Dotaz obsahuje nepovolené operace"}
    
    # Simulace DB call
    if "users" in table.lower():
        return {
            "results": [
                {"id": 1, "name": "Jan Novák", "email": "[email protected]"},
                {"id": 2, "name": "Marie Svobodová", "email": "[email protected]"}
            ],
            "count": 2
        }
    
    return {"results": [], "count": 0}

Optimalizace a monitoring

Pro produkční nasazení je důležité implementovat monitoring a optimalizace:

import time
import logging
from functools import wraps

def monitor_function_calls(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        function_name = func.__name__
        
        try:
            result = func(*args, **kwargs)
            execution_time = time.time() - start_time
            
            logging.info(f"Function {function_name} executed in {execution_time:.2f}s")
            return result
            
        except Exception as e:
            logging.error(f"Function {function_name} failed: {str(e)}")
            raise
    
    return wrapper

@monitor_function_calls
def get_weather_monitored(city, units="celsius"):
    # Implementace s monitoringem
    return get_weather(city, units)

Bezpečnostní aspekty

Function Calling přináší nové bezpečnostní výzvy, které je třeba řešit:

  • Sandboxing - Izolace funkcí od kritických systémových operací
  • Rate limiting - Omezení počtu volání funkcí na časovou jednotku
  • Whitelisting - Explicitní seznam povolených operací
  • Input validation - Důsledná validace všech parametrů
  • Audit logging - Logování všech volání funkcí pro analýzu

Shrnutí

Function Calling představuje zásadní evoluci v oblasti LLM aplikací, umožňující vytváření skutečně interaktivních AI agentů. Úspěšná implementace vyžaduje pečlivé navrhování funkcí, robustní error handling a důsledné zabezpečení. S rostoucí adopcí této technologie můžeme očekávat vznik stále sofistikovanějších AI systémů schopných komplexních interakcí s reálným světem. Klíčem k úspěchu je vyvážení funkčnosti s bezpečností a udržení kontroly nad tím, co AI agent může a nemůže dělat.

CORE SYSTEMS tým

Enterprise architekti a AI inženýři.