tmux 断开后 Claude Code 还在跑,Key 走 TaoToken,入口在这里 https://taotoken.net/?utm_source=taotoken_aicg_blog_end。最近 Claude Code 用得密,机器资源也紧张,索性把日常编辑环境换成了 kitty + tmux + lazyvim 这套轻量组合。换完才发现,真正被救回来的不是编辑器,而是会话:Session 断开之后进程继续跑,Server 还在,pane 里的 Claude Code 照旧按自己的节奏调用模型、读写文件、跑测试。可会话只是壳,壳里跑的东西总得有一条通道出 Key。官方通道在多 Key、多工具、频繁切模型的场景下很容易卡住,所以这篇把两件事接起来写——tmux 侧照旧 detach / attach,Claude Code 侧把 Base URL 指到 https://taotoken.net/api,Key 用 TaoToken 签发的那把,tmux 这边的配置一行都不用动。
1. kitty + tmux + lazyvim 之后,真正值钱的是长会话底座
1.1 编辑器可以随时关,Agent 的任务不能
kitty 快、lazyvim 启动轻,这两样解决的其实都是「打开快不快」的问题,属于手感层面。Claude Code 这类 Agent 完全不同,它一次任务动不动十几分钟:先扫一遍目录结构,再读七八个文件,中间可能还要跑一次构建、分析一段报错、重写两个模块。你不可能要求它在第 9 分钟因为你手贱按了个 Ctrl+W 就重头再来。
所以我换环境时最看重的不是启动速度,而是「关掉终端之后它还能不能接着干」。这也是 tmux 在这个组合里的真实位置——它不是给你分屏看日志的花架子,而是给长任务准备的一层托底:终端窗口关了、SSH 断了、笔记本合盖了,进程都还挂在 tmux Server 上,等着你回来。
1.2 断线一次,重跑一次的成本
很多人对「断线重跑」的代价没有直观感受,觉得无非是再敲一遍命令。实际损失的是上下文:Agent 已经读进内存的那一大坨文件内容没了,它对项目结构的理解没了,前面几轮纠偏攒下来的判断也没了。你重新启动,它得从零再问一遍「你这个项目是干什么的」,然后再把同样的文件读第二遍。
多花的不只是时间,还有 Token。同样一份任务,被断线打断两次,就是三倍的输入消耗。所以「把会话保住」这件事,其实是在省钱。
1.3 会话保住了,出 Key 的通道还悬着
原文那套 tmux 日常用法讲得很到位:怎么 detach、怎么列会话、怎么接回去、怎么用插件自动恢复,这些是骨架。但骨架之外还有一根线没接——会话里跑着的 Claude Code,究竟从哪条通道出 Key?
如果 Key 还是走官方通道,你会遇到另一种意义上的「断线」:额度用光、多工具互相挤、换模型要改一堆地方,甚至一个 Key 被几个项目同时用着,出了问题都不知道是谁的。这一层不解决,tmux 帮你保住的会话,接回来照样可能是一堆报错。解决办法不复杂:打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册账号、创建 API Key,然后把 Claude Code 的 Base URL 换掉即可,具体到下一节。
2. Prefix + d 断开之后,tmux 到底替你保住了什么
2.1 Ctrl+D、exit 与 Prefix + d 的区别
这三个操作经常被混着用,结果就是「我以为我 detach 了,其实我把进程杀了」。
- Ctrl+D:往 pane 里发一个 EOF。如果当前前台是 shell,shell 读到 EOF 就退出,pane 跟着被销毁,你之前启动的 Claude Code 一起没了。
- exit:和上面差不多,是显式让 shell 退出。
- Prefix + d:这才是 detach。它把当前 client 从 session 上摘下来,session 和里面所有 pane、所有进程原封不动留在 tmux Server 上继续跑。
记住一句话:想让任务活着离开,只用 Prefix + d;Ctrl+D 是告别,不是离开。日常建会话时养成带名字的习惯,后面接回来会省事很多。
tmux new -s claude-long命名之后,tmux ls列出来的就是claude-long: 1 windows (created ...)这种一眼能认出来的条目,不至于对着一串数字发呆。
2.2 tmux ls 与 tmux a -t 的完整接回流程
完整流程其实就三步,顺序别乱:
# 1. 离开,进程继续跑 # 在会话里按 Prefix + d # 2. 看会话还在不在 tmux ls # 3. 按名字接回去 tmux a -t claude-longtmux ls是这一步的判断依据。如果列表里能看到claude-long,说明 Server 还在、会话还在,里面的 Claude Code 大概率还在跑;如果列表空的,那就是别的问题,不是 attach 姿势不对。
tmux a -t是tmux attach -t的简写,-t后面跟会话名。名字记不清时可以直接tmux a,只有一两个会话时它会自动接上去。接回来之后先别急着敲命令,看一眼 pane 里的输出有没有在往前走,确认任务真的活着。
2.3 会话能保住,进程里的环境变量不一定保得住
这是最容易翻车的一点,也是原文没展开的部分。tmux Server 在你第一次执行tmux时就启动了,之后所有新 pane 继承的都是 Server 启动那一刻的环境变量快照。你在.zshrc/.bashrc里新加了一行export,然后source一下——当前 shell 有了,但 tmux 里的新 pane 未必有。
判断方法很直白,直接在 pane 里敲:
echo $ANTHROPIC_BASE_URL如果输出为空,或者还是老地址,就说明环境没刷新到 tmux 里。两个处理方式,选一个:
# 方式一:把变量写进 tmux 的全局环境 tmux set-environment -g ANTHROPIC_BASE_URL https://taotoken.net/api # 方式二:重建 Server,让所有 pane 重新继承 shell 环境 tmux kill-server方式二会把所有会话清掉,只适合没有正在跑的长任务时使用。有任务在跑的时候,用方式一,或者干脆只在新开的 window 里跑新配置。
3. 会话里跑的 Claude Code,Key 从 TaoToken 这把走
3.1 先在官网创建一把属于自己的 Key
前往 TaoToken 完成注册,进控制台创建 API Key。拿到之后不要直接粘进脚本里,先在本地记好,本文所有示例统一用占位符YOUR_API_KEY表示,你自己替换成真实值。
顺手在模型广场确认一下要用的模型 ID。模型列表是会更新的,别照着半年前的博客抄一个带日期后缀的名字填进去,以模型广场当时的列表为准。
3.2 Base URL 填 https://taotoken.net/api,末尾不要带 /v1
这是全篇最容易写错的一行。填进 Claude Code 的地址是:
https://taotoken.net/api三个要点:不带/v1、结尾不加斜杠、不要加任何查询参数。很多人习惯性写成https://taotoken.net/api/v1,然后收到 404 或者路径拼接错乱的报错,回头排查半天。另外要注意区分用途——注册、创建 Key、看用量、看模型列表这些动作在官网落地页做;填进工具里的 Base URL 才是接口地址,两者别混用。
3.3 shell 变量与 ~/.claude/settings.json 两种写法
写法一:环境变量,适合临时验证或者多套配置切换:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_MODEL="YOUR_MODEL_ID"写法二:写进~/.claude/settings.json,适合长期使用,跟着用户目录走,换终端也不丢:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "YOUR_MODEL_ID" } }两种写法可以共存,settings.json 里的值优先级更高,也更容易被复制到别的机器上。注意 JSON 里不能写注释,粘过去之前先把多余的逗号删干净。
3.4 配置改完,tmux 这边要做的只有刷新环境
tmux 侧的窗口、pane、快捷键配置统统不用动。你要做的只是让新 pane 拿到新变量:
tmux set-environment -g ANTHROPIC_BASE_URL https://taotoken.net/api tmux show-environment -g | grep ANTHROPIC第二行是自检命令,能看到变量名说明写进去了。之后在会话里新开一个 window 启动 Claude Code,它读到的就是新的通道地址。已经跑着的那个会话不用重启——它的进程早就把配置读进内存了,中途改环境反而容易出怪事,等当前任务收尾再重开。
4. tmux a -t 回来,验证会话里的 Claude Code 还通
4.1 detach → ls → attach 三步验证长任务
验证不用搞复杂,就按原文那套流程走一遍,重点是观察接回来之后有没有正常返回:
tmux ls # claude-long: 1 windows (created Thu Sep 11 10:21:33 2025) tmux a -t claude-long接回去之后,先给 Claude Code 发一句轻量请求,比如让它解释一下当前目录里的某个文件是干什么的。如果在几秒内看到流式输出正常往外吐,说明通道是通的;如果卡住不动,或者直接甩一个报错出来,去第 6 节对照排查。
我自己的习惯是:detach 之前先记一下当前的任务进度,attach 回来第一件事是确认那个进度还停在那,而不是重新开始。这一步能确认进程真的活着,而不只是 pane 壳还在。
4.2 focus-events 与 aggressive-resize 两个开关别漏
~/.tmux.conf里这两行值得加上:
set -g focus-events on set -g aggressive-resize on set -g mouse on set -g history-limit 50000focus-events打开后,pane 才能收到 focus in / focus out 事件。Claude Code 这类基于 Ink / React 的 TUI 会用它来决定什么时候重绘、什么时候暂停渲染,关着的时候容易看到界面残留、光标位置错乱、输入框里的字叠在一起这类毛病。
aggressive-resize解决的是多个 client 同时 attach 到同一个 session 时的尺寸问题。默认行为是按所有 client 里最小的那个尺寸来限制窗口大小,你在大屏上看着正常,手机上接进来一下就全挤成一条。打开这个开关后,tmux 只按当前实际在看这个窗口的 client 计算尺寸,多端切换会舒服很多。
改完配置用tmux source-file ~/.tmux.conf生效,或者直接重启 Server。
4.3 多 client attach 时,别在两边同时输入
同一个 session 被两个终端 attach 是常见操作,但有个坑:两边看到的是同一个 pane,键盘输入会同时生效。一边在 Claude Code 里打字,另一边也在打,最后拼出来的指令谁也看不懂。
规矩很简单:要操作的时候只在一个 client 上输入,另一个纯看。看完就 detach,别挂着。另外如果在笔记本和外接屏之间切换导致 TUI 花屏,Prefix + d再tmux a -t一次通常就能重绘干净。
5. tmux-resurrect / tmux-continuum 恢复现场之后查什么
5.1 TPM 与两个插件的配置写法
机器重启、Server 意外挂掉的时候,tmux ls就是空的,这时候靠的是插件。~/.tmux.conf里加上:
set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-resurrect' set -g @plugin 'tmux-plugins/tmux-continuum' set -g @continuum-restore 'on' set -g @continuum-save-interval '10' set -g @resurrect-capture-pane-contents 'on' run '~/.tmux/plugins/tpm/tpm'装完按Prefix + I让 TPM 拉取插件。手动存档和恢复分别是Prefix + Ctrl+s和Prefix + Ctrl+r,continuum 则按你设的间隔自动存档,并在 Server 启动时尝试恢复。
@resurrect-capture-pane-contents打开之后,恢复时能带回 pane 里最后一段可见输出,对判断「任务跑到哪了」帮助很大。
5.2 恢复回来的会话,先查这三样
resurrect 能恢复的是窗口布局、工作目录、pane 里的滚动内容和部分程序的启动命令,但它不负责恢复环境变量。所以恢复之后别急着继续干活,先过三关:
echo $ANTHROPIC_BASE_URL,确认通道地址还在;tmux show-environment -g | grep ANTHROPIC,确认 tmux 全局环境里有值;- 在 pane 里发一句轻量请求,确认 Claude Code 能正常返回。
三关都过,说明现场真的接回来了。如果第一关就空,按 3.4 的方式补一下变量即可,不用重装任何东西。
6. detach 回来常见的几种不对
6.1 请求层报错对照
| 现象 | 大概率原因 | 处理 |
|---|---|---|
| 401 / 鉴权失败 | Key 复制时带了换行或空格,或用了已删除的 Key | 回控制台重新复制,或新建一把 Key |
| 404 / Not Found | Base URL 写成了以/v1结尾,或结尾多了斜杠 | 改回https://taotoken.net/api |
| 模型不存在 | 模型 ID 抄了旧名字 | 以模型广场当时的列表为准,重新填 |
| 连着超时 | 变量只在当前 shell 生效,pane 里是空的 | tmux set-environment -g补上后重开会话 |
排查顺序建议从变量开始,再查地址,最后查 Key。反过来查容易绕远路。
6.2 会话层掉坑
- 会话不见了:多半是用了 Ctrl+D 或
exit,不是 detach。养成只用Prefix + d的习惯。 - 接回来界面乱码:先确认
TERM正常,再重新 attach 一次重绘;focus-events没开会更容易花。 - 进程还在但请求打不通:八成是环境变量没跟着恢复,按 5.2 的三关走一遍。
- 多端尺寸异常:检查
aggressive-resize是否打开。
这些问题里,真正跟 taoToken 有关的其实只有前两类,剩下的都是 tmux 自己的使用习惯问题,理清楚之后基本不会反复踩。
7. 下一步:把这次调用在控制台对一下
配置写完、会话跑通之后,还有一件值得做的事:确认这次的请求真的记在了你自己的账号上,而不是稀里糊涂走错了通道。
最省事的验证方式是在 TaoToken 模型对话 里用同一把 Key 发一条测试消息,模型 ID 和 Base URL 都填一样的值,能正常返回就说明配置没错位。如果打算把 Claude Code 当成日常主力,可以顺手看看 Coding Plan 的套餐是否够用;需要再建 Key 或者轮换 Key,在 控制台 API Keys 里操作。环境变量和 settings.json 的字段对照,可以翻 Claude Code 接入文档,比自己试要快。
回到 tmux 这条线,最后提醒一句:Prefix + d之前,确认 Claude Code 当前这一步是安全的、可中断的,再离开。绝大多数任务都能在 detach 之后自己跑完,但涉及删除文件、推代码、改数据库这类动作,还是等它到一个人畜无害的停顿点再走开。会话能保住进程,保不住你的判断力。