Remarque
Kit de développement logiciel (SDK) Copilot est actuellement en préversion technique. Les fonctionnalités et la disponibilité sont susceptibles de changer.
Tenez compte des différents modèles d’isolation des sessions CLI et de la façon dont vous souhaitez gérer des sessions et des ressources simultanées lors de l’implémentation de votre application.
**Meilleur pour :** Les développeurs de plateforme, les générateurs SaaS et tout déploiement servant plus de quelques utilisateurs simultanés.
Modèles d’isolation de session
Avant de choisir un modèle, tenez compte de trois dimensions :
-
**Isolation** : Qui peut voir quelles sessions ? -
**Concurrence** : combien de sessions peuvent s’exécuter simultanément ? -
**Persistance** : Quelle est la durée de vie des sessions ?

Modèle 1 : interface CLI isolée par utilisateur
Chaque utilisateur obtient sa propre instance de serveur CLI. Il s’agit de l’isolation la plus forte : les sessions, la mémoire et les processus d’un utilisateur sont complètement séparés.

**Quand les utiliser** :
- SaaS multilocataire où l’isolation des données est essentielle.
- Utilisateurs disposant d’informations d’identification d’authentification différentes.
- Exigences de conformité telles que SOC 2 ou HIPAA.
// CLI pool manager—one CLI per user
class CLIPool {
private instances = new Map<string, { client: CopilotClient; port: number }>();
private nextPort = 5000;
async getClientForUser(userId: string, token?: string): Promise<CopilotClient> {
if (this.instances.has(userId)) {
return this.instances.get(userId)!.client;
}
const port = this.nextPort++;
// Spawn a dedicated CLI for this user
await spawnCLI(port, token);
const client = new CopilotClient({
cliUrl: `localhost:${port}`,
});
this.instances.set(userId, { client, port });
return client;
}
async releaseUser(userId: string): Promise<void> {
const instance = this.instances.get(userId);
if (instance) {
await instance.client.stop();
this.instances.delete(userId);
}
}
}
Modèle 2 : interface CLI partagée avec isolation de session
Plusieurs utilisateurs partagent un serveur CLI, mais ont des sessions isolées via des ID de session uniques. Cela est plus léger sur les ressources, mais offre une isolation plus faible.

**Quand les utiliser** :
- Outils internes avec des utilisateurs approuvés.
- Environnements limités aux ressources.
- Exigences d’isolation inférieures.
const sharedClient = new CopilotClient({
cliUrl: "localhost:4321",
});
// Enforce session isolation through naming conventions
function getSessionId(userId: string, purpose: string): string {
return `${userId}-${purpose}-${Date.now()}`;
}
// Access control: ensure users can only access their own sessions
async function resumeSessionWithAuth(
sessionId: string,
currentUserId: string
): Promise<Session> {
const [sessionUserId] = sessionId.split("-");
if (sessionUserId !== currentUserId) {
throw new Error("Access denied: session belongs to another user");
}
return sharedClient.resumeSession(sessionId);
}
Modèle 3 : Sessions partagées (collaboratives)
Plusieurs utilisateurs interagissent avec la même session, comme une salle de conversation partagée avec Copilot. Ce modèle nécessite le verrouillage de session au niveau de l’application.

