运行已经结束,日志还在。
智能体失败后会留下一个文件:请求、流式分片、工具调用、重试,14:02:31 的一个 429。grep 给你一行行文本,却不会告诉你每行属于哪个会话、哪次调用改了文件、循环从哪里开始。
ThreadlineLM 解析这个文件,重建整次运行:模型看到的对话、调用过的工具、每次调用的开销。同样的证据,变得可读。
01
{
02
"id": "evt_0009",
03
"ts": "2026-05-17T15:30:09.000Z",
04
"client": "eval-runner",
05
"model": "gemini/gemini-2.0-flash",
06
"status": 429,
07
"duration_ms": 95,
08
"upstream": { "status": 429 },
09
"req_body": {
10
"messages": [
11
{
12
"role": "user",
13
"content": "Translate to Spanish: good night."
14
}
15
]
16
},
17
"resp_body": {
18
"error": {
19
"code": 429,
20
"status": "RESOURCE_EXHAUSTED"
21
}
22
}
23
}
同一个文件,四种读法。
时间线是索引,其余都在一个按键之外:同一批事件,四种读法,无需重新导入。
01 时间线
每次调用,按顺序
提供商、模型、状态、延迟和输入/输出 token。失败的请求保留 HTTP 状态码,而不是消失在堆栈里。
02 对话
重建的对话
用户消息、工具调用、工具结果、思考过程和最终回答——按模型真正收到的顺序排列。
03 图
工具调用变成流程
系统、用户、工具调用、工具结果、思考和助手节点。循环、重试和死路不再藏在 JSON 里。
04 指标
延迟、token、成本
p50/p95/p99 延迟、输入输出 token、内置价目表估算的成本,以及按模型的请求数。
Compare 是第五个标签页:把一次正常调用和一次失败调用放在一起,逐字段对比请求与响应。
Ctrl+1…5六种格式。按内容识别,不看扩展名。
把文件拖进窗口。解析器由最前面的记录决定,所以 .log、.jsonl 和 .json 都可以。
| 格式 | 读取内容 | 示例 | 事件 |
|---|---|---|---|
| 兼容 OpenAI 的审计 JSONL | 工具调用、SSE 流、思考内容、Anthropic tool_use、429 错误 | audit.log | 9 |
| JSON 数组形式的审计记录 | 同样的记录放在一个数组里 | audit-array.json | 3 |
| OpenTelemetry GenAI span | 每行一个 span;非 GenAI span 会跳过 | otel-genai-spans.jsonl | 3 |
| OTLP/JSON 信封 | 带 KeyValue 属性的 resourceSpans | otel-genai-otlp.json | 2 |
| LiteLLM StandardLoggingPayload | 流式响应、工具调用、embedding、失败 | litellm.jsonl | 5 |
| 纯文本代理日志 | 嵌在日志行里的审计 JSON | proxy-raw.log | 2 |
所有示例都是合成数据,随 inputExample/ 一起提供。每行一条记录:格式化后的多行 JSON 目前还不能识别。
- Watch
- 还在写入的运行
智能体工作时每 500 ms 重新读取文件,可以边跑边看。
- Compare
- 正常运行 vs 失败运行
两次调用的请求和响应并排对比,逐字段查看。
- Export
- 导出 Markdown 写进工单
模糊搜索调用,再把会话导出,粘进 bug 报告。
什么都不离开这台机器。
没有账号、没有遥测、没有云端、没有更新检查。解析在 Rust 中、在内存里完成。日志从不上传,除了你主动导出的 Markdown,不写任何文件。
应用不会打开任何 socket。拔掉网线,时间线照样生成。
文件被读取、解析,关窗即丢弃。没有缓存,不在磁盘留副本。
Apache-2.0。解析器和 IPC 命令就是几个 Rust 文件:可以读,也可以自己编译。
从文件到时间线。
解析和会话分组留在 Rust 后端;界面通过 Tauri IPC 接收带类型的结果。
最前面的记录决定解析器。无法识别的行会跳过,不会中断。
Rust请求、响应、工具调用、思考内容、用量和状态。
4 个解析器按客户端和 10 分钟窗口把调用归入会话。
session.rs每个会话的对话顺序、工具结果和图上的边。
store.ts虚拟列表、模糊搜索、Markdown 导出。
React · IPC拿一次运行试试。
把 inputExample/audit.log 拖进窗口:时间线里 9 次调用、重建的对话、图和 p50/p95 延迟。
构建产物尚未签名。Windows 上 SmartScreen 会提示“更多信息 → 仍要运行”;macOS 上只需清除一次隔离标记:xattr -dr com.apple.quarantine /Applications/ThreadlineLM.app
早期阶段:v0.3.0。格式和视图已经够日常排查使用;少见的日志形态仍可能让解析器出错。附上脱敏样本的 issue 是最有用的反馈。
或者自己编译
Node 20+、pnpm 10+、稳定的 Rust 工具链,以及 Tauri 的系统依赖。