Skip to main content

Copilot SDK의 세션 지속성

재시작 및 배포 후에도 세션을 일시 중지, 재개 및 관리 코필로트 SDK합니다.

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

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

참고

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

세션을 만들 때 대화 기록, 코필로트 SDK 도구 상태 및 계획 컨텍스트를 유지 관리합니다. 기본적으로 이 상태는 메모리에 있으며 세션이 종료되면 사라집니다. 지속성을 사용하도록 설정하면 다시 시작, 컨테이너 마이그레이션 또는 다른 클라이언트 인스턴스 간에 세션을 다시 시작할 수 있습니다. 세션 상태 수명 주기의 시각적 개요는 리포지토리를github/copilot-sdk 참조하세요.

어떻게 되나요?
          **창조하다** | 
          `sessionId` 할당 |

| 진행 중 | 프롬프트 보내기, 도구 호출, 응답 | | 일시 중지된 | 디스크에 저장된 상태 | | 다시 시작 | 디스크에서 로드된 상태 |

빠른 시작: 다시 시작 가능한 세션 만들기

다시 시작할 수 있는 세션의 핵심은 여러분 고유의 sessionId을 (다른 SDK는 session_id을 사용할 수 있습니다) 제공하는 것입니다. 이 ID가 없으면 SDK는 임의 ID를 생성하고 세션은 나중에 다시 시작될 수 없습니다.

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();

// Create a session with a meaningful ID
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
});

// Do some work...
await session.sendAndWait({ prompt: "Analyze my codebase" });

// Session state is automatically persisted
// You can safely close the client

Python, Go 및 C#의 예제는 github/copilot-sdk 참조하세요.

세션 다시 열기

세션이 종료된 위치에서 세션을 다시 시작할 수 있습니다(분, 시간 또는 며칠 후). 클라이언트 간 세션 재개에 대한 시각적 개요는 리포지토리를github/copilot-sdk 참조하세요.

// Resume from a different client instance (or after restart)
const session = await client.resumeSession("user-123-task-456");

// Continue where you left off
await session.sendAndWait({ prompt: "What did we discuss earlier?" });

Python, Go 및 C#의 예제는 리포지토리를github/copilot-sdk 참조하세요.

다시 시작 옵션

세션을 다시 시작하면 필요에 따라 여러 설정을 다시 구성할 수 있습니다. 이 기능은 모델을 변경하거나, 도구 구성을 업데이트하거나, 동작을 수정해야 하는 경우에 유용합니다.

Option설명
model다시 시작된 세션의 모델 변경
systemMessage시스템 프롬프트 재정의 또는 확장
availableTools사용할 수 있는 도구 제한
excludedTools특정 도구 사용 안 함
providerBYOK 자격 증명 다시 제공(BYOK 세션에 필요)
reasoningEffort추론 노력 수준 조정
streaming스트리밍 응답 사용/사용 안 함
workingDirectory작업 디렉터리 변경
configDir구성 디렉터리를 재정의
mcpServersMCP 서버 구성
customAgents사용자 지정 에이전트 구성
agent이름으로 사용자 지정 에이전트 사전 선택
skillDirectories기술을 로드하기 위한 디렉터리
disabledSkills사용하지 않도록 설정하는 기술
infiniteSessions무한 세션 동작 구성

예: 이력서에서 모델 변경하기

// Resume with a different model
const session = await client.resumeSession("user-123-task-456", {
  model: "claude-sonnet-4",  // Switch to a different model
  reasoningEffort: "high",   // Increase reasoning effort
});

다시 시작된 세션과 함께 BYOK 사용

사용자 고유의 API 키를 사용하는 경우 다시 시작 시 공급자 구성을 다시 제공해야 합니다. API 키는 보안상의 이유로 디스크에 유지되지 않습니다.

// Original session with BYOK
const session = await client.createSession({
  sessionId: "user-123-task-456",
  model: "gpt-5.2-codex",
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,
    deploymentId: "my-gpt-deployment",
  },
});

// When resuming, you MUST re-provide the provider config
const resumed = await client.resumeSession("user-123-task-456", {
  provider: {
    type: "azure",
    endpoint: "https://my-resource.openai.azure.com",
    apiKey: process.env.AZURE_OPENAI_KEY,  // Required again
    deploymentId: "my-gpt-deployment",
  },
});

지속되는 항목

세션 상태는 다음으로 저장됩니다 ~/.copilot/session-state/{sessionId}/.

~/.copilot/session-state/
└── user-123-task-456/
    ├── checkpoints/           # Conversation history snapshots
    │   ├── 001.json          # Initial state
    │   ├── 002.json          # After first interaction
    │   └── ...               # Incremental checkpoints
    ├── plan.md               # Agent's planning state (if any)
    └── files/                # Session artifacts
        ├── analysis.md       # Files the agent created
        └── notes.txt         # Working documents
데이터보존되었습니까?Notes
대화 내용
          ✅ 예 | 전체 메시지 스레드 |