**Quand les utiliser** :
- Outils de collaboration d’équipe.
- Sessions de révision de code partagé.
- Associez des assistants de programmation.
Remarque
Le Kit de développement logiciel (SDK) ne fournit pas de verrouillage de session intégré. Vous devez sérialiser l’accès pour empêcher les écritures simultanées dans la même session.
import Redis from "ioredis";
const redis = new Redis();
async function withSessionLock<T>(
sessionId: string,
fn: () => Promise<T>,
timeoutSec = 300
): Promise<T> {
const lockKey = `session-lock:${sessionId}`;
const lockId = crypto.randomUUID();
// Acquire lock
const acquired = await redis.set(lockKey, lockId, "NX", "EX", timeoutSec);
if (!acquired) {
throw new Error("Session is in use by another user");
}
try {
return await fn();
} finally {
// Release lock only if we still own it
const currentLock = await redis.get(lockKey);
if (currentLock === lockId) {
await redis.del(lockKey);
}
}
}
// Serialize access to a shared session
app.post("/team-chat", authMiddleware, async (req, res) => {
const result = await withSessionLock("team-project-review", async () => {
const session = await client.resumeSession("team-project-review");
return session.sendAndWait({ prompt: req.body.message });
});
res.json({ content: result?.data.content });
});
Comparaison des modèles d’isolation
| Interface CLI isolée par utilisateur | Interface CLI partagée + isolation de session | Sessions partagées |
|---|
**Isolation** | Terminé | Logical | Partagé |
| Utilisation des ressources | High (CLI par utilisateur) | Faible (une interface CLI) | Faible (une interface CLI et une session) | | Complexité : | Moyenne | Low | Élevé (nécessite un verrouillage) | | Flexibilité de l’authentification | Jetons par utilisateur | Jeton de service | Jeton de service | | Idéal pour | SaaS multilocataire | Outils internes | Collaboration |
Scalabilité horizontale
Plusieurs serveurs CLI derrière un équilibreur de charge
Pour servir davantage d’utilisateurs simultanés, exécutez plusieurs instances de serveur CLI derrière un équilibreur de charge. L’état de session doit être sur le stockage partagé afin que n’importe quel serveur CLI puisse reprendre n’importe quelle session.

// Route sessions across CLI servers
class CLILoadBalancer {
private servers: string[];
private currentIndex = 0;
constructor(servers: string[]) {
this.servers = servers;
}
// Round-robin selection
getNextServer(): string {
const server = this.servers[this.currentIndex];
this.currentIndex = (this.currentIndex + 1) % this.servers.length;
return server;
}
// Sticky sessions: same user always hits same server
getServerForUser(userId: string): string {
const hash = this.hashCode(userId);
return this.servers[hash % this.servers.length];
}
private hashCode(str: string): number {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash);
}
}
const lb = new CLILoadBalancer([
"cli-1:4321",
"cli-2:4321",
"cli-3:4321",
]);
app.post("/chat", async (req, res) => {
const server = lb.getServerForUser(req.user.id);
const client = new CopilotClient({ cliUrl: server });
const session = await client.createSession({
sessionId: `user-${req.user.id}-chat`,
model: "gpt-4.1",
});
const response = await session.sendAndWait({ prompt: req.body.message });
res.json({ content: response?.data.content });
});
Sessions sticky et stockage partagé

**Les sessions sticky** épinglent chaque utilisateur à un serveur CLI spécifique. Aucun stockage partagé n’est nécessaire, mais la distribution de charge peut être inégale si le trafic utilisateur varie considérablement.
**Le stockage partagé** permet à n’importe quelle interface CLI de gérer n’importe quelle session. La distribution de charge est plus uniforme, mais nécessite un stockage en réseau pour `~/.copilot/session-state/`.
Scalabilité verticale
Réglage d’un serveur CLI unique
Un serveur CLI unique peut gérer de nombreuses sessions simultanées. La clé consiste à gérer le cycle de vie de session pour éviter l’épuisement des ressources :

// Limit concurrent active sessions
class SessionManager {
private activeSessions = new Map<string, Session>();
private maxConcurrent: number;
constructor(maxConcurrent = 50) {
this.maxConcurrent = maxConcurrent;
}
async getSession(sessionId: string): Promise<Session> {
// Return existing active session
if (this.activeSessions.has(sessionId)) {
return this.activeSessions.get(sessionId)!;
}
// Enforce concurrency limit
if (this.activeSessions.size >= this.maxConcurrent) {
await this.evictOldestSession();
}
// Create or resume
const session = await client.createSession({
sessionId,
model: "gpt-4.1",
});
this.activeSessions.set(sessionId, session);
return session;
}
private async evictOldestSession(): Promise<void> {
const [oldestId] = this.activeSessions.keys();
const session = this.activeSessions.get(oldestId)!;
// Session state is persisted automatically—safe to disconnect
await session.disconnect();
this.activeSessions.delete(oldestId);
}
}
Sessions éphémères et persistantes

