Partager via


Compétences de l’agent

Les compétences de l’agent sont des packages portables d’instructions, de scripts et de ressources qui donnent aux agents des fonctionnalités spécialisées et une expertise de domaine. Les compétences suivent une spécification ouverte et implémentent un modèle de divulgation progressif afin que les agents chargent uniquement le contexte dont ils ont besoin, quand ils en ont besoin.

Utilisez les compétences de l’agent lorsque vous souhaitez :

  • Expertise de package dans le domaine — Capturez des connaissances spécialisées (stratégies de dépenses; flux de travail juridiques; pipelines d'analyse des données) sous forme de paquets réutilisables et portables.
  • Étendre les fonctionnalités de l’agent : donnez aux agents de nouvelles capacités sans modifier leurs instructions principales.
  • Garantir la cohérence : transformez les tâches en plusieurs étapes en flux de travail reproductibles et auditables.
  • Activer l’interopérabilité : réutilisez la même compétence entre différents produits compatibles avec les compétences de l’agent.

Structure des compétences

Une compétence est un répertoire contenant un SKILL.md fichier avec des sous-répertoires facultatifs pour les ressources :

expense-report/
├── SKILL.md                          # Required — frontmatter + instructions
├── scripts/
│   └── validate.py                   # Executable code agents can run
├── references/
│   └── POLICY_FAQ.md                 # Reference documents loaded on demand
└── assets/
    └── expense-report-template.md    # Templates and static resources

format SKILL.md

Le SKILL.md fichier doit contenir un frontmatter YAML suivi du contenu markdown :

---
name: expense-report
description: File and validate employee expense reports according to company policy. Use when asked about expense submissions, reimbursement rules, or spending limits.
license: Apache-2.0
compatibility: Requires python3
metadata:
  author: contoso-finance
  version: "2.1"
---
Champ Obligatoire Descriptif
name Oui 64 caractères maximum. Lettres minuscules, chiffres et traits d’union uniquement. Ne doit pas commencer ou se terminer par un trait d’union ou contenir des traits d’union consécutifs. Doit correspondre au nom du répertoire parent.
description Oui Que fait la compétence et quand l’utiliser. Nombre maximal de 1024 caractères. Doit inclure des mots clés qui aident les agents à identifier les tâches pertinentes.
license Non Nom de la licence ou référence à un fichier de licence groupé.
compatibility Non 500 caractères maximum. Indique la configuration requise pour l’environnement (produit prévu, packages système, accès réseau, etc.).
metadata Non Mappage de clé-valeur arbitraire pour des métadonnées supplémentaires.
allowed-tools Non Liste séparée par des espaces des outils pré-approuvés que la capacité peut utiliser. Expérimental : la prise en charge peut varier entre les implémentations de l’agent.

Le corps markdown après le frontmatter contient les instructions pour la compétence : instructions pas à pas, exemples d’entrées et de sorties, cas limites courants ou tout contenu qui aide l’agent à effectuer la tâche. Conservez moins de 500 lignes et déplacez SKILL.md des documents de référence détaillés vers des fichiers distincts.

Divulgation progressive

Les compétences de l’agent utilisent un modèle de divulgation progressive en quatre étapes pour réduire l’utilisation du contexte :

  1. Publier (~100 jetons par compétence) : les noms et descriptions des compétences sont injectés dans l’invite système au début de chaque exécution, de sorte que l’agent sait quelles compétences sont disponibles.
  2. Charger ( 5 000 jetons recommandés) :< lorsqu’une tâche correspond au domaine d’une compétence, l’agent appelle l’outil load_skill pour récupérer le corps complet SKILL.md avec des instructions détaillées.
  3. Lire les ressources (si nécessaire) : l’agent appelle l’outil read_skill_resource pour récupérer des fichiers supplémentaires (références, modèles, ressources) uniquement si nécessaire.
  4. Exécuter des scripts (si nécessaire) : l’agent appelle l’outil run_skill_script pour exécuter des scripts groupés avec une compétence.

Ce schéma maintient la fenêtre de contexte de l'agent allégée tout en lui donnant accès à une connaissance approfondie du domaine à la demande.

Note

load_skill est toujours annoncé. read_skill_resource est publié uniquement lorsque au moins une compétence possède des ressources. run_skill_script est annoncé uniquement quand au moins une compétence possède des scripts.

Fournir des compétences à un agent

AgentSkillsProvider (C#) et SkillsProvider (Python) sont des fournisseurs de contexte qui rendent les compétences disponibles pour les agents. Ils prennent en charge trois sources de compétences :

  • Basée sur des fichiers : compétences découvertes à partir de SKILL.md fichiers dans les répertoires du système de fichiers
  • Code défini : compétences définies dans le code à l’aide de AgentInlineSkill (C#) ou Skill (Python)
  • Basée sur des classes — compétences encapsulées dans une classe C# dérivée de AgentClassSkill<T> (C# uniquement)

Pour combiner plusieurs sources dans un seul fournisseur, utilisez AgentSkillsProviderBuilder (C# uniquement : Générateur : scénarios multi-sources avancés).

Compétences basées sur des fichiers

Créez un AgentSkillsProvider pointant vers un répertoire contenant vos compétences, et ajoutez-le aux fournisseurs de contexte de l’agent. Transmettez un exécuteur de script pour permettre l’exécution de scripts basés sur des fichiers trouvés dans les répertoires de compétences :

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;

string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

// Discover skills from the 'skills' directory
var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "skills"));

// Create an agent with the skills provider
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetResponsesClient()
    .AsAIAgent(new ChatClientAgentOptions
    {
        Name = "SkillsAgent",
        ChatOptions = new()
        {
            Instructions = "You are a helpful assistant.",
        },
        AIContextProviders = [skillsProvider],
    },
    model: deploymentName);

Avertissement

DefaultAzureCredential est pratique pour le développement, mais nécessite une considération minutieuse en production. En production, envisagez d’utiliser des informations d’identification spécifiques (par exemple ManagedIdentityCredential) pour éviter les problèmes de latence, la détection involontaire des informations d’identification et les risques de sécurité potentiels liés aux mécanismes de secours.

Répertoires de compétences multiples

Vous pouvez pointer le fournisseur vers un répertoire parent unique : chaque sous-répertoire contenant un SKILL.md est automatiquement découvert en tant que compétence :

var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "all-skills"));

