참고
코필로트 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 | 특정 도구 사용 안 함 |
provider | BYOK 자격 증명 다시 제공(BYOK 세션에 필요) |
reasoningEffort | 추론 노력 수준 조정 |
streaming | 스트리밍 응답 사용/사용 안 함 |
workingDirectory | 작업 디렉터리 변경 |
configDir | 구성 디렉터리를 재정의 |
mcpServers | MCP 서버 구성 |
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`);
});
배포 패턴
패턴 1: 사용자당 하나의 CLI 서버(권장)
최적 대상: 강력한 격리, 다중 테넌트 환경, 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/ |