Skip to main content
Select language: current language is Korean
Copilot 검색 또는 요청
메뉴 열기

Copilot SDK 배포 크기 조정

          GitHub Copilot SDK 여러 사용자에게 서비스를 제공하고, 동시 세션을 처리하고, 인프라 전체에서 수평으로 확장하도록 배포를 디자인합니다.

누가 이 기능을 사용할 수 있나요?

GitHub Copilot SDK 는 모든 Copilot 계획에서 사용할 수 있습니다.

참고

          코필로트 SDK가 현재 기술 미리 보기에 있습니다. 기능 및 가용성은 변경될 수 있습니다.

CLI 세션에 대한 다양한 격리 패턴과 애플리케이션을 구현할 때 동시 세션 및 리소스를 관리하는 방법을 고려합니다.

          **최적 대상:** 플랫폼 개발자, SaaS 작성기 및 여러 동시 사용자를 제공하는 모든 배포.

세션 격리 패턴

패턴을 선택하기 전에 다음 세 가지 차원을 고려합니다.

  •         **격리**: 누가 어떤 세션을 볼 수 있나요?
    
  •         **동시성**: 동시에 실행할 수 있는 세션 수는 몇 개입니까?
    
  •         **지속성**: 세션은 얼마나 오래 유지됩니까?
    

코필로트 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 서버를 공유하지만 고유한 세션 ID를 통해 격리된 세션이 있습니다. 이는 자원을 덜 소모하지만, 격리 수준은 더 낮습니다.

여러 사용자가 격리된 세션과 하나의 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: 공유 세션(공동 작업)

여러 사용자가 코필로트와 공유 채팅방과 같은 동일한 세션과 상호 작용합니다. 이 패턴을 사용하려면 애플리케이션 수준 세션 잠금이 필요합니다.

여러 사용자가 메시지 큐 및 세션 잠금을 통해 동일한 세션과 상호 작용하는 공유 세션 패턴을 보여 주는 다이어그램

          **사용 시기:**
  • 팀 공동 작업 도구.
  • 공유 코드 검토 세션.
  • 프로그래밍 도우미를 페어링합니다.

참고

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 (명령줄 인터페이스) + 세션 격리공유 세션
          **격리** | 완료됨 | Logical | 공유됨 |

| 리소스 사용량 | 높음(사용자당 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 서버는 여러 동시 세션을 처리할 수 있습니다. 핵심은 리소스 소모를 방지하기 위해 세션 수명 주기를 관리하는 것입니다.

수직 크기 조정을 위한 리소스 차원(CPU, 메모리, 디스크 I/O 및 네트워크)을 보여 주는 다이어그램

// 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

다음 예제에서는 모든 복제본이 세션을 다시 시작할 수 있도록 공유되는 PersistentVolumeClaim 3개의 CLI 복제본을 배포합니다.

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 서버 Pod가 세션 상태를 위해 PersistentVolumeClaim을 공유하는 상황을 보여주는 다이어그램.

프로덕션 체크리스트

관심사권장 사항
          **세션 정리** | 주기적 정리를 실행하여 TTL보다 오래된 세션을 삭제합니다. |

| 상태 검사 | 주기적으로 CLI 서버 Ping; 응답하지 않으면 다시 시작합니다. | | 스토리지 | ~/.copilot/session-state/에 대한 영구 볼륨을 탑재하십시오. | | 비밀 | 플랫폼의 시크릿 관리자(Vault, Kubernetes 시크릿 등)를 사용합니다. | | 모니터링 | 활성 세션 수, 응답 대기 시간 및 오류 비율을 추적합니다. | | Locking | 공유 세션 액세스에 Redis 또는 이와 유사한 것을 사용합니다. | | 종료 | CLI 서버를 중지하기 전에 활성 세션을 드레이닝합니다. |

제한점

Limitation세부 정보
          **기본 제공 세션 잠금 없음** | 동시 액세스를 위한 애플리케이션 수준 잠금을 구현합니다. |

| 기본 제공 부하 분산 없음 | 외부 부하 분산 장치 또는 서비스 메시를 사용합니다. | | 세션 상태는 파일 기반입니다. | 다중 서버 설치를 위해 공유 파일 시스템이 필요합니다. | | 30분 유휴 시간 제한 | 활동이 없는 세션은 CLI에서 자동으로 정리됩니다. | | CLI는 단일 프로세스입니다. | 스레드가 아닌 CLI 서버 인스턴스를 더 추가하여 크기를 조정합니다. |

다음 단계

Morty Proxy This is a proxified and sanitized view of the page, visit original site.