Ou passez une liste de chemins pour rechercher dans plusieurs répertoires racine :

var skillsProvider = new AgentSkillsProvider(
    [
        Path.Combine(AppContext.BaseDirectory, "company-skills"),
        Path.Combine(AppContext.BaseDirectory, "team-skills"),
    ]);

Le fournisseur recherche jusqu’à deux niveaux de profondeur.

Personnalisation de la découverte de ressources

Par défaut, le fournisseur reconnaît les ressources avec des extensions .md, .json, .yaml, .yml, .csv, .xml dans les sous-répertoires .txt et references, assets. Utilisez cette option AgentFileSkillsSourceOptions pour modifier les valeurs par défaut suivantes :

var fileOptions = new AgentFileSkillsSourceOptions
{
    AllowedResourceExtensions = [".md", ".txt"],
    ResourceDirectories = ["docs", "templates"],
};

var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "skills"),
    fileOptions: fileOptions);

Exécution des scripts

Passez SubprocessScriptRunner.RunAsync en tant que deuxième argument pour AgentSkillsProvider afin d’activer l’exécution de scripts basés sur des fichiers :

var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "skills"),
    SubprocessScriptRunner.RunAsync);

SubprocessScriptRunner.RunAsync équivaut à peu près à ce qui suit :

// Simplified equivalent of what SubprocessScriptRunner.RunAsync does internally
using System.Diagnostics;

static async Task<string> RunAsync(AgentSkill skill, AgentSkillScript script, IDictionary<string, object?>? args)
{
    var psi = new ProcessStartInfo("python3")
    {
        RedirectStandardOutput = true,
        UseShellExecute = false,
    };
    psi.ArgumentList.Add(Path.Combine(skill.Path, script.Path));
    if (args != null)
    {
        foreach (var (key, value) in args)
        {
            if (value is not null)
            {
                psi.ArgumentList.Add($"--{key}");
                psi.ArgumentList.Add(value.ToString()!);
            }
        }
    }
    using var process = Process.Start(psi)!;
    string output = await process.StandardOutput.ReadToEndAsync();
    await process.WaitForExitAsync();
    return output.Trim();
}

L’exécuteur exécute chaque script découvert en tant que sous-processus local, en transférant les arguments JSON fournis par l’agent en tant qu’indicateurs de ligne de commande.

Avertissement

SubprocessScriptRunner est fourni uniquement à des fins de démonstration. Pour une utilisation en production, envisagez d’ajouter :

  • Sandboxing (par exemple, conteneurs ou environnements d’exécution isolés)
  • Limites des ressources (processeur, mémoire, délai d’expiration de l’horloge murale)
  • Validation des entrées et liste d'autorisation des scripts exécutables
  • Pistes de journalisation et d’audit structurées

Personnalisation de la découverte de scripts

Par défaut, le fournisseur reconnaît les scripts avec des extensions.py, , .js.sh, .ps1, .cset .csx dans le scripts sous-répertoire. Utilisez cette option AgentFileSkillsSourceOptions pour modifier les valeurs par défaut suivantes :

Passez AgentFileSkillsSourceOptions au constructeur AgentSkillsProvider ou à UseFileSkill / UseFileSkills sur le constructeur :