| 도구 호출 결과 | ✅ 예 | 컨텍스트용으로 캐시됨 | | 에이전트 계획 상태 | ✅ 예 | plan.md 파일 | | 세션 아티팩트 | ✅ 예 | files/ 디렉터리 안에 | | 공급자/API 키 | ❌ 아니요 | 보안: 다시 제공해야 합니다. | | 메모리 내 도구 상태 | ❌ 아니요 | 도구는 무상태여야 합니다. |

세션 ID 모범 사례

소유권 및 용도를 인코딩하는 세션 ID를 선택합니다. 이렇게 하면 감사 및 정리가 훨씬 쉬워집니다.

패턴예시사용 사례
          ❌
          `abc123`
         | 임의 ID | 감사하기 어렵고 소유권 정보 없음 |

| ✅ user-{userId}-{taskId} | user-alice-pr-review-42 | 다중 사용자 앱 | | ✅ tenant-{tenantId}-{workflow} | tenant-acme-onboarding | 다중 사용자 SaaS | | ✅ {userId}-{taskId}-{timestamp} | alice-deploy-1706932800 | 시간 기반 정리 작업 |

구조적 ID의 이점:

  • 감사가 용이합니다: "사용자 alice의 모든 세션 표시"
  • 정리하기 쉽습니다. "X보다 오래된 모든 세션 삭제"
  • 자연 액세스 제어: 세션 ID에서 사용자 ID 추출

예: 세션 ID 생성

function createSessionId(userId: string, taskType: string): string {
  const timestamp = Date.now();
  return `${userId}-${taskType}-${timestamp}`;
}

const sessionId = createSessionId("alice", "code-review");
// → "alice-code-review-1706932800000"

Python의 예제는 리포지토리를github/copilot-sdk 참조하세요.

세션 수명 주기 관리

활성 세션 나열

// List all sessions
const sessions = await client.listSessions();
console.log(`Found ${sessions.length} sessions`);

for (const session of sessions) {
  console.log(`- ${session.sessionId} (created: ${session.createdAt})`);
}

// Filter sessions by repository
const repoSessions = await client.listSessions({ repository: "owner/repo" });

이전 세션 정리

async function cleanupExpiredSessions(maxAgeMs: number) {
  const sessions = await client.listSessions();
  const now = Date.now();
  
  for (const session of sessions) {
    const age = now - new Date(session.createdAt).getTime();
    if (age > maxAgeMs) {
      await client.deleteSession(session.sessionId);
      console.log(`Deleted expired session: ${session.sessionId}`);
    }
  }
}

// Clean up sessions older than 24 hours
await cleanupExpiredSessions(24 * 60 * 60 * 1000);

세션에서 연결 끊기

작업이 완료되면 시간 제한을 기다리지 않고 세션에서 명시적으로 연결을 끊습니다. 이렇게 하면 메모리 내 리소스가 해제되지만 디스크에 세션 데이터가 유지되므로 나중에 세션을 다시 시작해도 됩니다.

try {
  // Do work...
  await session.sendAndWait({ prompt: "Complete the task" });
  
  // Task complete — release in-memory resources (session can be resumed later)
  await session.disconnect();
} catch (error) {
  // Clean up even on error
  await session.disconnect();
  throw error;
}

각 SDK는 관용적인 자동 정리 패턴을 제공합니다.

언어패턴예시
          **TypeScript** | `Symbol.asyncDispose` | `await using session = await client.createSession(config);` |

| 파이썬 | async with 컨텍스트 관리자 | async with await client.create_session(config) as session: | | C# | IAsyncDisposable | await using var session = await client.CreateSessionAsync(config); | | 이동 | defer | defer session.Disconnect() |

참고

          `destroy()` 는 대체 `disconnect()` 되었으며 이후 릴리스에서 제거될 예정입니다. 사용하는 `destroy()` 기존 코드는 계속 작동하지만 마이그레이션해야 합니다.

세션 영구 삭제

디스크에서 세션과 그 모든 데이터(대화 기록, 계획 상태, 아티팩트)를 영구적으로 제거하려면 deleteSession를 사용하십시오. 이는 되돌릴 수 없습니다. 삭제 후 세션을 다시 시작 하지 못할 수 있습니다 .

// Permanently remove session data
await client.deleteSession("user-123-task-456");

          `disconnect()` 는 메모리 내 리소스를 해제하지만 나중에 다시 시작하기 위해 세션 데이터를 디스크에 유지합니다. 
          `deleteSession()` 는 디스크의 파일을 포함하여 모든 항목을 영구적으로 제거합니다.

자동 정리: 유휴 시간 제한

SDK에는 기본 제공 30분 유휴 시간 제한이 있습니다. 활동이 없는 세션은 자동으로 정리됩니다. 유휴 시간 제한 흐름에 대한 시각적 개요는 리포지토리를github/copilot-sdk 참조하세요.

작업이 완료되는 시기를 알 수 있도록 유휴 이벤트를 수신 대기합니다.

session.on("session.idle", (event) => {
  console.log(`Session idle for ${event.idleDurationMs}ms`);
});

