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.
| Concept | Description |
|---|
**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é | Type | Obligatoire | Description |
|---|---|---|---|
name | string | ✅ | Identificateur unique de l’agent |
displayName | string | ||
| Nom lisible par l’homme affiché dans les événements | |||
description | string | ||
| 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 session | Type | Description |
|---|---|---|
agent | string | Nom 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 :
-
**Correspondance d’intention**—L'environnement d'exécution analyse l’invite de l’utilisateur par rapport à chaque agent `name` et `description` -
**Sélection de l’agent** : si une correspondance est trouvée et `infer` non `false`, le runtime sélectionne l’agent -
**Exécution isolée** : le sous-agent s’exécute avec son propre invite et un jeu d’outils restreint -
**Streaming d’événements** : les événements de cycle de vie (`subagent.started`, `subagent.completed`, etc.) retournent vers la session parente. -
**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 quand | Data |
|---|---|---|
subagent.selected | Le 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
}
});