var fileOptions = new AgentFileSkillsSourceOptions
{
    AllowedScriptExtensions = [".py"],
    ScriptDirectories = ["scripts", "tools"],
};

// Via constructor
var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "skills"),
    fileOptions: fileOptions);

// Via builder
var skillsProvider = new AgentSkillsProviderBuilder()
    .UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"), options: fileOptions)
    .Build();

Compétences basées sur des fichiers

Créez un SkillsProvider pointant vers un répertoire contenant vos compétences et ajoutez-le aux fournisseurs de contexte de l’agent.

import os
from pathlib import Path
from agent_framework import SkillsProvider
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity.aio import AzureCliCredential

# Discover skills from the 'skills' directory
skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "skills"
)

# Create an agent with the skills provider
agent = OpenAIChatCompletionClient(
    model=os.environ["AZURE_OPENAI_CHAT_COMPLETION_MODEL"],
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    credential=AzureCliCredential(),
).as_agent(
    name="SkillsAgent",
    instructions="You are a helpful assistant.",
    context_providers=[skills_provider],
)

Répertoires de compétences multiples

Vous pouvez pointer le fournisseur vers un dossier parent unique : chaque sous-dossier contenant un SKILL.md est automatiquement découvert en tant que compétence :

skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "all-skills"
)

Ou passez une liste de chemins pour rechercher dans plusieurs répertoires racine :

skills_provider = SkillsProvider(
    skill_paths=[
        Path(__file__).parent / "company-skills",
        Path(__file__).parent / "team-skills",
    ]
)

Le fournisseur recherche jusqu’à deux niveaux de profondeur.

Personnalisation de la découverte de ressources

Par défaut, SkillsProvider reconnaît les ressources avec des extensions .md, .json, .yaml, .yml, .csv, .xml, et .txt. Il analyse tous les sous-répertoires au sein de chaque dossier de compétence. resource_extensions Passez un argument pour modifier les types de fichiers reconnus :

skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "skills",
    resource_extensions=(".md", ".txt"),
)

Exécution des scripts

Pour activer l’exécution de scripts basés sur des fichiers, passez-à script_runner à SkillsProvider. Toute synchronisation ou appel asynchrone qui satisfait le SkillScriptRunner protocole peut être utilisé :

from pathlib import Path
from agent_framework import Skill, SkillScript, SkillsProvider

def my_runner(skill: Skill, script: SkillScript, args: dict | None = None) -> str:
    """Run a file-based script as a subprocess."""
    import subprocess, sys
    cmd = [sys.executable, str(Path(skill.path) / script.path)]
    if args:
        for key, value in args.items():
            if value is not None:
                cmd.extend([f"--{key}", str(value)])
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    return result.stdout.strip()

skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "skills",
    script_runner=my_runner,
)

L’exécuteur reçoit Skill résolu, SkillScript, et un dictionnaire facultatif args. Les scripts basés sur des fichiers sont automatiquement détectés à partir de .py fichiers dans les répertoires de compétences.

Avertissement

L'outil d'exécution ci-dessus est fourni uniquement à des fins de démonstration. Pour une utilisation en production, envisagez d’ajouter :

  • Bac à sable (par exemple, conteneurs, seccomp, ou firejail)
  • Limites des ressources (processeur, mémoire, délai d’expiration de l’horloge murale)
  • Validation des entrées et liste d'autorisation des scripts exécutables
  • Pistes de journalisation et d’audit structurées

Note

Si les compétences basées sur des fichiers avec des scripts sont fournies, mais qu'aucun script_runner n'est défini, SkillsProvider lève un ValueError.

Compétences définies par le code

En plus des compétences basées sur des fichiers découvertes dans les fichiers SKILL.md, vous pouvez définir des compétences entièrement dans le code à l’aide de AgentInlineSkill. Les compétences définies par le code sont utiles quand :

  • Le contenu de compétence est généré dynamiquement (par exemple, lecture à partir d’une base de données ou d’un environnement).
  • Vous souhaitez conserver les définitions de compétences en même temps que le code d’application qui les utilise.
  • Vous avez besoin de ressources qui exécutent la logique au moment de la lecture plutôt que de servir des fichiers statiques.

Compétence de code de base

Créez un AgentInlineSkill avec un nom, une description et des instructions. Attacher des ressources à l’aide de .AddResource():

using Microsoft.Agents.AI;

var codeStyleSkill = new AgentInlineSkill(
    name: "code-style",
    description: "Coding style guidelines and conventions for the team",
    instructions: """
        Use this skill when answering questions about coding style, conventions, or best practices for the team.
        1. Read the style-guide resource for the full set of rules.
        2. Answer based on those rules, quoting the relevant guideline where helpful.
        """)
    .AddResource(
        "style-guide",
        """
        # Team Coding Style Guide
        - Use 4-space indentation (no tabs)
        - Maximum line length: 120 characters
        - Use type annotations on all public methods
        """);

