Skip to main content

Agentes personalizados e orquestração de subagentes

Defina agentes especializados com ferramentas com escopo e prompts e permita Copilot orquestrar esses agentes como sub-agentes em uma única sessão.

Quem pode usar esse recurso?

SDK do GitHub Copilot está disponível com todos os Copilot planos.

Observação

          SDK do Copilot está atualmente em versão prévia técnica. A funcionalidade e a disponibilidade estão sujeitas a alterações.

Agentes personalizados são as definições de agentes leves que você anexa a uma sessão. Cada agente tem seu próprio prompt do sistema, restrições de ferramenta e servidores MCP opcionais. Quando a solicitação de um usuário corresponde à especialização de um agente, o SDK do Copilot runtime delega automaticamente a esse agente como um subagente, executando-o em um contexto isolado enquanto transmite eventos de ciclo de vida de volta para a sessão pai. Para obter uma visão geral visual do fluxo de delegação, consulte o github/copilot-sdk repositório.

ConceitoDescrição
          **Agente personalizado** | Uma configuração de agente nomeado com seu próprio prompt e conjunto de ferramentas |

| Subagente | Um agente personalizado invocado pelo runtime para lidar com parte de uma tarefa | | Inferência | A capacidade do runtime de selecionar automaticamente um agente com base na intenção do usuário | | Sessão principal | A sessão que gerou o subagente; recebe todos os eventos do ciclo de vida. |

Definindo agentes personalizados

Passe customAgents ao criar uma sessão. No mínimo, cada agente precisa de um name e prompt.

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

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
    model: "gpt-4.1",
    customAgents: [
        {
            name: "researcher",
            displayName: "Research Agent",
            description: "Explores codebases and answers questions using read-only tools",
            tools: ["grep", "glob", "view"],
            prompt: "You are a research assistant. Analyze code and answer questions. Do not modify any files.",
        },
        {
            name: "editor",
            displayName: "Editor Agent",
            description: "Makes targeted code changes",
            tools: ["view", "edit", "bash"],
            prompt: "You are a code editor. Make minimal, surgical changes to files as requested.",
        },
    ],
    onPermissionRequest: async () => ({ kind: "approved" }),
});

Para obter exemplos em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Referência de configuração

PropriedadeTipoObrigatórioDescrição
namestringIdentificador exclusivo para o agente
displayNamestring
Nome legível por humanos exibido em eventos
descriptionstring
O que o agente faz — ajuda o runtime a selecioná-lo
tools
          `string[]` ou `null` |

| Nomes de ferramentas que o agente pode usar. null ou excluído = todas as ferramentas | | prompt | string | ✅ | Comando do sistema ao agente | | mcpServers | object | | Configurações de servidor MCP específicas para este agente | | infer | boolean | | Se o runtime pode selecionar automaticamente este agente (padrão: true) |

Dica

Um bom description ajuda o runtime a corresponder a intenção do usuário com o agente certo. Seja específico sobre a experiência e as funcionalidades do agente.

Além da configuração por agente, você pode definir agent na configuração da sessão para selecionar previamente qual agente personalizado está ativo quando a sessão é iniciada.

Propriedade de configuração de sessãoTipoDescrição
agentstringNome do agente personalizado a ser pré-selecionado na criação da sessão. Deve corresponder a um name em customAgents.

Selecionando um agente na criação da sessão

Você pode passar agent na configuração da sessão para predefinir qual agente personalizado deverá ser ativado quando a sessão for iniciada. O valor deve corresponder ao name de um dos agentes definidos em customAgents.

const session = await client.createSession({
    customAgents: [
        {
            name: "researcher",
            prompt: "You are a research assistant. Analyze code and answer questions.",
        },
        {
            name: "editor",
            prompt: "You are a code editor. Make minimal, surgical changes.",
        },
    ],
    agent: "researcher", // Pre-select the researcher agent
});

Para obter exemplos em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Como funciona a delegação de subagente

Quando você envia um prompt para uma sessão com agentes personalizados, o runtime avalia se deseja delegar a um subagente:

  1.        **Correspondência de intenção** – o runtime analisa o prompt do usuário em relação a cada agente `name` e `description`
    
  2.        **Seleção de agente**— Se uma correspondência for encontrada e `infer` não for `false`, o runtime selecionará o agente
    
  3.        **Execução isolada** – o sub-agente é executado com seu próprio prompt e conjunto de ferramentas restritas
    
  4.        **Transmissão de** eventos — eventos de ciclo de vida (`subagent.started`, `subagent.completed` etc.) são transmitidos de volta para a sessão pai
    
  5.        **Integração de resultados** – a saída do sub-agente é incorporada à resposta do agente pai
    

Controlando a inferência

Por padrão, todos os agentes personalizados estão disponíveis para seleção automática (infer: true). Defina infer: false para impedir que o runtime selecione automaticamente um agente, útil para agentes que você só deseja invocar por meio de solicitações explícitas do usuário:

{
    name: "dangerous-cleanup",
    description: "Deletes unused files and dead code",
    tools: ["bash", "edit", "view"],
    prompt: "You clean up codebases by removing dead code and unused files.",
    infer: false, // Only invoked when user explicitly asks for this agent
}

Escutando eventos de subagente

Quando um subagente é executado, a sessão pai emite eventos de ciclo de vida. Assine esses eventos para criar UIs que visualizam a atividade do agente.

Tipos de evento

AcontecimentoEmitido quandoDados
subagent.selectedO runtime seleciona um agente para a tarefa
          `agentName`
          `agentDisplayName`
          `tools`
         |