**Les sessions éphémères** sont créées par demande et détruites après utilisation. Elles sont idéales pour les tâches ponctuelles et les API sans état.
**Les sessions persistantes** sont nommées, survivent aux redémarrages et peuvent être reprise. Elles sont idéales pour les conversations à plusieurs tours et les flux de travail longs.
Sessions éphémères
app.post("/api/analyze", async (req, res) => {
const session = await client.createSession({
model: "gpt-4.1",
});
try {
const response = await session.sendAndWait({
prompt: req.body.prompt,
});
res.json({ result: response?.data.content });
} finally {
await session.disconnect();
}
});
Sessions persistantes
// Start a conversation
app.post("/api/chat/start", async (req, res) => {
const sessionId = `user-${req.user.id}-${Date.now()}`;
const session = await client.createSession({
sessionId,
model: "gpt-4.1",
infiniteSessions: {
enabled: true,
backgroundCompactionThreshold: 0.80,
},
});
res.json({ sessionId });
});
// Continue the conversation
app.post("/api/chat/message", async (req, res) => {
const session = await client.resumeSession(req.body.sessionId);
const response = await session.sendAndWait({ prompt: req.body.message });
res.json({ content: response?.data.content });
});
// Clean up when done
app.post("/api/chat/end", async (req, res) => {
await client.deleteSession(req.body.sessionId);
res.json({ success: true });
});
Déploiements de conteneurs
Kubernetes avec stockage persistant
L'exemple suivant déploie trois réplicas CLI partageant un PersistentVolumeClaim pour permettre à chaque réplica de reprendre une session quelconque.
apiVersion: apps/v1
kind: Deployment
metadata:
name: copilot-cli
spec:
replicas: 3
selector:
matchLabels:
app: copilot-cli
template:
metadata:
labels:
app: copilot-cli
spec:
containers:
- name: copilot-cli
image: ghcr.io/github/copilot-cli:latest
args: ["--headless", "--port", "4321"]
env:
- name: COPILOT_GITHUB_TOKEN
valueFrom:
secretKeyRef:
name: copilot-secrets
key: github-token
ports:
- containerPort: 4321
volumeMounts:
- name: session-state
mountPath: /root/.copilot/session-state
volumes:
- name: session-state
persistentVolumeClaim:
claimName: copilot-sessions-pvc
---
apiVersion: v1
kind: Service
metadata:
name: copilot-cli
spec:
selector:
app: copilot-cli
ports:
- port: 4321
targetPort: 4321

Liste de contrôle de production
| Préoccupation | Recommandation |
|---|
**Nettoyage de session** | Exécutez un nettoyage périodique pour supprimer les sessions plus anciennes que votre TTL. |
|
Vérifications d’intégrité | Effectuez régulièrement un test ping sur le serveur CLI ; redémarrez si vous ne répondez pas. |
|
Stockage | Monter des volumes persistants pour ~/.copilot/session-state/. |
|
Secrets | Utilisez le gestionnaire de secrets de votre plateforme (coffre, secrets Kubernetes, etc.). |
|
Surveillance | Suivez le nombre de sessions actives, la latence de réponse et les taux d’erreur. |
|
Locking | Utilisez Redis ou similaire pour l’accès à une session partagée. |
|
Arrêter | Videz les sessions actives avant d’arrêter les serveurs CLI. |
Limites
| Limitation | Détails |
|---|
**Aucun verrouillage de session intégré** | Implémentez le verrouillage au niveau de l’application pour l’accès simultané. |
| Aucun équilibrage de charge intégré | Utilisez un équilibreur de charge externe ou un maillage de service. | | L’état de session est basé sur des fichiers | Nécessite un système de fichiers partagé pour les configurations multiserveurs. | | Délai d’inactivité de 30 minutes | Les sessions sans activité sont nettoyées automatiquement par l’interface CLI. | | L’interface CLI est un processus unique | Effectuez une mise à l’échelle en ajoutant d’autres instances de serveur CLI, et non des threads. |
Étapes suivantes
- Pour la configuration côté serveur principale, consultez Configuration du Kit de développement logiciel (SDK) Copilot pour les services principaux.
- Pour l’authentification multi-utilisateur, consultez Utilisation de GitHub OAuth avec le Kit de développement logiciel (SDK) Copilot.
- Pour l’installation et votre premier message, consultez Getting started avec le Kit de développement logiciel (SDK) Copilot.