var skillsProvider = new AgentSkillsProvider(codeStyleSkill);

Ressources dynamiques

Passez un délégué d’usine à .AddResource() pour calculer le contenu au moment de l’exécution. Le délégué est appelé chaque fois que l’agent lit la ressource :

var projectInfoSkill = new AgentInlineSkill(
    name: "project-info",
    description: "Project status and configuration information",
    instructions: """
        Use this skill for questions about the current project.
        1. Read the environment resource for deployment configuration details.
        2. Read the team-roster resource for information about team members.
        """)
    .AddResource("environment", () =>
    {
        string env = Environment.GetEnvironmentVariable("APP_ENV") ?? "development";
        string region = Environment.GetEnvironmentVariable("APP_REGION") ?? "us-east-1";
        return $"Environment: {env}, Region: {region}";
    })
    .AddResource(
        "team-roster",
        "Alice Chen (Tech Lead), Bob Smith (Backend Engineer)");

Scripts définis par le code

Utilisez .AddScript() pour inscrire un délégué en tant que script exécutable. Les scripts définis par le code s’exécutent dans le même processus comme des appels de délégués directs. Aucun exécuteur de script n’est nécessaire. Les paramètres typés du délégué sont automatiquement convertis en schéma JSON que l’agent utilise pour passer des arguments :

using System.Text.Json;

var unitConverterSkill = new AgentInlineSkill(
    name: "unit-converter",
    description: "Convert between common units using a conversion factor",
    instructions: """
        Use this skill when the user asks to convert between units.
        1. Review the conversion-table resource to find the correct factor.
        2. Use the convert script, passing the value and factor from the table.
        3. Present the result clearly with both units.
        """)
    .AddResource(
        "conversion-table",
        """
        # Conversion Tables
        Formula: **result = value × factor**
        | From       | To         | Factor   |
        |------------|------------|----------|
        | miles      | kilometers | 1.60934  |
        | kilometers | miles      | 0.621371 |
        | pounds     | kilograms  | 0.453592 |
        | kilograms  | pounds     | 2.20462  |
        """)
    .AddScript("convert", (double value, double factor) =>
    {
        double result = Math.Round(value * factor, 4);
        return JsonSerializer.Serialize(new { value, factor, result });
    });

var skillsProvider = new AgentSkillsProvider(unitConverterSkill);

Note

Pour combiner des compétences définies par le code avec des compétences basées sur des fichiers ou basées sur des classes dans un seul fournisseur, utilisez AgentSkillsProviderBuilder : Générateur : scénarios multi source avancés.

En plus des compétences basées sur des fichiers découvertes à partir de fichiers SKILL.md, vous pouvez définir des compétences entièrement dans Python code. Les compétences définies par le code sont utiles quand :

  • Le contenu de compétence est généré dynamiquement (par exemple, lecture à partir d’une base de données ou d’un environnement).
  • Vous souhaitez conserver les définitions de compétences en même temps que le code d’application qui les utilise.
  • Vous avez besoin de ressources qui exécutent la logique au moment de la lecture plutôt que de servir des fichiers statiques.

Compétence de code de base

Créez une instance avec un Skill nom, une description et un contenu d’instruction. Attachez éventuellement des SkillResource instances avec du contenu statique :

from textwrap import dedent
from agent_framework import Skill, SkillResource, SkillsProvider

code_style_skill = Skill(
    name="code-style",
    description="Coding style guidelines and conventions for the team",
    content=dedent("""\
        Use this skill when answering questions about coding style,
        conventions, or best practices for the team.
    """),
    resources=[
        SkillResource(
            name="style-guide",
            content=dedent("""\
                # Team Coding Style Guide
                - Use 4-space indentation (no tabs)
                - Maximum line length: 120 characters
                - Use type annotations on all public functions
            """),
        ),
    ],
)

skills_provider = SkillsProvider(skills=[code_style_skill])

Ressources dynamiques

Utilisez le @skill.resource décorateur pour inscrire une fonction en tant que ressource. La fonction est appelée chaque fois que l’agent lit la ressource, afin qu’elle puisse retourner des données up-to-date. Les fonctions de synchronisation et asynchrone sont prises en charge :

import os
from agent_framework import Skill

project_info_skill = Skill(
    name="project-info",
    description="Project status and configuration information",
    content="Use this skill for questions about the current project.",
)

@project_info_skill.resource
def environment() -> Any:
    """Get current environment configuration."""
    env = os.environ.get("APP_ENV", "development")
    region = os.environ.get("APP_REGION", "us-east-1")
    return f"Environment: {env}, Region: {region}"

