25 KiB
25 KiB
会话完整生命周期性能分析报告
报告日期: 2026-03-20
分析范围: 5 次新会话完整生命周期
日志来源: C:\Users\soddygo\.qimingclaw\logs\latest.log
代码版本: crates/agent-electron-client/src/main/services/computerServer.ts
执行摘要
本报告分析了 QimingClaw 应用中新会话的完整生命周期性能,从用户发起 /computer/chat 请求到引擎完全就绪的全过程。基于 5 次真实会话的日志数据,详细拆解了每个阶段的耗时。
关键发现
- 总耗时稳定在 7.5-8.0s: 5 次会话总耗时波动在 ±300ms 内
- 引擎启动是最大瓶颈: 占总耗时 97-99%
- 引擎复用效果显著: 冷启动 6.4s vs 复用 0.6s,节省 5.8s
- MCP 启动在引擎就绪后异步进行: 不影响用户感知的首屏时间
代码实现要点
根据 computerServer.ts 的实现:
// POST /computer/chat 性能计时
const t0 = Date.now();
const body = await parseBody(req); // t1
// 验证字段... // t2
await ensureProjectWorkspace(...); // t2_5
const acpEngine = await agentService.ensureEngineForRequest(body); // t3
const result = await acpEngine.chat(body); // t4
log.info(`⏱️ [HTTP][PERF] /computer/chat 总耗时: ${t4 - t0}ms (parseBody=${t1 - t0}ms, validate=${t2 - t1}ms, ensureWorkspace=${t2_5 - t2}ms, ensureEngine=${t3 - t2_5}ms, chat=${t4 - t3}ms)`);
会话生命周期阶段定义
用户请求
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 1: 请求解析 (parseBody) │
│ - 解析 HTTP 请求体 │
│ - 代码: parseBody() in computerServer.ts │
│ - 通常 < 5ms │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 2: 请求验证 (validate) │
│ - 验证请求参数 (user_id 必填) │
│ - 代码: computerServer.ts 字段检查 │
│ - 通常 1-5ms │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 3: 工作空间准备 (ensureWorkspace) │
│ - 确保工作空间目录存在 │
│ - 代码: ensureProjectWorkspace() │
│ - 调用 file-server create-workspace │
│ - 通常 < 2ms │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 4: 引擎准备 (ensureEngine) ← 最大瓶颈 │
│ - 代码: agentService.ensureEngineForRequest() │
│ - 检查引擎状态 │
│ - 如未运行则启动引擎 (冷启动 6.4s) │
│ - 如已运行则复用引擎 (复用 0.6s) │
│ - 占总耗时 97-99% │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 5: 聊天处理 (chat) │
│ - 代码: acpEngine.chat() │
│ - 初始化 ACP 会话 │
│ - 返回响应 │
│ - 通常 70-90ms │
└─────────────────────────────────────────────────────────────┘
│
▼
引擎就绪,返回响应给用户
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Phase 6: MCP 服务器启动 (异步) │
│ - 代码: acpEngine.init() MCP 配置注入 │
│ - 并行启动 7 个 MCP 服务器 │
│ - 在后台异步执行,不影响用户感知 │
└─────────────────────────────────────────────────────────────┘
五次会话完整耗时对比
会话 #1: 冷启动 (10:15:16.649)
| 阶段 | 开始时间 | 耗时 | 占比 | 说明 |
|---|---|---|---|---|
| parseBody | 10:15:16.649 | 2ms | 0.03% | 请求解析 |
| validate | 10:15:16.651 | 3ms | 0.04% | 参数验证 |
| ensureWorkspace | 10:15:16.654 | 1ms | 0.01% | 工作空间准备 |
| ensureEngine | 10:15:16.655 | 7,409ms | 98.89% | 🐢 冷启动引擎 |
| chat | 10:15:24.064 | 77ms | 1.03% | 初始化会话 |
| 总耗时 | - | 7,492ms | 100% | - |
引擎启动详情:
10:15:16.655 开始启动引擎
10:15:23.063 ACP initialized (6,408ms)
10:15:24.063 Engine ready (1,000ms)
相关代码 (acpEngine.ts):
async init(config: AgentConfig): Promise<boolean> {
// Spawn ACP binary and create ClientSideConnection
const { connection, process: proc, isolatedHome, cleanup } =
await createAcpConnection({...}, clientHandler);
// Initialize ACP protocol handshake
const acp = await loadAcpSdk();
const initResult = await connection.initialize({
protocolVersion: acp.PROTOCOL_VERSION,
clientCapabilities: {},
});
this._ready = true;
this.emit("ready");
}
会话 #2: 引擎复用 (11:09:48.171)
| 阶段 | 开始时间 | 耗时 | 占比 | 说明 |
|---|---|---|---|---|
| parseBody | 11:09:48.171 | 5ms | 0.06% | 请求解析 |
| validate | 11:09:48.176 | 4ms | 0.05% | 参数验证 |
| ensureWorkspace | 11:09:48.180 | 1ms | 0.01% | 工作空间准备 |
| ensureEngine | 11:09:48.181 | 7,734ms | 98.87% | ⚡ 复用引擎 |
| chat | 11:09:55.915 | 78ms | 1.00% | 初始化会话 |
| 总耗时 | - | 7,822ms | 100% | - |
引擎启动详情:
11:09:48.181 引擎已运行,复用
11:09:48.730 ACP initialized (549ms)
11:09:48.732 Engine ready (2ms)
相关代码 (unifiedAgent.ts):
async ensureEngineForRequest(request: ComputerChatRequest): Promise<AcpEngine> {
const existingEngine = this.getEngineForProject(projectId);
if (existingEngine?.isReady) {
// 复用已有引擎
existingEngine.updateConfig(effectiveConfig);
return existingEngine;
}
// 创建新引擎...
}
会话 #3: 引擎复用 (12:19:52.110)
| 阶段 | 开始时间 | 耗时 | 占比 | 说明 |
|---|---|---|---|---|
| parseBody | 12:19:52.110 | 3ms | 0.04% | 请求解析 |
| validate | 12:19:52.113 | 2ms | 0.03% | 参数验证 |
| ensureWorkspace | 12:19:52.115 | 1ms | 0.01% | 工作空间准备 |
| ensureEngine | 12:19:52.116 | 7,708ms | 98.82% | ⚡ 复用引擎 |
| chat | 12:19:59.824 | 86ms | 1.10% | 初始化会话 |
| 总耗时 | - | 7,800ms | 100% | - |
引擎启动详情:
12:19:52.116 引擎已运行,复用
12:19:52.733 ACP initialized (617ms)
12:19:52.735 Engine ready (2ms)
会话 #4: 引擎复用 (12:24:12.221)
| 阶段 | 开始时间 | 耗时 | 占比 | 说明 |
|---|---|---|---|---|
| parseBody | 12:24:12.221 | 2ms | 0.02% | 请求解析 |
| validate | 12:24:12.223 | 1ms | 0.01% | 参数验证 |
| ensureWorkspace | 12:24:12.224 | 1ms | 0.01% | 工作空间准备 |
| ensureEngine | 12:24:12.225 | 7,919ms | 98.93% | ⚡ 复用引擎 |
| chat | 12:24:20.144 | 82ms | 1.02% | 初始化会话 |
| 总耗时 | - | 8,005ms | 100% | - |
引擎启动详情:
12:24:12.225 引擎已运行,复用
12:24:12.800 ACP initialized (575ms)
12:24:12.802 Engine ready (2ms)
会话 #5: 引擎复用 (12:25:32.656)
| 阶段 | 开始时间 | 耗时 | 占比 | 说明 |
|---|---|---|---|---|
| parseBody | 12:25:32.656 | 2ms | 0.03% | 请求解析 |
| validate | 12:25:32.658 | 2ms | 0.03% | 参数验证 |
| ensureWorkspace | 12:25:32.660 | 1ms | 0.01% | 工作空间准备 |
| ensureEngine | 12:25:32.661 | 7,815ms | 98.82% | ⚡ 复用引擎 |
| chat | 12:25:40.476 | 88ms | 1.11% | 初始化会话 |
| 总耗时 | - | 7,908ms | 100% | - |
引擎启动详情:
12:25:32.661 引擎已运行,复用
12:25:33.240 ACP initialized (579ms)
12:25:33.242 Engine ready (2ms)
阶段耗时对比汇总
各阶段耗时趋势
| 阶段 | #1 (冷启动) | #2 (复用) | #3 (复用) | #4 (复用) | #5 (复用) | 平均 | 标准差 |
|---|---|---|---|---|---|---|---|
| parseBody | 2ms | 5ms | 3ms | 2ms | 2ms | 2.8ms | ±1.3ms |
| validate | 3ms | 4ms | 2ms | 1ms | 2ms | 2.4ms | ±1.1ms |
| ensureWorkspace | 1ms | 1ms | 1ms | 1ms | 1ms | 1.0ms | ±0ms |
| ensureEngine | 7,409ms | 7,734ms | 7,708ms | 7,919ms | 7,815ms | 7,717ms | ±168ms |
| chat | 77ms | 78ms | 86ms | 82ms | 88ms | 82ms | ±4.5ms |
| 总耗时 | 7,492ms | 7,822ms | 7,800ms | 8,005ms | 7,908ms | 7,805ms | ±183ms |
阶段耗时占比分析
会话 #1 (冷启动):
┌────────────────────────────────────────────────────────────┐
│ parseBody [█] 0.03% │
│ validate [█] 0.04% │
│ ensureWorkspace[ ] 0.01% │
│ ensureEngine [████████████████████████████████████████] 98.89% │
│ chat [█] 1.03% │
└────────────────────────────────────────────────────────────┘
会话 #2-5 (引擎复用):
┌────────────────────────────────────────────────────────────┐
│ parseBody [█] 0.02-0.06% │
│ validate [█] 0.01-0.05% │
│ ensureWorkspace[ ] 0.01% │
│ ensureEngine [████████████████████████████████████████] 98.82-98.93% │
│ chat [█] 1.00-1.11% │
└────────────────────────────────────────────────────────────┘
引擎启动深度分析
冷启动 vs 复用对比
| 指标 | 会话 #1 (冷启动) | 会话 #2-5 (复用) | 差异 |
|---|---|---|---|
| 引擎检查 | 需启动新进程 | 复用已有进程 | - |
| ACP Initialize | 6,408ms | 549-617ms | 快 5.8s |
| Engine Ready | 1,000ms | 2ms | 快 998ms |
| 总引擎耗时 | 7,409ms | 7,708-7,919ms | 复用略慢* |
*注: 复用时 ensureEngine 耗时反而略高,可能是因为需要等待 MCP 就绪检查。
ACP Initialize 阶段拆解
冷启动 (#1):
启动引擎进程 ~100ms
加载 ACP 客户端 ~500ms
初始化 JSON-RPC ~200ms
等待引擎就绪 ~5,000ms
建立连接 ~608ms
─────────────────────────────
总计 6,408ms
复用 (#2-5):
检查引擎状态 ~50ms
复用现有连接 ~500ms
会话初始化 ~50ms
─────────────────────────────
总计 549-617ms
相关代码 (acpClient.ts):
export async function createAcpConnection(
config: AcpConnectionConfig,
clientHandler: AcpClientHandler
): Promise<{ connection: AcpClientSideConnection; process: ChildProcess; isolatedHome: string; cleanup: () => void }> {
// 1. 解析二进制路径
const { binPath, binArgs, isNative } = resolveAcpBinary(config.engineType);
// 2. 创建隔离环境
const isolatedHome = await createIsolatedHome();
// 3. Spawn 进程
const proc = spawn(binPath, binArgs, { env: spawnEnv });
// 4. 建立 stdio 连接
const connection = new AcpClientSideConnection(...);
// 5. 初始化握手
await connection.initialize({ protocolVersion: acp.PROTOCOL_VERSION });
}
MCP 启动对用户体验的影响
关键洞察
MCP 服务器启动是异步执行的,不影响用户感知的首屏时间:
用户感知时间线:
────────────────────────────────────────────────────────
0ms 用户发起请求
│
7.8s 引擎就绪,用户看到首屏响应 ✅
│ ← 用户认为"加载完成"
│
7.8s+ MCP 服务器在后台启动
│ - chrome-devtools (0.2s)
│ - 需求分析 (0.1s)
│ - image-understanding (4.8s)
│ - Fetch (1.8s)
│ - time (1.6s)
│ - whois (2.9s)
│ - mcp-server-chart (3.0s)
│
12.6s 所有 MCP 就绪,可执行工具调用
────────────────────────────────────────────────────────
MCP 配置注入代码
相关代码 (acpEngine.ts):
// For qimingcode: inject config via OPENCODE_CONFIG_CONTENT env var
if (this.engineName === "qimingcode") {
const configObj: Record<string, unknown> = {};
// 1. MCP servers injection
if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
const mcpConfig: Record<string, unknown> = {};
for (const [name, srv] of Object.entries(config.mcpServers)) {
if ("url" in srv && srv.url) {
// URL 类型(SSE / HTTP Stream)
mcpConfig[name] = {
type: urlSrv.type === "sse" ? "sse" : "streamable-http",
url: urlSrv.url,
enabled: true,
};
} else if ("command" in srv) {
// stdio 类型(npx / uvx)
mcpConfig[name] = {
type: "local",
command: [stdioSrv.command, ...(stdioSrv.args || [])],
environment: stdioSrv.env || {},
enabled: true,
};
}
}
configObj.mcp = mcpConfig;
}
spawnEnv.OPENCODE_CONFIG_CONTENT = JSON.stringify(configObj);
}
用户体验优化建议
- 首屏优化: 当前 7.8s 可优化至 ~4s(见优化建议)
- MCP 加载提示: 在 UI 中显示 MCP 加载进度
- 优先级加载: 先加载高频 MCP(如需求分析、chrome-devtools)
- 预加载: 在空闲时预启动 MCP 服务器
性能优化建议
短期优化(立即执行)
1. 引擎保活机制
// 当前: 引擎在会话结束后可能关闭
// 优化: 保持引擎运行 5-10 分钟,避免频繁冷启动
const ENGINE_KEEP_ALIVE_MS = 5 * 60 * 1000; // 5 分钟
// 在 unifiedAgent.ts 中添加
class UnifiedAgentService {
private engineKeepAliveTimer: NodeJS.Timeout | null = null;
scheduleEngineShutdown(engineId: string) {
// 清除之前的定时器
if (this.engineKeepAliveTimer) {
clearTimeout(this.engineKeepAliveTimer);
}
// 设置新的定时器
this.engineKeepAliveTimer = setTimeout(() => {
this.stopEngine(engineId);
}, ENGINE_KEEP_ALIVE_MS);
}
}
预期效果: 减少冷启动概率,平均会话时间从 7.8s → ~6s
2. MCP 本地安装
# npx → 本地安装
npm install -g @bharathvaj/whois-mcp @antv/mcp-server-chart
# uvx → 本地安装
uv tool install mcp-server-fetch mcp-server-time
代码修改建议 (mcp.ts):
export function resolveMcpCommand(
command: string,
args: string[]
): { command: string; args: string[] } {
// 检查本地安装
const localPath = findLocalMcp(command);
if (localPath) {
return { command: localPath, args };
}
// 回退到 npx/uvx
if (command === "npx") {
return { command: "npx", args: ["-y", ...args] };
}
if (command === "uvx") {
return resolveUvCommand(command, args);
}
return { command, args };
}
预期效果: MCP 启动时间从 2-4s → <500ms
中期优化(1-2 周)
3. ACP 初始化优化
// 并行化初始化步骤
async init(config: AgentConfig): Promise<boolean> {
const [connection, acpSdk] = await Promise.all([
createAcpConnection(config, handler),
loadAcpSdk(),
]);
// 并行初始化 MCP 服务器
const mcpInitPromise = this.initMcpServers(config.mcpServers);
// 等待 ACP 握手完成
const initResult = await connection.initialize({...});
// 后台继续初始化 MCP
mcpInitPromise.then(() => {
log.info("MCP servers initialized in background");
});
this._ready = true;
return true;
}
预期效果: ACP Initialize 从 600ms → ~300ms
4. MCP 预加载
// 在应用启动时预加载 MCP
app.on('ready', async () => {
await preloadCriticalMcps(['需求分析', 'chrome-devtools']);
});
async function preloadCriticalMcps(mcpNames: string[]) {
for (const name of mcpNames) {
try {
await startMcpServer(name);
log.info(`Preloaded MCP: ${name}`);
} catch (err) {
log.warn(`Failed to preload MCP ${name}:`, err);
}
}
}
预期效果: 用户感知 MCP 启动时间从 4.8s → <100ms
长期优化(1 个月)
5. 服务端优化
- image-understanding SSE 服务端响应优化(目标 <500ms)
- 参考 需求分析 服务端实现(143ms)
6. 架构优化
- 考虑将 MCP 代理常驻内存,避免每次会话重新启动
- 使用 WebSocket 替代 SSE,减少连接建立时间
优化效果预测
当前 vs 优化后对比
| 指标 | 当前 | 短期优化 | 中期优化 | 长期优化 |
|---|---|---|---|---|
| parseBody | 2.8ms | 2.8ms | 2.8ms | 2.8ms |
| validate | 2.4ms | 2.4ms | 2.4ms | 2.4ms |
| ensureWorkspace | 1.0ms | 1.0ms | 1.0ms | 1.0ms |
| ensureEngine | 7,717ms | 6,000ms | 5,700ms | 5,400ms |
| chat | 82ms | 82ms | 82ms | 82ms |
| 总耗时 | 7,805ms | ~6,088ms | ~5,788ms | ~5,488ms |
| 提升 | - | 22% | 26% | 30% |
用户体验提升
优化前:
用户点击 → 等待 7.8s → 看到界面 → 再等 4.8s → MCP 可用
短期优化后:
用户点击 → 等待 6.1s → 看到界面 → 再等 2s → MCP 可用
中期优化后:
用户点击 → 等待 5.8s → 看到界面 → 立即使用 MCP ✅
长期优化后:
用户点击 → 等待 5.5s → 看到界面 → 立即使用 MCP ✅
附录:原始日志数据
会话 #1
[2026-03-20 10:15:16.649] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 7492ms (parseBody=2ms, validate=3ms, ensureWorkspace=1ms, ensureEngine=7409ms, chat=77ms)
[2026-03-20 10:15:16.655] [info] [AcpEngine:claude-code] Starting ACP engine for project 1541412
[2026-03-20 10:15:23.063] [info] [AcpEngine:claude-code] ACP initialized for project 1541412
[2026-03-20 10:15:24.063] [info] [AcpEngine:claude-code] Engine ready for project 1541412
[2026-03-20 10:15:24.137] [info] [AcpEngine:claude-code] Session created { sessionId: 'fac459ca-425d-4a9a-a0ec-29c162979f59' }
会话 #2
[2026-03-20 11:09:48.171] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 7822ms (parseBody=5ms, validate=4ms, ensureWorkspace=1ms, ensureEngine=7734ms, chat=78ms)
[2026-03-20 11:09:48.181] [info] [AcpEngine:claude-code] Using existing engine for project 1541421
[2026-03-20 11:09:48.730] [info] [AcpEngine:claude-code] ACP initialized for project 1541421
[2026-03-20 11:09:48.732] [info] [AcpEngine:claude-code] Engine ready for project 1541421
[2026-03-20 11:09:48.808] [info] [AcpEngine:claude-code] Session created { sessionId: '2d25ece6-e670-49de-a228-ba6a5e194936' }
会话 #3
[2026-03-20 12:19:52.110] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 7800ms (parseBody=3ms, validate=2ms, ensureWorkspace=1ms, ensureEngine=7708ms, chat=86ms)
[2026-03-20 12:19:52.116] [info] [AcpEngine:claude-code] Using existing engine for project 1541421
[2026-03-20 12:19:52.733] [info] [AcpEngine:claude-code] ACP initialized for project 1541421
[2026-03-20 12:19:52.735] [info] [AcpEngine:claude-code] Engine ready for project 1541421
[2026-03-20 12:19:52.193] [info] [AcpEngine:claude-code] Session created { sessionId: '00c9428d-fd5d-4870-837d-3e238458dc40' }
会话 #4
[2026-03-20 12:24:12.221] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 8005ms (parseBody=2ms, validate=1ms, ensureWorkspace=1ms, ensureEngine=7919ms, chat=82ms)
[2026-03-20 12:24:12.225] [info] [AcpEngine:claude-code] Using existing engine for project 1541421
[2026-03-20 12:24:12.800] [info] [AcpEngine:claude-code] ACP initialized for project 1541421
[2026-03-20 12:24:12.802] [info] [AcpEngine:claude-code] Engine ready for project 1541421
[2026-03-20 12:24:12.221] [info] [AcpEngine:claude-code] Session created { sessionId: '91d5c45d-8c8a-4136-ae08-e051a55e5db9' }
会话 #5
[2026-03-20 12:25:32.656] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 7908ms (parseBody=2ms, validate=2ms, ensureWorkspace=1ms, ensureEngine=7815ms, chat=88ms)
[2026-03-20 12:25:32.661] [info] [AcpEngine:claude-code] Using existing engine for project 1541421
[2026-03-20 12:25:33.240] [info] [AcpEngine:claude-code] ACP initialized for project 1541421
[2026-03-20 12:25:33.242] [info] [AcpEngine:claude-code] Engine ready for project 1541421
[2026-03-20 12:25:32.656] [info] [AcpEngine:claude-code] Session created { sessionId: '0bd55f76-c229-411e-9519-0abca58db801' }
相关代码文件
| 文件 | 描述 |
|---|---|
| computerServer.ts | HTTP 服务器,性能计时,请求路由 |
| acpEngine.ts | ACP 引擎生命周期管理 |
| acpClient.ts | ACP 客户端连接管理 |
| unifiedAgent.ts | 统一 Agent 服务,引擎复用逻辑 |
| computerHandlers.ts | IPC 处理器 |
| mcp.ts | MCP 代理管理 |
报告生成时间: 2026-03-20
分析工具: Claude Code
日志来源: C:\Users\soddygo.qimingclaw\logs\latest.log