Observação
SDK do Copilot está em versão prévia técnica no momento. A funcionalidade e a disponibilidade estão sujeitas a alterações.
Considere os diferentes padrões de isolamento para sessões da CLI e como você deseja gerenciar sessões e recursos simultâneos ao implementar seu aplicativo.
**Melhor para:** Desenvolvedores de plataforma, construtores de SaaS e qualquer implantação que atende a mais de alguns usuários simultâneos.
Padrões de isolamento de sessões
Antes de escolher um padrão, considere três dimensões:
- Isolamento: Quem pode ver quais sessões?
- Simultaneidade: quantas sessões podem ser executadas simultaneamente?
- Persistência: quanto tempo as sessões duram?

Padrão 1: CLI isolada por usuário
Cada usuário obtém sua própria instância de servidor da CLI. Esse é o isolamento mais forte: as sessões, a memória e os processos de um usuário são completamente separados.

**Quando usar:**
- SaaS multilocatário em que o isolamento de dados é crítico.
- Usuários com credenciais de autenticação diferentes.
- Requisitos de conformidade, como 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);
}
}
}
Padrão 2: CLI compartilhada com isolamento de sessão
Vários usuários compartilham um servidor da CLI, mas têm sessões isoladas por meio de IDs de sessão exclusivas. Isso é mais leve em recursos, mas fornece isolamento mais fraco.

**Quando usar:**
- Ferramentas internas com usuários confiáveis.
- Ambientes restritos a recursos.
- Requisitos de isolamento mais baixos.
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);
}
Padrão 3: sessões compartilhadas (colaborativas)
Vários usuários interagem com a mesma sessão, como uma sala de chat compartilhada com o Copilot. Esse padrão requer bloqueio de sessão no nível do aplicativo.

**Quando usar:**
- Ferramentas de colaboração em equipe.
- Sessões de revisão de código compartilhado.
- Assistentes de programação em par.
Observação
O SDK não fornece bloqueio de sessão interno. Você deve serializar o acesso para evitar gravações simultâneas na mesma sessão.
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 });
});
Comparação de padrões de isolamento
| CLI isolada por usuário | CLI compartilhada + isolamento de sessão | Sessões partilhadas | |
|---|---|---|---|
| Isolamento | Concluído | Lógico | Compartilhado |
| Uso de recursos | Alta (CLI por usuário) | Baixo (uma CLI) | Baixo (uma CLI e uma sessão) |
| Complexidade | Medium | Baixo | Alto (requer bloqueio) |
| Flexibilidade de autenticação | Tokens por usuário | Token de serviço | Token de serviço |
| Mais adequado para | SaaS multilocatário | Ferramentas internas | Colaboração |
Escalabilidade horizontal
Vários servidores CLI por trás de um balanceador de carga
Para atender a usuários mais simultâneos, execute várias instâncias de servidor da CLI por trás de um balanceador de carga. O estado da sessão deve estar no armazenamento compartilhado para que qualquer servidor da CLI possa retomar qualquer sessão.

// 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 });
});
Sessões persistentes versus armazenamento compartilhado

**Sessões persistentes** fixam cada usuário em um servidor CLI específico. Nenhum armazenamento compartilhado é necessário, mas a distribuição de carga pode ser desigual se o tráfego do usuário variar significativamente.
**O armazenamento compartilhado** permite que qualquer CLI manipule qualquer sessão. A distribuição de carga é mais uniforme, mas requer armazenamento em rede para `~/.copilot/session-state/`.
Dimensionamento vertical
Ajustando um único servidor da CLI
Um único servidor da CLI pode lidar com muitas sessões simultâneas. A chave é gerenciar o ciclo de vida da sessão para evitar o esgotamento de recursos:

// 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);
}
}
Sessões efêmeras versus persistentes

**As sessões efêmeras são criadas** por solicitação e destruídas após o uso. São ideais para tarefas únicas e APIs sem estado.
**As sessões persistentes são nomeadas** , sobrevivem a reinicializações e são retomáveis. Eles são ideais para chat de vários turnos e fluxos de trabalho longos.
Sessões efêmeras
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();
}
});
Sessões persistentes
// 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 });
});
Implantações de contêiner
Kubernetes com armazenamento persistente
O exemplo a seguir implanta três réplicas da CLI compartilhando uma PersistentVolumeClaim para que qualquer réplica possa retomar qualquer sessão.
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

Lista de verificação de produção
| Preocupação | Recomendação |
|---|---|
| Limpeza de sessão | Execute a limpeza periódica para excluir as sessões mais antigas que o TTL. |
| Verificações de integridade | Executar ping no servidor da CLI periodicamente; reinicie se não responder. |
| Armazenamento | Montar volumes persistentes para ~/.copilot/session-state/. |
| Segredos | Use o gerenciador de segredos da plataforma (Cofre, Segredos do Kubernetes etc.). |
| Monitorização | Acompanhe a contagem de sessão ativa, a latência de resposta e as taxas de erro. |
| Locking | Use Redis ou semelhante para acesso de sessão compartilhado. |
| Desligamento | Escorra as sessões ativas antes de parar os servidores da CLI. |
Limitações
| Limitation | Detalhes |
|---|---|
| Nenhum bloqueio de sessão interno | Implemente o bloqueio no nível do aplicativo para acesso simultâneo. |
| Nenhum balanceamento de carga interno | Use um balanceador de carga externo ou uma malha de serviço. |
| O estado da sessão é baseado em arquivo | Requer um sistema de arquivos compartilhado para configurações de vários servidores. |
| Tempo limite ocioso de 30 minutos | As sessões sem atividade são limpas automaticamente pela CLI. |
| A CLI é de processo único | Escalone adicionando mais instâncias de servidor CLI, não threads. |
Próximas Etapas
- Para a configuração principal do lado do servidor, consulte Configurando o SDK do Copilot para serviços de back-end.
- Para autenticação de vários usuários, consulte Usando o GitHub OAuth com o SDK do Copilot.
- Para instalação e sua primeira mensagem, consulte Introdução ao SDK do Copilot.