@project_info_skill.resource(name="team-roster", description="Current team members")
def get_team_roster() -> Any:
    """Return the team roster."""
    return "Alice Chen (Tech Lead), Bob Smith (Backend Engineer)"

Lorsque le décorateur est utilisé sans arguments (@skill.resource), le nom de la fonction devient le nom de la ressource et la documentation devient la description. Permet @skill.resource(name="...", description="...") de les définir explicitement.

Scripts définis par le code

Utilisez le décorateur @skill.script pour enregistrer une fonction en tant que script exécutable sur une fonctionnalité. Les scripts définis par le code s’exécutent en cours et ne nécessitent pas d’exécuteur de script. Les fonctions de synchronisation et asynchrone sont prises en charge :

from agent_framework import Skill

unit_converter_skill = Skill(
    name="unit-converter",
    description="Convert between common units using a conversion factor",
    content="Use the convert script to perform unit conversions.",
)

@unit_converter_skill.script(name="convert", description="Convert a value: result = value × factor")
def convert_units(value: float, factor: float) -> str:
    """Convert a value using a multiplication factor."""
    import json
    result = round(value * factor, 4)
    return json.dumps({"value": value, "factor": factor, "result": result})

Lorsque le décorateur est utilisé sans arguments (@skill.script), le nom de la fonction devient le nom du script et la documentation devient la description. Les paramètres typés de la fonction sont automatiquement convertis en schéma JSON que l’agent utilise pour passer des arguments.

Combinaison de compétences basées sur des fichiers et définies par le code

Passez les deux skill_paths et skills à un seul SkillsProvider. Les compétences basées sur des fichiers sont découvertes en premier ; si une compétence définie par le code porte le même nom qu’une compétence existante basée sur un fichier, la compétence définie par le code est ignorée :

from pathlib import Path
from agent_framework import Skill, SkillsProvider

my_skill = Skill(
    name="my-code-skill",
    description="A code-defined skill",
    content="Instructions for the skill.",
)

skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "skills",
    skills=[my_skill],
)

Compétences par classe

Les compétences basées sur des classes vous permettent de regrouper tous les composants de compétence ( nom, description, instructions, ressources et scripts) dans une classe C# unique. Dérivez de AgentClassSkill<T> (où T est votre classe), puis annotez les propriétés avec [AgentSkillResource] et les méthodes avec [AgentSkillScript] pour une découverte automatique.

using System.ComponentModel;
using System.Text.Json;
using Microsoft.Agents.AI;

internal sealed class UnitConverterSkill : AgentClassSkill<UnitConverterSkill>
{
    public override AgentSkillFrontmatter Frontmatter { get; } = new(
        "unit-converter",
        "Convert between common units using a multiplication factor. Use when asked to convert miles, kilometers, pounds, or kilograms.");

    protected override string Instructions => """
        Use this skill when the user asks to convert between units.

        1. Review the conversion-table resource to find the correct factor.
        2. Use the convert script, passing the value and factor from the table.
        3. Present the result clearly with both units.
        """;

    [AgentSkillResource("conversion-table")]
    [Description("Lookup table of multiplication factors for common unit conversions.")]
    public string ConversionTable => """
        # Conversion Tables
        Formula: **result = value × factor**
        | From       | To         | Factor   |
        |------------|------------|----------|
        | miles      | kilometers | 1.60934  |
        | kilometers | miles      | 0.621371 |
        | pounds     | kilograms  | 0.453592 |
        | kilograms  | pounds     | 2.20462  |
        """;

    [AgentSkillScript("convert")]
    [Description("Multiplies a value by a conversion factor and returns the result as JSON.")]
    private static string ConvertUnits(double value, double factor)
    {
        double result = Math.Round(value * factor, 4);
        return JsonSerializer.Serialize(new { value, factor, result });
    }
}

Inscrivez la compétence basée sur la classe avec AgentSkillsProvider:

var skill = new UnitConverterSkill();
var skillsProvider = new AgentSkillsProvider(skill);

Lorsque l’attribut [AgentSkillResource] est appliqué à une propriété ou à une méthode, sa valeur de retour est utilisée comme contenu de ressource lorsque l’agent lit la ressource : utilisez une méthode lorsque le contenu doit être calculé au moment de la lecture. Lorsqu’elle [AgentSkillScript] est appliquée à une méthode, la méthode est appelée lorsque l’agent appelle le script. Utilisez [Description] de System.ComponentModel pour décrire chaque ressource et script pour l'agent.

Note

AgentClassSkill<T> prend également en charge le remplacement de Resources et des collections Scripts pour les scénarios où la découverte basée sur des attributs ne convient pas.

Générateur : scénarios multi source avancés

