# Настраиваемые навыки

Навыки — это многоразовые модули подсказок, расширяющие возможности Copilot. Загружайте навыки из каталогов, чтобы дать Copilot специализированные способности для конкретных областей или рабочих процессов.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## Обзор

Навык — это именованный каталог, содержащий файл `SKILL.md` — документ markdown, который предоставляет инструкции Copilot. При загрузке содержимое навыка вводится в контекст сессии.

Навыки позволяют вам:

* Экспертиза в области упаковки в повторно используемые модули
* Делитесь специализированными поведением между проектами
* Организовывать сложные конфигурации агентов
* Включать/отключать возможности за сессию

## Навыки загрузки

При создании сессии указывайте каталоги, содержащие навыки:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-4.1",
    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" });
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
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-4.1",
        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()
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
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-4.1",
        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)
    }
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
using GitHub.Copilot;
using GitHub.Copilot.Rpc;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-4.1",
    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"
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```java
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-4.1")
            .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();
}
```

</div>

</div>

## Навыки отключения

Отключите определённые навыки, сохраняя активность других:

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
const session = await client.createSession({
    skillDirectories: ["./skills"],
    disabledSkills: ["experimental-feature", "deprecated-tool"],
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
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"],
)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
package main

import (
    "context"
    copilot "github.com/github/copilot-sdk/go"
    "github.com/github/copilot-sdk/go/rpc"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)

    session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
        SkillDirectories: []string{"./skills"},
        DisabledSkills:   []string{"experimental-feature", "deprecated-tool"},
        OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
            return &rpc.PermissionDecisionApproveOnce{}, nil
        },
    })
    _ = session
}
```

```golang
session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
    SkillDirectories: []string{"./skills"},
    DisabledSkills:   []string{"experimental-feature", "deprecated-tool"},
})
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
using GitHub.Copilot;
using GitHub.Copilot.Rpc;

public static class SkillsExample
{
    public static async Task Main()
    {
        await using var client = new CopilotClient();

        var session = await client.CreateSessionAsync(new SessionConfig
        {
            SkillDirectories = new List<string> { "./skills" },
            DisabledSkills = new List<string> { "experimental-feature", "deprecated-tool" },
            OnPermissionRequest = (req, inv) =>
                Task.FromResult(PermissionDecision.ApproveOnce()),
        });
    }
}
```

```csharp
var session = await client.CreateSessionAsync(new SessionConfig
{
    SkillDirectories = new List<string> { "./skills" },
    DisabledSkills = new List<string> { "experimental-feature", "deprecated-tool" },
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
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();
```

</div>

</div>

## Структура каталога навыков

Каждый навык представляет собой именованный подкаталог, содержащий `SKILL.md` файл:

```text
skills/
├── code-review/
│   └── SKILL.md
└── documentation/
    └── SKILL.md
```

Опция указывает `skillDirectories` на родительский каталог (например, `./skills`). CLI обнаруживает все `SKILL.md` файлы в немедленных подкаталогах.

### формат SKILL.md

Файл `SKILL.md` — это документ markdown с опциональной YAML-фронтматерью:

```markdown
---
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.
```

Фронтматтерные поля:

* **`name`**: Идентификатор навыка (используется для `disabledSkills` выборочного отключения). Если оно опущено, используется имя каталога.
* **`description`**: Краткое описание того, что делает навык.

Тело markdown содержит инструкции, которые вводятся в контекст сессии при загрузке навыка.

## Варианты конфигурации

### Поля навыков SessionConfig

| Язык    | Поле                | Тип            | Description                   |
| ------- | ------------------- | -------------- | ----------------------------- |
| Node.js | `skillDirectories`  | `string[]`     | Каталоги для загрузки навыков |
| Node.js | `disabledSkills`    | `string[]`     | Навыки для отключения         |
| Python  | `skill_directories` | `list[str]`    | Каталоги для загрузки навыков |
| Python  | `disabled_skills`   | `list[str]`    | Навыки для отключения         |
| Go      | `SkillDirectories`  | `[]string`     | Каталоги для загрузки навыков |
| Go      | `DisabledSkills`    | `[]string`     | Навыки для отключения         |
| .NET    | `SkillDirectories`  | `List<string>` | Каталоги для загрузки навыков |
| .NET    | `DisabledSkills`    | `List<string>` | Навыки для отключения         |

## Лучшие практики

1. **Организовать по домену** — сгруппировать связанные навыки вместе (например, `skills/security/`, `skills/testing/`)

2. **Используйте frontmatter** — включите `name``description` и включите в YAML frontmatter для ясности

3. **Зависимости документов** — обратите внимание на любые инструменты или MCP-серверы, требуемые для навыка

4. **Проверяйте навыки по отдельности** — проверяйте работу навыков перед их объединением

5. **Используйте относительные пути** — Сохраняйте навыки в разных условиях

## Объединение с другими особенностями

### Навыки + кастомные агенты

Навыки, `skills` указанные в поле агента, с энтузиазмом **заранее загружаются** — их полное содержание внедряется в контекст агента при запуске, так что агент получает доступ к инструкциям навыков без необходимости вызывать инструмент навыков. Названия навыков решаются на уровне `skillDirectories`сессии.

```typescript
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" }),
});
```

> \[!NOTE]
> Навыки — это опция по выбору — если `skills` их опускают, контент навыков не вводится. Субагенты не наследуют навыки от родителя; Вы должны указывать их явно для каждого агента.

### Навыки + MCP-серверы

Навыки могут дополнять возможности MCP-сервера:

```typescript
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

### Навыки не загружаются

1. **Существует путь проверки** — убедитесь, что путь в каталоге навыков правильный и содержит подкаталоги с `SKILL.md` файлами
2. **Проверьте права** — убедитесь, что SDK может читать каталог
3. **Проверьте SKILL.md формат** — убедитесь, что markdown хорошо сформирован и любой YAML-фронтматтер использует корректный синтаксис
4. **Включить отладочный лог** — настройте `logLevel: "debug"` на просмотр логов загрузки навыков

### Конфликты навыков

Если несколько навыков дают противоречивые инструкции:

* Используйте `disabledSkills` для исключения конфликтующих навыков
* Реорганизуйте каталоги навыков, чтобы избежать пересечений

## См. также

* [Создайте своё первое приложение на базе Copilot](/ru/copilot/how-tos/copilot-sdk/getting-started#create-custom-agents) — определите специализированные ИИ-персоны
* [Создайте своё первое приложение на базе Copilot](/ru/copilot/how-tos/copilot-sdk/getting-started#step-4-add-a-custom-tool) — Создавайте свои собственные инструменты
* [Using MCP servers with the GitHub Copilot SDK](/ru/copilot/how-tos/copilot-sdk/features/mcp) — Подключите внешних поставщиков инструментов