---
title: Agent Snapshot
description: 捕获和回放 Agent 状态进行调试和测试
---

# Agent Snapshot

Agent Snapshot 是一个强大的功能，允许你在运行时捕获 Agent 的完整状态并稍后回放。这对于调试、测试和确保确定性 Agent 行为至关重要。

## 什么是 Agent Snapshot？

Agent Snapshot 捕获：
- 完整的对话历史
- 当前上下文状态
- 工具调用历史和结果
- Agent 配置
- 环境状态

## 创建快照

### 自动快照

启用自动快照创建：

```typescript
import { Agent } from '@tarko/agent';

const agent = new Agent({
  ...config,
  snapshot: {
    enabled: true,
    interval: 'on_tool_call', // 或 'on_message', 'manual'
    storage: {
      type: 'file',
      path: './snapshots'
    }
  }
});
```

### 手动快照

程序化创建快照：

```typescript
// 创建快照
const snapshot = await agent.createSnapshot({
  name: 'debug-session-1',
  description: '问题工具调用之前'
});

console.log('快照已创建:', snapshot.id);
```

## 快照结构

快照包含：

```typescript
interface AgentSnapshot {
  id: string;
  timestamp: string;
  name?: string;
  description?: string;
  
  // Agent 状态
  context: {
    messages: Message[];
    length: number;
    metadata: Record<string, any>;
  };
  
  // 配置
  config: AgentConfig;
  
  // 环境
  environment: {
    variables: Record<string, string>;
    workingDirectory: string;
    platform: string;
  };
  
  // 工具状态
  tools: {
    available: ToolDefinition[];
    history: ToolCall[];
  };
}
```

## 回放快照

### 加载和回放

```typescript
import { Agent, loadSnapshot } from '@tarko/agent';

// 加载快照
const snapshot = await loadSnapshot('./snapshots/debug-session-1.json');

// 从快照创建 Agent
const agent = Agent.fromSnapshot(snapshot);

// 从快照状态继续对话
const response = await agent.chat('接下来发生了什么？');
```

### 带修改的回放

```typescript
// 加载快照并修改配置
const snapshot = await loadSnapshot('./snapshots/debug-session-1.json');

// 覆盖测试的模型设置
snapshot.config.model.temperature = 0.1;
snapshot.config.model.model = 'gpt-4';

const agent = Agent.fromSnapshot(snapshot);
```

## 使用快照进行测试

### 基于快照的测试

```typescript
import { test, expect } from '@jest/globals';
import { Agent, loadSnapshot } from '@tarko/agent';

test('应该正确处理文件操作', async () => {
  // 加载预录制的快照
  const snapshot = await loadSnapshot('./test-snapshots/file-ops.json');
  const agent = Agent.fromSnapshot(snapshot);
  
  // 回放场景
  const response = await agent.chat('创建一个名为 test.txt 的新文件');
  
  // 断言预期行为
  expect(response).toContain('文件创建成功');
});
```

### 回归测试

```typescript
// 捕获基线行为
const baselineSnapshot = await agent.createSnapshot({
  name: 'baseline-v1.0'
});

// 稍后，针对基线测试
const currentSnapshot = await agent.createSnapshot({
  name: 'current-test'
});

// 比较快照
const diff = compareSnapshots(baselineSnapshot, currentSnapshot);
if (diff.hasChanges) {
  console.warn('行为已更改:', diff.changes);
}
```

## 快照管理

### 列出快照

```typescript
const snapshots = await agent.listSnapshots();
snapshots.forEach(snapshot => {
  console.log(`${snapshot.name} (${snapshot.timestamp})`);
});
```

### 删除快照

```typescript
// 删除特定快照
await agent.deleteSnapshot('debug-session-1');

// 清理旧快照
await agent.cleanupSnapshots({
  olderThan: '7d',
  keepLatest: 10
});
```

## 最佳实践

### 何时创建快照

- 复杂操作之前
- 成功工具调用之后
- 调试问题时
- 进行回归测试时

### 命名约定

```typescript
// 使用描述性名称
const snapshot = await agent.createSnapshot({
  name: 'before-file-upload-v2.1',
  description: '实施新文件上传逻辑之前的状态'
});
```

### 存储考虑

```typescript
// 配置适当的存储
const agent = new Agent({
  snapshot: {
    storage: {
      type: 'redis', // 用于生产
      url: 'redis://localhost:6379',
      ttl: 86400 // 24 小时
    },
    compression: true, // 减少存储大小
    maxSnapshots: 100  // 限制存储使用
  }
});
```

## 使用快照调试

### 捕获问题状态

```typescript
agent.on('error', async (error) => {
  // 错误时自动创建快照
  const snapshot = await agent.createSnapshot({
    name: `error-${Date.now()}`,
    description: `错误: ${error.message}`
  });
  
  console.log('错误快照已保存:', snapshot.id);
});
```

### 逐步调试

```typescript
// 加载问题快照
const snapshot = await loadSnapshot('./snapshots/error-123.json');
const agent = Agent.fromSnapshot(snapshot);

// 启用详细日志
agent.setLogLevel('debug');

// 带调试回放
const response = await agent.chat('从这里继续');
```

## 真实调试案例

### Model Provider 兼容性问题

Agent Snapshot 在调试 Model Provider 兼容性问题时特别有用。以下是 Agent TARS 开发中的真实案例：

**问题**：AWS Bedrock 兼容性错误

```
[Stream] Error in agent loop execution: Error: 400 operation error Bedrock Runtime: ConverseStream, https response error StatusCode: 400, RequestID: 31427985-ebcf-4321-af29-d498c474a20f, ValidationException: The json schema definition at toolConfig.tools.13.toolSpec.inputSchema is invalid. Fix the following errors and try again: $.properties: null found, object expected
```

**解决过程**：

1. **在 Agent TARS 中启用快照**：

```typescript
// agent-tars.config.ts
import { resolve } from 'node:path';
import { defineConfig } from '@agent-tars/interface';

export default defineConfig({
  // ...
  snapshot: {
    enable: true,
    storageDirectory: resolve(__dirname, 'snapshots')
  }
});
```

2. **分析快照结构**：

快照生成详细的目录结构：

```bash
snapshots
└── c3fMyx8jePXnhjYvHOhKr           # Session id
    ├── event-stream.jsonl          # Final event stream
    ├── loop-1                      # Loop 1
    │   ├── event-stream.jsonl
    │   ├── llm-request.jsonl
    │   ├── llm-response.jsonl
    │   └── tool-calls.jsonl
    ├── loop-2                      # Loop 2
    │   ├── event-stream.jsonl
    │   ├── llm-request.jsonl
    │   ├── llm-response.jsonl
    │   └── tool-calls.jsonl
    └── loop-3                      # Loop 3
        ├── event-stream.jsonl
        ├── llm-request.jsonl
        └── llm-response.jsonl
```

3. **根因分析**：

通过检查 `loop-1/llm-request.jsonl`，我们发现 AWS Bedrock 要求 JSON Schema 中当 `type` 为 "object" 时必须包含 `properties` 字段，即使为空。

4. **修复实现**：

```diff
"type": "function",
"function": {
    "name": "browser_get_clickable_elements",
    "description": "[browser] Get the clickable or hoverable or selectable elements on the current page, don't call this tool multiple times",
    "parameters": {
        "type": "object",
+       "properties": {}
    }
}
```

这个真实案例展示了 Agent Snapshot 如何实现 "白盒" 调试，使复杂的 Agent 系统更加透明和可调试。完整修复请参见 [bytedance/UI-TARS-desktop#770](https://github.com/bytedance/UI-TARS-desktop/pull/770)。