Pour les scénarios simples et à source unique, utilisez directement les AgentSkillsProvider constructeurs. Utilisez AgentSkillsProviderBuilder quand vous avez besoin de l’un des éléments suivants :

  • Types de compétences mixtes : combinez des compétences basées sur des fichiers, définies par le code (AgentInlineSkill) et basées surAgentClassSkill des classes dans un seul fournisseur.
  • Filtrage des compétences : inclure ou exclure des compétences à l’aide d’un prédicat.

Types de compétences mixtes

Combinez les trois types de compétences dans un seul fournisseur en chaînant UseFileSkill, UseSkillet UseFileScriptRunner:

var skillsProvider = new AgentSkillsProviderBuilder()
    .UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))  // file-based skills
    .UseSkill(volumeConverterSkill)                                  // AgentInlineSkill
    .UseSkill(temperatureConverter)                                  // AgentClassSkill
    .UseFileScriptRunner(SubprocessScriptRunner.RunAsync)            // runner for file scripts
    .Build();

Filtrage des compétences

Utilisez cette option UseFilter pour inclure uniquement les compétences qui répondent à vos critères, par exemple pour charger des compétences à partir d’un répertoire partagé, mais exclure celles expérimentales :

var approvedSkillNames = new HashSet<string> { "expense-report", "code-style" };

var skillsProvider = new AgentSkillsProviderBuilder()
    .UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
    .UseFilter(skill => approvedSkillNames.Contains(skill.Frontmatter.Name))
    .Build();

Approbation de script

Utilise AgentSkillsProviderOptions.ScriptApproval pour limiter l'exécution de tous les scripts avec l'approbation humaine. Lorsqu’il est activé, l’agent suspend et retourne une demande d’approbation au lieu d’exécuter immédiatement :

var skillsProvider = new AgentSkillsProvider(
    skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
    options: new AgentSkillsProviderOptions
    {
        ScriptApproval = true,
    });

Pour activer l’approbation de script sur un fournisseur configuré par le générateur, utilisez UseScriptApproval:

var skillsProvider = new AgentSkillsProviderBuilder()
    .UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
    .UseScriptApproval(true)
    .Build();

Utilisez require_script_approval=True sur SkillsProvider pour contrôler l'exécution de tous les scripts après l'approbation humaine. Au lieu d’exécuter immédiatement, l’agent suspend et retourne des demandes d’approbation :

from agent_framework import Agent, Skill, SkillsProvider

# Create provider with approval enabled
skills_provider = SkillsProvider(
    skills=[my_skill],
    require_script_approval=True,
)

# Run the agent — script calls pause for approval
result = await agent.run("Deploy version 2.5.0 to production", session=session)

# Handle approval requests
while result.user_input_requests:
    for request in result.user_input_requests:
        print(f"Script: {request.function_call.name}")
        print(f"Args: {request.function_call.arguments}")

        approval = request.to_function_approval_response(approved=True)
        result = await agent.run(approval, session=session)

Lorsqu’un script est rejeté (approved=False), l’agent est informé que l’utilisateur a refusé et peut répondre en conséquence.

Invite système personnalisé

Par défaut, le fournisseur de compétences injecte une invite système qui répertorie les compétences disponibles et indique à l’agent d’utiliser load_skill et read_skill_resource. Vous pouvez personnaliser cette invite :

var skillsProvider = new AgentSkillsProvider(
    skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
    options: new AgentSkillsProviderOptions
    {
        SkillsInstructionPrompt = """
            You have skills available. Here they are:
            {skills}
            {resource_instructions}
            {script_instructions}
            """
    });

Note

Le modèle personnalisé doit contenir les espaces réservés {skills} (liste de compétences), {resource_instructions} (indicateur d’outil de ressource), et {script_instructions} (indicateur d’outil de script). Les accolades littérales doivent être échappées en utilisant {{ et }}.

skills_provider = SkillsProvider(
    skill_paths=Path(__file__).parent / "skills",
    instruction_template=(
        "You have skills available. Here they are:\n{skills}\n"
        "Use the `load_skill` function to get skill instructions.\n"
        "Use the `read_skill_resource` function to read skill files."
    ),
)

Note

Le modèle personnalisé doit contenir un {skills} espace réservé où la liste de compétences est insérée et un {runner_instructions} espace réservé où les instructions liées au script sont insérées.

Comportement de mise en cache

Par défaut, les outils de compétence et les instructions sont mis en cache après la première génération. Définissez DisableCaching = true sur AgentSkillsProviderOptions pour forcer une reconstruction à chaque appel :

var skillsProvider = new AgentSkillsProvider(
    Path.Combine(AppContext.BaseDirectory, "skills"),
    options: new AgentSkillsProviderOptions
    {
        DisableCaching = true,
    });

Note

La désactivation de la mise en cache est utile pendant le développement lorsque le contenu des compétences change fréquemment. En production, laissez la mise en cache activée (valeur par défaut) pour améliorer les performances.

