Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le competenze dell'agente sono pacchetti portabili di istruzioni, script e risorse che offrono agli agenti funzionalità specializzate e competenze di dominio. Le competenze seguono una specifica aperta e implementano un modello di divulgazione progressiva in modo che gli agenti carichino solo il contesto di cui hanno bisogno, quando necessario.
Usare le competenze dell'agente quando si vuole:
- Competenze di dominio — Acquisire conoscenze specializzate (politiche di spesa, flussi di lavoro legali, pipeline di analisi dati) sotto forma di pacchetti riutilizzabili e portabili.
- Estendere le funzionalità degli agenti : offrire agli agenti nuove capacità senza modificare le istruzioni di base.
- Garantire la coerenza : trasformare le attività in più passaggi in flussi di lavoro ripetibili e controllabili.
- Abilitare l'interoperabilità: riutilizzare la stessa competenza in diversi prodotti compatibili con le competenze dell'agente.
Struttura delle competenze
Un'abilità è una directory contenente un file SKILL.md con sottodirectory facoltative per le risorse.
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
formato SKILL.md
Il SKILL.md file deve contenere il frontmatter YAML seguito dal contenuto 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"
---
| Campo | Obbligatorio | Descrzione |
|---|---|---|
name |
Sì | Massimo 64 caratteri. Solo lettere minuscole, numeri e trattini. Non deve iniziare o terminare con un trattino o contenere trattini consecutivi. Deve corrispondere al nome della directory principale. |
description |
Sì | Cosa fa la competenza e quando usarla. Massimo 1024 caratteri. Deve includere parole chiave che consentono agli agenti di identificare le attività pertinenti. |
license |
NO | Nome della licenza o riferimento a un file di licenza in bundle. |
compatibility |
NO | Massimo 500 caratteri. Indica i requisiti di ambiente (prodotto, pacchetti di sistema, accesso alla rete e così via). |
metadata |
NO | Mappatura chiave-valore arbitraria per metadati aggiuntivi. |
allowed-tools |
NO | Elenco delimitato da spazi di strumenti pre-approvati che l'abilità può utilizzare. Sperimentale: il supporto può variare tra le implementazioni dell'agente. |
Il corpo markdown dopo il frontmatter contiene le istruzioni delle competenze, indicazioni dettagliate, esempi di input e output, casi limite comuni o qualsiasi contenuto che aiuti l'agente a svolgere l'attività. Mantenere SKILL.md sotto 500 righe e spostare materiale di riferimento dettagliato in file separati.
Divulgazione progressiva
Le competenze dell'agente usano un modello di divulgazione progressiva a quattro fasi per ridurre al minimo l'utilizzo del contesto:
- Annuncio (~100 token per competenza): i nomi e le descrizioni delle competenze vengono inseriti nella richiesta di sistema all'inizio di ogni esecuzione, quindi l'agente sa quali competenze sono disponibili.
-
Carica (< 5000 token consigliati): quando un'attività si allinea al dominio di una competenza, l'agente utilizza lo strumento
load_skillper recuperare il corpo completo di SKILL.md con istruzioni dettagliate. -
Leggere le risorse (in base alle esigenze): l'agente chiama lo
read_skill_resourcestrumento per recuperare file supplementari (riferimenti, modelli, asset) solo quando necessario. -
Esegui script (se necessario): l'agente chiama lo
run_skill_scriptstrumento per eseguire script in bundle con una skill.
Questo modello mantiene snella la finestra di contesto dell'agente, concedendole l'accesso a conoscenze di dominio approfondite su richiesta.
Annotazioni
load_skill è sempre pubblicizzato.
read_skill_resource è pubblicizzato solo quando almeno un'abilità dispone di risorse.
run_skill_script viene annunciato solo quando almeno un'abilità ha script.
Fornire competenze a un agente
AgentSkillsProvider (C#) e SkillsProvider (Python) sono provider di contesto che rendono disponibili competenze agli agenti. Supportano tre origini di competenze:
-
Basato su file : competenze individuate dai
SKILL.mdfile nelle directory del file system -
Code-defined : competenze definite inline nel codice usando
AgentInlineSkill(C#) oSkill(Python) -
Basato su classi : competenze incapsulate in una classe C# derivata da
AgentClassSkill<T>(solo C#)
Per combinare più origini in un provider, usare AgentSkillsProviderBuilder (solo C#, vedere Generatore: scenari avanzati con più origini).
Competenze basate sui file
Creare un collegamento a una directory contenente le skill, e aggiungerlo ai fornitori di contesto dell'agente. Passare un esecutore di script per abilitare l'esecuzione di script basati su file presenti nelle directory delle abilità.
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);
Avviso
DefaultAzureCredential è utile per lo sviluppo, ma richiede un'attenta considerazione nell'ambiente di produzione. Nell'ambiente di produzione prendere in considerazione l'uso di credenziali specifiche ,ad esempio ManagedIdentityCredential, per evitare problemi di latenza, probe di credenziali indesiderate e potenziali rischi per la sicurezza dai meccanismi di fallback.
Molteplici directory di competenze
È possibile puntare il provider a una singola directory padre: ogni sottodirectory contenente un SKILL.md oggetto viene individuato automaticamente come competenza:
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "all-skills"));
In alternativa, passare un elenco di percorsi per eseguire ricerche in più directory radice:
var skillsProvider = new AgentSkillsProvider(
[
Path.Combine(AppContext.BaseDirectory, "company-skills"),
Path.Combine(AppContext.BaseDirectory, "team-skills"),
]);
Il provider cerca fino a due livelli di profondità.
Personalizzazione dell'individuazione delle risorse
Per impostazione predefinita, il provider riconosce le risorse con estensioni .md, .json, .yaml, .yml, .csv, .xml e .txt nelle sottodirectory references e assets. Usare AgentFileSkillsSourceOptions per modificare queste impostazioni predefinite:
var fileOptions = new AgentFileSkillsSourceOptions
{
AllowedResourceExtensions = [".md", ".txt"],
ResourceDirectories = ["docs", "templates"],
};
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
fileOptions: fileOptions);
Esecuzione degli script
Passare SubprocessScriptRunner.RunAsync come secondo argomento a AgentSkillsProvider per abilitare l'esecuzione di script basati su file.
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
SubprocessScriptRunner.RunAsync);
SubprocessScriptRunner.RunAsync è approssimativamente equivalente ai seguenti:
// 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();
}
Il runner esegue ogni script individuato come sottoprocesso locale, passando gli argomenti JSON forniti dall'agente come opzioni della riga di comando.
Avviso
SubprocessScriptRunner viene fornito solo a scopo dimostrativo. Per l'uso in produzione, è consigliabile aggiungere:
- Sandboxing (ad esempio, contenitori o ambienti di esecuzione isolati)
- Limiti delle risorse (CPU, memoria, timeout di wall-clock)
- Convalida dell'input e elenco consentito di script eseguibili
- Log strutturati e audit trail
Personalizzazione dell'individuazione di script
Per impostazione predefinita, il provider riconosce gli script con estensioni .py, .js, .sh, .ps1, .cs, e .csx nella sottodirectory scripts. Usare AgentFileSkillsSourceOptions per modificare queste impostazioni predefinite:
Passare AgentFileSkillsSourceOptions al AgentSkillsProvider costruttore o a UseFileSkill / UseFileSkills nel generatore:
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();
Competenze basate su file
Crea un SkillsProvider puntatore a una directory contenente le competenze e aggiungilo ai provider di contesto dell'agente:
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],
)
Molteplici directory di competenze
È possibile indirizzare il provider a una singola cartella principale: ogni sottocartella contenente un SKILL.md viene individuata automaticamente come abilità.
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "all-skills"
)
In alternativa, passare un elenco di percorsi per eseguire ricerche in più directory principali.
skills_provider = SkillsProvider(
skill_paths=[
Path(__file__).parent / "company-skills",
Path(__file__).parent / "team-skills",
]
)
Il provider cerca fino a due livelli di profondità.
Personalizzazione dell'individuazione delle risorse
Per impostazione predefinita, SkillsProvider riconosce le risorse con estensioni .md, , .json.yaml.yml, .csv, .xml, e ..txt Analizza tutte le sottodirectory all'interno di ogni cartella della competenza. Passare resource_extensions per modificare i tipi di file riconosciuti:
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
resource_extensions=(".md", ".txt"),
)
Esecuzione degli script
Per abilitare l'esecuzione di script basati su file, passare un script_runner a SkillsProvider. È possibile usare qualsiasi funzione o metodo sincrono o asincrono che soddisfi il protocollo SkillScriptRunner:
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'esecutore riceve l'oggetto Skill, SkillScript e un dizionario facoltativo args. Gli script basati su file vengono individuati automaticamente dai .py file nelle directory degli skill.
Avviso
Il runner precedente viene fornito solo a scopo dimostrativo. Per l'uso in produzione, è consigliabile aggiungere:
- Sandboxing (ad esempio, contenitori,
seccomp, ofirejail) - Limiti delle risorse (CPU, memoria, timeout di wall-clock)
- Convalida dell'input e elenco consentito di script eseguibili
- Log strutturati e audit trail
Annotazioni
Se vengono fornite competenze su file con script senza che script_runner sia impostato, SkillsProvider genera un ValueError.
Competenze definite dal codice
Oltre alle competenze basate su file individuate dai SKILL.md file, è possibile definire le competenze interamente nel codice usando AgentInlineSkill. Le competenze definite dal codice sono utili quando:
- Il contenuto della competenza viene generato in modo dinamico( ad esempio, la lettura da un database o un ambiente).
- Si vogliono mantenere le definizioni delle competenze insieme al codice dell'applicazione che le usa.
- Sono necessarie risorse che eseguono la logica in fase di lettura anziché gestire i file statici.
Competenza di codice di base
Creare un oggetto AgentInlineSkill con un nome, una descrizione e istruzioni. Collegare le risorse usando .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);
Risorse dinamiche
Passare un delegato factory a .AddResource() per calcolare il contenuto in fase di esecuzione. Il delegato viene richiamato ogni volta che l'agente legge la risorsa:
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)");
Script definiti dal codice
Usare .AddScript() per registrare un delegato come script eseguibile. Gli script definiti dal codice vengono eseguiti in-process come chiamate delegate dirette. Non è necessario alcun esecutore di script. I parametri tipizzati del delegato vengono convertiti automaticamente in uno Schema JSON che l'agente usa per passare gli argomenti.
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);
Annotazioni
Per combinare competenze definite dal codice con competenze basate su file o basate su classi in un singolo provider, usare AgentSkillsProviderBuilder . Vedere Generatore: scenari avanzati con più origini.
Oltre alle competenze basate su file individuate dai file SKILL.md, è possibile definire le competenze interamente nel codice Python. Le competenze definite dal codice sono utili quando:
- Il contenuto della competenza viene generato in modo dinamico( ad esempio, la lettura da un database o un ambiente).
- Si vogliono mantenere le definizioni delle competenze insieme al codice dell'applicazione che le usa.
- Sono necessarie risorse che eseguono la logica in fase di lettura anziché gestire i file statici.
Competenza di codice di base
Creare un'istanza Skill con un nome, una descrizione e un contenuto dell'istruzione. Facoltativamente, allegare SkillResource istanze al contenuto statico:
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])
Risorse dinamiche
Usa il decoratore @skill.resource per registrare una funzione come risorsa. La funzione viene chiamata ogni volta che l'agente legge la risorsa, in modo che possa restituire dati aggiornati. Sono supportate sia le funzioni di sincronizzazione che asincrone:
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)"
Quando l'elemento Decorator viene usato senza argomenti (@skill.resource), il nome della funzione diventa il nome della risorsa e la docstring diventa la descrizione. Usare @skill.resource(name="...", description="...") per impostarli in modo esplicito.
Script definiti dal codice
Usare il decoratore @skill.script per registrare una funzione come script eseguibile in una skill. Gli script definiti dal codice vengono eseguiti in-process e non richiedono un executor di script. Sono supportate sia le funzioni di sincronizzazione che asincrone:
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})
Quando l'elemento Decorator viene usato senza argomenti (@skill.script), il nome della funzione diventa il nome dello script e la docstring diventa la descrizione. I parametri tipizzato della funzione vengono convertiti automaticamente in uno schema JSON usato dall'agente per passare argomenti.
Combinazione di competenze basate su file e definite dal codice
Passa sia skill_paths che skills a un singolo SkillsProvider. Le competenze basate su file vengono individuate per prime; se una competenza definita dal codice ha lo stesso nome di una competenza basata su file esistente, la competenza definita dal codice viene ignorata:
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],
)
Competenze basate su classi
Le competenze basate su classi consentono di aggregare tutti i componenti della competenza, ovvero nome, descrizione, istruzioni, risorse e script, in una singola classe C#. Deriva da AgentClassSkill<T> (dove T è la tua classe), quindi annota le proprietà con [AgentSkillResource] e i metodi con [AgentSkillScript] per l'individuazione automatica.
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 });
}
}
Registrare la competenza basata sulla classe con AgentSkillsProvider:
var skill = new UnitConverterSkill();
var skillsProvider = new AgentSkillsProvider(skill);
Quando l'attributo [AgentSkillResource] viene applicato a una proprietà o a un metodo, il relativo valore restituito viene usato come contenuto della risorsa quando l'agente legge la risorsa, usare un metodo quando il contenuto deve essere calcolato in fase di lettura. Quando [AgentSkillScript] viene applicato a un metodo, il metodo viene richiamato quando l'agente chiama lo script. Usare [Description] da System.ComponentModel per descrivere ogni risorsa e script per l'agente.
Annotazioni
AgentClassSkill<T> supporta anche l'override Resources e Scripts come raccolte per scenari in cui l'individuazione basata su attributi non è adatta.
Generatore: scenari avanzati con più origini
Per scenari di origine singola semplici, usare direttamente i AgentSkillsProvider costruttori. Usare AgentSkillsProviderBuilder quando è necessario uno dei seguenti elementi:
-
Tipi di competenze miste : combinare competenze basate su file, definite dal codice (
AgentInlineSkill) e basate su classi (AgentClassSkill) in un singolo provider. - Filtro delle competenze: includere o escludere competenze usando un predicato.
Tipi di competenze misti
Combinare tutti e tre i tipi di competenza in un provider concatenando UseFileSkill, UseSkille 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();
Filtro delle competenze
Usare UseFilter per includere solo le competenze che soddisfano i criteri, ad esempio per caricare le competenze da una directory condivisa, ma escludere quelle sperimentali:
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();
Approvazione dello script
Usare AgentSkillsProviderOptions.ScriptApproval per controllare tutte le esecuzioni di script previa approvazione umana. Se abilitata, l'agente sospende e restituisce una richiesta di approvazione anziché eseguirlo immediatamente:
var skillsProvider = new AgentSkillsProvider(
skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
ScriptApproval = true,
});
Per abilitare l'approvazione degli script in un provider configurato dal generatore, usare UseScriptApproval:
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
.UseScriptApproval(true)
.Build();
Usare require_script_approval=True su SkillsProvider per limitare tutte le esecuzioni di script soggette ad approvazione umana. Anziché eseguirlo immediatamente, l'agente sospende e restituisce le richieste di approvazione:
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)
Quando uno script viene rifiutato (approved=False), l'agente viene informato che l'utente ha rifiutato e può rispondere di conseguenza.
Richiesta di sistema personalizzata
Per impostazione predefinita, il provider di competenze inserisce un prompt di sistema che elenca le competenze disponibili e indica all'agente di usare load_skill e read_skill_resource. È possibile personalizzare questa richiesta:
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}
"""
});
Annotazioni
Il modello personalizzato deve contenere {skills} (elenco di competenze), {resource_instructions} (suggerimento dello strumento di risorse) e {script_instructions} (suggerimento dello strumento di script) come segnaposto. Le parentesi graffe letterali devono essere precedute da un carattere di escape come {{ e }}.
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."
),
)
Annotazioni
Il modello personalizzato deve contenere un {skills} segnaposto in cui viene inserito l'elenco delle competenze e un {runner_instructions} segnaposto in cui vengono inserite le istruzioni correlate allo script.
Comportamento di memorizzazione nella cache
Per impostazione predefinita, gli strumenti e le istruzioni delle competenze vengono memorizzati nella cache dopo la prima compilazione. Imposta DisableCaching = true su AgentSkillsProviderOptions per forzare una ricompilazione a ogni invocazione:
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
DisableCaching = true,
});
Annotazioni
La disabilitazione della memorizzazione nella cache è utile durante lo sviluppo quando il contenuto delle competenze cambia frequentemente. Nell'ambiente di produzione lasciare abilitata la memorizzazione nella cache (impostazione predefinita) per ottenere prestazioni migliori.
Iniezione di dipendenze
Le risorse di abilità e i delegati di script possono dichiarare un parametro IServiceProvider che l'Agent Framework inserisce automaticamente. In questo modo è possibile risolvere i servizi dell'applicazione, ad esempio i client di database, la configurazione o la logica di business, senza codificarli in modo statico nella definizione della skill.
Setup
Registrare i servizi dell'applicazione e passare l'oggetto compilato IServiceProvider all'agente tramite il services parametro :
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);
Competenze definite dal codice con inserimento delle dipendenze
Dichiarare IServiceProvider come parametro in AddResource o AddScript delegati: il framework risolve e lo inserisce automaticamente quando l'agente legge una risorsa o esegue uno 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);
});
Competenze basate su classi con l'inserimento delle dipendenze
Annotare i metodi con [AgentSkillResource] o [AgentSkillScript] e dichiarare un IServiceProvider parametro: il framework individua questi membri tramite reflection e inserisce automaticamente il provider di servizi:
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);
}
}
Suggerimento
Le competenze basate su classi possono anche risolvere le dipendenze tramite il costruttore. Registrare la classe di competenza in ServiceCollection e risolverla dal contenitore invece di chiamare new direttamente:
services.AddSingleton<WeightConverterSkill>();
var weightSkill = serviceProvider.GetRequiredService<WeightConverterSkill>();
Ciò è utile quando la classe di competenza stessa necessita di servizi inseriti oltre a ciò che usano i delegati di risorse e script.
Funzioni di risorsa e di script che accettano **kwargs ricevono automaticamente gli argomenti di parole chiave a tempo di esecuzione passati a agent.run(). Ciò consente alle funzioni della competenza di accedere al contesto dell'applicazione, ad esempio la configurazione, l'identità utente o i client del servizio, senza codificarli nella definizione della competenza.
Passaggio di argomenti di runtime
Passare function_invocation_kwargs a agent.run() per fornire argomenti di parole chiave inoltrati dal framework alle funzioni di risorsa e script:
response = await agent.run(
"How many kilometers is 26.2 miles?",
function_invocation_kwargs={"precision": 2, "user_id": "alice"},
)
Funzioni delle risorse con kwargs
Quando una funzione di risorsa dichiara **kwargs, il framework inoltra gli argomenti della parola chiave di runtime ogni volta che l'agente legge la risorsa:
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}"
Le funzioni delle risorse senza **kwargs vengono chiamate senza argomenti e non ricevono il contesto di runtime.
Funzioni script con kwargs
Quando una funzione script dichiara **kwargs, il framework inoltra gli argomenti dell'istanza di runtime insieme all'oggetto args fornito dall'agente.
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'agente fornisce value e factor tramite la chiamata argsallo strumento . L'applicazione fornisce precision tramite function_invocation_kwargs. Funzioni script senza **kwargs ricevono solo gli argomenti forniti dall'agente.
Procedure consigliate per la sicurezza
Le competenze dell'agente devono essere considerate come qualsiasi codice di terze parti inserito nel progetto. Poiché le istruzioni sulle competenze vengono inserite nel contesto dell'agente e le competenze possono includere script, l'applicazione dello stesso livello di revisione e governance a una dipendenza open source è essenziale.
-
Esaminare prima dell'uso: leggere tutto il contenuto delle competenze (
SKILL.md, script e risorse) prima della distribuzione. Verificare che il comportamento effettivo di uno script corrisponda alla finalità dichiarata. Controllare le istruzioni antagoniste che tentano di ignorare le linee guida per la sicurezza, esfiltrare i dati o modificare i file di configurazione dell'agente. - Attendibilità origine : installa solo le competenze di autori attendibili o collaboratori interni controllati. Preferisce competenze con chiara provenienza, controllo della versione e manutenzione attiva. Guarda i nomi delle competenze digitati che simulano i pacchetti più diffusi.
- Sandboxing — eseguire abilità che includono script eseguibili in ambienti isolati. Limitare l'accesso a livello di file system, rete e sistema solo a ciò che richiede la competenza. Richiedi conferma esplicita dell'utente prima di eseguire operazioni potenzialmente sensibili.
- Controllo e registrazione : registrare le competenze caricate, quali risorse vengono lette e quali script vengono eseguiti. Questo consente di eseguire un audit trail risalendo al comportamento dell'agente fino al contenuto di competenza specifico, in caso di problemi.
Quando usare competenze e flussi di lavoro
I flussi di lavoro di Agent Skills e Agent Framework estendono entrambe le operazioni che gli agenti possono eseguire, ma funzionano in modi fondamentalmente diversi. Scegliere l'approccio più adatto alle proprie esigenze:
- Controllo : con una competenza, l'intelligenza artificiale decide come eseguire le istruzioni. Questo è ideale quando vuoi che l'agente sia creativo o adattivo. Con un flusso di lavoro, si definisce in modo esplicito il percorso di esecuzione. Usare i flussi di lavoro quando è necessario un comportamento deterministico e prevedibile.
- Resilienza — una abilità si attiva durante un singolo turno di agente. Se si verifica un errore, è necessario ritentare l'intera operazione. I flussi di lavoro supportano il checkpointing, consentendo di riprendere dall'ultimo passaggio riuscito dopo un errore. Scegliere i flussi di lavoro quando il costo di riesezione dell'intero processo è elevato.
- Effetti collaterali : le competenze sono adatte quando le operazioni sono idempotenti o a basso rischio. Preferisce i flussi di lavoro quando i passaggi producono effetti collaterali (invio di messaggi di posta elettronica, pagamenti in addebito) che non devono essere ripetuti al nuovo tentativo.
- Complessità : le competenze sono ideali per attività incentrate e a dominio singolo che un agente può gestire. I flussi di lavoro sono più adatti per processi aziendali in più passaggi che coordinano più agenti, approvazioni umane o integrazioni di sistemi esterni.
Suggerimento
Come regola generale: se si vuole che l'intelligenza artificiale sia in grado di capire come eseguire un'attività, usare una competenza. Se è necessario garantire quali passaggi eseguire e in quale ordine, usare un flusso di lavoro.