tmux:Coding Agent 缺失的环节

如何在一个持久化的终端工作区里运行 Codex、Claude Code、测试和开发服务器,同时不丢失"什么跑在哪里"的追踪。

tmux:Coding Agent 缺失的环节
AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo

晚上 11 点。Codex 在一个终端标签页里实现一个功能。Claude Code 在另一个标签页里审查另一个文件。某个开发服务器跑在一个你再也想不起确切位置的地方。还有两个标签页塞满了你二十分钟前就不再看的测试输出和日志。

你合上笔记本去喝咖啡。再打开时,一半东西都没了。SSH 会话断了。你完全不知道哪个智能体跑到哪一步了。

换个更好的智能体解决不了这个问题。这是一个环境问题。智能体能写代码、能修自己的测试,但这一切都改变不了一个事实:它们需要有个地方运行。一个能在断连后存活的、能让一个智能体的输出与另一个分开的、能让人类介入而不打断其他一切的地方。

那个地方不必是一个花哨的编排平台。对大多数日常智能体开发来说,它就是 tmux——一个已经存在了十五年的终端复用器,几乎可以说是偶然地解决了同时运行多个 AI 智能体所带来的运维问题。

1、终端标签页不是为这个而生的

一个开发者、一条命令、等它跑完、继续下一件事。这就是终端标签页所假设的模型。AI 辅助开发在三个具体方面打破了它。

智能体并行工作,而不是你串行干活。进程运行时间很长:一个实现智能体、一个测试监听器、一个开发服务器,同时存活,而不是一条两秒就退出的命令。而且一切都需要保持可见。日志、测试输出、diff。不能埋在早已丢失的滚动缓冲区里。

终端标签页组织的是你当下能看到的东西。它们不组织你移开视线后仍在运行的东西。这正是 tmux 值得你花二十分钟学习的原因。

2、三个概念,就是这整个工具

会话(session)是一个持久化工作区。无论你看不看它,它都持续运行。

窗口(window)是会话里的一个标签页,通常对应一个项目或任务。

窗格(pane)是窗口里的一个拆分单元,运行一个进程。

分离(detach)一个会话,它就在后台继续跑。稍后重新附着(reattach),你就能拿到一模一样的终端状态,包括滚动缓冲区。

映射到智能体工作上,这个类比非常贴合:

None
tmux new-session -s ai-workspace

把它拆成四个:一个实现智能体、一个审查智能体、开发服务器、测试和日志。

None
tmux split-window -h      # split vertically
tmux split-window -v      # split horizontally
tmux select-pane -t 0     # jump to a specific pane
tmux detach                # leave the session running
tmux attach -t ai-workspace   # come back to exactly where you left off

这就是你大部分时候需要的东西。往后的都是打磨,时间紧可以直接跳到"常见错误"一节。

3、给每个窗格一个任务

两个可写智能体在同一份代码上、没有明确分工。这是真正浪费时间的失败模式,比任何 tmux 配置都严重。你最终得去协调互相冲突的编辑,这比两个智能体省下的时间加起来都长。

一个有明确角色的工作区:

  • 窗格 1,主智能体,实现一个范围明确的改动。
  • 窗格 2,一个独立智能体,唯一任务是在那个改动里找出回归问题。自己不写代码。
  • 窗格 3,测试监听器,持续运行。
  • 窗格 4,服务器和运行时日志,让你看到改动落地时的实际效果。

你在这里的工作比两个智能体都更聚焦。批准决策、解决两个智能体报告之间的分歧、决定什么该合并。没有这种分离,更多智能体只会带来更多噪音。

4、持久化才是真正的功能

其他一切都是便利。这才是值得折腾的理由:

  • 关闭终端窗口
  • SSH 在任务中途断线
  • Wi-Fi 中断
  • 更换机器
  • 一次你不想守着的 40 分钟智能体任务

这些都不该杀死你的工作。

tmux detach
tmux list-sessions
tmux attach -t ai-workspace

界面消失了。工作没有。

有一个值得直说的注意事项:这是进程级持久化,不是机器级。宿主机重启,会话也随之消失。如果工作必须扛过一次完全重启,你需要在它之上再加一层东西——一个守护进程或一个恢复脚本。

5、窗格并不能阻止两个智能体编辑同一个文件

tmux 解决的是进程在哪里运行。它完全管不了两个智能体同时在同一分支上编辑同一批文件,而这比任何终端布局都更容易引发混乱。

危险的:

Agent A ─┐
         ├── same checkout, same branch
Agent B ─┘

更安全的做法,每个智能体有自己的目录和分支:

git worktree add ../project-api -b feature/api
git worktree add ../project-review -b review/api

每个 worktree 一个 tmux 窗口。现在每个智能体都有自己的文件系统视图,零风险踩到另一个智能体未提交的改动。

tmux 隔离进程和视图。Git worktree 隔离代码。你两者都需要。不管"隔离"这个词在两句话里听起来多像,它们解决的不是同一个问题。

6、tmux 到底是什么:一个控制层,不是大脑

实时看到每个智能体的输出。随时中断任何东西的能力。并发任务之间清晰的边界。在批准前审查 diff 的地方。