배포 패턴

최적 대상: 강력한 격리, 다중 테넌트 환경, Azure 동적 세션. 시각적 다이어그램은 리포지토리를github/copilot-sdk 참조하세요.

이점:

  • 완전한 격리
  • 간단한 보안
  • 간편한 크기 조정

패턴 2: 공유 CLI 서버(리소스 효율적)

적합 대상: 내부 도구, 신뢰할 수 있는 환경, 리소스 제한 설정. 시각적 다이어그램은 리포지토리를github/copilot-sdk 참조하세요.

요구 사항:

  • 사용자당 고유한 세션 ID
  • 애플리케이션 수준 액세스 제어
  • 작업 전 세션 ID 유효성 검사
// Application-level access control for shared CLI
async function resumeSessionWithAuth(
  client: CopilotClient,
  sessionId: string,
  currentUserId: string
): Promise<Session> {
  // Parse user from session ID
  const [sessionUserId] = sessionId.split("-");
  
  if (sessionUserId !== currentUserId) {
    throw new Error("Access denied: session belongs to another user");
  }
  
  return client.resumeSession(sessionId);
}

Azure 동적 세션

컨테이너를 다시 시작하거나 마이그레이션할 수 있는 서버리스/컨테이너 배포의 경우 세션 상태 디렉터리를 영구 스토리지에 탑재해야 합니다.

# Azure Container Instance example
containers:
  - name: copilot-agent
    image: my-agent:latest
    volumeMounts:
      - name: session-storage
        mountPath: /home/app/.copilot/session-state

volumes:
  - name: session-storage
    azureFile:
      shareName: copilot-sessions
      storageAccountName: myaccount

컨테이너 다시 시작 지속성의 시각적 다이어그램은 리포지토리를github/copilot-sdk 참조하세요.

장기 실행 워크플로에 대한 무한 세션

컨텍스트 제한을 초과할 수 있는 워크플로의 경우 자동 압축을 사용하여 무한 세션을 사용하도록 설정합니다.

const session = await client.createSession({
  sessionId: "long-workflow-123",
  infiniteSessions: {
    enabled: true,
    backgroundCompactionThreshold: 0.80,  // Start compaction at 80% context
    bufferExhaustionThreshold: 0.95,      // Block at 95% if needed
  },
});

참고

임계값은 절대 토큰 수가 아닌 컨텍스트 사용률(0.0–1.0)입니다.

제한 사항 및 고려 사항

Limitation설명완화 방법
          **BYOK 다시 인증** | API 키는 유지되지 않습니다. | 비밀 관리자에 키를 저장합니다. 이력서에 제공 |

| 쓰기 가능한 스토리지 | ~/.copilot/session-state/ 쓰기 가능해야 합니다. | 컨테이너에 영구 볼륨 탑재 | | 세션 잠금 없음 | 동일한 세션에 대한 동시 액세스가 정의되지 않았습니다. | 애플리케이션 레벨 잠금 또는 큐 시스템 구현 | | 도구 상태가 유지되지 않음 | 메모리 내 도구 상태가 손실됨 | 상태비저장이 되거나 자체 상태를 유지하도록 도구를 설계하십시오. |

동시 액세스 처리

SDK는 기본 제공 세션 잠금을 제공하지 않습니다. 여러 클라이언트가 동일한 세션에 액세스할 수 있는 경우 하이재킹을 방지하기 위해 각 세션이 잠겨 있는지 확인해야 합니다.

// Option 1: Application-level locking with Redis
import Redis from "ioredis";

const redis = new Redis();

async function withSessionLock<T>(
  sessionId: string,
  fn: () => Promise<T>
): Promise<T> {
  const lockKey = `session-lock:${sessionId}`;
  const acquired = await redis.set(lockKey, "locked", "NX", "EX", 300);
  
  if (!acquired) {
    throw new Error("Session is in use by another client");
  }
  
  try {
    return await fn();
  } finally {
    await redis.del(lockKey);
  }
}

// Usage
await withSessionLock("user-123-task-456", async () => {
  const session = await client.resumeSession("user-123-task-456");
  await session.sendAndWait({ prompt: "Continue the task" });
});

요약

특징사용 방법
          **다시 열 수 있는 세션 만들기** | 사용자 고유의 것을 제공하십시오 `sessionId` |

| 세션 다시 시작 | client.resumeSession(sessionId) | | BYOK 다시 시작 | provider 구성 다시 제공 | | 세션 목록 | client.listSessions(filter?) | | 활성 세션에서 연결 끊기 | session.disconnect()- 메모리 내 리소스를 해제합니다. 디스크의 세션 데이터는 재개를 위해 유지됩니다. | | 세션을 영구적으로 삭제 | client.deleteSession(sessionId)- 디스크에서 모든 세션 데이터를 영구적으로 제거합니다. 을(를) 다시 시작하지 못 함 | | 컨테이너화된 배포 | 영구 스토리지에 탑재 ~/.copilot/session-state/ |