Visión general
Una habilidad es un directorio con nombre que contiene un archivo SKILL.md: un documento Markdown que proporciona instrucciones a Copilot. Cuando se carga, el contenido de la habilidad se inyecta en el contexto de la sesión.
Las aptitudes le permiten:
- Empaquetar la experiencia de dominio en módulos reutilizables
- Uso compartido de comportamientos especializados entre proyectos
- Organizar las configuraciones complejas del agente
- Habilitación o deshabilitación de funcionalidades por sesión
Aptitudes de carga
Especifique directorios que contengan aptitudes al crear una sesión:
Lenguajes 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();
}
Deshabilitación de aptitudes
Deshabilite aptitudes específicas mientras mantiene a otros usuarios activos:
Lenguajes 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();
Estructura del directorio de aptitudes
Cada aptitud es un subdirectorio con nombre que contiene un SKILL.md archivo:
skills/
├── code-review/
│ └── SKILL.md
└── documentation/
└── SKILL.md
La skillDirectories opción apunta al directorio primario (por ejemplo, ./skills). La CLI detecta todos los SKILL.md archivos en subdirectorios inmediatos.
formato SKILL.md
Un archivo SKILL.md es un documento Markdown con un frontmatter YAML opcional.
---
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.
Los campos de frontmatter:
name: identificador de la aptitud (que se usa condisabledSkillspara deshabilitarla de forma selectiva). Si se omite, se usa el nombre del directorio.description: Una breve descripción de lo que hace la habilidad.
El cuerpo de Markdown contiene las instrucciones que se insertan en el contexto de sesión cuando se carga la aptitud.
Proveedores de habilidades (experimental)
Nota:
Los proveedores de skills son experimentales. La API puede cambiar en futuras versiones del SDK.
Un proveedor de habilidades proporciona habilidades del propio almacenamiento de la aplicación, como una base de datos en un servicio multiinquilino, en lugar de SKILL.md archivos en el disco. Las habilidades del proveedor se unen al catálogo de habilidades de la sesión junto con las habilidades basadas en archivos. El modelo los carga a petición a través de la herramienta skill, y los usuarios pueden invocarlos como cualquier otra habilidad.
Un proveedor implementa dos operaciones:
- Enumerar habilidades: devuelve metadatos de catálogo para cada habilidad:
name,descriptiony, opcionalmente,userInvocable,disableModelInvocationyargumentHint. El tiempo de ejecución lo llama cuando carga las habilidades de la sesión. - Leer aptitud: devuelve el markdown de una aptitud o un resultado no encontrado si la aptitud ya no existe. El tiempo de ejecución lo llama solo cuando se carga la habilidad.
Pase el proveedor al crear o reanudar una sesión:
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(),
});
}
}
Los tipos de proveedor de aptitudes .NET generan el GHCP001 diagnóstico experimental. Suprímalo con #pragma warning disable GHCP001 o con un <NoWarn>GHCP001</NoWarn> a nivel de proyecto.
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();
}
}
La API del proveedor de skills de Java es @CopilotExperimental, por lo que la clase o el método que consume deben habilitarse explícitamente con @AllowCopilotExperimental (o compilar con -Acopilot.experimental.allowed=true). Consulte Uso de API experimentales.
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?;
Contenido de habilidades del proveedor
La habilidad Read devuelve el texto de la habilidad SKILL.md. El frontmatter de YAML es opcional:
- Sin frontmatter, todo el texto es el cuerpo de la skill y todos los metadatos proceden de la skill enumerada.
- Con frontmatter, un campo omitido hereda el valor indicado. Cualquier campo incluido debe coincidir con el valor enumerado o la aptitud no se puede cargar.
allowed-toolssolo se puede leer desde frontmatter.- Si la primera línea del texto es
---, el runtime lo analiza como frontmatter, por lo que no inicie una skill de solo cuerpo con un salto temático de Markdown.
De forma predeterminada, las habilidades del proveedor son de solo texto: no tienen ningún directorio base, por lo que no pueden hacer referencia a scripts, plantillas u otros archivos agrupados. Para proporcionar a una aptitud de proveedor dichos archivos, consulte Archivos auxiliares.
skills.list muestra las capacidades del proveedor con la fuente sdk y un path vacío, con o sin archivos auxiliares.
Archivos auxiliares (experimentales)
Una aptitud de proveedor puede tener archivos auxiliares, como scripts, referencias, plantillas y recursos, de la misma manera que la carpeta de una aptitud basada en archivos puede tenerlos. La aplicación mantiene los archivos de cada aptitud en una carpeta que controla y establece directory para la aptitud enumerada en la ruta de acceso absoluta de esa carpeta.
Cuando el modelo activa la habilidad, el entorno de ejecución enumera la carpeta de la misma manera que enumera la carpeta de una habilidad basada en archivos. El modelo obtiene la misma línea «Directorio base para esta skill» y la lista de archivos relacionados que obtiene una skill basada en archivos, en lugar del aviso de solo texto, y lee los archivos con sus herramientas de archivos normales. El entorno de ejecución nunca lee, copia ni escribe los archivos por sí mismo.
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 establece la carpeta en su tipo de aptitud de la lista:
| SDK | Campo |
|---|---|
| Node.js | directory: "/ |
| Python | directory="/ |
| Ir | Directory: copilot.String("/ |
| .NET | Directory = "/ |
| Java | El sexto Skill argumento del constructor |
| Rust | directory: Some("/ |
Dónde reside la carpeta
Coloque todos los archivos de una skill en su directory, una carpeta por skill. La carpeta debe ser accesible donde se ejecuta el runtime:
- Disco local. Sin un sistema de archivos de sesión,
directoryes una ruta de acceso en el equipo o contenedor que ejecuta el entorno de ejecución. El modelo puede leer los archivos con cualquier herramienta de archivos y puede ejecutar scripts. - Sistema de archivos de sesión (Multiinquilino e implementaciones de servidor). Con un
sessionFshandler,directoryusa las convenciones de ruta de acceso del handler y el handler sirve los archivos; el tiempo de ejecución enumera la carpeta a través de él.view,create,edityapply_patchacceden a los archivos.grep,globy los comandos de shell no, por lo que los scripts no se pueden ejecutar. El SDK de Java no tienesessionFsalmacenamiento, por lo que los proveedores de Java usan disco local.
El tiempo de ejecución enumera la carpeta después de que read skill devuelva el resultado, por lo que puede crear la carpeta de forma diferida en read skill. Si la carpeta falta o está vacía, o no se puede enumerar en un plazo de 15 segundos desde que el entorno de ejecución invoca read skill, el modelo sigue recibiendo la línea de directorio base, sin lista de archivos relacionados, como en una aptitud basada en archivos. Si el sessionFs controlador de eventos está desconectado cuando el entorno de ejecución enumera las habilidades, esas habilidades son de solo texto hasta la próxima enumeración.
Access
- Disco local. Una vez enumeradas las habilidades, el tiempo de ejecución trata cada habilidad de proveedor habilitada de
directorycomo una carpetaskillDirectoriesconfigurada: las lecturas en ella omiten la solicitud de ruta fuera del área de trabajo, y los procesos en espacio aislado obtienen acceso de solo lectura a ella. Las lecturas siguen yendo a tu controlador de permisos, como lo hacen para las habilidades basadas en archivos. No devuelva un directorio amplio, como la carpeta personal o una carpeta que contenga los archivos de cada inquilino. - Sistema de archivos de sesión. El tiempo de ejecución no concede acceso a la carpeta. Haga que el controlador de permisos apruebe las lecturas en él y, cuando el espacio aislado esté activado, agregue la carpeta a la lista de permitidos del espacio aislado
readonlyPaths.
Su aplicación posee la carpeta: dónde reside, cuánto tiempo dura, cómo limpiarla y evitar que el modelo la cambie. El acceso de solo lectura abarca solo los procesos de espacio aislado. Fuera del espacio aislado, o cuando la carpeta está dentro del área de trabajo, el modelo puede escribir en ella a menos que el controlador de permisos o el controlador sessionFs se niegue.
Escribir la habilidad
- Consulte los archivos auxiliares por su ruta de acceso en relación con la carpeta de la habilidad, como
references/guide.md. Al modelo se le indica la ruta de acceso absoluta de la carpeta. - Ejecute scripts a través de un intérprete, como
python3 scripts/changelog.pyobash scripts/build.sh, como El uso de scripts en habilidades describe. Los scripts solo se ejecutan cuando la carpeta está en el disco local.
Reglas y límites
directorydebe ser absoluto en las convenciones de ruta de acceso de la sesión; en un sistema de archivos de sesión de estilo Windows necesita una unidad o un prefijo UNC. Se resuelve de la misma forma en que las herramientas de archivo resuelven las rutas de acceso, por lo que los segmentos.y..y los separadores repetidos o finales se quitan, y no puede resolverse a la raíz del sistema de archivos. Cuenta para el límite de metadatos de 1 MiB del catálogo y no se muestra en los catálogos de aptitudes. Un valor no válidodirectoryhace que se rechace todo el catálogo, como cualquier otra habilidad enumerada no válida.- La lista de archivos relacionados sigue las reglas basadas en archivos: las carpetas de compilación y dependencias, como
node_modules,bin,objydist, están ocultas; se resume una carpeta con más de 50 entradas; los archivos ubicados a más de 10 niveles de profundidad no aparecen;SKILL.mdnunca aparece; y se muestran como máximo 100 archivos. - Una vez compactada la conversación, el modelo mantiene las instrucciones de la skill, pero no su ruta de acceso de carpeta. Invocar la skill de nuevo lo muestra. Las habilidades basadas en archivos mantienen su ruta de acceso.
- Los archivos auxiliares necesitan un Copilot CLI al menos tan nuevo como la versión del SDK que los agrega. Una CLI anterior rechaza todo el catálogo de aptitudes cuando cualquier aptitud enumerada tiene un
directory. Los proveedores que no establecendirectoryfuncionan con CLIs anteriores.
Uso de archivos SKILL.md existentes
Para servir SKILL.md archivos que ya tenga, como los archivos almacenados en una base de datos, analice la frontmatter YAML de cada archivo una vez para compilar su entrada de catálogo y, a continuación, devuelva el archivo sin cambios desde la habilidad read:
- Asigne
nameydescriptionalnameydescriptionde la aptitud enumerada. Ambos son necesarios en el catálogo; el tiempo de ejecución no recurre ni a un nombre de carpeta ni al cuerpo de la skill. - Asigne
user-invocable,disable-model-invocationyargument-hinta los campos opcionales coincidentes cuando el frontmatter los establezca. - Devuelve el texto original, frontmatter incluido, de read skill. Dado que los valores indicados proceden de la misma frontmatter, coinciden y el entorno de ejecución sigue leyendo
allowed-toolsde ella.
Contenido del proveedor de confianza
Tratar las aptitudes del proveedor como directorios de aptitudes: su contenido se considera una entrada de confianza. El modelo sigue las instrucciones de una habilidad y el frontmatter controla cómo se invoca la habilidad.
allowed-tools no otorga permisos en las sesiones del SDK. El tiempo de ejecución lo notifica en el campo allowedTools del evento skill.invoked, y el controlador de permisos todavía decide cada solicitud de herramienta.
No proporcione texto que los usuarios finales u otros clientes puedan editar a menos que les permita crear un archivo de skill. Si crea aptitudes a partir de la entrada del usuario, genere el frontmatter usted mismo en lugar de pasar el frontmatter proporcionado por el usuario.
Límites y errores del proveedor
El tiempo de ejecución valida el catálogo y el contenido del proveedor:
-
Los nombres deben coincidir con
^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$y ser únicos, sin distinguir entre mayúsculas y minúsculas. -
Un catálogo puede contener como máximo 1024 aptitudes y 1 MiB de metadatos. Cada descripción y indicación del argumento puede tener como máximo 1024 caracteres.
-
Markdown de cada aptitud puede ser como máximo 1 MiB de UTF-8.
-
Cada llamada debe completarse en un plazo de 30 segundos. Cuando el tiempo de ejecución deja de esperar una llamada, porque se agotó el tiempo de espera, la sesión terminó o una reanudación reemplazó al proveedor, cancela la solicitud y omite cualquier resultado posterior. Cada SDK pasa esa cancelación a su proveedor de la manera habitual:
SDK Señal de cancelación Node.js El signal(AbortSignal) de las opciones pasadas alistSkillsyreadSkillse aborta.Python La tarea del asyncioproveedor queda cancelada conasyncio.Cancelled. Los proveedores sincrónicos se ejecutan hasta la finalización.Error Ir Se cancela la context.Contextde la llamada..NET Se cancela el CancellationTokende la llamada.Java El valor devuelto CompletableFuturese cancela concancel(true), que no interrumpe el trabajo en ejecución.Rust Se elimina el future del proveedor. Estas señales cubren las llamadas que el entorno de ejecución cancela. Cuando la conexión se cierra o el cliente se detiene forzosamente, los SDK de .NET, Java y Rust también cancelan las llamadas que siguen en ejecución. Los SDK de Node.js, Python y Go no lo hacen: una llamada en ejecución continúa hasta que finaliza y el SDK descarta su resultado.
Si el listado falla o devuelve un catálogo no válido, el tiempo de ejecución notifica el problema en la errors lista devuelta por skills.reload. Una recarga errónea mantiene las aptitudes del proveedor de la última lista cargada correctamente. Si se produce un error en la lectura de una habilidad, la skill herramienta notifica un error de carga genérico al modelo. El SDK nunca reenvía el texto de los errores que lanza o devuelve el proveedor, de modo que ese texto no pueda filtrarse a la conversación.
Ciclo de vida del proveedor
Un proveedor está enlazado a una sesión:
- Un proveedor habilita las aptitudes a menos que establezcas
enableSkillsenfalse, lo que mantiene el proveedor enlazado, pero no se invoca nunca. Enmode: "empty", las aptitudes permanecen deshabilitadas hasta que establezcasenableSkillsentrue. - El proveedor nunca se guarda. Páselo de nuevo cuando reanude una sesión. Reanudar sin un proveedor lo elimina de la sesión. Las extensiones que se unen a la sesión no la cambian.
- Una habilidad de proveedor con el mismo nombre que una habilidad basada en archivos reemplaza la habilidad basada en archivos e
skills.reloadinforma de una advertencia. - Los subagentes usan el proveedor de la sesión principal.
- El tiempo de ejecución puede llamar al proveedor simultáneamente, por ejemplo desde la
skillherramienta, las invocaciones de usuario y los agentes personalizados que cargan previamente las habilidades, por lo que ambas operaciones deben ser seguras para su uso simultáneo. - Las sesiones en la nube no admiten proveedores de habilidades. El SDK rechaza la configuración antes de crear la sesión.
Opciones de configuración
Campos de habilidades de SessionConfig
| Language | Campo | Tipo | Description |
|---|---|---|---|
| Node.js | skillDirectories | string[] | Directorios desde los que cargar habilidades |
| Node.js | disabledSkills | string[] | Habilidades para desactivar |
| Node.js | skillProvider | SkillProvider | Proveedor experimental para skills proporcionadas por el SDK |
| Python | skill_directories | list[str] | Directorios desde los que cargar habilidades |
| Python | disabled_skills | list[str] | Habilidades para desactivar |
| Python | skill_provider | SkillProvider | Proveedor experimental para habilidades proporcionadas por el SDK |
| Ir | SkillDirectories | []string | Directorios desde los que cargar habilidades |
| Ir | DisabledSkills | []string | Habilidades para desactivar |
| Ir | SkillProvider | SkillProvider | Proveedor experimental para skills proporcionadas por el SDK |
| .NET | SkillDirectories | List<string> | Directorios desde los que cargar habilidades |
| .NET | DisabledSkills | List<string> | Habilidades para desactivar |
| .NET | SkillProvider | ISkillProvider | Proveedor experimental para skills proporcionadas por el SDK |
| Java | setSkillProvider | SkillProvider | Proveedor experimental para skills proporcionadas por el SDK |
| Rust | with_skill_provider | Arc<dyn SkillProvider> | Proveedor experimental para skills proporcionadas por el SDK |
Habilidades integradas y mode: "empty"
El entorno de ejecución incluye un conjunto de habilidades predefinidas que están habilitadas de forma predeterminada. Al ejecutar el cliente en mode: "empty" (la línea base recomendada para Multiinquilino e implementaciones de servidor), el SDK excluye todas las aptitudes integradas incluidas en tiempo de ejecución: envía una lista includedBuiltinSkills vacía en el parche de opciones posterior a la creación y posterior a la reanudación, junto con la lista installedPlugins vacía.
Esta exclusión es la predeterminada, no una restricción permanente. Para permitir capacidades seleccionadas agrupadas en tiempo de ejecución, establezca includedBuiltinSkills (o el uso de mayúsculas y minúsculas específicos del lenguaje) en sus nombres. También puede optar por usar sus propias habilidades personalizadas en mode: "empty": habilite las habilidades y proporcione sus propias skillDirectories; y estas siguen siendo totalmente utilizables, incluida una habilidad personalizada que comparte nombre con una integrada.
En mode: "copilot-cli" el campo se omite a menos que establezca la opción .
Los directorios de aptitudes personalizados se examinan cuando las aptitudes se cargan por primera vez, incluidos los directorios que faltan o están vacíos en ese momento. Los cambios del sistema de archivos en esos directorios no actualizan automáticamente el catálogo en ejecuciones posteriores. Después de agregar, editar o quitar habilidades, llame al RPC de su sesión:
| SDK | Recargar la llamada |
|---|---|
| Node.js | await session.rpc.skills.reload() |
| Python | await session.rpc.skills.reload() |
| Ir | session.RPC.Skills.Reload(ctx) |
| .NET | await session.Rpc.Skills.Reload |
| Java | session.get |
| Rust | session.rpc().skills().reload().await? |
Cambiar los directorios de habilidades configurados también actualiza el catálogo.
procedimientos recomendados
-
Organizar por dominio : agrupar aptitudes relacionadas (por ejemplo,
skills/security/,skills/testing/) -
Usa metadatos preliminares - Incluye
nameydescriptionen los metadatos preliminares de YAML para mayor claridad -
Dependencias del documento: indica las herramientas o servidores MCP que requiere una habilidad.
-
Prueba de aptitudes de forma aislada : compruebe que las aptitudes funcionan antes de combinarlas
-
Utiliza rutas relativas - Mantén las habilidades portátiles en distintos entornos
Combinación con otras características
Habilidades + agentes personalizados
Las habilidades enumeradas en el campo skills de un agente se precargan de forma anticipada: su contenido completo se inserta en el contexto del agente al iniciarse, por lo que el agente tiene acceso inmediato a las instrucciones de la habilidad sin necesidad de invocar una herramienta de habilidades. Los nombres de las aptitudes se resuelven a partir de skillDirectories de nivel de sesión.
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" }),
});
Nota:
Las aptitudes son opcionales, cuando skills se omite, no se inserta ningún contenido de aptitudes. Los subagentes no heredan habilidades del agente principal; debe enumerarlas explícitamente para cada agente.
Habilidades y servidores MCP
Las aptitudes pueden complementar las funcionalidades del 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" }),
});
Solución de problemas
Las aptitudes no cargan
- Compruebe que la ruta existe - Verifique que la ruta del directorio de habilidades es correcta y que contiene subdirectorios con archivos
SKILL.md - Comprobación de permisos : asegúrese de que el SDK puede leer el directorio.
- Comprobar el formato de SKILL.md - Verificar que el archivo Markdown esté bien formado y que cualquier encabezado YAML utilice una sintaxis válida.
- Habilitar el registro de depuración: configure
logLevel: "debug"para ver los registros de carga de habilidades
Conflictos de aptitudes
Si varias aptitudes proporcionan instrucciones en conflicto:
- Use
disabledSkillspara excluir habilidades en conflicto - Reorganización de directorios de aptitudes para evitar superposiciones
Consulte también
- Crea tu primera aplicación con tecnología Copilot - Definir perfiles de IA especializados
- Crea tu primera aplicación con tecnología Copilot : crear sus propias herramientas
- Uso de servidores MCP con el SDK de GitHub Copilot : conexión de proveedores de herramientas externos