Delen via


Agentvaardigheden

Agentvaardigheden zijn draagbare pakketten met instructies, scripts en resources die agents gespecialiseerde mogelijkheden en domeinexpertise bieden. Vaardigheden volgen een open specificatie en implementeren een progressief openbaarmakingspatroon, zodat agents alleen de context laden die ze nodig hebben, wanneer ze het nodig hebben.

Gebruik agentvaardigheden als u het volgende wilt doen:

  • Expertise van pakketdomein - Leg gespecialiseerde kennis vast (onkostenbeleid, juridische werkstromen, pijplijnen voor gegevensanalyse) als herbruikbare, draagbare pakketten.
  • Mogelijkheden van agents uitbreiden : geef agents nieuwe mogelijkheden zonder de belangrijkste instructies te wijzigen.
  • Consistentie garanderen : verander taken met meerdere stappen in herhaalbare, controleerbare werkstromen.
  • Interoperabiliteit inschakelen : gebruik dezelfde vaardigheid voor verschillende producten die compatibel zijn met agentvaardigheden.

Vaardigheidsstructuur

Een vaardigheid is een directory met een SKILL.md bestand en optionele submappen voor resources.

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

SKILL.md-formaat

Het SKILL.md bestand moet YAML-frontmatter bevatten, gevolgd door Markdown-inhoud:

---
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"
---
Veld Verplicht Description
name Ja Maximaal 64 tekens. Alleen kleine letters, cijfers en koppeltekens. Mag niet beginnen of eindigen met een afbreekstreepje of opeenvolgende afbreekstreepjes bevatten. Moet overeenkomen met de naam van de bovenliggende map.
description Ja Wat de vaardigheid doet en wanneer u deze moet gebruiken. Maximaal 1024 tekens. Moet trefwoorden bevatten waarmee agents relevante taken kunnen identificeren.
license Nee. Licentienaam of verwijzing naar een gebundeld licentiebestand.
compatibility Nee. Maximaal 500 tekens. Geeft de omgevingsvereisten aan (bedoeld product, systeempakketten, netwerktoegang, enzovoort).
metadata Nee. Willekeurige sleutelwaardetoewijzing voor aanvullende metagegevens.
allowed-tools Nee. Door spaties gescheiden lijst met vooraf goedgekeurde hulpmiddelen die de vaardigheid kan gebruiken. Experimenteel: ondersteuning kan variëren tussen agent-implementaties.

De Markdown-hoofdtekst na de frontmatter bevat de vaardigheidsinstructies, stapsgewijze richtlijnen, voorbeelden van invoer en uitvoer, algemene randcases of inhoud waarmee de agent de taak kan uitvoeren. Houd SKILL.md onder de 500 regels en verplaats gedetailleerd referentiemateriaal naar aparte bestanden.

Progressieve openbaarmaking

Agentvaardigheden gebruiken een patroon voor progressieve openbaarmaking in vier fasen om het contextgebruik te minimaliseren:

  1. Adverteren (~100 tokens per vaardigheid): namen en beschrijvingen van vaardigheden worden aan het begin van elke uitvoering in de systeemprompt geïnjecteerd, zodat de agent weet welke vaardigheden beschikbaar zijn.
  2. Laden (< 5000 tokens aanbevolen): wanneer een taak overeenkomt met het domein van een vaardigheid, roept de agent het load_skill hulpprogramma aan om de volledige SKILL.md hoofdtekst op te halen met gedetailleerde instructies.
  3. Resources lezen (indien nodig): de agent roept het read_skill_resource hulpprogramma aan om aanvullende bestanden (verwijzingen, sjablonen, assets) op te halen wanneer dat nodig is.
  4. Scripts uitvoeren (indien nodig): de agent roept het run_skill_script hulpprogramma aan om scripts uit te voeren die zijn gebundeld met een vaardigheid.

Dit patroon houdt het contextvenster van de agent compact, terwijl de agent op aanvraag toegang krijgt tot diepgaande domeinkennis.

Opmerking

load_skill wordt altijd geadverteerd. read_skill_resource wordt alleen geadverteerd wanneer ten minste één vaardigheid over middelen beschikt. run_skill_script wordt alleen geadverteerd wanneer ten minste één vaardigheid scripts heeft.

