Tracon 发布:为 Claude Code 并行子智能体提供空中交通管制式监控
Show HN: Tracon (air traffic control for subagents)
Tracon 是一个面向并行 Claude Code 子智能体的只读监控工具,提供终端界面和浏览器视图,可同时展示每个智能体的状态、是否卡在权限提示、是否偏离任务简报,以及两个智能体同时编辑同一文件的冲突。
为并行 Claude Code 子代理提供空中交通管制。 一个实时终端和浏览器监控器,能发现卡住、受阻和偏离的代理,以及即将进入你合并流程的 worktree 文件冲突。
左侧:一个 Claude Code 会话正在编排七个 worktree 代理。右侧:tracon 在旁边的分屏中。一次虚构的运行,来自 tracon --demo,已加速。
uvx tracon --demo # look around a made-up run; no Claude Code session needed uvx tracon # watch your newest Claude Code session that has subagents
一小时前你派出了六个代理。其中一个已经在无人能看到的权限提示上等了 40 分钟。两个正在同时编辑 shop/cart.py。一个正在重新设计其任务简报中要求不要碰的管理页面,另一个已经运行了同一条失败命令六次。Claude Code 的状态行对这些一概不显示。
就像一位 TRACON 管制员在一个雷达屏幕上监视每一架飞机,tracon 一次性显示所有代理:它在做什么、是否在等待、是否偏离了任务简报,以及其中两个是否在同一文件中处于碰撞航向。把它放在你的会话旁边的分屏中运行。
- 只读且本地。 它读取 Claude Code 已经写入磁盘的记录,从不写入你的仓库。只有当你按下
n时,它才会向会话发送内容。参见 它触及什么。 - 无需设置。 没有钩子、没有配置、没有账户。将它指向一个项目,或让它找到最新的会话。
- 可选的 LLM 评判器。 一个小模型会根据任务简报检查每个忙碌的代理,每次检查约花费十分之一美分,并有每次运行的硬性预算。
--no-judge可将其关闭。
tracon 是一个独立项目。它与 Anthropic 无关联、未获其认可或赞助。“Claude”和“Claude Code”是 Anthropic 的商标。
它能捕捉什么
所有代理尽在一个雷达屏幕
在无人能应答的权限提示上等待的代理、变得安静的代理、挂起的测试运行、遗留的进程、循环、对错误检出或过期基线的编辑、两个代理修改同一文件,以及(使用可选的 评判器)偏离任务简报的代理。红色表示现在需要你;琥珀色值得一看。
为什么某个代理出了问题
enter 打开一个代理:它在做什么、评判器的担忧以及判定如何变化、每个标记的解释、它在任务简报之外触及的文件,以及它所说内容的实时完整尾部。两条消息之间的工具调用折叠为一行(▸ 23 tool calls Read 5 · Edit 8 …);点击它可打开那次运行,或按 e 打开全部。
合并前的合并冲突
x 显示哪个代理编辑了哪个文件。! 标记两个代理同时编辑的文件。
一键提醒主控
n 就选中的代理提醒你的编排会话:tracon 起草一条包含该代理状态、标记、评判器担忧和应对措施的备注,并立即发送(参见 提醒主控)。
回放整个运行
t 是时间线。[ 和 ] 后退和前进,space 回放,--at "07:20" 打开任何过去的会话,呈现其当时的状态。
解读屏幕 列出了每种状态和标记、其含义以及应对措施。
使用 --notify 时,当某个代理需要你时会触发桌面通知。终端标题被设置为所监视会话的名称(◎ <name>,与 Claude Code 的 ✳ <name> 对应),因此该分屏读起来像是那个会话的一部分。
安装
需要 Python 3.12+,在 macOS 或 Linux 上。
uv tool install tracon # or: pipx install tracon uv tool install 'tracon[api]' # optional: judge through the Anthropic API instead of `claude -p`
或不安装直接运行:uvx tracon。从源码:
git clone https://github.com/phalladar/tracon && cd tracon uv tool install --editable .
使用
cd your-project && tracon # newest session with subagents in this project (or anywhere) tracon --demo # a made-up run, to look around tracon web # browser view only tracon --list # recent sessions that spawned subagents tracon -s 4f2a # pick a session by id prefix tracon --at "2026-10-11 07:20" # replay a session as it stood at that time tracon --once # print one snapshot and exit
一个好的布局:你的编排会话在一侧,tracon 在旁边的分屏中(在 Ghostty 中,cmd+d)。
终端按键
| 按键 | |
|---|---|
enter |
agent 详情:状态、judge 判定、flags、文件、实时进程,以及 agent 说了什么,其中 lead 的消息和它的工具调用折叠在它们之间(e 或点击可展开) |
e |
展开或折叠每一段工具调用,在表格下方的窗格和详情中(点击 ▸ 可执行一次) |
t |
时间线:整个运行中的所有 agent,按活动着色,并显示 lead 的合并和消息 |
x |
文件热力图:哪些 agent 编辑了哪些文件,并发编辑标记为 ! |
w |
打开浏览器视图 |
j |
立即就选中的 agent 询问 judge |
d |
忽略 judge 对选中 agent 的漂移或卡住判定(再次按下可恢复) |
n |
就选中的 agent 提醒 lead:发送一条包含其状态、flags 和该做什么的备注(仅实时) |
[ ] / { } |
回退 / 前进 5 / 30 分钟(进入回放)· space 播放 · l 回到实时 |
o / c |
在新终端窗口中打开 agent 的 worktree(若已安装则用 Ghostty)/ 复制其路径 |
h / s / q |
隐藏已完成的 agent / 下一个会话 / 退出 |
浏览器视图
在终端中运行 w,或 tracon web,会在 127.0.0.1 上提供一个页面:
- Timeline:用滚轮缩放,拖动平移,双击适应。悬停任意条形 可查看它覆盖的调用。超过空闲阈值的静默时段以橙色绘制。
- Files:每个 agent 对每个文件的编辑热力图,共享文件优先。
- Replay scrubber:拖动浏览整个运行,或按 ▶ 回放。
- 点击某个 agent 可查看其详情抽屉和实时活动流。
阅读屏幕
每个 agent 行都有一个 state(它现在在做什么)、一个 JUDGE 列(LLM 对其
是否符合 brief 的解读),以及任意数量的 flags(值得一看的事项)。在某行上按 enter
可查看详情,其中显示 judge 的一行关切以及每个 flag 的解释。
你无法从 tracon 控制 agent;它是只读的。当需要采取行动时,你在 编排会话中行动:在那里回答提示,或让 lead 给 agent 发消息、停止或重新调度。
列
| 列 | 显示 |
|---|---|
| STATE | 它现在在做什么(见下文) |
| TASK | lead 给 agent 的描述;固定行是 lead 本身 |
| MODEL | 它运行的模型 |
| JUDGE | judge 的最新判定(见下文) |
| NOW | 它当前或最近的操作 |
| QUIET | 自其 transcript 上次变动以来的时间;超过 5 分钟空闲阈值显示红色 |
| RUN | 自其启动以来的时间 |
| CONTEXT | 上下文大小(以 token 计);超过 300k 显示琥珀色,超过 450k 显示红色 |
| EDITS | 它编辑过的文件;(n⚑) 统计 brief 从未提及的文件 |
| COMMITS | 它发起的 git commit 调用 |
| MSGS | lead 发给它的消息 |
| FLAGS | 值得一看的事项(见下文) |
颜色
| 颜色 | 浏览器标签 | 含义 |
|---|---|---|
| 红色 | Needs you | 立即行动:agent 无法继续,或正在造成损害 |
| 琥珀色 | Check | 有空时看一下;通常没事 |
| 绿色 | Working | 无需处理 |
| 灰色 | Done / Note | 已完成,或为上下文保留的历史 |
一旦 agent 完成,其 flags 变为灰色:它们是历史,而非行动。只有 OUTSIDE 和 ORPHAN 保持醒目,因为它们描述的内容比 agent 存续更久。
状态
| 状态 | 含义 | 该做什么 |
|---|---|---|
| BLOCKED | 一个即时调用(Edit、Read、git status)已打开 45 秒,或一个没有运行任何内容的 shell 调用:它在等待权限提示 |
如果提示显示在你的会话中,就回答它。如果没人能看到它,就在权限设置中允许该工具,或让 lead 停止并重新调度该 agent |
| IDLE | 5 分钟内无转录活动且无任何运行 | 检查其 feed 的最后几行:它通常遇到了错误,或在等待永远不会到来的输入。让 lead 给它发消息或停止它 |
| STALLED | 某个进程已运行 20 分钟,无文件变更或提交 | 通常是挂起的测试或永不退出的 watcher。在详情中检查该进程;将其终止,或让 lead 停止该 agent |
| ORPHANED | 静默,但它启动的分离进程在其父进程死后仍在运行 | 终止该进程(pid 在详情中) |
| WAITING | 它的回合已结束(或处于静默),而它启动的后台工作仍在运行 | 通常无需处理:该工作完成后它会恢复。如果该工作卡住,参见 STALLED |
| PENDING | 仅回放:某个工具调用处于打开状态,且没有进程数据时 tracon 无法区分长时间运行与提示 | 无需处理;进入实时模式查看是哪种情况 |
| RUNNING | 某个工具调用正在进行中(构建、测试运行) | 无需处理 |
| WORKING | 正常发起调用 | 无需处理 |
| STARTING | 已派发,尚无活动 | 无需处理 |
| DONE | 已完成:交回了报告,lead 被告知它已完成,或它以最终答案结束且无任何运行 | 阅读其报告;合并 |
| STOPPED | 被 lead 停止、失败或被终止 | 如果你没预料到,检查原因 |
固定的 ◆ lead 行显示编排会话本身(正在运行、工作,或在等待其 agent 或你),因此其活动绝不会被误认为子 agent 的。
标志
| 标志 | 含义 | 该做什么 |
|---|---|---|
| LOOP | 同一调用连续 3 次,中间无编辑 | 它在空转。让 lead 告诉它缺了什么,或停止它 |
| ERRORS | 其最近 3 次工具调用失败 | 查看 feed 中的错误;它可能会自行恢复 |
| DENIED | 工具调用被拒绝,附分类器的原因(例如 "Modify Shared Resources"),或被 guard 拒绝(Claude Code 的 worktree 隔离或其 sleep 阻断,会说明该怎么做)。拒绝为琥珀色 30 分钟,然后变灰。guard 拒绝保持灰色,同时该 agent 的下一次调用通过,只有连续两次被拒时才变为琥珀色 | 对于拒绝,判断它是否应拥有该权限;如果是,允许它并让 lead 告诉它重试。对于琥珀色拒绝,让 lead 告诉它按拒绝说明去做,或报告它做不到的事 |
| OUTSIDE | 某个 worktree agent 编辑了主检出而非其 worktree | 检查你主检出中的 git status,撤销或移动这些编辑 |
| BRANCH | 其 worktree 所在分支与分配给它的分支不同 | 在合并前检查它没有提交到错误的分支 |
| STALE-BASE | 在 lead 已合并某些内容后,它在合并基础分支之前就开始编辑。实时情况下,git 有最终决定权:一旦其 HEAD 包含基础分支,标志消失,且该标志会说明它落后多少个提交 | 预期会有冲突;让它在继续之前合并基础分支 |
| COLLIDE | 另一个 agent 在两者都运行时编辑了同一文件。按 x 查看热力图 |
第二次合并可能会冲突。决定哪个 agent 拥有该文件,或规划合并顺序 |
| OFF-BRIEF | 它编辑了 brief 从未提及的文件(灰色:通常合理) | 扫一眼列表;只有文件看起来无关时才值得一问 |
| BG | 它启动了后台或分离运行。当其 brief 要求在前台运行且没有任何地方允许后台或 nohup 运行时,显示琥珀色 |
如果是琥珀色,说明它忽略了简报;让 lead 提醒它 |
| UNCOMMITTED | 编辑内容已 45 分钟未提交 | 如果工作树被清理,工作将面临风险;让它提交 |
| CTX | 上下文超过 300k(琥珀色)或 450k(红色)token | 它会变慢并忘记先前的指令。让它收尾并交回,或者重新派发剩余部分 |
| ORPHAN | 一个分离的进程仍在从其工作树运行。当 agent 仍在工作时显示灰色(通常它在轮询自己的 nohup 运行);一旦 agent 安静下来或完成则显示红色 |
一旦你确定没有东西需要它,就杀掉它 |
| DRIFT | judge 说它在漂移(见下文),而你没有忽略它 | 见下文 |
| STUCK | judge 说它卡住了(见下文),而你没有忽略它 | 见下文 |
Judge 判定
JUDGE 列显示来自可选的 LLM 检查的最新判定。
这是一个小模型根据最后 40 个动作对简报的看法,所以把它当作
提示去查看,而不是事实。详情视图(enter)显示 agent 正在做什么、
judge 的担忧,以及判定如何随时间变化。
| 判定 | 含义 | 该怎么做 |
|---|---|---|
| ✓ on track | 它最近的动作服务于简报的步骤,即使很慢 | 无需操作 |
| ↯ drifting(琥珀色,添加 DRIFT) | 它在做简报未要求的工作、扩大范围,或违反简报规定的规则(被要求在前台运行测试时却在后台运行,编辑被要求不要触碰的文件)。担忧会指出它能看到的某个动作;仍然服务于简报的增长,或在基础分支上取得的基线,不算数 | 阅读详情中的担忧。如果属实,让 lead 给 agent 发消息让它回到简报,或停止它。如果额外工作没问题(你的简报比你本意更窄),让 lead 用 SendMessage 告诉 agent:judge 会把 lead 的消息视为简报的一部分,并在 agent 的下一个动作后再次检查。如果是误报,按 d 忽略它 |
| ⟳ stuck(红色,添加 STUCK) | 它重复动作而没有进展,不改变方法就重试失败,或等待不会到来的东西 | 在信息流中找到重复的失败。通过 lead 给它缺失的部分,或停止它并用更好的简报重新派发。如果是误报,按 d 忽略它 |
| ? unclear | 活动太少,无法判断 | 无需操作;等待 |
| … judging | 检查正在进行中 | 无需操作 |
| 空白 | 尚未判定(需要 5 次工具调用),或 judge 已关闭 | 无需操作 |
每个 agent 的判定最多每 3 分钟刷新一次,在再有 5 次工具调用之后。按 j 立即重新检查
选中的 agent,例如在 lead 提醒它之后。已完成的 agent 永远不会
被判定;它们的最后判定会保留,显示为灰色,并且 DRIFT 和 STUCK 会被丢弃。
忽略。 在漂移或卡住的 agent 上按 d 会将该判定标记为已忽略:它会
显示为灰色的“· dismissed”,DRIFT 或 STUCK 消失,提醒会省略该担忧,并且
下一次检查会把它列为已清除的担忧给 judge,因此它不应在同一批动作上
再次被提出。新的担忧会照常标记。再次按 d 可恢复该判定。
judge(可选,默认开启)
规则能捕捉机械性故障。对于漂移,tracon 会定期让一个小模型
(Claude Haiku 5.5)读取 agent 的任务简报、lead 发给它的消息,以及它最近 40
个动作,然后回答 on_track、drifting、stuck 或 unclear,并附上一行摘要。
lead 的消息会修订简报,因此 lead 已批准的工作不算漂移。失败的调用
会带着完整消息到达它那里,因此它能区分 agent 是在执行拒绝指令所要求的事(拆分
命令、换用另一个工具),还是在换个说法绕开它。
每种判定含义见 Judge verdicts。
- 时机:仅限活跃 agent,每个最多每 3 分钟一次,且仅在 5 次新工具调用之后。 一个例外:在漂移或卡住判定之后,lead 发给该 agent 的消息 会在 agent 对其采取行动后立即获得一次提前复查。已完成和空闲的 agent 永远不会被判定。
- 成本:每次检查约 $0.001。在真实运行的一天中,15 个 agent 的 85 次检查 总共花费 $0.09,最忙的 agent 不到 2 美分。每次运行的预算(默认 $1.00)在达到时停止判定, 支出显示在标题栏中。
- 后端:设置
ANTHROPIC_API_KEY并安装[api]附加组件后,它使用 Anthropic SDK。否则它使用你 Claude Code 登录上的claude -p,计入 你的套餐。 - 隐私:检查会将简报和最近工具调用的摘要(命令、文件
路径、错误文本)发送给 Anthropic,正如你的会话已经在做的那样。
--no-judge可将其关闭。
判定缓存在 ~/.cache/tracon/judgments.json 中,驳回缓存在
其旁边的 dismissed.json 中,因此重放和重启都会显示它们。每条判定都会记录做出该判定的
提示词版本;当更新更改了提示词时,每个活跃 agent
会获得一次复查,而不是保留旧提示词做出的判定。
推动 lead
上面大多数“该做什么”的建议都是“让 lead……”。在某个 agent 上按 n(在表格
或其详情中),tracon 就会用该提示推动 lead:agent 的 id、状态、标志、
判定者的关切,以及匹配的建议,措辞针对 lead 自己的工具(SendMessage、
TaskStop)。当提示涉及拒绝、漂移或卡住的 agent,且该 agent 曾被
拒绝过任何东西时,它会逐字引用最后一次拒绝,这样 lead 无需打开记录就能核实该说法。
你一按键它就会发送;会有通知确认。
它通过 Claude Code 的跨会话收件箱投递:tracon 在
~/.claude/sessions/ 中找到 lead 的进程,并向那里列出的 Unix socket 写入一条消息。lead 会将其
视为来自另一个会话的消息,在工具调用之间,或在空闲时作为新一轮对话,且它
无法批准权限提示。如果 lead 的 crossSessionInbound 设置为 hold(或
其权限模式使 Claude Code 审查对等消息),该消息会等待你在该会话中
批准。如果 lead 未在运行,n 会将提示复制到
剪贴板。tracon 从不读取收件箱认证密钥;在 macOS 和 Linux 上,该 socket 接受来自你自己用户的未认证
消息。
选项
| 标志 | 默认值 | |
|---|---|---|
--project PATH |
当前目录 | 监视哪个项目的会话 |
--session ID |
最新 | 会话 id 或前缀 |
--at TIME |
实时 | 按本地时间重放(07:20 或 2026-10-11 07:20) |
--idle MIN |
5 | IDLE 前的静默时间 |
--stall MIN |
20 | 无变化运行多久后 STALLED |
--notify |
关闭 | agent 需要你时的桌面通知(macOS 上为 osascript,Linux 上为 notify-send) |
--no-judge |
关闭 LLM 检查 | |
--judge-model |
claude-haiku-5-5 |
检查所用模型 |
--judge-backend |
auto |
api 或 cli |
--judge-budget USD |
1.00 | 每次运行超过此金额后停止判定 |
--judge-every MIN |
3 | 同一 agent 两次检查之间的最短时间 |
--demo |
监视一个虚构运行而非真实会话 | |
--port |
8765 | 浏览器视图端口(若被占用则用下一个空闲端口) |
--title-prefix |
◎ |
终端标题前缀 tracon 设置为会话名称 |
--no-title |
不修改终端标题 |
涉及范围
tracon 是只读的。以下是它在自身进程之外所做的全部事情:
| 读取 | ~/.claude/projects/ 中的转录文件;~/.claude/sessions/<pid>.json 以查找正在运行的 lead 的收件箱(绝不读取 *.key 认证文件) |
| 运行 | lsof(macOS)或 /proc(Linux)、ps,以及每个 agent 工作树中的只读 git(status、rev-parse、rev-list、branch) |
| 写入 | ~/.cache/tracon/(judge 裁决和你的驳回记录)。不写入你的仓库或 ~/.claude/ 中的任何内容 |
| 发送 | 当你按下 n 时向 lead 的收件箱 socket 发送一条消息,绝不自行发送,也绝不发给子 agent。Judge 检查发送至 Anthropic(或 claude -p),除非 --no-judge |
| 监听 | 浏览器视图,仅监听 127.0.0.1,在你打开它之后(w 或 tracon web) |
无遥测、无账户、无配置文件。
工作原理
Claude Code 按会话写入:
~/.claude/projects/<encoded project path>/
<session>.jsonl the orchestrating ("lead") session
<session>/subagents/agent-<id>.jsonl each subagent's transcript
<session>/subagents/agent-<id>.meta.json description, model, worktree, branch
tracon 增量跟踪这些文件。每隔几秒它还会按工作树检查
那里正在运行哪些进程(lsof 和 ps,只保留 Claude 启动的进程,外加
孤儿进程)以及 git 状态(分支、领先提交数、脏文件)。状态和标志由
两者推导得出。
tracon/
transcript.py JSONL -> compact events (all knowledge of the transcript format lives here)
session.py find sessions, track the lead and its agents
probe.py live processes and git state per worktree
signals.py one agent -> state + flags (pure, testable)
lane.py whole-run view: file collisions, judge results, assess_all()
judge.py the optional LLM check, its scheduling, budget and cache
advice.py the nudge `n` sends the lead
demo.py the made-up run behind `--demo`
inbox.py find a live session's inbox socket and send to it
app.py Textual TUI
web.py local HTTP server + JSON API; static/index.html is the page
cli.py entry point
局限性
- 转录文件是 Claude Code 的内部实现,不是公开 API。格式变更可能会破坏
解析;修复应放在
transcript.py中。会话注册表和n使用的收件箱 socket 也是如此,位于inbox.py中。 - 在 macOS 上开发;测试在 macOS 和 Linux 上运行。在 Linux 上,进程从
/proc读取 (无需lsof),通知使用notify-send,复制使用wl-copy、xclip或xsel(否则使用终端的 OSC 52),o打开 Ghostty 或x-terminal-emulator。不支持 Windows; WSL 应表现得像 Linux。 - 在回放中没有进程数据,因此长时间运行的 shell 调用会显示为 PENDING 而不是 RUNNING 或 BLOCKED。
开发
uv sync --group dev uv run pytest # synthetic transcripts; no Claude Code or network needed uv run tracon --once --no-judge # quick check against your latest session uv run --with pillow python scripts/screenshots.py # regenerate docs/screenshots from the demo (macOS, Chrome) uv run --with pillow python scripts/hero.py # regenerate the README's split-terminal hero.gif
架构说明和约定见 CLAUDE.md。
许可证
来源:Hacker News · github.com





