注意
Copilot SDK 当前处于 技术预览版. 功能和可用性可能会发生更改。
创建会话时, Copilot 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 存储库。
继续选项
恢复会话时,可以选择重新配置许多设置。 如果需要更改模型、更新工具配置或修改行为,这非常有用。
| 选项 | 说明 |
|---|---|
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
| 数据 | 持久化? | 备注 |
|---|---|---|
| 对话历史记录 |
✅ 是 | 完整消息线程 |
| 工具调用结果 |
✅ 是 | 为提供上下文而缓存 |
| 代理规划状态 |
✅ 是 |
plan.md 文件 |
| 会话产物 |
✅ 是 | 在 files/ 目录中 |
| 提供者/API 密钥 |
❌ 否 | 安全性:必须重新提供 |
| 内存中工具状态 |
❌ 否 | 工具应为无状态 |
会话 ID 最佳实践
选择能编码拥有者和用途的会话 ID。 这使得审核和清理更加容易。
| 图案 | 示例 | 用例 |
|---|
❌
`abc123`
| 随机 ID | 难以审核,没有所有权信息 |
|
✅
user-{userId}-{taskId}
| user-alice-pr-review-42 | 多用户应用 |
|
✅
tenant-{tenantId}-{workflow}
| tenant-acme-onboarding | 多租户软件即服务 |
|
✅
{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);` |
|
Python |
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),而不是绝对令牌计数。
限制和注意事项
| 限度 | 说明 | 缓解措施 |
|---|
**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/ 到永久性存储 |