跳到主要内容

轨迹回放界面

核对日期:2026-08-26。

1. 定义与边界

轨迹回放界面是给研发、运营、安全和业务 owner 看的 run 时间线:把 trace / span、工具卡片、审批、模型版本和最终产物按发生顺序展示,并支持只读复现。它不是用户聊天页的「历史消息」。

后端回放 runner、fixture、副作用隔离见 ../09-Agent工程化/回放与调试.md。指标与告警见 ../11-可观测性与运维/README.md。本文件只写控制台信息架构和权限。

不适用:

  • 在回放页对真实生产工具发写请求。
  • 把完整 Prompt、完整工具返回、原始 PII 默认展示给所有角色。
  • 用聊天 UI 冒充可观测性。

2. 为什么重要

Agent 事故很少能靠「用户说助手胡说了」定位:

  • 失败发生在中间工具、错误的参数或该审批却没停。
  • 没有时间线就无法对比「Prompt 版本变更前后」。
  • 线上评测样本要从失败 run 一键入库,而不是让人复制粘贴。
  • 前端如果只存 message 文本,trace 再完整也无法给业务同学用。

成熟度 L3 要求 100% trace,见 ../00-总览与学习路径/Agent能力成熟度模型.md。没有回放页,这条只是后端字段。

3. 核心机制

界面消费的是已经脱敏的 span 视图,不是直接查生产库。

4. 架构模式

4.1 页面结构

区域内容
页头run_idtrace_id、用户 / 会话、模型、Prompt 版本、状态、成本、耗时
时间线模型 span、工具 span、审批 span、错误、中断
详情当前 span 的输入摘要、输出摘要、schema 错误、重试次数
产物最终文本、UI part、人工修改
动作mock 回放、加入回归集、打开原始告警、复制脱敏链接

用户聊天页只保留叙事;控制台才展开参数和策略命中。

4.2 span 视图

interface ReplaySpanView {
spanId: string;
parentSpanId?: string;
kind: 'model' | 'tool' | 'approval' | 'retrieval' | 'guardrail';
name: string;
status: 'ok' | 'error' | 'cancelled';
startedAt: string;
endedAt: string;
summary: string;
redactedInputRef?: string;
redactedOutputRef?: string;
}

完整输入输出走「申请查看」而不是默认展开。这与最小权限一致,见 ../12-安全与治理/权限最小化.md

5. 工程实现

5.1 Vue 3 时间线

<script setup lang="ts">
interface ReplaySpanView {
spanId: string;
kind: 'model' | 'tool' | 'approval' | 'retrieval' | 'guardrail';
name: string;
status: 'ok' | 'error' | 'cancelled';
summary: string;
startedAt: string;
}

defineProps<{ spans: ReplaySpanView[]; activeId?: string }>();
defineEmits<{ select: [spanId: string] }>();
</script>

<template>
<ol class="replay-timeline">
<li v-for="span in spans" :key="span.spanId">
<button type="button" @click="$emit('select', span.spanId)">
<span>{{ span.kind }}</span>
<strong>{{ span.name }}</strong>
<span>{{ span.status }}</span>
<time>{{ span.startedAt }}</time>
<p>{{ span.summary }}</p>
</button>
</li>
</ol>
</template>

5.2 回放动作

type ReplayMode = 'mock_all' | 'model_rerun_tools_mocked' | 'readonly_inspect';

interface ReplayRequest {
runId: string;
mode: ReplayMode;
promptVersion?: string;
}

async function enqueueReplay(request: ReplayRequest): Promise<{ replayId: string }> {
const response = await fetch('/api/agent/replays', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
});
if (!response.ok) {
throw new Error(`replay_http_${response.status}`);
}
return (await response.json()) as { replayId: string };
}

UI 必须把 mode 展示成不可忽略的文案:「不会调用真实退款工具」。默认选 readonly_inspectmock_all

5.3 入库评测

失败 run 一键生成候选样本时,只提交 run_id、失败标签、期望终态;完整轨迹由评测服务从已脱敏 store 拉取。不要让浏览器上传原始工具返回。

../11-可观测性与运维/用户反馈闭环.md 对齐:用户点「答错了」应能跳到同一 trace_id

6. 生产实践

实践说明
角色视图客服只看摘要;研发可申请原始;安全看策略命中
深链/ops/runs/:runId 可从告警跳入
对比选择两个 Prompt 版本做工具序列 diff
时钟统一 UTC 存储,界面按时区显示
性能时间线虚拟列表;详情懒加载
只读库控制台查副本或只读账号,避免回放打满生产库

7. 常见反模式

反模式表现后果修正
聊天记录当 trace只有气泡看不到工具参数时间线 + span
回放即重跑生产按钮叫 Replay 却打真实 API重复副作用mock / 沙箱模式强制选择
全员可见原文Prompt 含客户数据泄露角色脱敏 + 申请查看
run_id 深链只能按时间翻日志事故沟通靠截图稳定 URL
前端自己算成本用估算 token和账单对不上用服务端 span 指标
把控制台当聊天修数据在回放页改订单绕过业务系统控制台只读,修复走工单

8. 评测方法

指标说明
Trace-to-UI Coverage有 trace 的 run 能在控制台打开的比例,目标 100%
Time to Span从告警点击到看到出错 span
Replay Safety回放产生的真实写操作次数,目标 0
Redaction Leak Samples界面快照中的 PII 红队检出
Eval Ingest Time从失败 run 到回归集候选的时间

9. 安全与治理

  • 控制台 SSO + 细粒度授权,按环境(prod / staging)隔离。
  • 查看原始 Prompt 记审计日志。
  • 分享链接默认短时、脱敏、不可公开索引。
  • 回放 worker 使用无写权限的工具凭证。
  • ../12-安全与治理/审计日志.md 使用同一 run_id 关联。

10. 权威资料