aiconfig-tools

Par launchdarkly · agent-skills

Donnez des capacités à vos agents IA grâce aux outils (function calling). Aide à identifier ce que votre IA doit faire, créer des définitions d'outils et les associer aux variations d'AI Config.

npx skills add https://github.com/launchdarkly/agent-skills --skill aiconfig-tools

Outils de configuration IA

Tu utilises une compétence qui te guidera dans l'ajout de capacités à tes agents IA par le biais des outils (function calling). Ton rôle est d'identifier ce que ton IA doit faire, de créer des définitions d'outils, de les attacher aux variations et de vérifier qu'ils fonctionnent.

Prérequis

Cette compétence nécessite que le serveur MCP LaunchDarkly hébergé à distance soit configuré dans ton environnement.

Outils MCP requis :

  • create-ai-tool -- créer une nouvelle définition d'outil avec un schéma
  • update-ai-config-variation -- attacher des outils à une variation de configuration IA
  • get-ai-config -- vérifier que les outils sont attachés à la variation

Outils MCP optionnels :

  • list-ai-tools -- parcourir les outils existants dans le projet
  • get-ai-tool -- inspecter le schéma d'un outil spécifique

Principes fondamentaux

  1. Commencer par les capacités : réfléchis à ce que ton IA doit faire avant de créer des outils
  2. Le framework compte : LangGraph/CrewAI génèrent souvent les schémas automatiquement ; le SDK OpenAI nécessite des schémas manuels
  3. Créer avant d'attacher : les outils doivent exister avant de pouvoir les attacher aux variations
  4. Vérifier : l'agent récupère la configuration pour confirmer l'attachement
  5. Compléter le workflow complet : lister les outils existants est une étape de découverte, pas l'objectif final. Après avoir listé, procède toujours à la création de l'outil demandé, à son attachement et à sa vérification. N'arrête pas après l'exploration.

Workflow

Étape 1 : Identifier les capacités nécessaires

Que devrait pouvoir faire l'IA ?

  • Interroger des bases de données, appeler des API, effectuer des calculs, envoyer des notifications
  • Vérifier ce qui existe dans la base de code (clients API, fonctions)
  • Prendre en compte le framework : LangGraph/LangChain génèrent les schémas automatiquement ; le SDK direct nécessite des schémas manuels

Si l'utilisateur te demande de d'abord vérifier les outils existants, ou si tu n'as pas de contexte de base de code sur les outils disponibles, suis cet ordre exact :

  1. list-ai-tools -- explorer ce qui existe
  2. create-ai-tool -- créer le nouvel outil (avec une clé différente de celles existantes)
  3. update-ai-config-variation -- l'attacher
  4. get-ai-config -- vérifier

Appelle list-ai-tools comme ton premier appel d'outil avant toute création. Ne t'arrête jamais après avoir listé seul -- procède toujours par les quatre étapes.

Étape 2 : Créer les outils

