écrits/blog/2026/08
Blog3 août 2026·6 min

GitHub Copilot SDK : intégrer le runtime d'agent

Le SDK Copilot expose le vrai runtime d'agent en six langages. Sessions, hooks, outils personnalisés, mode flotte et budgets de crédits, avec du code.

Pendant deux ans, la question intéressante dans le codage assisté par IA était quel modèle. En 2026, elle est discrètement devenue quel harnais — cette boucle qui planifie, appelle des outils, édite des fichiers, demande des permissions et sait quand s'arrêter. Tous les acteurs sérieux en proposent un désormais : OpenAI a le harnais Codex, Google a replié son travail CLI dans Antigravity, Anthropic expose la boucle de Claude Code via l'Agent SDK.

La proposition de GitHub s'appelle Copilot SDK, et son argument est d'une littéralité inhabituelle. Ce n'est ni une réimplémentation ni un simple wrapper HTTP : c'est le runtime qui fait tourner l'application Copilot et la CLI, exposé sous forme de bibliothèque. Depuis sa disponibilité générale, il est livré en six langages — TypeScript, Python, Go, .NET, Rust et Java — tous sous licence MIT.

Ce guide couvre ce que le SDK apporte réellement, la surface d'API qui compte, et le compromis architectural que vous acceptez en l'adoptant.

Ce que « le vrai runtime » signifie

La plupart des frameworks d'agents vous donnent des primitives et vous laissent assembler la boucle. Le SDK Copilot inverse la logique : la boucle existe déjà, durcie par le trafic de production, et vous vous y raccordez.

Concrètement, le SDK est un client qui parle JSON-RPC à la CLI Copilot lancée en mode serveur. Le SDK est la couche de transport ; la CLI est l'orchestrateur qui exécute le cycle d'utilisation des outils et effectue les appels au modèle.

Cette distinction compte pour raisonner sur le coût et le comportement. La documentation de GitHub est d'une franchise rafraîchissante sur la mécanique :

Chaque itération de cette boucle correspond exactement à un appel API au modèle, visible sous la forme d'une paire assistant.turn_start / assistant.turn_end dans le journal d'événements. Il n'y a aucun appel caché.

Un tour (turn) est un appel au modèle et ses conséquences. Un seul message utilisateur en produit généralement plusieurs : rechercher dans le code, lire les fichiers correspondants, en lire d'autres, puis répondre. Le modèle voit l'intégralité de la conversation accumulée à chaque tour et décide à chaque fois s'il dispose d'assez de contexte pour s'arrêter. Lorsqu'il renvoie une réponse sans demande d'outil, la boucle se termine et la session émet session.idle.

Quiconque a tenté de construire cela sait que la difficulté n'est pas le chemin heureux : ce sont l'annulation, les échecs partiels d'outils, les demandes de permission et la comptabilité du contexte. C'est précisément ce que vous achetez.

Démarrage

Le seul véritable prérequis est la CLI Copilot : elle doit être installée et authentifiée, puisque le SDK la lance et dialogue avec elle. Vérifiez avec copilot --version. TypeScript exige Node.js 20 ou plus, Python la version 3.11 ou plus.

npm install @github/copilot-sdk

Le programme TypeScript minimal tient en quatre lignes utiles :

import { CopilotClient } from "@github/copilot-sdk";
 
const client = new CopilotClient();
const session = await client.createSession({ model: "auto" });
 
const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);
 
await client.stop();

Python suit la même structure — créer un client, une session, envoyer — avec un gestionnaire de permissions explicite :

import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler
 
async def main():
    client = CopilotClient()
    await client.start()
 
    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="auto",
    )
    response = await session.send_and_wait("What is 2 + 2?")
    print(response.data.content)
 
    await client.stop()
 
asyncio.run(main())

sendAndWait bloque jusqu'à ce que la boucle atteigne l'inactivité. Pour toute interface visible par l'utilisateur, préférez le mode streaming.

Streaming et journal d'événements

Le SDK expose plus de quarante types d'événements. Les premiers dont vous aurez besoin sont les fragments de texte et le signal d'inactivité :

const session = await client.createSession({ model: "gpt-4.1", streaming: true });
 
session.on("assistant.message_delta", (event) => {
  process.stdout.write(event.data.deltaContent);
});
 
session.on("session.idle", () => console.log());

Au-delà des fragments de texte, vous disposez de assistant.turn_start et assistant.turn_end pour les frontières de tours, ainsi que tool.execution_start et tool.execution_complete autour de chaque appel d'outil. Ce flux fait la différence entre une barre de progression qui veut dire quelque chose et un spinner qui ment. C'est aussi, en pratique, votre couche d'observabilité : associez-le au traçage OpenTelemetry intégré et vous suivez une exécution d'agent de bout en bout, avec propagation du contexte de trace W3C dans votre stack existante.

