Skip to main content

Agents personnalisés et orchestration de sous-agents

Définissez des agents spécialisés avec des outils et des invites délimités, et laissez Copilot les orchestrer en tant que sous-agents au sein d’une même session.

Qui peut utiliser cette fonctionnalité ?

SDK GitHub Copilot est disponible dans tous les forfaits Copilot.

Remarque

          Kit de développement logiciel (SDK) Copilot est actuellement en préversion technique. Les fonctionnalités et la disponibilité sont susceptibles de changer.

Les agents personnalisés sont des définitions légères d’agents que vous associez à une session. Chaque agent possède son propre invite de commande système, ses restrictions d’outil et ses serveurs MCP facultatifs. Lorsque la demande d’un utilisateur correspond à l’expertise d’un agent, le Kit de développement logiciel (SDK) Copilot runtime délègue de manière automatique à cet agent en tant que sous-agent, l’exécutant dans un contexte isolé tout en retransmettant les événements de cycle de vie à la session parente. Pour obtenir une vue d’ensemble visuelle du flux de délégation, consultez le github/copilot-sdk référentiel.

ConceptDescription
          **Agent personnalisé** | Configuration d’agent nommé avec sa propre demande et son jeu d’outils |

| Sous-agent | Agent personnalisé appelé par le runtime pour gérer une partie d’une tâche | | Inférence | Capacité du runtime à sélectionner automatiquement un agent en fonction de l’intention de l’utilisateur | | Session parente | Session qui a généré le sous-agent ; reçoit tous les événements de cycle de vie |

Définition d’agents personnalisés

Indiquez customAgents lors de la création d'une session. Au minimum, chaque agent a besoin d’un name et 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" }),
});

Pour obtenir des exemples dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.

Référence de configuration

PropriétéTypeObligatoireDescription
namestringIdentificateur unique de l’agent
displayNamestring
Nom lisible par l’homme affiché dans les événements
descriptionstring
Ce que fait l’agent : aide le runtime à le sélectionner
tools
          `string[]` ou `null` |

| Les noms des outils que l’agent peut utiliser. null ou omis = tous les outils | | prompt | string | ✅ | Invite de commande du système pour l'agent | | mcpServers | object | | Configurations de serveur MCP spécifiques à cet agent | | infer | boolean | | Indique si le runtime peut sélectionner automatiquement cet agent (par défaut : true) |

Conseil

Une bonne description aide le runtime à faire correspondre l’intention de l’utilisateur à l’agent approprié. Soyez spécifique sur l’expertise et les capacités de l’agent.

En plus de la configuration par agent, vous pouvez définir agent sur la configuration de session pour prééleciter l’agent personnalisé actif au démarrage de la session.

Propriété de configuration de sessionTypeDescription
agentstringNom de l’agent personnalisé à préélectionnez lors de la création de la session. Doit correspondre à un name dans customAgents.

Sélection d’un agent lors de la création de session

Vous pouvez passer agent la configuration de session pour pré-sélectionner l’agent personnalisé qui doit être actif au démarrage de la session. La valeur doit correspondre à name l’un des agents définis dans 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
});

Pour obtenir des exemples dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.

Fonctionnement de la délégation de sous-agent

Lorsque vous envoyez une invite à une session avec des agents personnalisés, le runtime évalue s’il faut déléguer à un sous-agent :

  1.        **Correspondance d’intention**—L'environnement d'exécution analyse l’invite de l’utilisateur par rapport à chaque agent `name` et `description`
    
  2.        **Sélection de l’agent** : si une correspondance est trouvée et `infer` non `false`, le runtime sélectionne l’agent
    
  3.        **Exécution isolée** : le sous-agent s’exécute avec son propre invite et un jeu d’outils restreint
    
  4.        **Streaming d’événements** : les événements de cycle de vie (`subagent.started`, `subagent.completed`, etc.) retournent vers la session parente.
    
  5.        **Intégration des résultats** : la sortie du sous-agent est incorporée dans la réponse de l’agent parent
    

Contrôle de l’inférence

Par défaut, tous les agents personnalisés sont disponibles pour la sélection automatique (infer: true). Définissez infer: false pour empêcher le runtime de sélectionner automatiquement un agent, ce qui est utile pour les agents que vous souhaitez appeler uniquement par le biais de requêtes utilisateur explicites :

{
    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
}

Écoute des événements de sous-agent

Lorsqu’un sous-agent s’exécute, la session parente émet des événements de cycle de vie. Abonnez-vous à ces événements pour générer des interfaces utilisateur qui visualisent l’activité de l’agent.

Types d’événements

ÉvénementÉmis quandData
subagent.selectedLe runtime sélectionne un agent pour la tâche
          `agentName`, `agentDisplayName`, `tools` |

| subagent.started | Le sous-agent commence l’exécution | toolCallId, agentName, agentDisplayName, agentDescription | | subagent.completed | Le sous-agent se termine avec succès. | toolCallId, agentName, agentDisplayName | | subagent.failed | Un sous-agent rencontre une erreur | toolCallId, agentName, agentDisplayName, error | | subagent.deselected | Le runtime s’éloigne du sous-agent | — |

Abonnement aux événements

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

Pour obtenir des exemples dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.

Création d’une interface utilisateur pour l’arborescence des agents

Les événements de sous-agent incluent des toolCallId champs qui vous permettent de reconstruire l’arborescence d’exécution. Voici un modèle pour le suivi de l’activité de l’agent :

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);
});

Outils de portée par agent

Utilisez la tools propriété pour restreindre les outils auxquels un agent peut accéder. Ceci est essentiel pour la sécurité et pour garder les agents concentrés :

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.",
        },
    ],
});

Remarque

Lorsque la balise tools est null ou omise, l’agent hérite de l'accès à tous les outils configurés sur la session. Utilisez des listes d’outils explicites pour appliquer le principe du privilège minimum.

Attachement de serveurs MCP à des agents

Chaque agent personnalisé peut avoir ses propres serveurs MCP (Model Context Protocol), ce qui lui donne accès à des sources de données spécialisées :

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

Modèles et bonnes pratiques

Associer un chercheur à un éditeur

Un modèle courant consiste à définir un agent de recherche en lecture seule et un agent d’édition capable d’écrire. Le runtime délègue les tâches d'exploration au chercheur et les tâches de modification à l'éditeur.

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.",
    },
]

Conserver des descriptions spécifiques de l’agent

Le runtime utilise description pour répondre à l'intention de l’utilisateur. Les descriptions vagues mènent à une délégation médiocre :

// ❌ 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" }

Gérer correctement les défaillances

Les sous-agents peuvent échouer. Écoutez toujours les événements subagent.failed et gérez-les dans votre application :

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
    }
});