跳到正文
Hacker News· allocate·· 6 天前AI 评分62

Tracon 发布:为 Claude Code 并行子智能体提供空中交通管制式监控

Show HN: Tracon (air traffic control for subagents)

AI 导读

Tracon 是一个面向并行 Claude Code 子智能体的只读监控工具,提供终端界面和浏览器视图,可同时展示每个智能体的状态、是否卡在权限提示、是否偏离任务简报,以及两个智能体同时编辑同一文件的冲突。

正文 · AI 翻译

为并行 Claude Code 子代理提供空中交通管制。 一个实时终端和浏览器监控器,能发现卡住、受阻和偏离的代理,以及即将进入你合并流程的 worktree 文件冲突。

PyPI Python 3.12+ tests MIT

A terminal split in two. On the left, a Claude Code session is asked to /expedite checkout-v2 and dispatches seven worktree agents. On the right, tracon lists them as they start; over the run one agent is blocked on a permission prompt, one goes idle, one drifts off its brief and one is stuck retrying a failing command. The user selects the stuck agent in tracon, presses n to nudge the lead with a drafted note; it arrives in the Claude Code session, the lead messages the agent, and tracon shows it back on track.

左侧:一个 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 的商标。

它能捕捉什么

所有代理尽在一个雷达屏幕

在无人能应答的权限提示上等待的代理、变得安静的代理、挂起的测试运行、遗留的进程、循环、对错误检出或过期基线的编辑、两个代理修改同一文件,以及(使用可选的 评判器)偏离任务简报的代理。红色表示现在需要你;琥珀色值得一看。

tracon's terminal view: a table of agents with states BLOCKED, IDLE, RUNNING and WORKING, judge verdicts on track, drifting and stuck, and flags such as LOOP, COLLIDE and STALE-BASE; below it, the selected agent's feed of repeated connection-refused errors

为什么某个代理出了问题

enter 打开一个代理:它在做什么、评判器的担忧以及判定如何变化、每个标记的解释、它在任务简报之外触及的文件,以及它所说内容的实时完整尾部。两条消息之间的工具调用折叠为一行(▸ 23 tool calls Read 5 · Edit 8 …);点击它可打开那次运行,或按 e 打开全部。

tracon's detail view of an agent the judge marks as drifting: it has edited admin files its brief says to leave alone

合并前的合并冲突

x 显示哪个代理编辑了哪个文件。! 标记两个代理同时编辑的文件。

tracon's files heatmap: rows of files, one column per agent, with two agents both editing shop/cart.py marked with an exclamation mark

一键提醒主控

n 就选中的代理提醒你的编排会话:tracon 起草一条包含该代理状态、标记、评判器担忧和应对措施的备注,并立即发送(参见 提醒主控)。

回放整个运行

t 是时间线。[ 和 ] 后退和前进,space 回放,--at "07:20" 打开任何过去的会话,呈现其当时的状态。

tracon's terminal timeline: one row per agent, coloured by edits, shell calls and reads, with silent stretches dotted

解读屏幕 列出了每种状态和标记、其含义以及应对措施。

使用 --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 上提供一个页面:

The tracon browser timeline replaying a run: seven subagents spawn and work, coloured by edits, shell calls and reads, with judge verdicts per agent and the lead's merges and messages along the top

  • 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。

许可证

MIT

来源:Hacker News · github.com