这才是真正的清单。注意缺了什么:tmux 没有任务、依赖、权限或成功标准的概念。它不知道智能体是什么。它是一个终端复用器。什么该跑、按什么顺序跑、谁允许碰什么——这些判断仍然是你来做。

一旦你看到 tmux 明确不覆盖什么,这一点就更重要了:

None

一个拥有文件系统写权限的智能体,在 tmux 窗格内拥有的访问权限和窗格外完全一样。tmux 不是安全边界。把它当安全边界用,你会以最痛苦的方式发现这一点。相反,要把它与真正的隔离搭配使用:tmux 加 git worktree 加容器加受限的智能体权限,每一层只做自己真正擅长的一件事。

7、随着规模增长组织窗口

两种结构几乎覆盖所有情况。一个功能、几个并发阶段:

ai-project
├── 1: plan
├── 2: implement
├── 3: review
├── 4: tests
├── 5: server
└── 6: logs

几个功能并行开发:

ai-project
├── auth
├── payments
├── frontend
├── infrastructure
└── monitoring

深扎一个功能、想同时看到每个阶段时,用阶段导向。几个独立工作流同时推进时,用功能导向。当工作真的是另一个项目时,创建一个新的会话,而不是又一个窗口。把不相关的项目混进同一个会话的窗口里,状态栏就从地图变成了噪音。

8、把布局脚本化,不要每天手搭

每天早上手动重建一个六窗格布局,大概到第三天你就烦了。

#!/usr/bin/env bash
tmux new-session -d -s ai-project -n agents
tmux split-window -h -t ai-project:agents
tmux new-window -t ai-project -n tests
tmux new-window -t ai-project -n server
tmux attach -t ai-project

保存它,提交到你的项目旁边。布局就变成你可以做版本管理的东西,而不是靠记忆重建的东西。如果你宁愿写 YAML 而不是 bash,tmuxptmuxinator 也能用声明式的方式做同样的事。

一个值得加在顶层的最小配置:

set -g mouse on
set -g history-limit 50000
set -g status-left "#[bold]#S "
set -g pane-border-style fg=colour238
set -g pane-active-border-style fg=colour39
bind h select-pane -L
bind l select-pane -R
bind j select-pane -D
bind k select-pane -U

滚动缓冲区提升比看起来更重要。二十分钟前的智能体输出和错误追踪在默认限制下很快消失,而让一个智能体重说它已经告诉过你的东西,既浪费你的时间,也浪费它的上下文窗口。

9、它在哪里失效,按实际发生频率排序

两个可写智能体在同一个 worktree 里。冲突、难以厘清的编辑最常见的单一来源。在拆窗格之前,先把检出目录分开。

任务定义不清、相互重叠。如果两个智能体可能出于同样的原因碰同一个文件,你花在协调上的时间会比任何一个智能体省下的都多。

把 tmux 当安全边界用。它不是。不要因为一个无人值守的智能体碰巧坐在自己的窗格里,就给它破坏性权限。

窗格太多以至于看不过来。四到六个是真实的天花板。超过这个数,你不是在监督,你是在碰运气。

弄不清哪个窗格拥有开发服务器。在错误的窗格里多按一次 ctrl-c,你就杀掉了错误的进程。给窗格命名。

把滚动缓冲区当项目记忆用。它既不持久,也谈不上真正可搜索。值得留存的决策应该写进提交信息,而不是窗格历史。

并行放大好的协调。它也以同样的速度放大坏的协调。

10、一个站得住的工作流

  1. 附着到项目会话。
  2. 每个智能体任务开一个 worktree。
  3. 第一个智能体实现一个范围明确的改动。
  4. 第二个独立智能体审查它。不是让同一个智能体给自己打分。
  5. 测试持续运行并保持可见。
  6. 运行时日志放在自己的窗口里。
  7. 你自己读一遍 diff 再接受任何改动。
  8. 之后才合并。
  9. 杀掉不再需要的进程。工作区很快会积累僵尸服务器。
  10. 分离,相信重新附着能让你回到这里的一分一毫。

11、什么时候这不是对的工具

一次短暂的智能体任务不需要持久化的多窗格工作区。如果你的 IDE 已经能很好管理进程,再加一层 tmux 只是多一个要来回切换的东西。

必须扛过整机重启的工作,需要 tmux 单靠自己给不了的东西。多用户编排,或者跨多台机器的智能体,需要真正的基础设施:CI 流水线、Kubernetes 作业、专门的智能体运维工具。任何你需要真正安全或资源隔离的地方,tmux 都是错误的层。那是容器存在的意义。

12、这一切底下更大的转变

工作正在从"自己写每一行"转向"定义任务、分配上下文、监督并行工作、审查结果、恢复你不在场时失败了的进程"。

AI 模型可以当工人。但总得有个地方当工作场所。对当下很多智能体开发来说,那个地方就是一个已经在这一点上默默优秀了十多年的终端复用器。

从一个会话、四个窗格开始:一个智能体、一个服务器、你的测试、你的日志。分离,走开,回来时工作区还在你离开的地方。在那之后,普通的终端标签页会显得出奇的脆弱。


原文链接:Tmux is the Missing Operating System for AI Coding Agents

汇智网翻译整理,转载请标明出处