Utilise create-ai-tool avec :

  • key -- identifiant unique pour l'outil
  • description -- description claire (le LLM l'utilise pour décider quand appeler l'outil)
  • schema -- schéma JSON brut (n'utilise PAS le wrapper OpenAI function calling) :
{
  "type": "object",
  "properties": {
    "query": {"type": "string", "description": "Search query"},
    "limit": {"type": "integer", "default": 10}
  },
  "required": ["query"]
}

Étape 3 : Attacher à la variation

Utilise update-ai-config-variation pour attacher les outils. Passe uniquement le champ tools. Ne regroupe pas instructions, messages, model ou parameters dans ce PATCH à moins que l'utilisateur ne t'ait explicitement demandé de mettre à jour aussi ces champs. Ces champs peuvent avoir été modifiés dans l'interface LaunchDarkly depuis la création de la variation, et les inclure dans un PATCH d'attachement d'outil écrasera silencieusement les modifications de l'interface.

{
  "projectKey": "my-project",
  "configKey": "support-chatbot",
  "variationKey": "default",
  "tools": [
    {"key": "search-knowledge-base", "version": 1}
  ]
}

Si tu observes un bug manifeste d'interface où l'attachement d'outils efface d'autres champs, ne le contourne pas en renvoyant ces champs depuis la réponse get-ai-config précédente -- cela masque le bug et peut ressusciter des valeurs obsolètes que l'utilisateur a depuis modifiées. Signale le bug à la place.

Étape 4 : Vérifier

  1. Utilise get-ai-tool pour confirmer que l'outil existe avec un schéma valide
  2. Utilise get-ai-config pour confirmer que l'outil est attaché à la variation (vérifies tools dans la sortie de la variation)

Signale les résultats :

  • Outil créé avec un schéma valide
  • Outil attaché à la variation
  • Signale tout problème

Schéma par fournisseur au point d'appel

LaunchDarkly stocke le schéma d'outil une seule fois -- la forme plate {type, name, description, parameters} que tu as passée à create-ai-tool. Ton application le relit via config.model.parameters.tools (mode completion) ou agent_config.model.parameters.tools (mode agent), puis le convertit en la forme que le SDK du fournisseur attend. LaunchDarkly ne fait jamais l'appel au fournisseur ; ton code le fait. Les gestionnaires qui implémentent chaque outil restent aussi dans le code applicatif -- LaunchDarkly stocke le schéma, ton application possède le comportement.

Fournisseur / framework Forme cible Où ça va sur l'appel
OpenAI Chat Completions (SDK direct) {type: "function", function: {name, description, parameters}} top-level tools=[...]
Anthropic SDK direct {name, description, input_schema} -- renomme parametersinput_schema top-level tools=[...]
Bedrock Converse {toolSpec: {name, description, inputSchema: {json: parameters}}} dans toolConfig.tools=[...]
Gemini (google-genai) {function_declarations: [{name, description, parameters}]} (Python) / {functionDeclarations: [...]} (Node) GenerateContentConfig.tools=[...]
OpenAI Responses API La forme plate de LaunchDarkly passe inchangée top-level tools=[...]
LangChain / LangGraph LangChainProvider.createLangChainModel(config) et passe ai_config.tools (ou ta propre liste StructuredTool) dans bind_tools(...) / create_react_agent(tools=[...]) framework-native ; aucune conversion par appel
Strands Agents Forme plate de LaunchDarkly ; abandonne parameters.tools avant de passer les params à la classe de modèle Strands (AnthropicModel, OpenAIModel) -- les callables décorés Python @tool restent dans le code constructeur Agent(tools=[...]) ; aucune conversion par appel

Snippets de conversion minimale (Python) :

ld_tools = (ai_config.model.to_dict().get("parameters") or {}).get("tools", []) or []

# OpenAI Chat Completions
openai_tools = [
    {
        "type": "function",
        "function": {
            "name": t["name"],
            "description": t.get("description", ""),
            "parameters": t.get("parameters", {"type": "object", "properties": {}}),
        },
    }
    for t in ld_tools
]

# Anthropic
anthropic_tools = [
    {
        "name": t["name"],
        "description": t.get("description", ""),
        "input_schema": t.get("parameters", {"type": "object", "properties": {}}),
    }
    for t in ld_tools
]

# Bedrock Converse
bedrock_tool_config = {
    "tools": [
        {
            "toolSpec": {
                "name": t["name"],
                "description": t.get("description", ""),
                "inputSchema": {"json": t.get("parameters", {"type": "object", "properties": {}})},
            }
        }
        for t in ld_tools
    ]
}

# Gemini
gemini_tools = [
    {
        "function_declarations": [
            {
                "name": t["name"],
                "description": t.get("description", ""),
                "parameters": t.get("parameters", {"type": "object", "properties": {}}),
            }
            for t in ld_tools
        ]
    }
] if ld_tools else []

Boucle agent avec appels d'outils

Un agent qui utilise des outils exécute une courte boucle : appelle le fournisseur, distribue les appels d'outils, boucle à nouveau, arrête-toi quand le fournisseur retourne une réponse finale. Trois règles s'appliquent quel que soit le fournisseur :

  1. Limiter la boucle. MAX_STEPS = 5 est une valeur par défaut sûre. Une boucle d'outils qui s'emballe est presque toujours un bug de prompt ou de schéma, pas un cas qui nécessite 50 itérations.
  2. Suivre chaque invocation d'outil. Appelle tracker.track_tool_call(tool_name) / tracker.trackToolCall(toolName) pour chaque outil que l'agent exécute réellement. C'est ce que l'onglet Monitoring compte comme utilisation d'outils.
  3. Arrête-toi au signal « pas plus d'appels d'outils » du fournisseur. Le signal exact diffère par fournisseur : OpenAI Chat Completions → choice.finish_reason != "tool_calls"; Anthropic → response.stop_reason != "tool_use"; Bedrock Converse → response["stopReason"] != "tool_use"; Gemini → response.function_calls vide ; OpenAI Responses API → pas d'éléments function_call dans response.output.

Skeleton (Python, Anthropic -- les autres fournisseurs suivent la même forme avec leur propre vérification de raison d'arrêt et formatage de résultat d'outil) :

messages = [{"role": "user", "content": initial_input}]
MAX_STEPS = 5
for _ in range(MAX_STEPS):
    response = tracker.track_metrics_of(
        lambda: anthropic_client.messages.create(
            model=agent.model.name,
            system=agent.instructions,
            messages=messages,
            tools=anthropic_tools,
            **params,
        ),
        anthropic_metrics,
    )
    if response.stop_reason != "tool_use":
        break

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

    tool_results = []
    for block in response.content:
        if block.type != "tool_use":
            continue
        if block.name not in tool_handlers:
            raise ValueError(f"Unknown tool: {block.name}")
        result = tool_handlers[block.name](**block.input)
        tracker.track_tool_call(block.name)
        tool_results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": result,
        })
    messages.append({"role": "user", "content": tool_results})

Les formes de payload d'appel d'outil par fournisseur vivent dans les références aiconfig-ai-metrics :

Note de l'orchestrateur

LangGraph, CrewAI et AutoGen génèrent souvent les schémas à partir des définitions de fonction. Tu dois toujours créer des outils dans LaunchDarkly et attacher les clés aux variations pour que le SDK sache ce qui est disponible.

Cas limites

Situation Action
L'outil existe déjà (409) Utilise celui existant ou crée avec une clé différente
Schéma invalide Utilise le format JSON Schema brut (type: object, properties, required)
Mauvais endpoint supposé Les outils utilisent /ai-tools, pas /ai-configs/tools

Ce qu'il NE FAUT PAS faire

  • N'essaye pas d'attacher des outils pendant la création de config -- mets à jour la variation après
  • N'omets pas des descriptions claires d'outils (le LLM en a besoin pour décider quand appeler)
  • N'oublie pas de vérifier l'attachement après la mise à jour de la variation
  • Ne regroupe pas instructions, messages, model ou parameters dans le PATCH d'attachement d'outil. Envoie tools seul à moins que l'utilisateur ne t'ait explicitement demandé une mise à jour multi-champs -- les PATCHes regroupés écrasent silencieusement les modifications de l'interface sur les autres champs.

Compétences connexes

  • aiconfig-create -- Créer une config avant d'attacher les outils
  • aiconfig-variations -- Gérer les variations avec des ensembles d'outils différents

Skills similaires