Vaardigheden bieden aan een agent

AgentSkillsProvider (C#) en SkillsProvider (Python) zijn contextproviders die vaardigheden beschikbaar maken voor agents. Ze ondersteunen drie vaardigheidsbronnen:

  • Op bestanden gebaseerde vaardigheden die zijn gedetecteerd uit SKILL.md bestanden in bestandssysteemmappen
  • Code-defined — vaardigheden die inline zijn gedefinieerd in code met behulp van AgentInlineSkill (C#) of Skill (Python)
  • Op klassen gebaseerde vaardigheden die zijn ingekapseld in een C#-klasse die is afgeleid van AgentClassSkill<T> (alleen C#)

Als u meerdere bronnen in één provider wilt combineren, gebruikt AgentSkillsProviderBuilder u (alleen C# - zie Builder: geavanceerde scenario's met meerdere bronnen).

Bestandsgebaseerde vaardigheden

Maak een AgentSkillsProvider verwijzing naar een map met uw vaardigheden en voeg deze toe aan de contextproviders van de agent. Stel een scriptrunner in om de uitvoering van bestandsscripts in skill-mappen mogelijk te maken.

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);

Waarschuwing

DefaultAzureCredential is handig voor ontwikkeling, maar vereist zorgvuldige overwegingen in de productieomgeving. Overweeg in productie een specifieke referentie te gebruiken (bijvoorbeeld ManagedIdentityCredential) om latentieproblemen, onbedoelde referentieprobing en potentiële beveiligingsrisico's van terugvalmechanismen te voorkomen.

Meerdere vaardighedencatalogi

U kunt de provider naar één enkele bovenliggende map laten wijzen, waarbij elke submap die een SKILL.md bevat automatisch als een vaardigheid wordt gedetecteerd.

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

U kunt ook een lijst met paden doorgeven om in meerdere hoofdmappen te zoeken:

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

De provider doorzoekt maximaal twee niveaus diep.

Resourcedetectie aanpassen

Standaard herkent de provider resources met extensies .md, .json, .yaml, , .yml, .csv, .xmlen .txt in references en assets submappen. Gebruik AgentFileSkillsSourceOptions dit om deze standaardinstellingen te wijzigen:

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

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

Scriptuitvoering

Geef SubprocessScriptRunner.RunAsync als het tweede argument door naar AgentSkillsProvider om de uitvoering van bestandsgebaseerde scripts in te schakelen:

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

SubprocessScriptRunner.RunAsync komt ongeveer overeen met het volgende:

// 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();
}

De runner voert elk gedetecteerd script uit als een lokaal subproces, en stuurt de JSON-argumenten van de agent door als opdrachtregelvlagken.

Waarschuwing

SubprocessScriptRunner wordt alleen ter demonstratie verstrekt. Voor productiegebruik kunt u overwegen het volgende toe te voegen:

  • Sandboxing (bijvoorbeeld containers of geïsoleerde uitvoeringsomgevingen)
  • Resourcelimieten (CPU, geheugen, time-out voor wandklok)
  • Invoervalidatie en acceptatielijst met uitvoerbare scripts
  • Gestructureerde logboekregistratie en audittrails

Scriptdetectie aanpassen

Standaard herkent de provider scripts met extensies .py, .js, .sh, .ps1, .cs en .csx in de scripts subdirectory. Gebruik AgentFileSkillsSourceOptions dit om deze standaardinstellingen te wijzigen:

Geef AgentFileSkillsSourceOptions aan de AgentSkillsProvider constructor of aan UseFileSkill / UseFileSkills de builder:

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();

Vaardigheden op basis van bestanden

Maak een SkillsProvider verwijzing naar een map met uw vaardigheden en voeg deze toe aan de contextproviders van de 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],
)

Meerdere vaardighedencatalogi

U kunt de provider naar een enkele bovenliggende map laten wijzen. Elke submap die een SKILL.md bevat, wordt automatisch herkend als een vaardigheid.

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

U kunt ook een lijst met paden doorgeven om in meerdere hoofdmappen te zoeken:

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

