Overview
Uma habilidade é um diretório nomeado que contém um arquivo SKILL.md — um documento markdown que fornece instruções para Copilot. Quando carregado, o conteúdo da habilidade é injetado no contexto da sessão.
As habilidades permitem que você:
- Empacotar expertise de domínio em módulos reutilizáveis
- Compartilhar comportamentos especializados entre projetos
- Organizar configurações complexas do agente
- Habilitar/desabilitar recursos por sessão
Carregando habilidades
Especifique os diretórios que contêm habilidades ao criar uma sessão:
Idiomas de código navigation
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-5.4",
skillDirectories: [
"./skills/code-review",
"./skills/documentation",
],
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
// Copilot now has access to skills in those directories
await session.sendAndWait({ prompt: "Review this code for security issues" });
from copilot import CopilotClient, PermissionDecisionApproveOnce
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
model="gpt-5.4",
skill_directories=[
"./skills/code-review",
"./skills/documentation",
],
)
# Copilot now has access to skills in those directories
await session.send_and_wait("Review this code for security issues")
await client.stop()
package main
import (
"context"
"log"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}
defer client.Stop()
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-5.4",
SkillDirectories: []string{
"./skills/code-review",
"./skills/documentation",
},
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
if err != nil {
log.Fatal(err)
}
// Copilot now has access to skills in those directories
_, err = session.SendAndWait(ctx, copilot.MessageOptions{
Prompt: "Review this code for security issues",
})
if err != nil {
log.Fatal(err)
}
}
using GitHub.Copilot;
using GitHub.Copilot.Rpc;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5.4",
SkillDirectories = new List<string>
{
"./skills/code-review",
"./skills/documentation",
},
OnPermissionRequest = (req, inv) =>
Task.FromResult(PermissionDecision.ApproveOnce()),
});
// Copilot now has access to skills in those directories
await session.SendAndWaitAsync(new MessageOptions
{
Prompt = "Review this code for security issues"
});
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
import java.util.List;
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setModel("gpt-5.4")
.setSkillDirectories(List.of(
"./skills/code-review",
"./skills/documentation"
))
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
// Copilot now has access to skills in those directories
session.sendAndWait(new MessageOptions()
.setPrompt("Review this code for security issues")
).get();
}
Desativando funcionalidades
Desabilite habilidades específicas mantendo outras pessoas ativas:
Idiomas de código navigation
const session = await client.createSession({
skillDirectories: ["./skills"],
disabledSkills: ["experimental-feature", "deprecated-tool"],
});
from copilot.session import PermissionHandler
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
skill_directories=["./skills"],
disabled_skills=["experimental-feature", "deprecated-tool"],
)
session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
SkillDirectories: []string{"./skills"},
DisabledSkills: []string{"experimental-feature", "deprecated-tool"},
})
var session = await client.CreateSessionAsync(new SessionConfig
{
SkillDirectories = new List<string> { "./skills" },
DisabledSkills = new List<string> { "experimental-feature", "deprecated-tool" },
});
import com.github.copilot.rpc.*;
import java.util.List;
var session = client.createSession(
new SessionConfig()
.setSkillDirectories(List.of("./skills"))
.setDisabledSkills(List.of("experimental-feature", "deprecated-tool"))
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
Estrutura do diretório de habilidades
Cada habilidade é um subdiretório nomeado que contém um SKILL.md arquivo:
skills/
├── code-review/
│ └── SKILL.md
└── documentation/
└── SKILL.md
A skillDirectories opção aponta para o diretório pai (por exemplo, ./skills). A CLI descobre todos os SKILL.md arquivos em subdiretórios imediatos.
formato SKILL.md
Um SKILL.md arquivo é um documento de markdown com metadados YAML opcionais:
---
name: code-review
description: Specialized code review capabilities
---
# Code Review Guidelines
When reviewing code, always check for:
1. **Security vulnerabilities** - SQL injection, XSS, etc.
2. **Performance issues** - N+1 queries, memory leaks
3. **Code style** - Consistent formatting, naming conventions
4. **Test coverage** - Are critical paths tested?
Provide specific line-number references and suggested fixes.
Os campos de elementos iniciais:
name: o identificador da habilidade (usado comdisabledSkillspara desativá-la seletivamente). Se omitido, o nome do diretório será usado.description: uma breve descrição do que a habilidade faz.
O corpo do markdown contém as instruções que são injetadas no contexto da sessão quando a habilidade é carregada.
Provedores de skills (experimental)
Observação
Os Skill providers são experimentais. A API pode mudar em versões futuras do SDK.
Um provedor de habilidades fornece habilidades do próprio armazenamento do aplicativo, como um banco de dados em um serviço multilocatário, em vez de arquivos SKILL.md no disco. As habilidades do provedor ingressam no catálogo de habilidades da sessão juntamente com as habilidades baseadas em arquivo. O modelo os carrega sob demanda por meio da ferramenta skill, e os usuários podem invocá-los como qualquer outra skill.
Um provedor implementa duas operações:
- Listar habilidades: retorna metadados de catálogo para cada habilidade: um
name, umdescriptione, opcionalmente,userInvocable,disableModelInvocationeargumentHint. O runtime faz essa chamada quando carrega as habilidades da sessão. - Ler habilidade: retorna o markdown para uma habilidade ou um resultado de não encontrado se a habilidade não existir mais. O runtime o chama somente quando a skill é carregada.
Passe o provedor ao criar ou retomar uma sessão:
import { approveAll, CopilotClient, type SkillProvider } from "@github/copilot-sdk";
const releaseSkills = new Map([
[
"release-notes",
{
description: "Writes release notes in the team's format.",
markdown: "Group changes by feature area and link each pull request.",
},
],
]);
const skillProvider: SkillProvider = {
listSkills: () =>
[...releaseSkills].map(([name, skill]) => ({ name, description: skill.description })),
readSkill: (name) => releaseSkills.get(name)?.markdown ?? null,
};
const client = new CopilotClient();
const session = await client.createSession({
onPermissionRequest: approveAll,
skillProvider,
});
from copilot import CopilotClient, SkillProviderDescriptor
from copilot.session import PermissionHandler
RELEASE_SKILLS = {
"release-notes": (
"Writes release notes in the team's format.",
"Group changes by feature area and link each pull request.",
),
}
class ReleaseSkills:
async def list_skills(self) -> list[SkillProviderDescriptor]:
return [
SkillProviderDescriptor(name=name, description=description)
for name, (description, _) in RELEASE_SKILLS.items()
]
async def read_skill(self, name: str) -> str | None:
skill = RELEASE_SKILLS.get(name)
return skill[1] if skill else None
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
skill_provider=ReleaseSkills(),
)
package main
import (
"context"
"fmt"
"log"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
type releaseSkill struct {
description string
markdown string
}
type releaseSkills map[string]releaseSkill
func (s releaseSkills) ListSkills(ctx context.Context) ([]rpc.SkillProviderDescriptor, error) {
descriptors := make([]rpc.SkillProviderDescriptor, 0, len(s))
for name, skill := range s {
descriptors = append(descriptors, rpc.SkillProviderDescriptor{Name: name, Description: skill.description})
}
return descriptors, nil
}
func (s releaseSkills) ReadSkill(ctx context.Context, name string) (string, error) {
skill, ok := s[name]
if !ok {
return "", fmt.Errorf("%w: %s", copilot.ErrSkillNotFound, name)
}
return skill.markdown, nil
}
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
SkillProvider: releaseSkills{
"release-notes": {
description: "Writes release notes in the team's format.",
markdown: "Group changes by feature area and link each pull request.",
},
},
})
if err != nil {
log.Fatal(err)
}
_ = session
}
#pragma warning disable GHCP001 // Skill providers are experimental.
using GitHub.Copilot;
using GitHub.Copilot.Rpc;
public sealed class ReleaseSkills : ISkillProvider
{
private readonly Dictionary<string, (string Description, string Markdown)> _skills = new()
{
["release-notes"] = (
"Writes release notes in the team's format.",
"Group changes by feature area and link each pull request."),
};
public Task<IReadOnlyList<SkillProviderDescriptor>> ListSkillsAsync(CancellationToken cancellationToken) =>
Task.FromResult<IReadOnlyList<SkillProviderDescriptor>>(
_skills.Select(skill => new SkillProviderDescriptor
{
Name = skill.Key,
Description = skill.Value.Description,
}).ToList());
public Task<string?> ReadSkillAsync(string name, CancellationToken cancellationToken) =>
Task.FromResult(_skills.TryGetValue(name, out var skill) ? skill.Markdown : null);
}
public static class SkillProviderExample
{
public static async Task RunAsync(CopilotClient client)
{
await using var session = await client.CreateSessionAsync(new SessionConfig
{
OnPermissionRequest = PermissionHandler.ApproveAll,
SkillProvider = new ReleaseSkills(),
});
}
}
Os tipos de provedor de habilidades .NET geram o GHCP001 diagnóstico experimental. Suprima isso com #pragma warning disable GHCP001 ou com um <NoWarn>GHCP001</NoWarn> em nível de projeto.
import com.github.copilot.AllowCopilotExperimental;
import com.github.copilot.CopilotClient;
import com.github.copilot.CopilotSession;
import com.github.copilot.SkillProvider;
import com.github.copilot.SkillProviderDescriptor;
import com.github.copilot.rpc.PermissionHandler;
import com.github.copilot.rpc.SessionConfig;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@AllowCopilotExperimental
class ReleaseSkills implements SkillProvider {
private final Map<String, String> markdown = Map.of(
"release-notes", "Group changes by feature area and link each pull request.");
@Override
public CompletableFuture<List<SkillProviderDescriptor>> listSkills() {
return CompletableFuture.completedFuture(List.of(new SkillProviderDescriptor(
"release-notes", "Writes release notes in the team's format.", null, null, null)));
}
@Override
public CompletableFuture<String> readSkill(String name) {
return CompletableFuture.completedFuture(markdown.get(name));
}
}
@AllowCopilotExperimental
class SkillProviderExample {
static CopilotSession createSession(CopilotClient client) throws Exception {
return client.createSession(new SessionConfig()
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
.setSkillProvider(new ReleaseSkills()))
.get();
}
}
A API Java de skill provider está @CopilotExperimental, portanto, a classe ou o método que a consome deve optar explicitamente por @AllowCopilotExperimental (ou compilar com -Acopilot.experimental.allowed=true). Consulte Usando APIs experimentais.
use std::sync::Arc;
use async_trait::async_trait;
use github_copilot_sdk::{Error, SessionConfig, SkillProvider, SkillProviderDescriptor};
struct ReleaseSkills;
#[async_trait]
impl SkillProvider for ReleaseSkills {
async fn list_skills(&self) -> Result<Vec<SkillProviderDescriptor>, Error> {
Ok(vec![SkillProviderDescriptor {
name: "release-notes".into(),
description: "Writes release notes in the team's format.".into(),
..Default::default()
}])
}
async fn read_skill(&self, name: &str) -> Result<Option<String>, Error> {
Ok((name == "release-notes")
.then(|| "Group changes by feature area and link each pull request.".to_string()))
}
}
let session = client
.create_session(
SessionConfig::default()
.approve_all_permissions()
.with_skill_provider(Arc::new(ReleaseSkills)),
)
.await?;
Conteúdo da skill do provedor
Read skill retorna o texto da habilidade SKILL.md. O frontmatter YAML é opcional:
- Sem o frontmatter, todo o texto é o corpo da habilidade e todos os metadados vêm da habilidade listada.
- Com o frontmatter, um campo omitido herda o valor listado. Um campo que você inclui deve corresponder ao valor listado, ou a habilidade falha ao carregar.
allowed-toolsé lido somente do frontmatter.- Se a primeira linha do texto for
---, o runtime o analisará como frontmatter, portanto, não inicie uma skill apenas com corpo com uma quebra temática markdown.
Por padrão, as habilidades do provedor são somente texto: elas não têm diretório base, portanto, não podem referenciar scripts agrupados, modelos ou outros arquivos. Para atribuir esses arquivos a uma habilidade de provedor, consulte Arquivos de suporte.
skills.list informa as competências do provedor com a origem sdk e um path vazio, com ou sem arquivos de suporte.
Arquivos de suporte (experimental)
Uma habilidade de provedor pode vir com arquivos de suporte, como scripts, referências, modelos e recursos, da mesma forma que uma pasta de habilidade baseada em arquivo pode. Seu aplicativo mantém os arquivos de cada skill em uma pasta que ele controla e define directory da skill listada como o caminho absoluto dessa pasta.
Quando a habilidade é ativada pelo modelo, o runtime lista a pasta da mesma forma que lista a pasta de uma habilidade baseada em arquivo. O modelo obtém a mesma linha "Diretório base para essa habilidade" e a lista de arquivos relacionados que uma habilidade baseada em arquivo obtém, no lugar do aviso somente texto, e lê os arquivos com suas ferramentas de arquivo comuns. O runtime nunca lê, copia ou grava os arquivos em si.
import { approveAll, CopilotClient, type SkillProvider } from "@github/copilot-sdk";
const skillProvider: SkillProvider = {
listSkills: () => [
{
name: "release-notes",
description: "Writes release notes in the team's format.",
directory: "/srv/skills/release-notes",
},
],
readSkill: (name) =>
name === "release-notes"
? "Run `python3 scripts/changelog.py` and fill in `templates/notes.md`."
: null,
};
const client = new CopilotClient();
const session = await client.createSession({
onPermissionRequest: approveAll,
skillProvider,
});
Cada SDK define a pasta em seu tipo de habilidade listado:
| SDK | Campo |
|---|---|
| Node.js | directory: "/ |
| Python | directory="/ |
| Go | Directory: copilot.String("/ |
| .NET | Directory = "/ |
| Java | O sexto Skill argumento do construtor |
| Rust | directory: Some("/ |
Onde a pasta reside
Coloque todos os arquivos de uma habilidade em directory, uma pasta por habilidade. A pasta deve ser acessível onde o runtime é executado:
- Disco rígido local. Sem um sistema de arquivos de sessão,
directoryé um caminho no computador ou contêiner que executa o runtime. O modelo pode ler os arquivos com qualquer ferramenta de arquivo e pode executar scripts. - Sistema de arquivos de sessão (Multilocação e implantações de servidores). Com um
sessionFsmanipulador,directoryusa as convenções de caminho do manipulador e o manipulador serve os arquivos; o runtime lista a pasta por meio dele.view,create,editeapply_patchalcançam os arquivos.grep,globe os comandos de shell não o fazem, portanto, os scripts não podem ser executados. O SDK do Java não temsessionFs, portanto, provedores Java usam disco local.
O runtime lista a pasta após o retorno da habilidade de leitura, para que você possa criar a pasta sob demanda na habilidade de leitura. Se a pasta estiver ausente ou vazia, ou não puder ser listada em até 15 segundos após o runtime chamar a habilidade de leitura, o modelo ainda obterá a linha de diretório base, sem nenhuma lista de arquivos relacionados, como em uma habilidade baseada em arquivo. Se o handler sessionFs estiver desconectado quando o runtime listar habilidades, essas habilidades serão somente texto até a próxima listagem.
Access
- Disco Local. A partir do momento em que as habilidades são listadas, o runtime trata cada
directoryde habilidade de provedor habilitada como umaskillDirectoriespasta configurada: as leituras nela ignoram o prompt de caminho fora do workspace, e os processos em área restrita obtêm acesso somente leitura a ela. As leituras ainda vão para o manipulador de permissões, assim como acontece com habilidades baseadas em arquivo. Não retorne um diretório amplo, como sua pasta inicial ou uma pasta que contém os arquivos de cada locatário. - Sistema de arquivos de sessão. O runtime não adiciona acesso à pasta. Faça com que o manipulador de permissões aprove leituras nele e, quando a área restrita estiver ativada, adicione a pasta ao
readonlyPathsda área restrita.
Seu aplicativo é o proprietário da pasta: onde ela reside, por quanto tempo ela existe, sua limpeza e impedir que o modelo a altere. O acesso somente leitura abrange apenas processos em sandbox. Fora da área restrita ou quando a pasta estiver dentro da área de trabalho, o modelo poderá gravar nela, a menos que o manipulador de permissões ou seu manipulador sessionFs se recuse.
Criando a skill
- Consulte os arquivos de suporte por seu caminho em relação à pasta da habilidade, como
references/guide.md. O modelo é informado do caminho absoluto da pasta. - Execute scripts por meio de um interpretador, como
python3 scripts/changelog.pyoubash scripts/build.sh, como o uso de scripts em skills descreve. Os scripts são executados somente quando a pasta está no disco local.
Regras e limites
directorydeve ser absoluto nas convenções de caminho da sessão; em um sistema de arquivos de sessão no estilo Windows, ele precisa de uma unidade ou prefixo UNC. É resolvido da mesma maneira que as ferramentas de arquivo resolvem caminhos, de modo que os segmentos.e..e os separadores repetidos ou finais são removidos, e não pode ser resolvido para uma raiz do sistema de arquivos. Ele conta para o limite de metadados de 1 MiB do catálogo e não é mostrado em catálogos de habilidades. Uma entrada inválidadirectoryfaz com que todo o catálogo seja rejeitado, como qualquer outra habilidade inválida listada.- A lista de arquivos relacionados segue as regras baseadas em arquivo: pastas de build e dependência, como
node_modules,bin,objedist, estão ocultas; uma pasta com mais de 50 entradas é resumida; arquivos aninhados com mais de 10 pastas profundas não são listados;SKILL.mdnunca é listado; e no máximo 100 arquivos são mostrados. - Depois que a conversa é compactada, o modelo mantém as instruções da habilidade, mas não o caminho da pasta. Invocá-la novamente mostra isso. As habilidades baseadas em arquivo mantêm seu caminho.
- Os arquivos de suporte precisam de uma CLI Copilot pelo menos tão nova quanto a versão do SDK que os adicionou. Uma CLI mais antiga rejeita todo o catálogo de habilidades quando qualquer habilidade listada tem um
directory. Os provedores que não definemdirectoryfuncionam com CLIs mais antigos.
Usando arquivos SKILL.md existentes
Para fornecer SKILL.md arquivos que você já tem, como arquivos armazenados em um banco de dados, analise o frontmatter YAML de cada arquivo uma vez para criar sua entrada de catálogo e, em seguida, retorne o arquivo inalterado da read skill:
- Mapear
nameedescriptionpara osnameedescriptionda habilidade listada. Ambos são necessários no catálogo; o runtime não faz fallback para um nome de pasta ou o corpo da habilidade. - Mapear
user-invocable,disable-model-invocationeargument-hintpara os campos opcionais correspondentes quando o frontmatter os define. - Retorne o texto original, frontmatter incluído, da read skill. Como os valores listados vieram do mesmo frontmatter, eles correspondem e o runtime ainda lê
allowed-toolsdele.
Confiar no conteúdo do provedor
Trate as habilidades do provedor como diretórios de habilidades: seu conteúdo é uma entrada confiável. O modelo segue as instruções de uma habilidade e o frontmatter controla como a habilidade é invocada.
allowed-tools não concede permissões em sessões do SDK. O runtime o relata no campo allowedTools do evento skill.invoked, e seu manipulador de permissões ainda decide cada solicitação de ferramenta.
Não forneça texto que os usuários finais ou outros inquilinos possam editar, a menos que você permita que eles criem um skill file. Se você criar habilidades com base na entrada do usuário, gere o frontmatter por conta própria em vez de passar o frontmatter fornecido pelo usuário.
Limites e erros do provedor
O runtime valida o catálogo e o conteúdo do provedor:
-
Os nomes devem corresponder a
^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$e ser exclusivos sem diferenciar maiúsculas de minúsculas. -
Um catálogo pode conter no máximo 1.024 habilidades e 1 MiB de metadados. Cada descrição e dica de argumento pode ter no máximo 1.024 caracteres.
-
O markdown de cada habilidade pode ter no máximo 1 MiB de UTF-8.
-
Cada chamada deve ser concluída em até 30 segundos. Quando o runtime para de aguardar uma chamada, porque ela atingiu o tempo limite, a sessão terminou ou uma retomada substituiu o provedor, o runtime cancela a solicitação e ignora qualquer resultado posterior. Cada SDK passa essa solicitação de cancelamento para seu provedor da maneira usual:
SDK Sinal de cancelamento Node.js O signal(AbortSignal) passado nas opções paralistSkillsereadSkillé abortado.Python A tarefa do provedor asyncioé cancelada comasyncio.Cancelled. Provedores síncronos são executados até a conclusão.Error Go A chamada context.Contextfoi cancelada..NET O/A CancellationTokenda chamada foi cancelado(a).Java O retornado CompletableFutureé cancelado comcancel(true), o que não interrompe o trabalho em execução.Rust O future do provedor é descartado. Esses sinais abrangem chamadas que o runtime cancela. Quando a conexão é fechada ou o cliente é interrompido à força, os SDKs .NET, Java e Rust também cancelam chamadas que ainda estão em execução. Os SDKs de Node.js, Python e Go não cancelam: uma chamada em execução continua até que ela retorne, e o SDK descarta seu resultado.
Se a listagem falhar ou retornar um catálogo inválido, o runtime relatará o problema na lista errors retornada por skills.reload. Uma recarga com falha mantém as competências do provedor da última lista bem-sucedida. Se a leitura de uma habilidade falhar, a ferramenta skill relatará uma falha de carga genérica no modelo. O SDK nunca encaminha o texto de erros que seu provedor lança ou retorna, de modo que o texto não possa vazar para a conversa.
Ciclo de vida do provedor
Um provedor está associado a uma sessão:
- Um provedor habilita habilidades, a menos que você defina
enableSkillsparafalse, o que mantém o provedor vinculado, mas nunca chamado. Emmode: "empty", as habilidades permanecem desabilitadas até você definirenableSkillscomotrue. - O provedor nunca é persistido. Passe-o novamente quando você retomar uma sessão. Retomar sem um provedor o remove da sessão. As extensões que ingressam na sessão não a alteram.
- Uma habilidade de provedor com o mesmo nome de uma habilidade baseada em arquivo substitui a habilidade baseada em arquivo e
skills.reloadrelata um aviso. - Os sub-agentes usam o provedor da sessão pai.
- O runtime pode chamar o provedor simultaneamente, por exemplo, pela ferramenta
skill, invocações de usuário e agentes personalizados que pré-carregam habilidades, portanto, ambas as operações devem ser seguras para uso simultâneo. - As sessões na nuvem não dão suporte a provedores de skills. O SDK rejeita a configuração antes de criar a sessão.
Opções de configuração
Campos de habilidade SessionConfig
| Linguagem | Campo | Tipo | Description |
|---|---|---|---|
| Node.js | skillDirectories | string[] | Diretórios para carregar habilidades de |
| Node.js | disabledSkills | string[] | Funções a desativar |
| Node.js | skillProvider | SkillProvider | Provedor experimental para habilidades fornecidas pelo SDK |
| Python | skill_directories | list[str] | Diretórios para carregar habilidades de |
| Python | disabled_skills | list[str] | Funções a desativar |
| Python | skill_provider | SkillProvider | Provedor experimental para habilidades fornecidas pelo SDK |
| Go | SkillDirectories | []string | Diretórios para carregar habilidades de |
| Go | DisabledSkills | []string | Funções a desativar |
| Go | SkillProvider | SkillProvider | Provedor experimental para habilidades fornecidas pelo SDK |
| .NET | SkillDirectories | List<string> | Diretórios para carregar habilidades de |
| .NET | DisabledSkills | List<string> | Funções a desativar |
| .NET | SkillProvider | ISkillProvider | Provedor experimental para habilidades fornecidas pelo SDK |
| Java | setSkillProvider | SkillProvider | Provedor experimental para habilidades fornecidas pelo SDK |
| Rust | with_skill_provider | Arc<dyn SkillProvider> | Provedor experimental para habilidades fornecidas pelo SDK |
Habilidades internas e mode: "empty"
O runtime vem com um conjunto de habilidades internas integradas que são habilitadas por padrão. Quando você executa o cliente em mode: "empty" (a linha de base recomendada para Multilocação e implantações de servidores), o SDK exclui todas as habilidades integradas incluídas no runtime: ele envia uma lista includedBuiltinSkills vazia no patch das opções pós-criação e pós-retomada, juntamente com a lista installedPlugins vazia.
Essa exclusão é o padrão, não uma restrição permanente. Para permitir habilidades selecionadas incluídas no runtime, defina includedBuiltinSkills (ou a grafia específica da linguagem) com os nomes delas. Você também pode optar por usar suas próprias habilidades personalizadas em mode: "empty"—habilitar habilidades e fornecer as suas próprias skillDirectories—e elas permanecem totalmente utilizáveis, inclusive uma habilidade personalizada que compartilhe o nome com uma nativa.
Em mode: "copilot-cli", o campo é omitido, a menos que você defina a opção.
Os diretórios de habilidades personalizados são verificados quando as habilidades são carregadas pela primeira vez, incluindo diretórios ausentes ou vazios nesse ponto. As alterações no sistema de arquivos nesses diretórios não atualizam automaticamente o catálogo em interações posteriores. Depois de adicionar, editar ou remover skills, chame o RPC da sua sessão skills.reload:
| SDK | Atualizar chamada |
|---|---|
| Node.js | await session.rpc.skills.reload() |
| Python | await session.rpc.skills.reload() |
| Go | session.RPC.Skills.Reload(ctx) |
| .NET | await session.Rpc.Skills.Reload |
| Java | session.get |
| Rust | session.rpc().skills().reload().await? |
Alterar os diretórios de habilidades configurados também atualiza o catálogo.
Práticas recomendadas
-
Organizar por domínio – Agrupar habilidades relacionadas (por exemplo,
skills/security/, )skills/testing/ -
Usar frontmatter – Incluir
nameedescriptionno frontmatter do YAML para maior clareza -
Dependências de documento – Observe as ferramentas ou servidores MCP que uma habilidade requer
-
Testar habilidades isoladamente – Verificar se as habilidades funcionam antes de combiná-las
-
Usar caminhos relativos – Manter as habilidades portáveis entre ambientes
Combinando com outros recursos
Habilidades + agentes personalizados
As habilidades listadas no campo de skills um agente são ansiosamente pré-carregadas– seu conteúdo completo é injetado no contexto do agente na inicialização, portanto, o agente tem acesso às instruções de habilidade imediatamente sem precisar invocar uma ferramenta de habilidade. Os nomes de habilidade são resolvidos no nível da sessão skillDirectories.
const session = await client.createSession({
skillDirectories: ["./skills/security"],
customAgents: [{
name: "security-auditor",
description: "Security-focused code reviewer",
prompt: "Focus on OWASP Top 10 vulnerabilities",
skills: ["security-scan", "dependency-check"],
}],
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
Observação
As habilidades são opcionais — quando skills é omitido, nenhum conteúdo de habilidades é injetado. Os sub-agentes não herdam habilidades do pai; você deve listá-los explicitamente por agente.
Habilidades + servidores MCP
As habilidades podem complementar os recursos do servidor MCP:
const session = await client.createSession({
skillDirectories: ["./skills/database"],
mcpServers: {
postgres: {
type: "local",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-postgres"],
tools: ["*"],
},
},
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
Troubleshooting
Habilidades que não estão carregando
- Caminho de verificação existe - Verifique se o caminho do diretório de habilidades está correto e contém subdiretórios com
SKILL.mdarquivos - Verificar permissões – verifique se o SDK pode ler o diretório
- Verificar o formato de SKILL.md — certifique-se de que o markdown está bem formado e que qualquer frontmatter YAML use sintaxe válida
- Habilitar o registro em log de depuração — defina
logLevel: "debug"para ver os logs de carregamento de habilidades
Conflitos de habilidades
Se várias habilidades fornecerem instruções conflitantes:
- Usar
disabledSkillspara excluir habilidades conflitantes - Reorganizar diretórios de habilidades para evitar sobreposições
Consulte também
- Crie seu primeiro aplicativo com tecnologia do Copilot – Definir personas de IA especializadas
- Crie seu primeiro aplicativo com tecnologia do Copilot – Criar suas próprias ferramentas
- Usando servidores MCP com o SDK do GitHub Copilot – Conectar provedores de ferramentas externas