Les hooks : la couche de gouvernance

Les hooks sont ce qui justifie la présence de ce SDK dans une base de code d'entreprise. Ils permettent d'intercepter la boucle à des points définis plutôt que de s'en remettre au jugement du modèle.

const session = await client.createSession({
  hooks: {
    onSessionStart: async (input, invocation) => { /* injecter du contexte */ },
    onPreToolUse: async (input, invocation) => { /* approuver, refuser, réécrire */ },
    onPostToolUse: async (input, invocation) => { /* transformer ou masquer */ },
  },
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

onPreToolUse se déclenche avant l'exécution d'un outil et peut approuver ou refuser l'exécution, modifier les arguments, ajouter du contexte, ou supprimer entièrement la sortie de la conversation. C'est un véritable point de contrôle de politique, pas un simple callback de journalisation. Si votre équipe conformité exige que « l'agent ne doit jamais exécuter git push sur main, et toute écriture de fichier hors de /src est journalisée », vous l'exprimez ici — dans votre code, dans votre processus — plutôt qu'en espérant qu'un prompt système tienne.

La famille de hooks couvre le cycle de vie de session, l'avant et l'après-utilisation d'outil, la soumission de prompt utilisateur et la gestion d'erreurs. Python emploie les mêmes noms en snake_case :

session = await client.create_session(
    on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
    hooks={
        "on_session_start": on_session_start,
        "on_pre_tool_use": on_pre_tool_use,
        "on_post_tool_use": on_post_tool_use,
    },
)

Outils personnalisés

Les outils intégrés couvrent la lecture, la recherche et l'édition de fichiers. Vos outils couvrent votre métier. En Python, l'ergonomie est excellente : un décorateur dérive le schéma JSON depuis les annotations de types :

@define_tool
def deploy_to_staging(branch: str, region: str) -> str:
    """Déploie une branche sur l'environnement de staging et renvoie l'URL de déploiement."""
    return run_deployment(branch, region)

La docstring n'est pas décorative : c'est ce que le modèle lit pour décider s'il appelle l'outil. Des descriptions vagues produisent des agents qui appellent la mauvaise chose au mauvais moment, et aucune ingénierie de prompt en amont ne rattrape une description d'outil ambiguë.

Les définitions d'outils acceptent quelques options utiles. skipPermission contourne la demande de permission pour les outils que vous avez déjà jugés sûrs. overridesBuiltInTool remplace un outil de la CLI par votre implémentation — pratique si votre organisation impose un wrapper validé autour de l'exécution shell. defer contrôle le chargement paresseux afin qu'un large catalogue d'outils ne consomme pas de contexte à chaque tour.

.NET emprunte une voie plus idiomatique en enveloppant des méthodes ordinaires avec AIFunctionFactory.Create et en faisant le pont vers Microsoft.Extensions.AI ; Java expose ToolDefinition.create() avec des paramètres typés. Le concept est identique dans les six langages.

Pilotage et mise en file

Quiconque a regardé un agent s'engager avec assurance dans la mauvaise direction connaît la frustration de devoir tuer l'exécution. Le SDK modélise cela correctement via un champ mode dans les options de message.

Le pilotage (mode: "immediate") injecte votre message dans le tour déjà en cours. L'agent voit la correction en temps réel et s'ajuste sans interrompre le tour :

const msgId = await session.send({
  prompt: "Refactor the authentication module to use sessions",
});
 
// L'agent travaille déjà — réorientez-le
await session.send({
  prompt: "Actually, use JWT tokens instead of sessions",
  mode: "immediate",
});

La mise en file (mode: "enqueue") met le message en tampon jusqu'à la fin du tour courant — le bon choix pour « ensuite, corrige aussi les tests ». Deux lignes d'API pour une distinction que la plupart des harnais maison n'implémentent jamais.

Mode flotte : sous-agents en parallèle

Le mode flotte répartit plusieurs sous-agents en parallèle depuis une session parente, coordonnés par un état de tâches partagé. La méthode protocolaire est session.fleet.start :

const result = await session.rpc.fleet.start({
  prompt: "Refactor each SDK package independently, then summarize the changes.",
});
 
if (result.started) {
  console.log("Fleet mode started");
}

GitHub est remarquablement précis sur les cas où c'est le mauvais outil. Le mode flotte convient au travail qui se décompose proprement avant exécution : refactorisations multi-fichiers où chaque worker possède un paquet, revues par lots sur des diffs distincts, recherche parallèle sur des services indépendants. Il est inadapté aux tâches séquentielles où l'étape deux dépend de la sortie concrète de l'étape un, aux éditions fortement couplées où les workers se disputent les mêmes fichiers, et aux petites tâches qu'un seul agent termine plus vite que le coût d'orchestration.

Une réserve tirée de la documentation : le binding flotte est expérimental dans la surface RPC générée. Si vous en dépendez, épinglez à la fois le SDK et le runtime CLI.

Maîtriser la facture

Les boucles autonomes consomment la capacité plus vite qu'un chat, car un seul message utilisateur devient de nombreux tours. Le SDK offre un levier direct : un budget de crédits IA par session.

const session = await client.createSession({
  onPermissionRequest: approveAll,
  sessionLimits: {
    maxAiCredits: 30,
  },
});

Lisez bien la sémantique : il s'agit d'un plafond souple. La consommation est vérifiée après le retour des appels au modèle, donc une seule réponse peut dépasser la valeur configurée avant que le runtime ne bloque l'appel suivant. Prévoyez ce dépassement plutôt que de le traiter comme une limite stricte. Le même objet sessionLimits s'applique à la reprise d'une session, et la surface d'usage et facturation expose le nombre de jetons, l'utilisation de la fenêtre de contexte et le quota du compte si vous souhaitez bâtir vos propres garde-fous.

Côté accès, le SDK est inclus dans les abonnements Copilot existants — y compris Copilot Free, avec un usage mensuel limité — et les exécutions d'agent puisent dans la capacité Copilot standard. L'authentification accepte les identifiants de l'utilisateur connecté, des jetons d'application GitHub via OAuth, des variables d'environnement telles que COPILOT_GITHUB_TOKEN ou GITHUB_TOKEN, ou encore votre propre clé (BYOK) chez un fournisseur de modèles pris en charge. Le BYOK est la porte de sortie décisive pour les équipes hors de la relation de facturation GitHub : il supprime totalement l'exigence d'abonnement.

Le compromis, dit clairement

La plus grande force du SDK et sa contrainte principale sont un seul et même fait : c'est un client de la CLI Copilot, pas une bibliothèque HTTP sans état.

Cela vous achète une parité de distribution. Vous exécutez exactement le runtime que GitHub livre à des millions de développeurs, avec les mêmes implémentations d'outils, le même modèle de permissions et les mêmes correctifs. Vous héritez de l'identité et de la facturation GitHub au lieu de monter les vôtres.

Ce que cela coûte, c'est le poids du déploiement. Le binaire CLI doit être présent partout où votre code s'exécute : une couche de conteneur, une image CI, une Lambda à laquelle il faut désormais réfléchir davantage. Le SDK Rust l'embarque par défaut, ce qui atténue le problème dans cet écosystème. Le SDK gère par ailleurs automatiquement le cycle de vie du processus CLI, même si vous pouvez le pointer vers un serveur externe pour des déploiements avancés.

Choisissez-le si vous êtes déjà investi dans GitHub et voulez du codage agentique intégré — outils internes, assistants CI, fonctionnalités destinées aux clients — sans construire l'orchestration de zéro. Soyez plus prudent si vous avez besoin d'appels sans état à faible dépendance, si vous tournez dans un environnement serverless contraint, ou si vous opérez largement hors de l'écosystème GitHub. Dans ces cas, un runtime plus léger comme le Claude Agent SDK ou un harnais TypeScript ouvert conviendra mieux.

Ce que cela dit du débat sur les harnais

L'existence même de ce SDK est un argument sur l'emplacement de la valeur. GitHub parie que la boucle, les implémentations d'outils, le modèle de permissions et la taxonomie d'événements constituent la partie difficile et différenciante — et que le modèle devient de plus en plus un choix de configuration. Le défaut model: "auto" et le support complet du BYOK le disent à voix haute.

Pour les équipes qui construisent des fonctionnalités agentiques plutôt que des produits agentiques, le pari est raisonnable. Les éléments que vous passeriez un trimestre à reconstruire — annulation, pilotage, demandes de permission, comptabilité des crédits, plus de quarante événements bien nommés — sont exactement ceux que personne ne met en feuille de route et dont tout le monde a besoin.

Commencez par une session unique et une boucle de streaming. Ajoutez des hooks dès que l'agent touche quoi que ce soit que vous ne laisseriez pas un stagiaire manipuler sans supervision. Ajoutez des outils personnalisés quand l'agent doit atteindre vos systèmes. Ne sortez le mode flotte que lorsque le travail se décompose vraiment — et épinglez vos versions ce jour-là.


À lire aussi : L'agent de codage GitHub Copilot et les PR autonomes · Ingénierie de harnais pour agents en production · Injection de prompt et sécurité des agents IA

Vous intégrez des fonctionnalités pilotées par agents dans votre produit ? Noqta accompagne les équipes en Tunisie et dans le Golfe pour concevoir, sécuriser et livrer des systèmes d'IA en production.