De provider doorzoekt maximaal twee niveaus diep.

Resourcedetectie aanpassen

SkillsProvider Herkent standaard resources met extensies .md, .json, .yaml, .yml, .csv, .xml en .txt. Het scant alle submappen binnen elke vaardigheidsmap. Geef door resource_extensions om de herkende bestandstypen te wijzigen:

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

Scriptuitvoering

Als u het uitvoeren van op bestanden gebaseerde scripts wilt inschakelen, geeft u een script_runner door aan SkillsProvider. Elke synchrone of asynchrone oproep die voldoet aan het SkillScriptRunner protocol kan worden gebruikt.

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,
)

De runner ontvangt de opgeloste Skill, SkillScripten een optionele args woordenlijst. Bestandsgebaseerde scripts worden automatisch gedetecteerd uit .py bestanden in vaardigheidsmappen.

Waarschuwing

De bovenstaande runner is alleen bedoeld voor demonstratiedoeleinden. Voor productiegebruik kunt u overwegen het volgende toe te voegen:

  • Sandboxing (bijvoorbeeld containers, seccomp, of firejail)
  • Resourcelimieten (CPU, geheugen, time-out voor wandklok)
  • Invoervalidatie en acceptatielijst met uitvoerbare scripts
  • Gestructureerde logboekregistratie en audittrails

Opmerking

Als er op bestanden gebaseerde vaardigheden met scripts worden opgegeven, maar er geen script_runner is ingesteld, veroorzaakt SkillsProvider een ValueError.

Door code gedefinieerde vaardigheden

Naast op bestanden gebaseerde vaardigheden die zijn gedetecteerd op basis van SKILL.md bestanden, kunt u vaardigheden volledig definiëren in code met behulp van AgentInlineSkill. Door code gedefinieerde vaardigheden zijn handig wanneer:

  • Inhoud van vaardigheden wordt dynamisch gegenereerd (bijvoorbeeld lezen uit een database of omgeving).
  • U wilt vaardigheidsdefinities naast de toepassingscode die deze gebruikt, behouden.
  • U hebt resources nodig die logica op leestijd uitvoeren in plaats van statische bestanden te leveren.

Basiscodevaardigheden

Maak een AgentInlineSkill met een naam, beschrijving en instructies. Resources koppelen met behulp van .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);

Dynamische middelen

Geef een factory-delegate door aan .AddResource() om de inhoud tijdens uitvoering te berekenen. De gemachtigde wordt telkens aangeroepen wanneer de agent de resource leest:

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)");

Met code gedefinieerde scripts

Gebruik .AddScript() om een delegate te registreren als een uitvoerbaar script. Met code gedefinieerde scripts worden in het proces uitgevoerd als directe gemachtigde aanroepen. Er is geen scriptrunner nodig. De getypte parameters van de gemachtigde worden automatisch geconverteerd naar een JSON-schema dat de agent gebruikt om argumenten door te geven:

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);

Opmerking

Als u codegedefinieerde vaardigheden wilt combineren met op bestanden of klassen gebaseerde vaardigheden in één provider, raadpleegt AgentSkillsProviderBuilder u Builder: geavanceerde scenario's met meerdere bronnen.

Naast op bestanden gebaseerde vaardigheden die zijn gedetecteerd uit SKILL.md bestanden, kunt u vaardigheden volledig definiëren in Python code. Door code gedefinieerde vaardigheden zijn handig wanneer:

  • Inhoud van vaardigheden wordt dynamisch gegenereerd (bijvoorbeeld lezen uit een database of omgeving).
  • U wilt vaardigheidsdefinities naast de toepassingscode die deze gebruikt, behouden.
  • U hebt resources nodig die logica op leestijd uitvoeren in plaats van statische bestanden te leveren.

Basiscodevaardigheden

Maak een Skill exemplaar met een naam, beschrijving en instructie-inhoud. Optioneel SkillResource exemplaren toevoegen met statische inhoud:

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])

Dynamische middelen

Gebruik de @skill.resource decorator om een functie als resource te registreren. De functie wordt aangeroepen elke keer dat de agent de resource leest, zodat het kan zorgen voor actuele gegevens. Synchronisatie- en asynchrone functies worden ondersteund:

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)"

