Skip to main content

Масштабирование развертываний Copilot SDK

Спроектируйте развертывание GitHub Copilot SDK так, чтобы обслуживать нескольких пользователей, работать с параллельными сессиями и масштабироваться горизонтально по инфраструктуре.

Кто может использовать эту функцию?

GitHub Copilot SDK Доступна со всеми Copilot тарифными планами.

Примечание.

          Второй пилот SDK в настоящее время находится в Technical Preview. Функциональность и доступность могут меняться.

Рассмотрите различные схемы изоляции для CLI-сессий и то, как вы хотите управлять параллельными сессиями и ресурсами при реализации приложения.

          **Лучше всего для:** Разработчики платформы, SaaS-конструкторы и любое развертывание, обслуживающее более нескольких одновременных пользователей.

Шаблоны изоляции сессий

Перед выбором узора рассмотрим три измерения:

  • Изоляция: кто может видеть какие сеансы?
  • Параллельность: сколько сессий может проходить одновременно?
  • Упорство: как долго длятся сессии?

Диаграмма, показывающая три измерения масштабирования для развертывания Copilot SDK: изоляция, параллельность и устойчивость.

Шаблон 1: Изолированный CLI на пользователя

Каждый пользователь получает свой собственный экземпляр CLI-сервера. Это самая сильная изоляция — сессии, память и процессы пользователя полностью разделены.

Диаграмма, показывающая изолированный шаблон CLI для каждого пользователя, где каждый пользователь получает выделенный экземпляр CLI-сервера.

          **Когда следует использовать:**
  • Мультиарендный SaaS, где изоляция данных крайне важна.
  • Пользователи с разными учетными данными аутентификации.
  • Требования к соответствию, такие как SOC 2 или 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);
        }
    }
}

Шаблон 2: Общий CLI с изоляцией сессий

Несколько пользователей используют один CLI-сервер, но имеют изолированные сессии через уникальные идентификаторы сессий. Это меньше ресурсов, но обеспечивает более слабую изоляцию.

Диаграмма, показывающая общий шаблон CLI, где несколько пользователей делят один CLI-сервер с изолированными сессиями.

          **Когда следует использовать:**
  • Внутренние инструменты с надёжными пользователями.
  • Среды с ограниченными ресурсами.
  • Более низкие требования к изоляции.
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);
}

Шаблон 3: Совместные сессии (совместные)

Несколько пользователей взаимодействуют с одной и той же сессией — как в общем чате с Copilot. Этот паттерн требует блокировки сессии на уровне приложения.

Диаграмма, показывающая шаблон общих сессий, где несколько пользователей взаимодействуют с одной сессией через очередь сообщений и блокировку сессии.

          **Когда следует использовать:**
  • Инструменты для командной работы.
  • Общие сессии обзора кода.
  • Спарите помощников программирования.

Примечание.

SDK не обеспечивает встроенную блокировку сессий. Необходимо сериализировать доступ, чтобы предотвратить одновременные записи в одну и ту же сессию.

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

Сравнение моделей изоляции

Изолированный CLI на пользователяСовместная CLI + изоляция сессииОбщие сеансы
ИзоляцияЗавершеноЛогичныйОбщее
Использование ресурсовВысокий (CLI на пользователя)Низкий (один CLI)Низкий уровень (один CLI и сессия)
СложностьСреднийLowВысокий (требует блокировки)
Гибкость аутентификацииТокены на пользователяСервисный токенСервисный токен
лучше всего подходит дляМногопользовательский SaaSВнутренние инструментыСотрудничество

Горизонтальное масштабирование

Несколько CLI-серверов за балансировщиком нагрузки

Чтобы обслуживать более одновременных пользователей, запускайте несколько экземпляров CLI-сервера за балансировщиком нагрузки. Состояние сессии должно находиться на общем хранилище , чтобы любой CLI-сервер мог возобновить любую сессию.

Диаграмма, показывающая несколько CLI-серверов за балансировщиком нагрузки с общим хранилищем для состояния сессии.

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

Закреплённые сессии против общего хранилища

Диаграмма, сравнивающая закреплённые сессии и подходы к совместному хранению для масштабирования развертываний Copilot SDK.

          **Закреплённые сессии** привязывают каждого пользователя к конкретному CLI-серверу. Общее хранилище не требуется, но распределение нагрузки может быть неравномерным, если пользовательский трафик сильно варьируется.

          **Общее хранилище** позволяет любому CLI обрабатывать любую сессию. Распределение нагрузки более равномерное, но требует сетевого хранения для `~/.copilot/session-state/`.

Вертикальное масштабирование

Настройка одного CLI-сервера

Один CLI-сервер может обрабатывать множество одновременных сессий. Главное — управлять жизненным циклом сессии, чтобы избежать истощения ресурсов:

Диаграмма, показывающая размеры ресурсов для вертикального масштабирования: процессор, память, дисковый ввод-вывод и сеть.

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

Эфемерные и постоянные сессии

Диаграмма, сравнивающая эфемерные и постоянные сессии для развертывания Copilot SDK.

          **Эфемерные сессии** создаются по запросу и уничтожаются после использования. Они идеально подходят для одноразовых задач и безсостоятельных API.

          **Постоянные сессии** называются, перезапускаются и возобновляются. Они идеально подходят для многоповоротного чата и длительных рабочих процессов.

Эфемерные сессии

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

Постоянные сеансы

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

Развертывания контейнеров

Kubernetes с постоянным хранением памяти

В следующем примере используются три реплики CLI, которые объединяют A PersistentVolumeClaim , чтобы любая реплика могла возобновить любую сессию.

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

Диаграмма, показывающая развертывание Kubernetes с несколькими серверными подами CLI, разделяющими PersistentVolumeClaim для состояния сессии.

Контрольный список рабочей среды

БеспокойствоRecommendation
Уборка сессииЗапускайте периодическую очистку, чтобы удалять сессии старше вашего TTL.
Медицинские проверкиПериодически пингуйте CLI-сервер; Если не реагирует, перезапустите.
ХранениеМонтировать постоянные тома для ~/.copilot/session-state/.
СекретыИспользуйте менеджер секретов вашей платформы (Vault, Kubernetes Secrets и т.д.).
MonitoringОтслеживайте количество активных сессий, задержку ответа и уровень ошибок.
LockingИспользуйте Redis или подобные для общего доступа к сессиям.
Завершение работыСпустите активные сессии перед закрытием CLI-серверов.

Ограничения

ОграничениеСведения
Нет встроенной блокировки сессииРеализовать блокировку на уровне приложения для одновременного доступа.
Нет встроенной балансировки нагрузкиИспользуйте внешний балансировщик нагрузки или сервисную сетку.
Состояние сессии основано на файлахТребуется общая файловая система для многосерверных настроек.
30-минутный тайм-аут на холостом ходуСессии без активности автоматически очищаются CLI.
CLI — это однопроцессный процессМасштабируйтесь, добавляя больше экземпляров CLI-сервера, а не потоков.

Дальнейшие действия