Injection de dépendances

Les délégués de ressources de compétence et de script peuvent déclarer un IServiceProvider paramètre que le cadre de l'agent injecte automatiquement. Cela permet aux compétences de résoudre les services d’application , tels que les clients de base de données, la configuration ou la logique métier, sans les coder en dur dans la définition de compétence.

Paramétrage

Inscrivez vos services d’application et passez l’élément IServiceProvider construit à l’agent via le paramètre services :

using Microsoft.Extensions.DependencyInjection;

// Register application services
ServiceCollection services = new();
services.AddSingleton<ConversionService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

// Create the agent and pass the service provider
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetResponsesClient()
    .AsAIAgent(
        options: new ChatClientAgentOptions
        {
            Name = "ConverterAgent",
            ChatOptions = new() { Instructions = "You are a helpful assistant." },
            AIContextProviders = [skillsProvider],
        },
        model: deploymentName,
        services: serviceProvider);

Compétences définies par le code avec DI

Déclarez IServiceProvider en tant que paramètre dans AddResource ou AddScript délégués : l’infrastructure résout et l’injecte automatiquement lorsque l’agent lit une ressource ou exécute un script :

var distanceSkill = new AgentInlineSkill(
    name: "distance-converter",
    description: "Convert between distance units (miles and kilometers).",
    instructions: """
        Use this skill when the user asks to convert between miles and kilometers.
        1. Read the distance-table resource for conversion factors.
        2. Use the convert script to compute the result.
        """)
    .AddResource("distance-table", (IServiceProvider sp) =>
    {
        return sp.GetRequiredService<ConversionService>().GetDistanceTable();
    })
    .AddScript("convert", (double value, double factor, IServiceProvider sp) =>
    {
        return sp.GetRequiredService<ConversionService>().Convert(value, factor);
    });

Compétences basées sur des classes avec DI

Annoter les méthodes avec [AgentSkillResource] ou [AgentSkillScript] déclarer un IServiceProvider paramètre : l’infrastructure découvre ces membres via la réflexion et injecte automatiquement le fournisseur de services :

internal sealed class WeightConverterSkill : AgentClassSkill<WeightConverterSkill>
{
    public override AgentSkillFrontmatter Frontmatter { get; } = new(
        "weight-converter",
        "Convert between weight units (pounds and kilograms).");

    protected override string Instructions => """
        Use this skill when the user asks to convert between pounds and kilograms.
        1. Read the weight-table resource for conversion factors.
        2. Use the convert script to compute the result.
        """;

    [AgentSkillResource("weight-table")]
    [Description("Lookup table of multiplication factors for weight conversions.")]
    private static string GetWeightTable(IServiceProvider serviceProvider)
    {
        return serviceProvider.GetRequiredService<ConversionService>().GetWeightTable();
    }

    [AgentSkillScript("convert")]
    [Description("Multiplies a value by a conversion factor and returns the result as JSON.")]
    private static string Convert(double value, double factor, IServiceProvider serviceProvider)
    {
        return serviceProvider.GetRequiredService<ConversionService>().Convert(value, factor);
    }
}

Conseil / Astuce

Les compétences basées sur des classes peuvent également résoudre les dépendances par le biais de leur constructeur. Inscrivez la classe de compétence dans le ServiceCollection conteneur et résolvez-la à partir du conteneur au lieu d’appeler new directement :

services.AddSingleton<WeightConverterSkill>();
var weightSkill = serviceProvider.GetRequiredService<WeightConverterSkill>();

Cela est utile lorsque la classe de compétences elle-même a besoin de services injectés au-delà de ce que les délégués de ressource et de script utilisent.

Les fonctions de ressource et de script qui acceptent **kwargs reçoivent automatiquement les arguments de mots-clés d'exécution passés à agent.run(). Cela permet aux fonctions de compétence d’accéder au contexte d’application ( configuration, identité utilisateur ou clients de service) sans les coder en dur dans la définition de compétence.

Passage d’arguments d’exécution

Passez function_invocation_kwargs à agent.run() pour fournir des arguments nommés que le framework transmet aux fonctions de ressource et de script :

response = await agent.run(
    "How many kilometers is 26.2 miles?",
    function_invocation_kwargs={"precision": 2, "user_id": "alice"},
)

Fonctions de ressources avec kwargs

Lorsqu’une fonction de ressource déclare **kwargs, l’infrastructure transfère les arguments de mot clé runtime chaque fois que l’agent lit la ressource :

from typing import Any
from agent_framework import Skill

project_info_skill = Skill(
    name="project-info",
    description="Project status and configuration information",
    content="Use this skill for questions about the current project.",
)

