仪表盘与轨迹
这页写给管理员:员工的会话轨迹传到企业后端之后,怎么在「仪表盘」和「轨迹」两页里看、筛、标注、导出。
轨迹是一次会话的完整记录:每次模型请求和响应、每个工具调用及结果、最终状态、token 和成本。员工端怎么采集、落盘了什么、怎么打开上传,写在轨迹采集与可观测,这页不重复。
如果你只想知道「谁花了多少钱」,看成本,不用读这页。
轨迹是弱归因
上传接口用的是全员共享的口令 UPLOAD_TOKEN(请求头 X-Upload-Token),不是设备凭据。轨迹上的 user_id、device_id 都是客户端自己填的,服务端不校验。拿到口令的人可以用任意身份上传。
所以轨迹适合看「会话里发生了什么」,不适合按人统计或追责。按人看用量以成本页为准,按人看行为以审计页为准,这两处的身份取自设备凭据。
联动:数据从哪来、什么时候到
仪表盘和轨迹页不向员工端下发任何东西。这里写员工那边发生了什么、管理台什么时候能看到。
| 员工端发生了什么 | 管理台什么时候看到 | 上传失败时 | 员工看到什么 |
|---|---|---|---|
没配 trace.upload.token | 看不到。默认就是这样 | —— | 无 |
| 配了上传,会话结束 | 几秒内出现在轨迹列表 | 401:口令不对,不重试;其他错误指数退避重试,最多 5 次,之后进本机重试队列 | 无 |
| 下次启动 | 补传配置上传之后、还没传成功的会话,每次最多 20 个 | 继续留在队列 | 无 |
会话中执行 /debug | 立即上传当前会话快照 | 同上 | 本地路径和上传结果 |
员工开了 essential-traffic 或 --trace-upload-disabled | 看不到这些会话 | —— | 无 |
- 默认不上传。
trace.upload里要同时有url和token。url缺省取backend.url,所以接了企业后端的员工只需要再配 token。打开方式见轨迹采集与可观测;全员下发地址见团队默认配置分发。不要把 token 写进团队默认配置,理由在可观测页的 warning 里。 - 一个会话一条。 按
session_id去重。同一会话的session.traj再传一次返回 409,客户端当作「已存在」跳过,不会覆盖旧记录。 - 只上传配置之后的会话。 配置上传之前的历史,要员工自己跑
sid-code --upload-traces --include-history。
出处:packages/core/src/trace/uploader.ts;agent-backend: backend/app/modules/trajectory/router/upload.py、backend/app/core/auth/data_plane.py。
谁能看
仪表盘和轨迹页的接口接受两种凭据:
| 凭据 | 结果 |
|---|---|
| 管理台登录会话,且是管理员 | 通过 |
| 管理台登录会话,但不是管理员(飞书登录的普通成员) | 403 |
HTTP Basic(AUTH_USERNAME / AUTH_PASSWORD) | 通过。脚本和 curl 用这条 |
| 都没有,或口令不对 | 401 |
导出接口也一样。也就是说,拿到 Basic 口令就能读写全部轨迹。部署时怎么设这对口令见部署与配置。
仪表盘
左侧菜单「仪表盘」,页面标题「统计仪表盘」。右上角两个筛选:
| 筛选 | 取值 |
|---|---|
| 粒度 | 「按天」/「按周」。只影响两张趋势图 |
| 来源 | 留空为「全部来源」;可选 Claude Code(claude-code)、Codex(codex)、Gemini CLI(gemini-cli)、sid-code(sid-code)。影响整页 |
仪表盘统计的是全部历史,没有时间范围筛选。
四张卡片
| 卡片 | 含义 |
|---|---|
| 总轨迹数 | 轨迹条数;下方小字是平均步骤 |
| 总 Token | token 合计;下方小字是成功率 |
| 总成本 | 轨迹上记录的成本合计;下方小字是单条平均。口径见下文成本口径 |
| 评审分布 | 质量状态为「通过」的条数;下方小字是未评审条数 |
成功率的算法:exit_status 为 end_turn(正常完成)的会话数 ÷(全部会话 − terminal_closed 会话)。terminal_closed 是「开了就关、一轮都没跑」的空会话,不算成功也不算失败。
图表
| 图表 | 含义 |
|---|---|
| Token 消耗趋势 | 每天或每周的 token 合计 |
| 工具来源分布 | 各来源的轨迹条数占比 |
| 工具使用频率 | 调用次数最多的 8 个工具 |
| 模型使用分布 | 轨迹条数最多的 6 个模型 |
| 成本趋势 | 每天或每周的成本,按来源堆叠 |
| 最近轨迹 | 最新 10 条,点一行打开详情 |
轨迹列表
左侧菜单「轨迹」,页面标题「轨迹列表」。从「设备」页某一行点「轨迹」跳过来时,地址带 ?device_id=,标题下方显示这台设备的 ID。
筛选
| 筛选 | 说明 |
|---|---|
| 搜索用户输入... | 只搜首条输入,包含即命中。不搜后续对话和工具结果 |
| 工具来源 | Claude Code / Codex / Gemini CLI / sid-code,值同仪表盘 |
| 退出状态 | 见下表 |
| 质量状态 | 未评审(unreviewed)/ 通过(approved)/ 拒绝(rejected) |
| 任务类型 | Bug Fix(bug_fix)/ Feature(feature)/ Refactor(refactor)/ Explain(explain)/ Other(other) |
| 项目名 | 精确匹配,不是模糊搜索 |
| 日期范围 | 按会话开始时间 |
列表没有按人筛选,也不显示 user_id 列。这是有意的:身份是自报的,见页首的 warning。
「退出状态」筛的是会话的结果(exit_status)。下拉里显示为「中文名(取值)」:
| 取值 | 中文名 | 列表图标颜色 |
|---|---|---|
end_turn | 正常完成 | 绿 |
tool_use | 停在工具调用 | 黄 |
user_interrupt | 用户中断 | 黄 |
max_turns | 轮次用尽 | 黄 |
budget_exceeded | 预算停止 | 灰 |
abort | 强制终止 | 红 |
error | 运行错误 | 红 |
clear | /clear 清空 | 灰 |
terminal_closed | 未提问即关闭 | 灰 |
incomplete | 未收尾 | 灰 |
unknown | unknown | 灰 |
不在表里的值按原文显示。
会话怎么结束的是另一个字段 end_source,不能筛,只在列表「状态」列的悬停提示和详情页「结束方式」里显示:
| 取值 | 显示 |
|---|---|
exit | 正常退出 |
abort | 中断退出 |
terminal_closed | 关闭终端 |
error | 异常退出 |
clear | /clear |
other | 其他 |
两个字段不要混。员工空闲时直接关终端,end_source 是 terminal_closed,exit_status 按最后一轮推断,多半是 end_turn,照样算成功。只有一轮都没跑就关掉,exit_status 才是 terminal_closed。
出处:agent-backend: frontend/src/modules/trajectory/exitStatus.ts、backend/app/modules/trajectory/service/stats_service.py。
列表的列
时间、来源、模型、首条输入、步骤、Token、成本、耗时、状态(退出状态图标)、质量(质量状态和星级,没评过显示「未评分」)、操作(「查看」)。时间、步骤、Token、成本可以点列头排序。
批量标注
勾选若干行,点「批量标注」。
填写:
字段 说明 质量状态 必填 任务类型 选填,留空不改 项目名 选填,留空不改 标签 选填,留空不改。填了会整体替换原有标签,不是追加 确定,提示「已更新 N 条轨迹」。
批量标注改不了星级评分,评分只能在详情页一条条打。
导出 .traj
勾选若干行,点「导出 .traj」,下载一个 zip:每条轨迹一个 <session_id>.traj,外加一份 manifest.json,列出来源、模型、开始时间、步骤、token、成本、质量状态。
适合交给别人复现、用 trace-digest 离线分析,或换一台企业后端重新导入。zip 里只有 session.traj,不含 raw.jsonl 和 events.jsonl。
导出 SFT
点「导出 SFT」,弹窗标题「导出 SFT 训练数据」。勾选了行就导出勾选的;没勾选就按当前筛选条件导出全部匹配的轨迹。
| 导出格式 | 每行长什么样 | 适合 |
|---|---|---|
| messages(推荐) | messages 数组(system / user / assistant / tool,带 tool_calls)+ tools + metadata | 直接喂给支持 OpenAI 风格多轮对话和工具调用的微调框架 |
| tool 文本 | prompt + response,response 是按 [USER]、[SYSTEM] 等标记拼成的纯文本 | 只接受 prompt / completion 两列的训练脚本 |
| XML 文本 | prompt + response,response 是 <conversation><message role="..."> 结构 | 用 XML 标记区分角色和工具调用的训练格式 |
「保留 thinking」默认「否」。选「是」时,模型的思考内容拼在每条 assistant 内容前面。
下载的文件是 traj-sft-<格式>-<时间>.jsonl,一行一条轨迹。没有任何 assistant 回复的轨迹会被跳过;一条都导不出时提示「SFT 导出失败」(服务端 404)。
从设备页跳进来时,SFT 导出不按设备过滤
地址里的 ?device_id= 只作用于列表显示。不勾选直接点「导出 SFT」,导出的是全部设备里符合其他筛选条件的轨迹。只想导这台设备的,先在列表里勾选。
轨迹详情
列表点「查看」进入。顶部是 session_id、步骤数、工具数和「下载 .traj」按钮;下面是元数据卡片(来源、模型、时间、状态、结束方式、API 调用、Token、成本、工具、任务类型、项目名、工作目录、首条输入、Thinking、子代理有无)。
四个视图
| 标签页 | 内容 | 什么时候用 |
|---|---|---|
| 阅读视图 | 按回合整理的对话,工具调用折叠显示。可以开关「系统提示」「Thinking」「展开工具结果」 | 默认打开。想知道员工问了什么、Agent 怎么一步步做的 |
| History 视图 | 原始的对话历史,按消息排列 | 阅读视图的整理结果看着不对,想看未经整理的消息顺序 |
| 调试视图 | info、trajectory、history 三段 JSON,可折叠 | 排查采集或解析问题,要看具体字段的原始值 |
| 原始 JSON | 整个 .traj 文件的原文 | 要复制原文,或核对某个字段到底有没有上传 |
质量标注
详情页「质量标注」卡片:
| 操作 | 说明 |
|---|---|
| 质量评分 | 1 到 5 星,点一下立即保存,提示「评分已保存」 |
| 状态 | 未评审 / 通过 / 拒绝,改了立即保存 |
| 任务类型、项目名、质量备注 | 改完点「保存备注与分类」。任务类型没选时按 Other 保存 |
| 标签管理 | 输入一个或多个标签,点「保存标签」 |
标注只存在企业后端,不回传员工端,员工看不到。
成本口径
轨迹页的成本和成本页不是一份数
仪表盘和轨迹页上的成本来自 .traj 文件里的 total_cost_usd:只算上传了的会话,身份是自报的,没有设备归属。
成本页的数字来自用量账本,按设备凭据归属,没开上传的员工也会计入。两边对不上时以成本页为准。轨迹页的成本只用来比较会话之间谁贵谁便宜。
隐私:管理员能看到全部内容
轨迹里有员工发给模型的代码原文和完整对话。客户端上传前只脱敏凭证,不处理代码;working_directory 通常带着员工的用户名。能登录管理台的管理员,和持有 Basic 口令的人,都能看到全部内容并导出。
上线前建议:
- 提前告知员工哪些会话会上传、谁能看到,以及怎么在单次会话里关掉(
--trace-upload-disabled); - 需要的话让员工打开
trace.upload.redact_home_dir,把路径里的家目录换成~; - 管理员范围尽量小,Basic 口令不要共享。
员工端的数据流向和三个隐私级别见隐私与数据流向。
能力边界(如实说)
1. 身份不可信。 上传口令全员共享,身份字段是客户端自报的。不要拿轨迹做按人考核。
2. 只能看到上传了的会话。 没配 token、开了 essential-traffic、单次关了上传的会话都不在这里。仪表盘的数字是下限,不是全量。
3. 管理台不能删除轨迹。 界面上没有删除按钮。服务端有一个软删除接口 DELETE /api/v1/trajectories/{session_id},用 Basic 口令调用:轨迹立即从列表和统计里消失,文件保留,由服务端定时任务在 30 天后清理。管理台没有恢复入口。
4. 重复上传不更新。 同一会话已有记录时,再传返回 409,客户端跳过。员工本地改过的轨迹不会覆盖服务端那份。
5. 仪表盘没有时间范围。 卡片和图表统计全部历史,只能按来源筛。要看某段时间,用列表页的日期筛选。
6. 不是实时的。 会话结束才上传,回答不了「现在有几个人在跑任务」。
常见问题
轨迹页没有某人的会话
按顺序排查:
- 他有没有配
trace.upload.token。默认不上传,只配backend.url不够。 - 他是不是开了
essential-traffic,或启动时带了--trace-upload-disabled、--no-trace。 - 会话是不是在配置上传之前产生的。历史会话要他手动
sid-code --upload-traces --include-history。 - 上传是不是一直失败。让他跑
sid-code --upload-traces看重试队列的报错。口令不对返回 401,客户端不会重试。
列表不能按人筛,找他的会话可以从「设备」页他那台设备点「轨迹」,或者用首条输入搜。
某人的轨迹成本和成本页对不上
正常。两边数据来源不同,以成本页为准,见上文成本口径。
成功率看起来偏低
先看退出状态分布。user_interrupt(用户中断)和 max_turns(轮次用尽)都算失败;员工习惯中途按 Esc 打断,成功率就会偏低。这说明的是使用习惯,不一定是任务失败。
星级评分想清空回「未评分」
目前做不到。评分只接受 1 到 5,清空会提示「保存失败」。
导出 SFT 提示失败
最常见的是筛选条件下没有轨迹,或者匹配到的轨迹都没有 assistant 回复。放宽筛选或换几条再试。