| subagent.started | Subagente inicia a execução | toolCallId, agentName, , agentDisplayName``agentDescription | | subagent.completed | O subagente foi concluído com êxito | toolCallId agentName agentDisplayName | | subagent.failed | O subagente encontra um erro | toolCallId, agentName, , agentDisplayName``error | | subagent.deselected | O runtime muda seu foco do sub-agente | — |

Inscrevendo-se para eventos

session.on((event) => {
    switch (event.type) {
        case "subagent.started":
            console.log(`▶ Sub-agent started: ${event.data.agentDisplayName}`);
            console.log(`  Description: ${event.data.agentDescription}`);
            console.log(`  Tool call ID: ${event.data.toolCallId}`);
            break;

        case "subagent.completed":
            console.log(`✅ Sub-agent completed: ${event.data.agentDisplayName}`);
            break;

        case "subagent.failed":
            console.log(`❌ Sub-agent failed: ${event.data.agentDisplayName}`);
            console.log(`  Error: ${event.data.error}`);
            break;

        case "subagent.selected":
            console.log(`🎯 Agent selected: ${event.data.agentDisplayName}`);
            console.log(`  Tools: ${event.data.tools?.join(", ") ?? "all"}`);
            break;

        case "subagent.deselected":
            console.log("↩ Agent deselected, returning to parent");
            break;
    }
});

const response = await session.sendAndWait({
    prompt: "Research how authentication works in this codebase",
});

Para obter exemplos em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Construindo uma interface do usuário de árvore de agente

Eventos de subagente incluem campos que permitem toolCallId reconstruir a árvore de execução. Aqui está um padrão para acompanhar a atividade do agente:

interface AgentNode {
    toolCallId: string;
    name: string;
    displayName: string;
    status: "running" | "completed" | "failed";
    error?: string;
    startedAt: Date;
    completedAt?: Date;
}

const agentTree = new Map<string, AgentNode>();

session.on((event) => {
    if (event.type === "subagent.started") {
        agentTree.set(event.data.toolCallId, {
            toolCallId: event.data.toolCallId,
            name: event.data.agentName,
            displayName: event.data.agentDisplayName,
            status: "running",
            startedAt: new Date(event.timestamp),
        });
    }

    if (event.type === "subagent.completed") {
        const node = agentTree.get(event.data.toolCallId);
        if (node) {
            node.status = "completed";
            node.completedAt = new Date(event.timestamp);
        }
    }

    if (event.type === "subagent.failed") {
        const node = agentTree.get(event.data.toolCallId);
        if (node) {
            node.status = "failed";
            node.error = event.data.error;
            node.completedAt = new Date(event.timestamp);
        }
    }

    // Render your UI with the updated tree
    renderAgentTree(agentTree);
});

Ferramentas de escopo por agente

Use a tools propriedade para restringir quais ferramentas um agente pode acessar. Isso é essencial para a segurança e para manter os agentes focados:

const session = await client.createSession({
    customAgents: [
        {
            name: "reader",
            description: "Read-only exploration of the codebase",
            tools: ["grep", "glob", "view"],  // No write access
            prompt: "You explore and analyze code. Never suggest modifications directly.",
        },
        {
            name: "writer",
            description: "Makes code changes",
            tools: ["view", "edit", "bash"],   // Write access
            prompt: "You make precise code changes as instructed.",
        },
        {
            name: "unrestricted",
            description: "Full access agent for complex tasks",
            tools: null,                        // All tools available
            prompt: "You handle complex multi-step tasks using any available tools.",
        },
    ],
});

Observação

Quando tools é null ou omitido, o agente herda o acesso a todas as ferramentas configuradas na sessão. Use listas de ferramentas explícitas para impor o princípio do privilégio mínimo.

Anexando servidores MCP a agentes

Cada agente personalizado pode ter seus próprios servidores MCP (Model Context Protocol), dando-lhe acesso a fontes de dados especializadas:

const session = await client.createSession({
    customAgents: [
        {
            name: "db-analyst",
            description: "Analyzes database schemas and queries",
            prompt: "You are a database expert. Use the database MCP server to analyze schemas.",
            mcpServers: {
                "database": {
                    command: "npx",
                    args: ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
                },
            },
        },
    ],
});

Padrões e melhores práticas

Emparelhar um pesquisador com um editor

Um padrão comum é definir um agente de pesquisa somente leitura e um agente editor com capacidade de escrita. O tempo de execução delega tarefas de exploração ao pesquisador e tarefas de modificação ao editor.

customAgents: [
    {
        name: "researcher",
        description: "Analyzes code structure, finds patterns, and answers questions",
        tools: ["grep", "glob", "view"],
        prompt: "You are a code analyst. Thoroughly explore the codebase to answer questions.",
    },
    {
        name: "implementer",
        description: "Implements code changes based on analysis",
        tools: ["view", "edit", "bash"],
        prompt: "You make minimal, targeted code changes. Always verify changes compile.",
    },
]

Manter descrições de agente específicas

O runtime usa o description para corresponder à intenção do usuário. Descrições vagas levam à má delegação:

// ❌ Too vague — runtime can't distinguish from other agents
{ description: "Helps with code" }

// ✅ Specific — runtime knows when to delegate
{ description: "Analyzes Python test coverage and identifies untested code paths" }

Lidar com falhas de forma elegante

Sub-agentes podem falhar. Sempre ouça subagent.failed eventos e manipule-os em seu aplicativo:

session.on((event) => {
    if (event.type === "subagent.failed") {
        logger.error(`Agent ${event.data.agentName} failed: ${event.data.error}`);
        // Show error in UI, retry, or fall back to parent agent
    }
});