Claude Code 的 agent view:一屏管住多个后台会话,以及让会话之间互相传话
手上有几件互不相干的事要交给 Claude Code,不想开一排终端盯着。agent view 把它们变成一张表:谁在干活、谁在等你回答、谁做完了。本站在服务器上实测了派发、回答提问、进入对话、删除会话,以及让一个会话去问另一个会话。通过中转站都能用。
本站已实测,测试日期:2026-10-13。
本页目录(15 节)
这篇教程解决一个问题:有三四件互不相干的事想同时交给 Claude Code,怎么不用开一排终端、挨个盯着?
官方的做法叫 agent view,目前是研究预览,界面和快捷键还可能变。本站在服务器上把主要的流程走了一遍。
| 实测环境 | |
|---|---|
| 日期 | 2026-10-13 |
| 版本 | Claude Code 2.1.296 |
| 系统 | Ubuntu 24.04,在 tmux 里操作 |
| 模型 | Sonnet 5.5 |
| 连接方式 | 通过酷站AI 中转站,不是直连官方 |
先分清三样东西
- 后台会话:一场完整的 Claude Code 对话,只是不占着终端。你关掉终端它照样跑,想看的时候再进去。
- agent view:看这些后台会话的一张表,用
claude agents打开。 - 后台服务:真正托着这些会话的一个进程。第一次用到时自动启动,平时不用管。
它和子代理、agent teams 的区别在于:每个后台会话都是你派出去的一场独立对话,彼此不知道对方的存在。
一、从命令行派发两个任务
示例仓库里有一个 calc.py 和一个测试文件,div 函数有个 bug。在仓库目录里连着派两个任务:
claude --bg --name fix-div --model claude-sonnet-5-5 "修复 calc.py 里的 div,让 python3 test_calc.py 通过。"
claude --bg --name add-mul --model claude-sonnet-5-5 "给 calc.py 加一个 mul(a, b) 函数,并在 test_calc.py 里加一条对应的测试。"
Starting background service…
backgrounded · e4b8a8ee · fix-div
claude agents list sessions
claude attach e4b8a8ee open in this terminal
claude logs e4b8a8ee show recent output
claude stop e4b8a8ee stop this session
backgrounded · 0914032e · add-mul
…
命令马上返回,终端还给你。几点说明:
- 任务描述是直接跟在后面的参数,不是
-p的值。--bg和-p不能一起用。 --name给会话起名字,不写的话它自己起一个。- 目录要先被信任过。本站是先在这个目录里开过一次普通的
claude,过了信任确认。
用 --json 可以从脚本里看状态。本站每十秒查一次:
19:19:47 desk=idle fix-div=working add-mul=working
…
19:20:50 desk=idle fix-div=done add-mul=working
19:21:00 desk=idle fix-div=done add-mul=done
两个任务同时跑,一个用了一分多钟,另一个再多十秒。desk 是本站开着的另一个普通会话,它也出现在这份列表里,类型是 interactive。
二、它们把改动放到哪了
这是最该先弄明白的一件事。两个会话跑完后,主目录里的 calc.py 一个字没变:
$ git worktree list
/home/ccdemo/demo/h15-agents 97013bf [main]
/home/ccdemo/demo/h15-agents/.claude/worktrees/add-mul bd13b92 [worktree-add-mul] locked
/home/ccdemo/demo/h15-agents/.claude/worktrees/fix-div b166907 [worktree-fix-div] locked
$ git log --oneline --all --graph
* bd13b92 Add mul function with test
| * b166907 Fix div to use true division
|/
* 97013bf init
每个后台会话在动手改文件之前,会先搬进自己的一份 worktree,在 .claude/worktrees/ 下面,分支名是 worktree- 加会话名。所以两个会话可以读同一份代码,写的时候互不干扰。
做完之后它不问就提交了。文档写了它收尾时的规矩:
| 做法 | |
|---|---|
| 提交 | 不问,直接提交 |
| 推送 | 仓库有远程才推。示例仓库没有远程,所以两个会话都没有推 |
| PR | 任务需要时开一个草稿 PR |
| 绝不做 | 推到 main 或 master、强制推送、合并 |
| 你另有规定 | 任务描述、CLAUDE.md 或记忆里说了提交和推送由你自己来,它就不碰 git |
要用它的成果,自己合并:
git merge worktree-fix-div
有几种情况不会进 worktree:目录不是 git 仓库;会话是你从一个已经开着的对话转到后台的(第六节);会话本来就在一个 worktree 里。不是 git 仓库时,几个会话直接写同一个目录,彼此没有隔离,别让它们改同一批文件。
仓库不方便用 worktree 的话,可以在项目的 .claude/settings.json 里关掉隔离:
{ "worktree": { "bgIsolation": "none" } }
三、打开 agent view
claude agents
▐▛███▛█ Claude Code v2.1.296
▝▜██████▀ Sonnet 5.5 · ~/demo/h15-agents
▝▝ ▝▝ 0 awaiting input · 0 working · 2 completed
Completed
✻ add-mul mul(a, b) and test_mul added and committed (bd13b92) on worktree-add-mul; test_mul passes, pre-existing test_div fails … 1m
✻ fix-div calc.py 的 div 由 a // b 改为 a / b,测试通过;提交 b166907 在分支 worktree-fix-div,需合并时在主目录运行 git merge worktr… 1m
────────────────────────────────────────────────────────────
❯ describe a task for a new session
────────────────────────────────────────────────────────────
claude-sonnet-5-5 · enter to open · space to reply · ctrl+x to delete · ? for shortcuts
每行是一个会话:名字、一句话的现状、存在了多久。会话按状态分组,需要你处理的排在前面。那句现状写得很实在,连提交号和“另一个测试本来就是坏的”都带上了,多数时候不用点进去。
这张表默认列出你所有项目里的后台会话,不只是当前目录。只想看一个项目,加 --cwd 和路径。在别的终端里开着的普通会话不在表里(上一节的 desk 就没有出现),要转到后台才会进来。
状态一共六种:
| 状态 | 意思 |
|---|---|
| Working | 正在调用工具或生成回答 |
| Needs input | 在等只有你能给的东西:回答一个问题、批准一个操作 |
| Idle | 没事可做,等你下一条指令 |
| Completed | 做完了 |
| Failed | 出错结束 |
| Stopped | 被你停掉了,或者进程被从外面结束了 |
行首的图标形状另有含义:✻ 表示进程还活着,∙ 表示进程已经退出。退出了的会话照样能看、能回复,一回复它就从存下来的对话里接着跑。
底部的输入框是派发新任务用的。在这里每敲一次回车,都是新开一个会话,不是给某个会话追加一句话。
四、它问你问题的时候
在输入框里派一个需要先问清楚的任务:
在 calc.py 里加一个 mod(a, b)。动手之前先问我一个问题:对负数取余,要按 Python 的规则还是按 C 的规则。等我回答了再写。
几秒后这一行出现在 Needs input 一组里,问题和选项直接显示在行上:
Needs input
✻ calc.py mod function answer: mod(a, b) 对负数取余时,应该遵循哪种规则? (Python 规则 · C 规则) 6s
--json 里对应的是 state 为 blocked,waitingFor 为 input needed。
选中这一行,按空格打开预览面板:
╭──────────────────────────────────────────────────────────────────╮
│ mod(a, b) 对负数取余时,应该遵循哪种规则?
│ 1. Python 规则 · 结果的符号与除数 b 相同(向下取整除法),例如 mod(-7, 3) == 2 …
│ 2. C 规则 · 结果的符号与被除数 a 相同(向零截断除法),例如 mod(-7, 3) == -1 …
│ waiting 33s
│
│ ❯ press 1-2 or type your answer
╰──────────────────────────────────────────────────────────────────╯
按 1,输入框里填上“Python 规则”,回车发出去。半分钟多一点它做完了,又是自己的 worktree、自己的分支、一个提交。
本站在这里走过一次弯路,值得说一下:焦点不在某一行上的时候,你敲的字会进到底部的派发输入框里。本站第一次按 1,结果输入框里多了个“1”,底部提示变成 enter to create,再按回车就会新开一个会话。看底部那行提示可以知道焦点在哪:
| 底部提示 | 焦点在 |
|---|---|
enter to open · space to reply |
某个会话那一行上 |
enter to collapse |
分组的标题上 |
enter to create · esc to clear |
派发输入框里有字 |
预览面板开着时,用上下箭头可以直接切到相邻的会话。
要注意一种情况:会话等的如果是权限确认这类对话框,在预览面板里回话是答不了的,你的话只会排进队列。那种要进到会话里去答。
五、进到会话里
在某一行上按回车或右箭头,agent view 就换成了那场完整的对话:它问了什么、读了哪些文件、怎么改的,最后还有一段你不在时发生了什么的回顾。在里面和普通会话一样用。
在里面运行 /status,能看到这是哪一种会话:
Session name: calc.py mod function
Session kind: background job · attached
cwd: /home/ccdemo/demo/h15-agents/.claude/worktrees/add-mod
输入框空着的时候按左箭头,回到那张表,会话继续在后台。
六、把手头的会话送到后台
正在用的普通会话也可以送过去。在里面运行 /bg,后面可以再带一句指令:
/bg 新建 NOTES.md,只写一行:desk 会话转到后台之后写的。不要提交。
实测的结果:这个会话的类型从 interactive 变成了 background,有了自己的短编号,终端换成了 agent view。它没有进 worktree,NOTES.md 直接出现在主目录里。这和文档说的一致:转到后台的会话接着在原来的地方改文件。
输入框空着时按左箭头,效果和 /bg 一样,顺带打开 agent view。
文档里还有一个 /fork:把当前对话复制一份到后台,原来的对话留着接着用。本站没有试。
七、只跑一条 shell 命令
后台任务不一定非得是一场对话:
claude --bg --exec "python3 test_calc.py"
它也成了表里的一行,显示命令最后一行输出。主目录里的 bug 还在,所以这一行是:
∙ python3 test_calc.py exit 1 — AssertionError
这种任务不调用模型。文档说它的输出只留在内存里,命令退出大约五分钟后连同这一行一起清掉,要结果就早点看。在 agent view 的输入框里以 ! 开头,是同一个意思。
八、删除会话:没推送的提交它不肯丢
在命令行里删一个会话:
$ claude rm 0914032e
kept 0914032e — its worktree is still at “…/.claude/worktrees/add-mul”
2 unpushed commits on “worktree-add-mul”: bd13b92 “Add mul function with test” and 1 more.
They exist on no remote, so deleting the worktree would lose them.
push them and run 'claude rm 0914032e' again, or discard the worktree and its commits:
claude rm 0914032e --discard-unpushed bd13b92ea8e7…@eaf709325ad9…
它没删,理由是这些提交不在任何远程上,删了就没了。这是个好的默认。
但有一个本站没料到的结果:先把分支合并进本地的 main,再删,它还是不肯。
$ git merge -q worktree-fix-div && python3 test_calc.py
ok
$ claude rm e4b8a8ee
kept e4b8a8ee — …
2 unpushed commits on “worktree-fix-div”: b166907 “Fix div to use true division” and 1 more.
They exist on no remote, so deleting the worktree would lose them.
文档的规则是:提交在远程上,或者在 origin 的默认分支的本地副本上,才算“保存在别处”。示例仓库根本没有配远程,所以合并到本地 main 不算数。这时照它给的命令加上 --discard-unpushed:
$ claude rm e4b8a8ee --discard-unpushed b166907c…@9f5ff25b…
removed e4b8a8ee
worktree: “…/.claude/worktrees/fix-div”
worktree 和 worktree-fix-div 分支都没了,main 上那个合并进来的提交还在。所以在没有远程的仓库里,顺序是:先合并,确认主分支上有了,再带着这个参数删。
另外三点:
- 删掉的只是表里的一行和那份 worktree。对话记录还在本机,可以用
claude --resume找回来。 - 在 agent view 里删更狠。 按两次
Ctrl+X会把 worktree 连同里面没提交的改动一起删掉;claude rm遇到没提交的改动会留着。 claude stop只是停,不删。
九、让一个会话去问另一个会话
几个会话各干各的,有时一个需要另一个手里的信息。这叫跨会话消息,符合条件时默认就开着。
先看一个会话够得着谁,在里面运行 /list-agents:
❯ /list-agents
⎿ This session: desk [5e5b1d] (the name other sessions use to message it)
Other Claude sessions (3):
[idle] · add-mul · /home/ccdemo/demo/h15-agents/.claude/worktrees/add-mul · started 4m ago
[idle] · fix-div · /home/ccdemo/demo/h15-agents/.claude/worktrees/fix-div · started 4m ago
[idle] · calc.py mod function · …
然后用平常的话让它去问:
❯ 问一下 fix-div 那个会话:它把 div 改成了什么写法,提交号是多少。等它回了,把它的回答告诉我。
⎿ “Ask fix-div for div change and commit hash” → sent to fix-div — another Claude session on this machine
⎿ Allowed by auto mode classifier
● 已经把问题发给 fix-div 了……它回了我就转告你。
› Message from @fix-div: div 已改完并提交。 (ctrl+o to expand)
● fix-div 回复了:
1. 改后的写法:return a / b,原来是 a // b。
2. 提交号:b166907,在分支 worktree-fix-div 上。
它还说 python3 test_calc.py 的输出是 ok。这是它自己报的,我没有核实。
整个来回用了二十多秒。消息的正文是 Claude 自己写的,你只要说清楚想问什么。对方空闲时,消息会让它开始新的一轮;对方正忙时,它在两次工具调用之间读到。
想点名的话,输入 @ 加会话名的头几个字母,从列表里选。
一条别的会话发来的消息能做什么
文档列了几条限制,都是为了不让一个会话借另一个会话越权:
- 它不能替你批准任何事。 来自别的会话的消息不算你的同意,答不了挂着的权限确认。
- 它不能让对方改配置。 权限设置、
CLAUDE.md都不会因为别的会话一句话就改。 - 里面的命令不会执行。 消息里写
/compact,到了对面就是几个字。 - 该问你的照样问你。 照消息去做事如果需要对方会话没有的权限,你会看到平常那个确认框。
收不收消息由 crossSessionInbound 这项设置决定,三个值:accept 收,hold 先扣着等你批,refuse 直接丢。不设的时候按两边的权限模式逐条判断:一般都直接送达;只有一边是跳过全部权限确认的模式、另一边不是时,才扣下来等你批。
要彻底关掉发送,在权限的 deny 里加上 SendMessage 和 ListAgents。注意前一个工具也管着给子代理和 teammates 发消息,禁了会一起没。
能传多远
- 同一台机器上的会话:任何接入方式都能用,包括走中转站。本站测的就是这种。
- 别的机器上的会话、云端会话:要这个会话连着 Remote Control,而 Remote Control 要 claude.ai 账号登录。走中转站用不了。
走中转站要注意的两件事
一、接入配置要写在设置文件里。 文档专门说了:通过网关使用时,把网关的变量放进设置文件的 env 块,后台会话会跟着其他设置一起读到;只在 shell 里 export 的话,后台会话不一定拿得到。本站的测试机就是把接口地址和令牌写在 ~/.claude/settings.json 的 env 里的,后台会话全程正常。
如果派发时报 Could not resolve authentication method,说明后台服务没拿到凭据。文档的办法是让它重启一次:
claude daemon stop --any --keep-workers
然后在一分钟内重新运行 claude agents。
二、行上的那句摘要要用小模型写。 文档说摘要和自动起的名字由 Haiku 一档的模型生成,通过你平常的接入方式发请求、照常计费;没有配置这一档模型的网关,会改用会话的主模型。本站这把中转站的 key 不支持 Haiku 5.5,但摘要和名字都正常出来了。它们具体是哪个模型写的,本站没有查。
命令行速查
| 命令 | 作用 |
|---|---|
claude agents |
打开 agent view |
claude agents --json |
把会话列表打印成 JSON。加 --all 包括已经做完的 |
claude --bg "任务" |
派发一个后台会话 |
claude --bg --exec '命令' |
把一条 shell 命令作为后台任务跑 |
claude attach <编号> |
在当前终端进入一个会话 |
claude logs <编号> |
打印会话最近的输出 |
claude stop <编号> |
停止 |
claude rm <编号> |
从列表里删除 |
claude respawn <编号> |
重启一个会话,比如为了换上新版本 |
claude daemon status |
看后台服务的状态 |
claude daemon stop --any |
停掉后台服务和它托管的会话 |
打开 agent view 时可以带上派发的默认值,比如让之后派出去的会话都从计划模式开始:
claude agents --permission-mode plan --model opus --effort high
claude logs 有一点要知道:本站在管道里拿到的是整屏终端画面的原始输出,夹着大量控制字符,没法直接搜。脚本里要读状态,用 --json。
--json 里的 state 有五个值:
state |
意思 |
|---|---|
working |
一轮正在跑 |
blocked |
在等你。等的是什么,看 waitingFor |
done |
上一轮做完了,等你的下一条指令 |
failed、stopped |
出错结束,或者被停掉了 |
做完一轮、等你下一句话的会话是 done,不是 blocked。
后台服务会不会一直占着资源
- 做完了、没人看的会话,大约一小时后进程会被停掉。对话存在磁盘上,你一回复它就接着来。
- 电脑睡眠不影响,醒来后接上。关机会停掉正在跑的会话,开机后它们显示为失败或已停止,进去回一句让它继续就行。
- 不想要这个功能,把
disableAgentView设成true。
本站测完后运行了一次 claude daemon stop --any,状态变成 not running,机器上没有留下进程。
花费
每个后台会话各自计费,同时开十个,额度消耗的速度大约是一个的十倍。后台会话结束时不打印花费,这次实测的总花费本站没有统计。四场对话都是几轮就结束的小任务,用的是 Sonnet 5.5。
这次实测没有覆盖到的
- 没有远程的仓库是唯一测过的情况。有远程时的推送、草稿 PR、行尾的 PR 标签,都没有试。
/fork、置顶、重命名、筛选、按目录分组、把 agent view 设成默认界面,没有试。- 权限确认卡住会话的情况没有遇到。测试机的会话都是 auto 模式,没有弹过确认。
- 跨机器的消息、空闲通知、
crossSessionInbound的三个值,没有试。 - 关机后的恢复、自动更新后的迁移,没有试。
- 每个场景只跑了一次,只在 Linux 的 tmux 里。