Übersicht
Eine Fähigkeit ist ein benanntes Verzeichnis, das eine SKILL.md-Datei enthält – ein Markdown-Dokument, das Anweisungen für Copilot bereitstellt. Beim Laden wird der Inhalt der Fähigkeit in den Sitzungskontext eingefügt.
Fähigkeiten ermöglichen Folgendes:
- Packen von Domänenkenntnissen in wiederverwendbare Module
- Spezialisierte Verhaltensweisen über Projekte hinweg teilen
- Organisieren komplexer Agentkonfigurationen
- Aktivieren/Deaktivieren von Funktionen pro Sitzung
Ladefähigkeiten
Geben Sie Verzeichnisse an, die Fähigkeiten enthalten, wenn Sie eine Sitzung erstellen:
Codesprachen 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();
}
Deaktivieren von Fähigkeiten
Deaktivieren Sie bestimmte Fähigkeiten, während andere aktiv bleiben:
Codesprachen 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();
Kompetenzverzeichnisstruktur
Jede Fähigkeit ist ein benanntes Unterverzeichnis, das eine SKILL.md Datei enthält:
skills/
├── code-review/
│ └── SKILL.md
└── documentation/
└── SKILL.md
Die skillDirectories Option verweist auf das übergeordnete Verzeichnis (z. B. ./skills). Die CLI ermittelt alle SKILL.md Dateien in unmittelbaren Unterverzeichnissen.
SKILL.md Format
Eine SKILL.md Datei ist ein Markdowndokument mit optionalem YAML-Frontmatter:
---
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.
Die Frontmatterfelder:
name: Die Kennung der Fähigkeit (wird zusammen mitdisabledSkillsverwendet, um sie gezielt zu deaktivieren). Wenn nicht angegeben, wird der Verzeichnisname verwendet.description: Eine kurze Beschreibung, was die Fähigkeit tut.
Der Markdown Body enthält die Anweisungen, die in den Sitzungskontext injiziert werden, wenn die Fertigkeit geladen wird.
Skill-Anbieter (experimentell)
Hinweis
Skill-Anbieter sind experimentell. Die API kann sich in zukünftigen SDK-Versionen ändern.
Ein Skillanbieter bietet Fähigkeiten aus dem eigenen Speicher Ihrer Anwendung, z. B. einer Datenbank in einem mandantenfähigen Dienst, anstelle von SKILL.md Dateien auf dem Datenträger. Anbieter-Skills werden dem Skillkatalog der Sitzung zusammen mit dateibasierten Skills hinzugefügt. Das Modell lädt sie nach Bedarf über das skill Tool, und Benutzer können sie wie jede andere Fähigkeit aufrufen.
Ein Anbieter implementiert zwei Operationen:
- Fähigkeiten auflisten: Gibt Katalogmetadaten für jede Fähigkeit zurück:
name,descriptionund optionaluserInvocable,disableModelInvocationundargumentHint. Die Laufzeit ruft sie auf, wenn sie die Skills der Sitzung lädt. - Fähigkeit lesen: Gibt den Markdown für eine Fähigkeit zurück oder ein Nicht-gefunden-Ergebnis, wenn die Fähigkeit nicht mehr vorhanden ist. Die Laufzeit ruft sie nur auf, wenn der Skill geladen wird.
Übergeben Sie den Provider, wenn Sie eine Sitzung erstellen oder fortsetzen:
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(),
});
}
}
Die .NET Skillprovidertypen geben die experimentelle Diagnosemeldung GHCP001 aus. Unterdrücken Sie es mit #pragma warning disable GHCP001 oder einem projektweiten <NoWarn>GHCP001</NoWarn>.
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();
}
}
Die Java Skill-Provider-API ist @CopilotExperimental, sodass die nutzende Klasse oder Methode mit @AllowCopilotExperimental explizit aktiviert werden muss (oder mit -Acopilot.experimental.allowed=true kompiliert werden muss). Siehe Verwenden experimenteller APIs.
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?;
Inhalte zu Anbieterkompetenzen
Read-Skill gibt den SKILL.md Text des Skills zurück. YAML-Frontmatter ist optional:
- Ohne Frontmatter ist der gesamte Text der Inhalt der Skill, und alle Metadaten stammen aus der aufgeführten Skill.
- Bei Frontmatter erbt ein weggelassenes Feld den aufgelisteten Wert. Ein Feld, das Sie angeben, muss mit dem aufgelisteten Wert übereinstimmen, oder die Fähigkeit kann nicht geladen werden.
allowed-toolskann nur aus dem Frontmatter gelesen werden.- Wenn die erste Zeile des Texts lautet
---, analysiert die Laufzeit sie als Frontmatter, sodass Sie keine Fähigkeit nur mit Body-Inhalt mit einem thematischen Markdown-Bruch beginnen.
Standardmäßig sind Anbieterkenntnisse nur textbasiert: Sie haben kein Basisverzeichnis, sodass sie nicht auf gebündelte Skripts, Vorlagen oder andere Dateien verweisen können. Um einer Anbieterkompetenz solche Dateien bereitzustellen, siehe Unterstützende Dateien.
skills.list meldet Anbieterkompetenzen mit der Quelle sdk und einer leeren path, mit oder ohne unterstützende Dateien.
Hilfsdateien (experimentell)
Ein Provider-Skill kann mit unterstützenden Dateien wie Skripts, Verweisen, Vorlagen und Ressourcen geliefert werden, genauso wie der Ordner eines dateibasierten Skills. Ihre Anwendung behält die Dateien der einzelnen Fähigkeiten in einem Ordner bei, den sie verwaltet, und setzt directory der aufgelisteten Fähigkeit auf den absoluten Pfad dieses Ordners.
Wenn das Modell den Skill aktiviert, listet die Laufzeit den Ordner auf dieselbe Weise auf wie den Ordner eines dateibasierten Skills. Das Modell erhält dieselbe Zeile „Basisverzeichnis für diesen Skill“ und die Liste zugehöriger Dateien, die auch ein dateibasierter Skill erhält, anstelle des Nur-Text-Hinweises, und liest die Dateien mit seinen gewöhnlichen Dateitools. Die Laufzeit liest, kopiert oder schreibt die Dateien selbst nie.
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,
});
Jedes SDK legt den Ordner für den listed-skill type fest:
| SDK | Feld |
|---|---|
| Node.js | directory: "/ |
| Python | directory="/ |
| Go | Directory: copilot.String("/ |
| .NET | Directory = "/ |
| Java | Das sechste Skill Konstruktorargument |
| Rust | directory: Some("/ |
Wo sich der Ordner befindet
Legen Sie alle Dateien einer Fähigkeit unter ihrem directory ab, je Fähigkeit ein Ordner. Der Ordner muss erreichbar sein, in der die Runtime ausgeführt wird:
- Lokaler Datenträger. Ohne ein Sitzungsdateisystem handelt es sich bei
directoryum einen Pfad auf dem Computer oder Container, der die Laufzeit ausführt. Das Modell kann die Dateien mit jedem Beliebigen Dateitool lesen und Skripts ausführen. - Sitzungsdateisystem (Mandantenfähigkeit und Serverbereitstellungen). Bei einem
sessionFsHandlerdirectorywerden die Pfadkonventionen des Handlers verwendet, und Ihr Handler stellt die Dateien bereit. Die Laufzeit listet den Ordner darüber auf. Mitview,create,editundapply_patcherreichen Sie die Dateien.grep,globund Shellbefehle funktionieren nicht, sodass Skripts nicht ausgeführt werden können. Das Java SDK hat keinesessionFs, sodass Java Anbieter lokale Datenträger verwenden.
Die Runtime listet den Ordner nach der Rückgabe der Read Skill auf, sodass Sie den Ordner verzögert in der Read Skill erstellen können. Wenn der Ordner fehlt oder leer ist oder innerhalb von 15 Sekunden nach dem Aufruf des Read-Skills durch die Laufzeit nicht aufgelistet werden kann, erhält das Modell weiterhin die Basisverzeichniszeile ohne Liste verwandter Dateien, wie bei einem dateibasierten Skill. Wenn Ihr sessionFs-Handler getrennt ist, wenn die Laufzeit Fähigkeiten auflistet, sind diese Fähigkeiten bis zur nächsten Auflistung nur als Text verfügbar.
Access
- Lokaler Datenträger. Sobald Skills aufgelistet sind, behandelt die Laufzeit
directoryjedes aktivierten Anbieterskills wie einen konfiguriertenskillDirectories-Ordner: Lesezugriffe darunter überspringen die Eingabeaufforderung für Pfade außerhalb des Arbeitsbereichs, und Sandkastenprozesse erhalten schreibgeschützten Zugriff darauf. Lesevorgänge gehen weiterhin zu Ihrem Berechtigungs-Handler, wie bei dateibasierten Skills. Geben Sie kein übergeordnetes Verzeichnis zurück, z. B. Ihren privaten Ordner oder einen Ordner, der die Dateien jedes Mandanten enthält. - Sitzungsdateisystem. Die Laufzeit gewährt keinen Zugriff auf den Ordner. Lassen Sie ihren Berechtigungshandler Lesevorgänge darunter genehmigen, und fügen Sie den Ordner beim Aktivieren des Sandkastens zur
readonlyPathsdes Sandkastens hinzu.
Ihre Anwendung ist für den Ordner verantwortlich: wo er sich befindet, wie lange er existiert, ihn zu bereinigen und das Modell daran zu hindern, ihn zu ändern. Der schreibgeschützte Zugriff deckt nur sandboxed Prozesse ab. Außerhalb des Sandkastens oder wenn sich der Ordner im Arbeitsbereich befindet, kann das Modell darauf schreiben, es sei denn, der Berechtigungshandler oder der sessionFs Handler lehnt ab.
Schreiben der Fertigkeit
- Verweisen Sie auf unterstützende Dateien anhand ihres Pfads relativ zum Ordner des Skills, zum Beispiel
references/guide.md. Dem Modell wird der absolute Pfad des Ordners mitgeteilt. - Führen Sie Skripts über einen Interpreter aus, z. B.
python3 scripts/changelog.pyoderbash scripts/build.sh, wie unter Verwendung von Skripts in Skills beschrieben. Skripts werden nur ausgeführt, wenn sich der Ordner auf einem lokalen Datenträger befindet.
Regeln und Grenzwerte
directorymuss in den Pfadkonventionen der Sitzung absolut sein; auf einem Windows Sitzungsdateisystem benötigt es ein Laufwerk- oder UNC-Präfix. Es wird so aufgelöst, wie Dateitools Pfade auflösen, sodass.- und..-Segmente sowie wiederholte oder abschließende Trennzeichen entfernt werden, und es kann nicht zu einem Dateisystemstamm aufgelöst werden. Es zählt zum 1 MiB-Metadatenlimit des Katalogs und wird nicht in Skill-Katalogen angezeigt. Ein ungültigesdirectoryführt zur Ablehnung des gesamten Katalogs, wie jede andere ungültige aufgeführte Fähigkeit.- Die Liste der zugehörigen Dateien folgt den dateibasierten Regeln: Build- und Abhängigkeitsordner, wie z. B.
node_modules,bin,objunddist, sind ausgeblendet; ein Ordner mit mehr als 50 Einträgen wird zusammengefasst; Dateien, die mehr als 10 Ordner tief verschachtelt sind, werden nicht aufgelistet;SKILL.mdwird nie aufgelistet; und höchstens 100 Dateien werden angezeigt. - Nachdem die Konversation komprimiert wurde, behält das Modell die Anweisungen des Skills bei, aber nicht den Ordnerpfad. Das Aufrufen des Skills zeigt es erneut. Dateibasierte Skills behalten ihren Pfad.
- Unterstützende Dateien benötigen eine Copilot CLI, die mindestens so neu ist wie das SDK-Release, das sie hinzufügt. Eine ältere CLI lehnt den gesamten Qualifikationskatalog ab, wenn eine der aufgelisteten Fähigkeiten ein
directoryenthält. Anbieter, diedirectorynicht festlegen, funktionieren mit älteren CLIs.
Bereitstellen vorhandener SKILL.md-Dateien
Um SKILL.md Dateien bereitzustellen, die Sie bereits haben, z. B. Dateien, die in einer Datenbank gespeichert sind, analysieren Sie die YAML-Frontmatter jeder Datei einmal, um den Katalogeintrag zu erstellen, und geben Sie dann die Datei unverändert aus der Read-Skill zurück:
- Ordnen Sie
nameunddescriptionden aufgelisteten Fähigkeitennameunddescriptionzu. Beide sind im Katalog erforderlich; die Laufzeit fällt nicht auf einen Ordnernamen oder den Skill-Text zurück. - Ordnen Sie
user-invocable,disable-model-invocationundargument-hintden übereinstimmenden optionalen Feldern zu, wenn das Frontmatter diese festlegt. - Geben Sie den ursprünglichen Text zurück, einschließlich des Frontmatters, aus der Read-Skill. Da die aufgelisteten Werte aus demselben Frontmatter stammen, stimmen sie überein, und die Laufzeit liest weiterhin
allowed-toolsdaraus.
Anbieterinhalten vertrauen
Behandeln Sie Anbieterkompetenzen wie Kompetenzverzeichnisse: Ihre Inhalte sind vertrauenswürdige Quellen. Das Modell folgt den Anweisungen eines Skills, und der Frontmatter steuert, wie der Skill aufgerufen wird.
allowed-tools erteilt in SDK-Sitzungen keine Berechtigungen. Die Laufzeit meldet sie im allowedTools Feld des skill.invoked Ereignisses, und Ihr Berechtigungshandler entscheidet weiterhin jede Toolanforderung.
Stellen Sie keinen Text bereit, den Endbenutzer oder andere Mandanten bearbeiten können, es sei denn, Sie würden ihnen erlauben, eine Skilldatei zu erstellen. Wenn Sie Fähigkeiten aus der Benutzereingabe erstellen, generieren Sie das Frontmatter selbst, anstatt das vom Benutzer bereitgestellte Frontmatter zu übergeben.
Anbieterbeschränkungen und Fehler
Die Laufzeit überprüft den Katalog und den Inhalt des Anbieters:
-
Namen müssen übereinstimmen
^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$und eindeutig sein, wobei die Groß-/Kleinschreibung ignoriert wird. -
Ein Katalog kann höchstens 1.024 Fähigkeiten und 1 MiB von Metadaten enthalten. Jeder Beschreibungs- und Argumenthinweis kann maximal 1.024 Zeichen lang sein.
-
Das Markdown jedes Skills kann höchstens 1 MiB UTF-8 umfassen.
-
Jeder Anruf muss innerhalb von 30 Sekunden abgeschlossen werden. Wenn die Laufzeit nicht mehr auf einen Aufruf wartet, weil das Zeitlimit abgelaufen ist, die Sitzung beendet wurde oder eine Wiederaufnahme den Anbieter ersetzt hat, wird die Anforderung abgebrochen und das spätere Ergebnis ignoriert. Jedes SDK übergibt diesen Abbruch an Ihren Anbieter in der üblichen Weise:
SDK Abbruchsignal Node.js Die signal(AbortSignal) in den anlistSkillsundreadSkillübergebenen Optionen wurde abgebrochen.Python Die Aufgabe des Anbieters asynciowird mitasyncio.Cancelledstorniert. Synchrone Provider werden vollständig ausgeführt.Error Go Der Anruf context.Contextwurde abgebrochen..NET Der Anruf CancellationTokenwurde abgebrochen.Java Der zurückgegebene Vorgang CompletableFuturewird mitcancel(true)abgebrochen, was die laufende Arbeit nicht unterbricht.Rust Das Provider-Future wird verworfen. Diese Signale betreffen Aufrufe, die von der Laufzeit abgebrochen werden. Wenn die Verbindung geschlossen wird oder der Client zwangsweise beendet wird, brechen die .NET-, Java- und Rust-SDKs auch Aufrufe ab, die noch ausgeführt werden. Die Node.js-, Python- und Go-SDKs machen das nicht: Ein ausgeführter Aufruf wird fortgesetzt, bis er abgeschlossen ist, und das SDK verwirft das Ergebnis.
Wenn die Auflistung fehlschlägt oder einen ungültigen Katalog zurückgibt, meldet die Laufzeit das Problem in der von skills.reload zurückgegebenen errors Liste. Bei einem fehlgeschlagenen Neuladen bleiben die Anbieterfähigkeiten aus der letzten erfolgreichen Liste erhalten. Wenn das Lesen eines Skills fehlschlägt, meldet das skill Tool einen generischen Ladefehler beim Modell. Das SDK leitet niemals den Wortlaut der Fehlermeldungen weiter, die Ihr Anbieter auslöst oder zurückgibt, sodass dieser Text nicht in die Unterhaltung gelangen kann.
Anbieterlebenszyklus
Ein Anbieter ist an eine Sitzung gebunden:
- Ein Anbieter ermöglicht Fähigkeiten, es sei denn, Sie setzen
enableSkillsauffalse, wodurch der Anbieter gebunden bleibt, aber nie aufgerufen wird. Inmode: "empty", Fähigkeiten bleiben deaktiviert, bis SietrueaufenableSkillssetzen. - Der Anbieter wird nie gespeichert. Geben Sie sie erneut an, wenn Sie eine Sitzung fortsetzen. Wird ohne einen Anbieter fortgesetzt, wird dieser aus der Sitzung entfernt. Erweiterungen, die einer Sitzung hinzugefügt werden, ändern sie nicht.
- Eine Anbieterqualifikation mit demselben Namen wie eine dateibasierte Qualifikation ersetzt die dateibasierte Qualifikation, und
skills.reloadmeldet eine Warnung. - Unter-Agents verwenden den Anbieter ihrer übergeordneten Sitzung.
- Die Laufzeit kann den Anbieter gleichzeitig aufrufen, z. B. über das
skillTool, Benutzeraufrufe und benutzerdefinierte Agents, die Fähigkeiten vorab laden, sodass beide Vorgänge threadsicher sein müssen. - Cloudsitzungen unterstützen keine Skill-Anbieter. Das SDK lehnt die Konfiguration ab, bevor es die Sitzung erstellt.
Konfigurationsoptionen
SessionConfig-Qualifikationsfelder
| Sprache | Feld | Typ | Description |
|---|---|---|---|
| Node.js | skillDirectories | string[] | Verzeichnisse, aus denen Fähigkeiten geladen werden |
| Node.js | disabledSkills | string[] | Zu deaktivierende Fähigkeiten |
| Node.js | skillProvider | SkillProvider | Experimenteller Anbieter für vom SDK bereitgestellte Skills |
| Python | skill_directories | list[str] | Verzeichnisse, aus denen Fähigkeiten geladen werden |
| Python | disabled_skills | list[str] | Zu deaktivierende Fähigkeiten |
| Python | skill_provider | SkillProvider | Experimenteller Anbieter für vom SDK bereitgestellte Skills |
| Go | SkillDirectories | []string | Verzeichnisse, aus denen Fähigkeiten geladen werden |
| Go | DisabledSkills | []string | Zu deaktivierende Fähigkeiten |
| Go | SkillProvider | SkillProvider | Experimenteller Anbieter für vom SDK bereitgestellte Skills |
| .NET | SkillDirectories | List<string> | Verzeichnisse, aus denen Fähigkeiten geladen werden |
| .NET | DisabledSkills | List<string> | Zu deaktivierende Fähigkeiten |
| .NET | SkillProvider | ISkillProvider | Experimenteller Anbieter für vom SDK bereitgestellte Skills |
| Java | setSkillProvider | SkillProvider | Experimenteller Anbieter für vom SDK bereitgestellte Skills |
| Rust | with_skill_provider | Arc<dyn SkillProvider> | Experimenteller Provider für vom SDK bereitgestellte Skills |
Integrierte Fähigkeiten und mode: "empty"
Die Laufzeit enthält eine Reihe mitgelieferter integrierter Skills, die standardmäßig verfügbar sind. Wenn Sie den Client in mode: "empty" ausführen (die empfohlene Baseline für Mandantenfähigkeit und Serverbereitstellungen), schließt das SDK jeden zur Laufzeit gebündelten integrierten Skill aus: Es sendet im Options-Patch nach dem Erstellen und nach dem Fortsetzen eine leere includedBuiltinSkills-Liste zusammen mit der leeren installedPlugins-Liste.
Dieser Ausschluss ist die Standardeinstellung, keine dauerhafte Einschränkung. Um ausgewählte laufzeitgebündelte Fähigkeiten zu ermöglichen, legen Sie includedBuiltinSkills (oder die sprachspezifische Groß-/Kleinschreibung) auf ihre Namen fest. Sie können auch Ihre eigenen benutzerdefinierten Fähigkeiten unter mode: "empty" verwenden. Aktivieren Sie Fähigkeiten und übergeben Sie Ihre eigenen skillDirectories – diese bleiben uneingeschränkt nutzbar, einschließlich einer benutzerdefinierten Fähigkeit, die denselben Namen wie eine integrierte Fähigkeit hat.
Unter mode: "copilot-cli" wird das Feld weggelassen, sofern Sie die Option nicht setzen.
Benutzerdefinierte Skill-Verzeichnisse werden beim ersten Laden der Skills gescannt, einschließlich Verzeichnissen, die zu diesem Zeitpunkt fehlen oder leer sind. Dateisystemänderungen in diesen Verzeichnissen aktualisieren den Katalog bei späteren Durchläufen nicht automatisch. Rufen Sie nach dem Hinzufügen, Bearbeiten oder Entfernen von Skills den RPC Ihrer Sitzung skills.reload auf:
| SDK | Anruf neu laden |
|---|---|
| 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? |
Durch das Ändern der konfigurierten Skill-Verzeichnisse wird auch der Katalog aktualisiert.
Bewährte Methoden
-
Nach Domäne organisieren - Gruppieren verwandter Fähigkeiten (z. B.
skills/security/, )skills/testing/ -
Frontmatter verwenden –
nameunddescriptionzur besseren Übersicht in das YAML-Frontmatter aufnehmen -
Dokumentabhängigkeiten – Beachten Sie alle Tools oder MCP-Server, die eine Fähigkeit erfordern
-
Fähigkeiten isoliert testen – Überprüfen Sie, ob die Fähigkeiten funktionieren, bevor Sie sie kombinieren
-
Verwenden von relativen Pfaden – Portieren von Fähigkeiten über Umgebungen hinweg
Kombinieren mit anderen Features
Fähigkeiten + benutzerdefinierte Agents
Die im Feld eines Agenten skills aufgeführten Fähigkeiten werden eifrig vorab geladen – ihr vollständiger Inhalt wird beim Start in den Kontext des Agents eingefügt, sodass der Agent sofort Zugriff auf die Qualifikationsanweisungen hat, ohne ein Qualifikationstool aufrufen zu müssen. Qualifikationsnamen werden auf Sitzungsebene skillDirectoriesaufgelöst.
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" }),
});
Hinweis
Fähigkeiten sind opt-in – wenn skills nicht angegeben wird, wird kein Qualifikationsinhalt eingefügt. Sub-Agents erben keine Fähigkeiten vom Elternteil; Sie müssen sie pro Agent explizit auflisten.
Fähigkeiten + MCP-Server
Fähigkeiten können MCP-Serverfunktionen ergänzen:
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
Skills, die nicht geladen werden
- Check path exists – Überprüfen Sie, ob der Pfad zum Skillverzeichnis korrekt ist und Unterverzeichnisse mit
SKILL.md-Dateien enthält. - Überprüfen von Berechtigungen – Stellen Sie sicher, dass das SDK das Verzeichnis lesen kann
- Überprüfen sie SKILL.md Format : Überprüfen, ob der Markdown wohlgeformt ist und alle YAML-Frontmatter gültige Syntax verwenden
- Debug-Protokollierung aktivieren – Legen Sie
logLevel: "debug"fest, um Protokolle zum Laden von Skills anzuzeigen
Qualifikationskonflikte
Wenn mehrere Fähigkeiten widersprüchliche Anweisungen bereitstellen:
- Verwenden Sie
disabledSkills, um widersprüchliche Fähigkeiten auszuschließen - Neuorganisieren von Kompetenzverzeichnissen, um Überlappungen zu vermeiden
Siehe auch
- Erstellen Sie Ihre erste Copilot-gestützte App - Definieren von speziellen KI-Personas
- Erstellen Sie Ihre erste Copilot-gestützte App – Erstellen Eigener Tools
- Verwenden von MCP-Servern mit dem GitHub Copilot SDK – Verbinden externer Toolanbieter