@project_info_skill.resource(name="environment", description="Current environment configuration")
def environment(**kwargs: Any) -> Any:
    """Return environment config, optionally scoped to a user."""
    user_id = kwargs.get("user_id", "anonymous")
    env = os.environ.get("APP_ENV", "development")
    return f"Environment: {env}, Caller: {user_id}"

Les fonctions de ressource sans **kwargs sont appelées sans arguments et ne reçoivent pas de contexte d’exécution.

Fonctions de script avec kwargs

Lorsqu’une fonction de script déclare **kwargs, l’infrastructure transfère les arguments de mot clé runtime en même temps que ceux args fournis par l’agent :

import json
from typing import Any
from agent_framework import Skill

converter_skill = Skill(
    name="unit-converter",
    description="Convert between common units using a conversion factor",
    content="Use the convert script to perform unit conversions.",
)

@converter_skill.script(name="convert", description="Convert a value: result = value × factor")
def convert_units(value: float, factor: float, **kwargs: Any) -> str:
    """Convert a value using a multiplication factor.

    Args:
        value: The numeric value to convert (provided by the agent).
        factor: Conversion factor (provided by the agent).
        **kwargs: Runtime keyword arguments from agent.run().
    """
    precision = kwargs.get("precision", 4)
    result = round(value * factor, precision)
    return json.dumps({"value": value, "factor": factor, "result": result})

L’agent fournit value et factor par le biais de l’appel argsd’outil ; l’application fournit precision via function_invocation_kwargs. Les fonctions de script sans **kwargs recevoir uniquement les arguments fournis par l’agent.

Bonnes pratiques de sécurité

Les compétences de l’agent doivent être traitées comme tout code tiers que vous apportez dans votre projet. Étant donné que les instructions de compétence sont injectées dans le contexte de l’agent , et que les compétences peuvent inclure des scripts, l’application du même niveau de révision et de gouvernance que vous feriez à une dépendance open source est essentielle.

  • Passez en revue avant l’utilisation : lisez tout le contenu des compétences (SKILL.md, les scripts et les ressources) avant de déployer. Vérifiez que le comportement réel d’un script correspond à son intention indiquée. Recherchez les instructions contradictoires qui tentent de contourner les instructions de sécurité, d’exfiltrer les données ou de modifier les fichiers de configuration de l’agent.
  • Approbation de la source : installez uniquement les compétences des auteurs approuvés ou des contributeurs internes approuvés. Préférez les compétences avec une provenance claire, un contrôle de version et une maintenance active. Surveillez les noms de compétences typosquatés qui imitent les packages populaires.
  • Sandboxing : exécutez des compétences qui incluent des scripts exécutables dans des environnements isolés. Limitez l’accès au système de fichiers, au réseau et au niveau du système uniquement à ce dont la compétence a besoin. Exiger une confirmation explicite de l’utilisateur avant d’exécuter des opérations potentiellement sensibles.
  • Audit et journalisation : enregistrez les compétences chargées, les ressources lues et les scripts exécutés. Cela vous donne une piste d’audit pour tracer le comportement de l’agent vers un contenu de compétence spécifique si quelque chose ne va pas.

Quand utiliser des compétences et des workflows

Les compétences de l'agent et les flux de travail du cadre de l'agent étendent tous deux les capacités des agents, mais ils fonctionnent de manière fondamentalement différente. Choisissez l’approche qui correspond le mieux à vos besoins :

  • Contrôle : avec une compétence, l’IA décide comment exécuter les instructions. C’est idéal lorsque vous souhaitez que l’agent soit créatif ou adaptatif. Avec un flux de travail, vous définissez explicitement le chemin d’exécution. Utilisez des flux de travail quand vous avez besoin d’un comportement déterministe et prévisible.
  • Résilience — Une compétence qui s'exécute au cours d'un seul tour d'un agent. En cas d’échec, l’opération entière doit être retentée. Les flux de travail prennent en charge les points de contrôle, afin qu’ils puissent reprendre à partir de la dernière étape réussie après un échec. Choisissez des flux de travail lorsque le coût de réexécution de l’ensemble du processus est élevé.
  • Effets secondaires : les compétences conviennent lorsque les opérations sont idempotentes ou à faible risque. Préférez les flux de travail lorsque les étapes produisent des effets secondaires (envoi d’e-mails, paiements de facturation) qui ne doivent pas être répétés lors de nouvelles tentatives.
  • Complexité : les compétences sont les meilleures pour les tâches prioritaires et à domaine unique qu’un agent peut gérer. Les flux de travail sont mieux adaptés aux processus métier en plusieurs étapes qui coordonnent plusieurs agents, approbations humaines ou intégrations de système externe.

Conseil / Astuce

En règle générale : si vous souhaitez que l’IA détermine comment accomplir une tâche, utilisez une compétence. Si vous devez garantir les étapes qui s’exécutent et dans quel ordre, utilisez un flux de travail.

Prochaines étapes