Wanneer de decorator zonder argumenten wordt gebruikt (@skill.resource), wordt de naam van de functie de resourcenaam en wordt de docstring de beschrijving. Gebruik @skill.resource(name="...", description="...") dit om ze expliciet in te stellen.

Met code gedefinieerde scripts

Gebruik de @skill.script decorator om een functie te registreren als een uitvoerbaar script voor een vaardigheid. Met code gedefinieerde scripts worden in het proces uitgevoerd en is geen scriptuitvoering vereist. Synchronisatie- en asynchrone functies worden ondersteund:

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})

Wanneer de decorator zonder argumenten wordt gebruikt (@skill.script), wordt de naam van de functie de scriptnaam en wordt de docstring de beschrijving. De getypte parameters van de functie worden automatisch geconverteerd naar een JSON-schema dat de agent gebruikt om argumenten door te geven.

Combinatie van vaardigheden op basis van bestanden en code

Geef zowel skill_paths als skills door aan één SkillsProvider. Vaardigheden op basis van bestanden worden eerst ontdekt; als een door code gedefinieerde vaardigheid dezelfde naam heeft als een bestaande op bestanden gebaseerde vaardigheid, wordt de door code gedefinieerde vaardigheid overgeslagen:

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],
)

Klassengebaseerde vaardigheden

Met vaardigheden op basis van klassen kunt u alle vaardigheidsonderdelen ( naam, beschrijving, instructies, resources en scripts) bundelen in één C#-klasse. Oorsprong van AgentClassSkill<T> (waarin T uw klasse is), voeg vervolgens annotaties toe aan eigenschappen met [AgentSkillResource] en methoden met [AgentSkillScript] voor automatische detectie.

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 });
    }
}

Registreer de klassen-gebaseerde vaardigheid met AgentSkillsProvider:

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

Wanneer het [AgentSkillResource] kenmerk wordt toegepast op een eigenschap of methode, wordt de retourwaarde gebruikt als de resource-inhoud wanneer de agent de resource leest. Gebruik een methode wanneer de inhoud tijdens het lezen moet worden berekend. Wanneer [AgentSkillScript] wordt toegepast op een methode, wordt de methode aangeroepen wanneer de agent het script aanroept. Gebruik [Description] van System.ComponentModel om elke resource en elk script voor de agent te beschrijven.

Opmerking

AgentClassSkill<T> biedt ook ondersteuning voor het overschrijven Resources en Scripts als verzamelingen voor scenario's waarin detectie op basis van kenmerken niet past.

Opbouwfunctie: geavanceerde scenario's met meerdere bronnen

Voor eenvoudige scenario's met één bron gebruikt u de AgentSkillsProvider constructors rechtstreeks. Gebruik AgentSkillsProviderBuilder dit wanneer u een van de volgende zaken nodig hebt:

  • Gemengde vaardighedentypen — combineer op bestanden gebaseerde, code-gedefinieerde (AgentInlineSkill) en op klassen gebaseerde vaardigheden in één provider.
  • Vaardigheden filteren : vaardigheden opnemen of uitsluiten met behulp van een predicaat.

Typen gemengde vaardigheden

Combineer alle drie de vaardigheidstypen in één provider door te koppelen UseFileSkill, UseSkillen 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();

Vaardigheidsfilters

Gebruik UseFilter dit om alleen de vaardigheden op te nemen die voldoen aan uw criteria, bijvoorbeeld om vaardigheden uit een gedeelde map te laden, maar experimentele vaardigheden uit te sluiten:

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();

Goedkeuring van script

Gebruik AgentSkillsProviderOptions.ScriptApproval om alle uitvoeringen van scripts achter menselijke goedkeuring te plaatsen. Wanneer de agent is ingeschakeld, wordt een goedkeuringsaanvraag onderbroken en geretourneerd in plaats van onmiddellijk uit te voeren:

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

Als u scriptgoedkeuring wilt inschakelen voor een door de maker geconfigureerde provider, gebruikt u UseScriptApproval:

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

