Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
As Competências do Agente são pacotes portáteis de instruções, scripts e recursos que conferem aos agentes capacidades especializadas e conhecimento de domínio. As competências seguem uma especificação aberta e implementam um padrão progressivo de divulgação para que os agentes carreguem apenas o contexto de que precisam, quando precisam.
Use as Habilidades de Agente quando quiser:
- Especialização no domínio de pacotes — Capturar conhecimento especializado (políticas de despesas, fluxos de trabalho legais, pipelines de análise de dados) como pacotes reutilizáveis e portáteis.
- Estenda as capacidades dos agentes — Dê aos agentes novas capacidades sem alterar as suas instruções principais.
- Garanta consistência — Transforme tarefas em vários passos em fluxos de trabalho repetíveis e auditáveis.
- Permitir a interoperabilidade — Reutilizar a mesma competência em diferentes produtos compatíveis com Competências de Agente.
Estrutura de competências
Uma habilidade é um diretório que contém um SKILL.md ficheiro com subdiretórios opcionais para recursos:
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 formato
O SKILL.md ficheiro deve conter material inicial YAML seguido de conteúdo marcado:
---
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 | Obrigatório | Description |
|---|---|---|
name |
Yes | No máximo 64 caracteres. Apenas letras minúsculas, números e hífens. Não deve começar nem terminar com um hífen, nem conter hífens consecutivos. Deve corresponder ao nome do diretório principal. |
description |
Yes | O que a habilidade faz e quando a usar. Máximo 1024 caracteres. Deve incluir palavras-chave que ajudem os agentes a identificar tarefas relevantes. |
license |
Não | Nome da licença ou referência a um ficheiro de licença agrupado. |
compatibility |
Não | No máximo 500 caracteres. Indica os requisitos do ambiente (produto pretendido, pacotes do sistema, acesso à rede, etc.). |
metadata |
Não | Mapeamento chave-valor arbitrário para metadados adicionais. |
allowed-tools |
Não | Lista delimitada por espaço de ferramentas pré-aprovadas que a competência pode usar. Experimental — o suporte pode variar entre implementações de agentes. |
O corpo de markdown após o frontmatter contém as instruções de habilidades — orientações passo a passo, exemplos de entradas e saídas, casos excecionais comuns ou qualquer conteúdo que ajude o agente a realizar a tarefa. Mantenha SKILL.md com menos de 500 linhas e transfira o material de referência detalhado para ficheiros separados.
Divulgação progressiva
As Competências do Agente utilizam um padrão progressivo de divulgação em quatro etapas para minimizar o uso do contexto:
- Publicitar (~100 tokens por habilidade) — Nomes e descrições das habilidades são inseridos no prompt do sistema no início de cada jogada, para que o agente saiba que habilidades estão disponíveis.
-
Load (< 5000 tokens recomendados) — Quando uma tarefa está dentro do domínio de uma aptidão, o agente usa a ferramenta
load_skillpara recuperar o corpo completo do SKILL.md com instruções detalhadas. -
Leia recursos (conforme necessário) — O agente chama a
read_skill_resourceferramenta para obter ficheiros suplementares (referências, modelos, recursos) apenas quando necessário. -
Executar scripts (conforme necessário) — O agente chama a
run_skill_scriptferramenta para executar scripts incluídos com um skill.
Este padrão mantém a janela de contexto do agente enxuta, ao mesmo tempo que lhe dá acesso a conhecimento profundo do domínio sob demanda.
Observação
load_skill é sempre anunciado.
read_skill_resource é anunciada apenas quando pelo menos uma habilidade tem recursos.
run_skill_script é anunciado apenas quando pelo menos uma habilidade contém scripts.
Fornecer competências a um agente
AgentSkillsProvider (C#) e SkillsProvider (Python) são fornecedores de contexto que disponibilizam competências aos agentes. Suportam três fontes de competências:
-
Baseado em ficheiros — competências descobertas a partir de
SKILL.mdficheiros em diretórios de sistemas de ficheiros -
definido por código — competências definidas em linha no código usando
AgentInlineSkill(C#) ouSkill(Python) -
Baseado em classes — competências encapsuladas numa classe C# derivada de
AgentClassSkill<T>(apenas C#)
Para misturar múltiplas fontes num só fornecedor, use AgentSkillsProviderBuilder (apenas C# — ver Builder: cenários avançados multi-fonte).
Competências baseadas em ficheiros
Cria um AgentSkillsProvider que aponte para um diretório que contenha as suas competências e adicione-o aos fornecedores de contexto do agente. Passe um script runner para permitir a execução de scripts baseados em ficheiros encontrados em diretórios de competências:
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);
Advertência
DefaultAzureCredential é conveniente para o desenvolvimento, mas requer uma consideração cuidadosa na produção. Em produção, considere usar uma credencial específica (por exemplo, ManagedIdentityCredential) para evitar problemas de latência, sondagens não intencionais de credenciais e potenciais riscos de segurança provenientes de mecanismos de recurso.
Múltiplos diretórios de competências
Pode apontar o fornecedor para um único diretório pai — cada subdiretório contendo um SKILL.md é automaticamente descoberto como uma competência:
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "all-skills"));
Ou passar uma lista de caminhos para pesquisar em múltiplos diretórios raiz:
var skillsProvider = new AgentSkillsProvider(
[
Path.Combine(AppContext.BaseDirectory, "company-skills"),
Path.Combine(AppContext.BaseDirectory, "team-skills"),
]);
O prestador pesquisa até dois níveis de profundidade.
Personalização da descoberta de recursos
Por defeito, o fornecedor reconhece recursos com extensões .md, .json, .yaml, .yml, .csv, .xml, e .txt em subdiretórios references e assets. Use AgentFileSkillsSourceOptions para alterar estes predefinidos:
var fileOptions = new AgentFileSkillsSourceOptions
{
AllowedResourceExtensions = [".md", ".txt"],
ResourceDirectories = ["docs", "templates"],
};
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
fileOptions: fileOptions);
Execução de scripts
Passe SubprocessScriptRunner.RunAsync como segundo argumento para AgentSkillsProvider permitir a execução de scripts baseados em ficheiros:
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
SubprocessScriptRunner.RunAsync);
SubprocessScriptRunner.RunAsync é aproximadamente equivalente ao seguinte:
// 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();
}
O runner executa cada script descoberto como um subprocesso local, encaminhando os argumentos JSON fornecidos pelo agente como flags na linha de comandos.
Advertência
SubprocessScriptRunner é fornecido apenas para fins demonstrativos. Para uso em produção, considere adicionar:
- Sandboxing (por exemplo, contentores ou ambientes de execução isolados)
- Limites de recursos (limites de CPU, limites de memória, tempo limite de execução)
- Validação de entrada e listagem de scripts executáveis
- Registos estruturados e trilhas de auditoria
Personalizar a descoberta de scripts
Por defeito, o fornecedor reconhece scripts com extensões .py, .js, .sh, .ps1, .cs, , e .csx no scripts subdiretório. Use AgentFileSkillsSourceOptions para alterar estes predefinidos:
Passe AgentFileSkillsSourceOptions ao construtor ou ao AgentSkillsProviderUseFileSkill / construtor:UseFileSkills
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();
Competências baseadas em ficheiros
Crie um SkillsProvider apontando para um diretório que contenha as suas competências e adicione-o aos provedores de contexto do 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],
)
Múltiplos diretórios de competências
Pode apontar o fornecedor para uma única pasta principal — cada subpasta que contenha um SKILL.md é automaticamente identificada como uma aptidão:
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "all-skills"
)
Ou passar uma lista de caminhos para pesquisar em múltiplos diretórios raiz:
skills_provider = SkillsProvider(
skill_paths=[
Path(__file__).parent / "company-skills",
Path(__file__).parent / "team-skills",
]
)
O prestador pesquisa até dois níveis de profundidade.
Personalização da descoberta de recursos
Por defeito, SkillsProvider reconhece recursos com extensões .md, .json, .yaml, .yml, .csv, .xml, e .txt. Escaneia todos os subdiretórios dentro de cada pasta de competências. Passe resource_extensions para alterar os tipos de ficheiros reconhecidos:
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
resource_extensions=(".md", ".txt"),
)
Execução de scripts
Para permitir a execução de scripts baseados em ficheiros, passe a script_runner para SkillsProvider. Qualquer função síncrona ou assíncrona que satisfaça o protocolo SkillScriptRunner pode ser usada:
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,
)
O executante recebe o Skill resolvido, SkillScript, e um dicionário opcional args. Os scripts baseados em ficheiros são automaticamente descobertos a partir de .py ficheiros em diretórios de competências.
Advertência
O corredor acima é fornecido apenas para fins de demonstração. Para uso em produção, considere adicionar:
- Sandboxing (por exemplo, contentores,
seccomp, oufirejail) - Limites de recursos (limites de CPU, limites de memória, tempo limite de execução)
- Validação de entrada e listagem de scripts executáveis
- Registos estruturados e trilhas de auditoria
Observação
Se forem fornecidas competências baseadas em ficheiros com scripts mas nenhuma script_runner estiver definida, SkillsProvider gera um ValueError.
Competências definidas por código
Para além das competências baseadas em ficheiros descobertas a partir de SKILL.md ficheiros, podes definir competências inteiramente em código usando AgentInlineSkill. Competências definidas pelo código são úteis quando:
- O conteúdo de competências é gerado dinamicamente (por exemplo, leitura de uma base de dados ou ambiente).
- Deves manter as definições de competências juntamente com o código da aplicação que as utiliza.
- Precisas de recursos que executem lógica em tempo de leitura em vez de servirem ficheiros estáticos.
Competências básicas de programação
Cria um AgentInlineSkill com nome, descrição e instruções. Anexe recursos 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);
Recursos dinâmicos
Passe um delegado de fábrica para .AddResource() a fim de calcular o conteúdo durante o tempo de execução. O delegado é invocado cada vez que o agente lê o recurso:
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 definidos por código
Use .AddScript() para registar um delegado como script executável. Scripts definidos por código são executados dentro do processo como chamadas diretas a delegados. Não é necessário um script runner. Os parâmetros tipados pelo delegado são automaticamente convertidos num Esquema JSON que o agente utiliza para passar os argumentos:
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);
Observação
Para combinar competências definidas por código com competências baseadas em ficheiros ou classes num único fornecedor, use AgentSkillsProviderBuilder — veja Builder: cenários avançados multi-fonte.
Para além das competências baseadas em ficheiros descobertas a partir de ficheiros SKILL.md, podes definir competências inteiramente em código Python. Competências definidas pelo código são úteis quando:
- O conteúdo de competências é gerado dinamicamente (por exemplo, leitura de uma base de dados ou ambiente).
- Deves manter as definições de competências juntamente com o código da aplicação que as utiliza.
- Precisas de recursos que executem lógica em tempo de leitura em vez de servirem ficheiros estáticos.
Competências básicas de programação
Crie uma Skill instância com um nome, descrição e conteúdo de instruções. Opcionalmente, anexe SkillResource instâncias com conteúdo estático:
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])
Recursos dinâmicos
Use o @skill.resource decorador para registar uma função como recurso. A função é chamada cada vez que o agente lê o recurso, para que possa devolver dados atualizados. São suportadas tanto funções de sincronização como assíncronas:
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 o decorador é usado sem argumentos (@skill.resource), o nome da função torna-se o nome do recurso e a docstring torna-se a descrição. Use @skill.resource(name="...", description="...") para os definir explicitamente.
Scripts definidos por código
Use o @skill.script decorador para registar uma função como um script executável numa capacidade. Scripts definidos por código correm em processo e não requerem um executor de script. São suportadas tanto funções de sincronização como assíncronas:
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 o decorador é usado sem argumentos (@skill.script), o nome da função torna-se o nome do script e a docstring torna-se a descrição. Os parâmetros tipados da função são automaticamente convertidos num Esquema JSON que o agente usa para passar argumentos.
Combinação de competências baseadas em ficheiros e definidas por código
Passe ambos skill_paths e skills para um único SkillsProvider. As competências baseadas em ficheiros são descobertas primeiro; Se uma competência definida por código tiver o mesmo nome de uma competência baseada em ficheiros existente, a competência definida por código é ignorada:
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],
)
Competências baseadas em classes
As competências baseadas em classes permitem-lhe agrupar todos os componentes — nome, descrição, instruções, recursos e scripts — numa única classe de C#. Derive de AgentClassSkill<T> (onde T é a sua classe), depois anote propriedades com [AgentSkillResource] e métodos com [AgentSkillScript] para descoberta automática:
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 });
}
}
Registe a competência baseada em classe com AgentSkillsProvider:
var skill = new UnitConverterSkill();
var skillsProvider = new AgentSkillsProvider(skill);
Quando o [AgentSkillResource] atributo é aplicado a uma propriedade ou método, o seu valor de retorno é usado como conteúdo de recurso quando o agente lê o recurso — use um método quando o conteúdo precisa de ser calculado em tempo de leitura. Quando [AgentSkillScript] é aplicado a um método, o método é invocado quando o agente chama o script. Use [Description] from System.ComponentModel para descrever cada recurso e script para o agente.
Observação
AgentClassSkill<T> também suporta sobrescrever Resources e Scripts como coleções para cenários onde a descoberta baseada em atributos não é adequada.
Construtor: cenários avançados multifonte
Para cenários simples, de fonte única, use diretamente os AgentSkillsProvider construtores. Use AgentSkillsProviderBuilder quando precisar de algum dos seguintes:
-
Tipos de competências mistas — combinam competências baseadas em ficheiros, definidas por código (
AgentInlineSkill) e baseadas em classes (AgentClassSkill) num único fornecedor. - Filtragem de competências — incluir ou excluir competências usando um predicado.
Tipos de habilidades mistas
Combine os três tipos de competências num único fornecedor, encadeando UseFileSkill, UseSkill, e 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();
Filtragem de competências
Use UseFilter para incluir apenas as competências que cumprem os seus critérios — por exemplo, para carregar competências de um diretório partilhado mas excluir as experimentais:
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();
Aprovação de script
Use AgentSkillsProviderOptions.ScriptApproval para condicionar toda a execução de scripts à aprovação humana. Quando ativado, o agente pausa e devolve um pedido de aprovação em vez de executar imediatamente:
var skillsProvider = new AgentSkillsProvider(
skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
ScriptApproval = true,
});
Para permitir a aprovação de scripts num fornecedor configurado pelo construtor, utilize UseScriptApproval:
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
.UseScriptApproval(true)
.Build();
Use require_script_approval=True em SkillsProvider para colocar toda execução de scripts atrás de aprovação humana. Em vez de executar imediatamente, o agente pausa e devolve os pedidos de aprovação:
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 um script é rejeitado (approved=False), o agente é informado de que o utilizador recusou e pode responder em conformidade.
Indicação de sistema personalizada
Por defeito, o fornecedor de competências insere um prompt do sistema que lista as competências disponíveis e instrui o agente a usar load_skill e read_skill_resource. Pode personalizar este prompt:
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}
"""
});
Observação
O modelo personalizado deve conter {skills} (lista de competências), {resource_instructions} (sugestão de ferramenta de recursos) e {script_instructions} (sugestão de ferramenta de script) espaços reservados. Os parênteses literais devem ser escapados como {{ 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."
),
)
Observação
O modelo personalizado deve conter um {skills} marcador onde a lista de competências é inserida e um {runner_instructions} marcador onde são inseridas instruções relacionadas com o script.
Comportamento de cache
Por padrão, as ferramentas de competências e as instruções são armazenadas em cache após a primeira construção. Configure-se DisableCaching = true em AgentSkillsProviderOptions para forçar a reconstrução em cada invocação.
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
DisableCaching = true,
});
Observação
Desativar o cache é útil durante o desenvolvimento, quando o conteúdo das habilidades muda frequentemente. Em produção, deixe a cache ativada (o padrão) para melhor desempenho.
Injeção de dependência
Os delegados de recursos de competências e scripts podem declarar um IServiceProvider parâmetro que o Agent Framework injeta automaticamente. Isto permite que as competências resolvam serviços de aplicação — como clientes de base de dados, configuração ou lógica de negócio — sem os codificar diretamente na definição da competência.
Configuração
Registe os seus serviços de aplicação e passe o build IServiceProvider ao agente através do parâmetro 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);
Competências definidas por código com DI
Declare IServiceProvider como um parâmetro em AddResource ou AddScript delegados — o framework resolve e injeta-o automaticamente quando o agente lê um recurso ou executa um 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);
});
Competências baseadas em classes com DI
Anote métodos com [AgentSkillResource] ou [AgentSkillScript] e declare um IServiceProvider parâmetro — o framework descobre estes membros através de reflexão e injeta automaticamente o fornecedor de serviços:
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);
}
}
Sugestão
Competências baseadas em classes também podem resolver dependências por meio do seu construtor. Registe a classe de habilidade no ServiceCollection e resolve-a a partir do contentor em vez de chamar new diretamente:
services.AddSingleton<WeightConverterSkill>();
var weightSkill = serviceProvider.GetRequiredService<WeightConverterSkill>();
Isto é útil quando a própria classe de habilidades precisa de serviços injetados além daqueles utilizados pelos delegados de recursos e scripts.
As funções de recursos e scripts que aceitam **kwargs recebem automaticamente argumentos de palavra-chave em tempo de execução passados para agent.run(). Isto permite que as funções de competência acedam ao contexto da aplicação — como configuração, identidade do utilizador ou clientes de serviço — sem os codificar diretamente na definição de competência.
Passagem de argumentos de tempo de execução
Passe function_invocation_kwargs a agent.run() para fornecer argumentos de palavras-chave que o framework encaminha para funções de recurso e script:
response = await agent.run(
"How many kilometers is 26.2 miles?",
function_invocation_kwargs={"precision": 2, "user_id": "alice"},
)
Funções de recurso com kwargs
Quando uma função de recurso declara **kwargs, a estrutura encaminha os argumentos das palavras-chave em tempo de execução cada vez que o agente lê o recurso:
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}"
Funções de recurso sem **kwargs são chamadas sem argumentos e não recebem contexto em tempo de execução.
Funções de script com kwargs
Quando uma função de script declara **kwargs, a estrutura encaminha os argumentos de palavras-chave em tempo de execução juntamente com os args que são fornecidos pelo 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})
O agente fornece value e factor através da chamada à ferramenta args; a aplicação fornece precision através de function_invocation_kwargs. Funções de script sem **kwargs recebem apenas os argumentos fornecidos pelo agente.
Práticas recomendadas de segurança
As Competências de Agente devem ser tratadas como qualquer código de terceiros que introduza no seu projeto. Como as instruções de skill são inseridas no contexto do agente — e as skills podem incluir scripts — aplicar o mesmo nível de revisão e governação que aplicaria a uma dependência open-source é essencial.
-
Revise antes de usar — Leia todo o conteúdo de competências (
SKILL.mdscripts e recursos) antes de implementar. Verifique se o comportamento real de um script corresponde à sua intenção declarada. Verifique instruções adversariais que tentem contornar as diretrizes de segurança, exfiltrar dados ou modificar ficheiros de configuração do agente. - Confiança na fonte — Só instale competências de autores de confiança ou colaboradores internos verificados. Prefiro competências com proveniência clara, controlo de versões e manutenção ativa. Fique atento a nomes de habilidades typosquatted que imitam pacotes populares.
- Sandboxing — Executar funcionalidades que incluam scripts executáveis em ambientes isolados. Limite o acesso ao sistema de ficheiros, rede e sistema apenas ao que a competência exige. Exija confirmação explícita do utilizador antes de executar operações potencialmente sensíveis.
- Auditoria e registo — Registar as competências carregadas, os recursos lidos e os scripts executados. Isto dá-te um registo de auditoria para rastrear o comportamento dos agentes até ao conteúdo específico de competências caso algo corra mal.
Quando usar competências vs. fluxos de trabalho
As Competências do Agente e os Fluxos de Trabalho do Framework do Agente estendem o que os agentes podem fazer, mas funcionam de formas fundamentalmente diferentes. Escolha a abordagem que melhor se adeque às suas necessidades:
- Controlo — Com uma habilidade, a IA decide como executar as instruções. Isto é ideal quando se quer que o agente seja criativo ou adaptativo. Com um fluxo de trabalho, defines explicitamente o caminho de execução. Use fluxos de trabalho quando precisar de comportamento determinístico e previsível.
- Resiliência — Uma habilidade é executada num único turno completo de um agente. Se algo falhar, toda a operação tem de ser tentada novamente. Os fluxos de trabalho suportam o armazenamento de pontos de verificação, para que possam retomar a partir do último passo bem-sucedido após uma falha. Escolha fluxos de trabalho quando o custo de reexecutar todo o processo for elevado.
- Efeitos secundários — As competências são adequadas quando as operações são idempotentes ou de baixo risco. Prefira fluxos de trabalho quando as etapas produzem efeitos secundários (envio de emails, cobrança de pagamentos) que não devam ser repetidos numa nova tentativa.
- Complexidade — As competências são melhores para tarefas focadas e de domínio único que um agente pode gerir. Os fluxos de trabalho são mais adequados para processos empresariais em múltiplas etapas que coordenam múltiplos agentes, aprovações humanas ou integrações de sistemas externos.
Sugestão
Como regra geral: se quiseres que a IA descubra como realizar uma tarefa, usa uma habilidade. Se precisares de garantir que passos são executados e em que ordem, usa um fluxo de trabalho.