版本:v2.0 更新日期:2026-02-03
本 API 提供 Agent 执行过程的实时可视化能力,包括:
核心概念:
http://localhost:8000application/json获取 Trace 列表(支持过滤)
GET /api/traces?status=running&limit=20
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| status | string | 否 | 过滤状态:running / completed / failed |
| mode | string | 否 | 过滤模式:call / agent |
| limit | int | 否 | 返回数量(默认 50,最大 100)|
响应示例:
{
"traces": [
{
"trace_id": "abc123",
"mode": "agent",
"task": "分析代码库结构",
"status": "running",
"total_steps": 15,
"total_tokens": 5000,
"total_cost": 0.05,
"created_at": "2026-02-03T15:30:00"
}
],
"total": 1
}
GET /api/traces/{trace_id}
响应示例:
{
"trace_id": "abc123",
"mode": "agent",
"task": "分析代码库结构",
"status": "running",
"total_steps": 15,
"total_tokens": 5000,
"total_cost": 0.05,
"total_duration_ms": 12345,
"last_sequence": 15,
"last_event_id": 15,
"created_at": "2026-02-03T15:30:00",
"completed_at": null
}
获取 Trace 的完整 Step 树(适合小型 Trace,<100 个 Step)
GET /api/traces/{trace_id}/tree?view=compact&max_depth=10
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| view | string | compact | compact - 精简视图 / full - 完整视图 |
| max_depth | int | 无限 | 最大树深度 |
响应示例:
{
"trace_id": "abc123",
"root_steps": [
{
"step_id": "step-001",
"step_type": "thought",
"status": "completed",
"sequence": 1,
"parent_id": null,
"description": "分析项目结构...",
"has_children": true,
"children_count": 2,
"duration_ms": 1234,
"tokens": 500,
"cost": 0.005,
"created_at": "2026-02-03T15:30:01",
"data": {
"content": "让我先看看项目的目录结构...",
"model": "claude-sonnet-4.5"
},
"children": [
{
"step_id": "step-002",
"step_type": "action",
"status": "completed",
"parent_id": "step-001",
"description": "glob_files(**/*.py)",
"data": {
"tool_name": "glob_files",
"arguments": {"pattern": "**/*.py"}
},
"children": [
{
"step_id": "step-003",
"step_type": "result",
"status": "completed",
"parent_id": "step-002",
"data": {
"tool_name": "glob_files",
"output": ["src/main.py", "src/utils.py"]
}
}
]
}
]
}
]
}
注意:
children 字段包含嵌套的子节点(递归结构)compact 视图:data 中的大字段(如 messages)会被省略full 视图:返回所有字段(数据量可能很大)适用于大型 Trace(>100 Step),按需加载子树
GET /api/traces/{trace_id}/node/{step_id}?expand=true&max_depth=2
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| expand | bool | false | 是否展开子节点 |
| max_depth | int | 1 | 展开深度 |
| view | string | compact | 视图类型 |
响应:与 /tree 格式相同,但只返回指定节点及其子树。
const ws = new WebSocket(
'ws://localhost:8000/api/traces/{trace_id}/watch?since_event_id=0'
)
查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| since_event_id | int | 0 | 从哪个事件 ID 开始0 = 补发所有历史>0 = 只补发指定 ID 之后的 |
{
"event": "connected",
"trace_id": "abc123",
"current_event_id": 15
}
说明:连接建立后的第一条消息,包含当前最新的 event_id
前端处理:
if (data.event === 'connected') {
// 保存 event_id 用于断线重连
localStorage.setItem('last_event_id', data.current_event_id)
}
{
"event": "step_added",
"event_id": 16,
"ts": "2026-02-03T15:30:10.123456",
"step": {
"step_id": "step-016",
"step_type": "action",
"status": "completed",
"sequence": 16,
"parent_id": "step-001",
"description": "read_file(config.yaml)",
"has_children": false,
"children_count": 0,
"duration_ms": 50,
"data": {
"tool_name": "read_file",
"arguments": {"file_path": "config.yaml"}
}
}
}
前端处理:
if (data.event === 'step_added') {
// 添加到树结构
addStepToTree(data.step)
// 更新 event_id
localStorage.setItem('last_event_id', data.event_id)
}
{
"event": "step_updated",
"event_id": 17,
"ts": "2026-02-03T15:30:15.123456",
"step_id": "step-016",
"patch": {
"status": "completed",
"duration_ms": 1234
}
}
说明:patch 是增量更新(只包含变化的字段)
前端处理:
if (data.event === 'step_updated') {
const step = findStepById(data.step_id)
Object.assign(step, data.patch)
updateUI()
}
{
"event": "trace_completed",
"event_id": 18,
"ts": "2026-02-03T15:35:00.123456",
"trace_id": "abc123",
"total_steps": 18
}
前端处理:
if (data.event === 'trace_completed') {
console.log('Task completed!')
ws.close()
}
{
"event": "error",
"message": "Too many missed events (150), please reload full tree via REST API"
}
说明:
场景:网络断开后重新连接,不丢失中间的更新
实现方式:
let lastEventId = 0
// 初次连接
const ws = new WebSocket(
`ws://localhost:8000/api/traces/abc123/watch?since_event_id=0`
)
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
// 保存最新 event_id
if (data.event_id) {
lastEventId = data.event_id
localStorage.setItem('trace_abc123_event_id', lastEventId)
}
}
ws.onclose = () => {
// 3 秒后重连
setTimeout(() => {
// 从上次的 event_id 继续
const ws2 = new WebSocket(
`ws://localhost:8000/api/traces/abc123/watch?since_event_id=${lastEventId}`
)
// 服务器会补发 lastEventId 之后的所有事件
}, 3000)
}
注意:
event_id 和 ts 字段since_event_id,服务器自动补发缺失的事件(最多 100 条)保持连接活跃,检测僵尸连接
// 每 30 秒发送心跳
const heartbeat = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send('ping')
}
}, 30000)
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.event === 'pong') {
console.log('Connection alive')
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
trace_id |
string | 唯一 ID |
mode |
string | call - 单次调用 / agent - Agent 模式 |
task |
string | 任务描述(Agent 模式) |
status |
string | running / completed / failed |
total_steps |
int | Step 总数 |
total_tokens |
int | Token 总消耗 |
total_cost |
float | 成本总和 |
total_duration_ms |
int | 总耗时(毫秒) |
last_sequence |
int | 最新 Step 的 sequence |
last_event_id |
int | 最新事件 ID |
created_at |
string | 创建时间(ISO 8601) |
completed_at |
string | null | 完成时间 |
| 字段 | 类型 | 说明 |
|---|---|---|
step_id |
string | 唯一 ID |
trace_id |
string | 所属 Trace ID |
step_type |
string | 步骤类型(见下表) |
status |
string | 状态(见下表) |
sequence |
int | 在 Trace 中的顺序(递增) |
parent_id |
string | null | 父节点 ID |
description |
string | 简短描述 |
summary |
string | null | 总结(仅 evaluation 类型) |
has_children |
bool | 是否有子节点 |
children_count |
int | 子节点数量 |
duration_ms |
int | null | 耗时(毫秒) |
tokens |
int | null | Token 消耗 |
cost |
float | null | 成本 |
created_at |
string | 创建时间 |
data |
object | 类型相关的详细数据 |
| 类型 | 说明 | 来源 |
|---|---|---|
goal |
目标/计划 | LLM |
thought |
思考/分析 | LLM |
evaluation |
评估总结 | LLM |
response |
最终回复 | LLM |
action |
工具调用 | System |
result |
工具结果 | System |
memory_read |
读取记忆 | System |
memory_write |
写入记忆 | System |
| 状态 | 说明 |
|---|---|
planned |
计划中(未执行) |
in_progress |
执行中 |
awaiting_approval |
等待用户确认 |
completed |
已完成 |
failed |
失败 |
skipped |
跳过 |
thought / response:
{
"model": "claude-sonnet-4.5",
"content": "让我先分析...",
"messages": [...], // full 视图才有
"tool_calls": [...] // 如果有工具调用
}
action:
{
"tool_name": "read_file",
"arguments": {
"file_path": "config.yaml"
}
}
result:
{
"tool_name": "read_file",
"output": "file content...",
"error": null
}
memory_read:
{
"experiences_count": 5,
"skills_count": 3
}
适用于:实时监控进行中的任务,Step 数量 < 100
// 只用 WebSocket,自动获取历史
const ws = new WebSocket(
'ws://localhost:8000/api/traces/abc123/watch?since_event_id=0'
)
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.event === 'step_added') {
// 历史 + 新增的 Step 都会收到
addStepToTree(data.step)
}
}
优点:代码简单 缺点:超过 100 个 Step 会失败
适用于:查看历史任务,或 Step 数量 > 100
// 1. 先用 REST API 获取完整树
const response = await fetch(
`/api/traces/${traceId}/tree?view=compact`
)
const treeData = await response.json()
renderTree(treeData.root_steps)
// 2. 连接 WebSocket 监听增量更新
const ws = new WebSocket(
`ws://localhost:8000/api/traces/${traceId}/watch?since_event_id=0`
)
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.event === 'step_added') {
addStepToTree(data.step) // 只处理新增的
}
}
优点:可靠,支持大型 Trace 缺点:略复杂
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 404 | Trace/Step 不存在 |
| 400 | 参数错误 |
| 500 | 服务器错误 |
ws.onerror = (error) => {
console.error('WebSocket error:', error)
// 重连
}
ws.onclose = (event) => {
console.log('Connection closed:', event.code, event.reason)
// 自动重连
}
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.event_id) {
localStorage.setItem(
`trace_${traceId}_event_id`,
data.event_id
)
}
}
function connectWebSocket(traceId) {
const lastEventId = localStorage.getItem(`trace_${traceId}_event_id`) || 0
const ws = new WebSocket(
`ws://localhost:8000/api/traces/${traceId}/watch?since_event_id=${lastEventId}`
)
ws.onclose = () => {
setTimeout(() => connectWebSocket(traceId), 3000)
}
return ws
}
// ✅ 推荐
const response = await fetch(`/api/traces/${id}/tree?view=compact`)
// ❌ 避免(数据量可能很大)
const response = await fetch(`/api/traces/${id}/tree?view=full`)
// 初次只加载第一层
const tree = await fetch(
`/api/traces/${id}/tree?max_depth=1`
).then(r => r.json())
// 用户点击展开时,懒加载子树
async function onExpand(stepId) {
const node = await fetch(
`/api/traces/${id}/node/${stepId}?expand=true&max_depth=1`
).then(r => r.json())
appendChildren(stepId, node.children)
}
如有问题请提 Issue:https://github.com/anthropics/agent/issues