Gebruik require_script_approval=True op SkillsProvider om alle uitvoering van scripts achter menselijke goedkeuring te plaatsen. In plaats van onmiddellijk uit te voeren, onderbreekt en retourneert de agent goedkeuringsaanvragen:

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)

Wanneer een script wordt geweigerd (approved=False), wordt de agent geïnformeerd dat de gebruiker heeft geweigerd en dienovereenkomstig kan reageren.

Aangepaste systeemprompt

Standaard injecteert de provider van vaardigheden een systeemprompt waarin de beschikbare vaardigheden worden vermeld en wordt de agent geïnstrueerd om te gebruiken load_skill en read_skill_resource. U kunt deze prompt aanpassen:

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}
            """
    });

Opmerking

De aangepaste sjabloon moet de tijdelijke aanduidingen {skills} (lijst met vaardigheden), {resource_instructions} (resource tool hint) en {script_instructions} (script tool hint) bevatten. Letterlijke accolades moeten worden ontsnapt met {{ en }}.

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."
    ),
)

Opmerking

De aangepaste sjabloon moet een {skills} tijdelijke aanduiding bevatten waarin de lijst met vaardigheden wordt ingevoegd en een {runner_instructions} tijdelijke aanduiding waarin scriptgerelateerde instructies worden ingevoegd.

Cachinggedrag

Standaard worden hulpprogramma's en instructies voor vaardigheden in de cache opgeslagen na de eerste build. Stel DisableCaching = true in op AgentSkillsProviderOptions om bij elke aanroep een herbouw af te dwingen:

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

Opmerking

Het uitschakelen van caching is handig tijdens de ontwikkeling wanneer de skillinhoud regelmatig verandert. Laat cache in productie ingeschakeld (de standaardinstelling) voor betere prestaties.

Afhankelijkheidsinjectie

Gedelegeerden van vaardigheidsbronnen en scripts kunnen een IServiceProvider parameter declareren die het Agent Framework automatisch injecteert. Hierdoor kunnen vaardigheden toepassingsservices – zoals databaseclients, configuratie of bedrijfslogica – aanroepen zonder deze hard te coderen in de definitie van de vaardigheid.

Installatie

Registreer uw toepassingsservices en geef het gebouwde IServiceProvider door aan de agent via de services parameter:

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);

Door code gedefinieerde vaardigheden met DI

Declareer IServiceProvider als een parameter in AddResource of AddScript delegaties — het framework lost dit automatisch op en injecteert het automatisch wanneer de agent een bron leest of een script uitvoert.

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);
    });

Vaardigheden op basis van klassen met DI

Annoteren van methoden met [AgentSkillResource] of [AgentSkillScript] en declareren van een IServiceProvider-parameter — het framework ontdekt deze leden via reflectie en injecteert de serviceprovider automatisch.

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);
    }
}

Aanbeveling

Op klassen gebaseerde vaardigheden kunnen ook afhankelijkheden oplossen via hun constructor. Registreer de vaardigheidsklasse in de ServiceCollection klasse en los deze op vanuit de container in plaats van rechtstreeks aan te roepen new :

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

Dit is nuttig wanneer de klasse van vaardigheden zelf geïnjecteerde services nodig heeft, buiten wat de resource- en scriptdelegaties gebruiken.

Resource- en scriptfuncties die **kwargs accepteren, ontvangen automatisch runtime-trefwoordargumenten die worden doorgegeven aan agent.run(). Hierdoor hebben vaardighedenfuncties toegang tot toepassingscontext, zoals configuratie, gebruikersidentiteit of serviceclients, zonder ze hard te coderen in de vaardigheidsdefinitie.

Runtime-argumenten doorgeven

Geef function_invocation_kwargs door aan agent.run() om trefwoordargumenten te verstrekken die het framework doorstuurt naar resource- en scriptfuncties.

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

Resourcefuncties met kwargs (keyword arguments)

Wanneer een resourcefunctie declareert **kwargs, stuurt het framework de argumenten voor runtime-trefwoorden door telkens wanneer de agent de resource leest:

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}"

Resourcefuncties zonder **kwargs worden aangeroepen zonder argumenten en krijgen geen runtimecontext.

Scriptfuncties met kwargs

Wanneer een scriptfunctie declareert **kwargs, stuurt het framework de argumenten van het runtime-trefwoord door naast de args opgegeven door de 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})

De agent biedt value en factor via de aanroep argsvan het hulpprogramma; de toepassing biedt precision via function_invocation_kwargs. Scriptfuncties zonder **kwargs ontvangen alleen de argumenten die door de agent worden opgegeven.

Aanbevolen procedures voor beveiliging

Agentvaardigheden moeten worden behandeld als code van derden die u in uw project invoert. Omdat vaardigheidsinstructies worden geïnjecteerd in de context van de agent, en vaardigheden kunnen scripts bevatten, is het toepassen van hetzelfde beoordelingsniveau en governance essentieel voor een opensource-afhankelijkheid.

  • Controleer voor gebruik : lees alle vaardigheidsinhoud (SKILL.md, scripts en resources) voordat u implementeert. Controleer of het werkelijke gedrag van een script overeenkomt met de vermelde intentie. Controleer op instructies met kwade bedoelingen die proberen veiligheidsrichtlijnen te omzeilen, data te exfiltreren of agentconfiguratiebestanden te wijzigen.
  • Bronvertrouwen : installeer alleen vaardigheden van vertrouwde auteurs of gecontroleerde interne inzenders. Geef de voorkeur aan vaardigheden met duidelijke herkomst, versiebeheer en actief onderhoud. Kijk naar getypeerde vaardigheidsnamen die populaire pakketten nabootsen.
  • Sandboxing : voer vaardigheden uit die uitvoerbare scripts bevatten in geïsoleerde omgevingen. Beperk het bestandssysteem, het netwerk en het systeemniveau tot alleen wat de vaardigheid vereist. Expliciete gebruikersbevestiging vereisen voordat mogelijk gevoelige bewerkingen worden uitgevoerd.
  • Controle en logboekregistratie : noteer welke vaardigheden worden geladen, welke resources worden gelezen en welke scripts worden uitgevoerd. Dit geeft u een audit trail om het gedrag van agents te traceren naar specifieke vaardigheden als er iets misgaat.

Wanneer u vaardigheden versus werkstromen gebruikt

AgentVaardigheden en Agent Framework-werkstromen breiden beide uit wat agents kunnen doen, maar ze werken op fundamenteel verschillende manieren. Kies de methode die het beste overeenkomt met uw vereisten:

  • Controle : met een vaardigheid bepaalt de AI hoe de instructies moeten worden uitgevoerd. Dit is ideaal als u wilt dat de agent creatief of adaptief is. Met een werkstroom definieert u expliciet het uitvoeringspad. Gebruik werkstromen wanneer u deterministisch, voorspelbaar gedrag nodig hebt.
  • Veerkracht — Een vaardigheid wordt voltooid binnen één beurt van een agent. Als er iets mislukt, moet de hele bewerking opnieuw worden uitgevoerd. Werkstromen ondersteunen controlepunten, zodat ze kunnen hervatten vanaf de laatste geslaagde stap na een fout. Kies werkstromen wanneer de kosten voor het opnieuw uitvoeren van het hele proces hoog zijn.
  • Bijwerkingen — Vaardigheden zijn geschikt wanneer bewerkingen idempotent zijn of een laag risico vormen. Geef de voorkeur aan werkstromen wanneer stappen bijwerkingen opleveren (e-mailberichten verzenden, betalingen in rekening brengen) die niet moeten worden herhaald bij opnieuw proberen.
  • Complexiteit : vaardigheden zijn het beste voor gerichte taken met één domein die door één agent kunnen worden verwerkt. Werkstromen zijn beter geschikt voor bedrijfsprocessen met meerdere stappen die meerdere agents, menselijke goedkeuringen of externe systeemintegraties coördineren.

Aanbeveling

Als u wilt dat de AI erachter komt hoe een taak moet worden uitgevoerd, gebruikt u een vaardigheid. Als u wilt garanderen welke stappen worden uitgevoerd en in welke volgorde, gebruikt u een werkstroom.

Volgende stappen