Prompt Engineering

Au-delà du texte : Maîtriser l'appel de fonctions dans les applications LLM

Les grands modèles de langage (LLM) ont révolutionné notre interaction avec les données, mais leur nature statique constitue un goulot d'étranglement majeur. Bien qu'un LLM puisse générer un texte convaincant sur la météo, il ne peut pas réellement vérifier la température actuelle. Cet écart entre la capacité générative et l'action dans le monde réel est comblé par l'appel de fonctions. Cette technique permet aux LLM d'interagir avec des outils externes, des API et des bases de données, les transformant de générateurs de texte passifs en agents actifs capables d'exécuter des tâches au sein de votre écosystème applicatif.

Comprendre la boucle d'appel de fonctions

L'appel de fonctions n'est pas un tour de magie où le modèle exécute directement du code. Il s'agit plutôt d'un protocole de communication structuré. Le processus suit généralement une interaction en boucle fermée :

  1. Définition des outils : Vous fournissez au LLM un schéma (généralement en JSON) définissant les fonctions disponibles, leurs noms, descriptions et paramètres.
  2. Requête de l'utilisateur : L'utilisateur pose une question ou donne une commande.
  3. Décision du modèle : Le LLM analyse la demande et détermine si une fonction est nécessaire. Il renvoie une sortie structurée spécifiant quelle fonction appeler et quels arguments utiliser.
  4. Exécution : Le code de votre application reçoit cette sortie structurée, l'analyse et exécute réellement la fonction (par exemple, en effectuant une requête HTTP).
  5. Finalisation de la réponse : Le résultat de l'exécution de la fonction est renvoyé au LLM, qui synthétise ensuite une réponse finale en langage naturel pour l'utilisateur.

Définir les outils : L'art des schémas

La qualité de l'appel de fonctions dépend fortement de la qualité de vos définitions d'outils. Le LLM utilise les descriptions pour décider quand et comment utiliser les outils. Des descriptions vagues mènent à des hallucinations ou à une utilisation incorrecte des paramètres.

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "The temperature unit to use. Infer this from the user's location."
                    }
                },
                "required": ["location"]
            }
        }
    }
]

Notez la description explicite du paramètre unit. En indiquant au modèle de « déduire cela de l'emplacement de l'utilisateur », vous l'orientez vers des hypothèses logiques plutôt que de lui faire demander à l'utilisateur des informations redondantes.

Implémentation pratique en Python

Voici un exemple simplifié de la gestion de la boucle d'appel de fonctions à l'aide d'un client API hypothétique. Notez que le LLM n'exécute jamais la fonction Python ; il décide simplement de l'appeler.

import json
from openai import OpenAI

client = OpenAI()

def get_weather(location, unit="fahrenheit"):
    # Placeholder for actual API call
    return f"The weather in {location} is sunny and {72 if unit == 'fahrenheit' else 22} degrees."

# Initial chat
response = client.chat.completions.create(
    model="gpt-4o",
    tools=tools,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What's the weather like in Boston?"}
    ]
)

# Check if the model wants to call a function
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    
    # Parse arguments
    function_name = tool_call.function.name
    arguments = json.loads(tool_call.function.arguments)
    
    # Execute the actual function
    if function_name == "get_current_weather":
        result = get_weather(**arguments)
    else:
        result = "Unknown function"
    
    # Send result back to the model
    final_response = client.chat.completions.create(
        model="gpt-4o",
        tools=tools,
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "What's the weather like in Boston?"},
            {"role": "assistant", "content": response.choices[0].message.content},
            {"role": "tool", "tool_call_id": tool_call.id, "content": result}
        ]
    )
    print(final_response.choices[0].message.content)

Meilleures pratiques pour les systèmes de production

  1. Garder les descriptions claires et concises : Le LLM lit ces descriptions. Évitez l'ambiguïté. Utilisez des exemples si les paramètres sont complexes.
  2. Limiter le nombre d'outils : Trop d'options peuvent confondre le modèle. Regroupez les outils liés ou utilisez un modèle « routeur » pour sélectionner le bon ensemble d'outils.
  3. Gérer les erreurs avec élégance : Si une fonction échoue (par exemple, délai d'attente réseau), renvoyez le message d'erreur au LLM. Il peut souvent s'excuser ou suggérer une alternative.
  4. Valider les entrées : Ne faites jamais confiance aveuglément à la sortie du LLM. Validez les types et les plages avant d'exécuter toute opération sensible.

Conclusion

L'appel de fonctions est la pierre angulaire de la construction d'agents IA intelligents. En maîtrisant l'art de définir les outils et de gérer la boucle d'exécution, vous pouvez libérer tout le potentiel des LLM pour interagir avec le monde réel. Commencez petit avec un seul outil bien défini, itérez sur les descriptions et élargissez progressivement les capacités de votre agent. L'avenir de l'IA ne consiste pas seulement à discuter ; il s'agit d'agir.

Share: