ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Claude Code卡顿全解析:从Spinner到工具阻塞的排查路径

Claude Code卡顿全解析:从Spinner到工具阻塞的排查路径 Claude Code 用久了最磨人的不是模型偶尔答错而是终端里那个 Spinner 一直转、界面像按了暂停键。指令发出去左下角的小圈圈开始转一秒、两秒、三十秒……你不敢回车怕打断任务不舍得 CtrlC怕前功尽弃。这篇文章就从 Spinner 状态标识说起把 Claude Code 卡顿的根源一层层拆开再给出一套能直接上手的排查方案。它不会让网络变快、也不会让模型变聪明但能让你在下次卡住时知道该看什么、该做什么、该按哪个键。1. Spinner 不是装饰品先搞懂它在表达什么1.1 终端里常见的几种 Spinner 形态与真实含义Claude Code 的界面是典型的 CUIConversational UI它不像网页版那样有丰富的加载状态提示大多数时候你只能看到一个小动画在转。很多人把 Spinner 等同于模型正在思考并据此判断转得越久Claude 想得越深。这个直觉只对了一半Spinner 的本质只是当前有一个请求在途它完全没有区分正在正常生成和已经彻底卡死的能力。我观察了一段时间归纳出终端里常见的几种形态。第一种是消息流末尾的单行 Spinner 持续旋转这通常意味着请求已经发出但还没等到服务端返回第一个数据包也就是常说的 TTFB 阶段。第二种是 Spinner 停了、光标还能动这种反而更像假死因为事件循环可能已经等不到下一个事件了。第三种是 Spinner 消失但命令迟迟不回来十有八九是工具调用挂住比如 Bash 命令开了一个不会结束的进程。第四种比较隐晦输出区出现[bash]、[read]这类工具名称前缀表示本地工具正在执行这个阶段界面往往停留在等待工具结果状态看起来和卡死没什么区别。第一次遇到这种问题的人最容易踩的坑就是只看 Spinner 的转或不转而忽略它背后的 Promise 状态。Spinner 的视觉状态只告诉你有没有一个挂起的任务不告诉你这个任务会不会成功返回。理解了这一点排查的起点就变了你要找的不是Spinner 为什么不动而是这个挂起的请求卡在了哪一层。1.2 Spinner 背后的执行状态机一次请求的完整生命周期Claude Code 一次普通交互内部大体会走这么一圈流程。你输入 prompt 后工具会把系统提示、工具定义、历史消息、以及可能被 Read 过的文件内容全部组装进一个 Messages API 请求体然后发出 HTTP 请求。这个阶段 Spinner 立刻开始转而且往往是最容易误导人的阶段——网络差的时候它能转几十秒甚至更久。接下来是 SSEServer-Sent Events流式接收阶段模型开始一点一点吐内容终端里出现打字机效果。如果你能看到文字在增量输出就说明请求已经成功进入生成阶段。这里有个关键分支如果模型返回的内容里包含tool_use块Claude Code 会暂停生成转而在本地执行对应的工具——比如 Bash 运行命令、Read 读取文件、Edit 修改代码。工具执行完成后结果会被塞回上下文作为新的一轮消息再次发给模型然后循环往复直到模型给出最终的文字回复。Spinner 的每一次常驻旋转本质上意味着流程停在了上面几个环节的某一个里。我在实际测试中倾向于把停驻状态归成三类请求在途还没收到首包、输出阻塞流式中断但连接没断、工具挂起本地命令没有返回。后面所有排查方案基本就是围绕这三种状态展开的。这也是为什么我一直说日志比肉眼判断靠谱得多。1.3 快速判断当前卡在哪一步的三个技巧在没开 verbose 日志的情况下也有一些几分钟就能上手的速判方法。第一看屏幕有没有增量文字输出。如果有增量说明已经进入流式生成阶段卡点大概率在后续的工具调用或者新一轮请求上如果从最开始就没有任何输出问题基本锁死在请求发出但没收到响应。第二按一下 Esc 或者 CtrlC观察界面是否有反应。如果出现中断或停止的提示说明事件循环还活着只是当前请求挂起如果按了以后毫无反应那可能是终端本身出了问题Claude Code 这个进程已经不在事件循环里了。第三另开一个终端用ps aux | grep nodemacOS/Linux或者任务管理器查看进程状态。CPU 占用高说明本地在做大量文件扫描或正则处理CPU 占用为 0 而 Spinner 还在转典型的网络等待。这三个方法不需要任何配置能帮你在五分钟内缩小排查范围。但它只负责回答大概在哪个阶段真要溯源还得靠日志。我把这个流程叫先定性、再定位——先分清是不是终端问题再判断是请求还是工具最后才动手修。2. 卡顿根源从终端到服务端的全链路拆解2.1 网络链路TTFB 和流式响应是头号嫌疑说句不太好听的大实话Claude Code 绝大多数Spinner 无限旋转根源根本不在代码也不在模型本身而在网络链路。命令行工具每发一次请求都要经历 TCP 连接建立、TLS 握手、服务端返回首字节三个时间阶段三段加起来决定了一次请求的起跑速度。如果前面几段很慢哪怕模型回答得飞快用户体感依然是卡到怀疑人生。不同的慢有完全不同的信号。如果 TTFB 大但一旦开始接收、后续输出很稳定通常是链路距离远、请求体大或者服务端排队。如果首包很快但流式输出一段一段断开大多是带宽不稳或者网络中间层对长连接不友好SSE 分块到达时间被人为拉长了。如果请求完全无响应那就要先查基本连通性再考虑是不是本地安全软件或者防火墙在做什么额外检查。这里分享一个我常用的实证方法在另一个终端里不用跑完整请求直接对 API 端点发一个轻量的空请求用 curl 的-w参数看各阶段耗时。curl -o /dev/null -s -w DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n https://api.anthropic.com/v1/messages这个请求大概率会返回一个 401 或者 404但网络时序已经完整测出来了。如果 DNS 解析就花了三秒那问题在域名解析这一层如果 Connect 很慢那是基础连接问题如果 TTFB 很长那要么是链路跨区要么是服务端在忙。我用这个方式排查过不少Spinner 一直转的情况结论往往很直接——模型根本还没开始思考是请求在网络上堵住了。2.2 上下文过长请求体体积被悄悄撑大排除网络问题后第二大头是上下文体积。Claude Code 每次请求并不是只发送你刚刚输入的那句话它会自动携带整个会话的历史消息、工具执行结果、Read 工具读过的文件内容甚至包括当前工作目录的结构信息。这意味着一个看似简单的帮我把这个函数改成异步在一个长会话里可能携带了几万甚至几十万 token 的输入。这里有一个可计算的原理模型处理输入的时间会随着 token 数量上涨同时大请求体的带宽占用也在拖慢首字节时间。我做过一次对比实验同一句话在新会话里只需要 1.5k token而在一个连续工作了两小时的会话里input_tokens 涨到了 65k 左右Spinner 转的时间差了将近十倍。这不是玄学是实打实的开销。很多人抱怨Claude Code 越用越卡其实不是工具变笨了而是你带着一整个仓库的上下文在反复发请求。如果你用的版本支持/context或/status命令可以直接看当前会话的上下文使用情况。看到 input_tokens 上万就说明这个会话该瘦身了。瘦身的具体方法我放到第三节讲这里想先点破一个观念Claude Code 的会话不是越连续越好它和人类开会一样议题太多、纪要太长后面反而所有人都抓不住重点。2.3 服务端限流与过载429、529 和没有报错的沉默还有一种常见卡顿来源发生在你完全控制不了的远端服务端限流或过载。当 API 请求量突然升高或者账号、组织被限速时服务端会返回 429 Too Many Requests当服务端本身负载过高可能会返回 529 Overloaded 或者类似的overloaded_error。这类错误在 Claude Code 的界面上不一定每次都会弹出来有时候工具会选择默默重试表现为 Spinner 长时间空转然后突然吐一个错误或者半截回复。遇到这种情况优先看 verbose 日志里的 HTTP 状态码和响应头。如果日志里出现 429、529或者看到retry-after头基本可以断定是被限流或过载了。此时最优解是暂停几分钟、降低并发而不是疯狂重试。我见过有人同时开五六个 Claude Code 会话跑任务结果每个会话都在限流边缘反复横跳时间全花在等待上了。组织订阅场景下还要注意组织策略是否限制了个人使用额度如果你在日志里看到类似 your organization has disabled 之类的内容直接找管理员确认策略就好自己在客户端侧反复重试没有任何意义。2.4 本地终端与系统资源被忽略的隐形卡顿有时候 Spinner 的表现非常诡异转两秒、停四秒、再转两秒断断续续。很多人第一时间怀疑 API实际上很可能是本地终端环境在拖后腿。我总结过几个高频因素排在首位的是终端渲染性能。新版 Windows Terminal 和 iTerm2 对 ANSI 转义序列、超长行、特殊字符的处理都不错但一些老终端或者 SSH 客户端在输出一大片文本时渲染线程会卡到界面直接变 PPT。其次是字体和字符集问题。Claude Code 的输出里偶尔会带一些不常见符号或非 ASCII 字符如果当前终端字体没有对应的字形系统会触发字体回退和重绘肉眼可见地卡顿。第三个容易被忽略的是安全软件和文件系统监控。Windows 平台上尤其明显Defender 或其他安全软件会对 node_modules 目录、日志文件做实时扫描磁盘 IO 一忙整个工具链都跟着变慢。我在 Windows 11 上实测过把工作目录加入杀软的排除列表、并把终端升级到新版之后Claude Code 的流畅度提升非常明显。最后是电脑本身的资源状况。内存不足、CPU 被占满、磁盘接近写满时任何终端命令都会受影响。那些通用的电脑卡顿怎么处理经验——清后台、关无用应用、看资源占用——在 Claude Code 场景下同样适用。这类本地问题的坑在于日志里看不到任何 API 报错请求数据全正常但你就是体感卡。排查思路也很简单先切个轻量终端试试再临时关实时病毒扫描最后看任务管理器。如果切终端以后立刻顺畅那基本就是渲染层的问题跟模型和网络都没关系。2.5 工具调用阻塞卡在执行而不是思考Claude Code 的核心能力是让模型直接调用工具执行命令、改文件。这一步的实际机制是模型先生成一个tool_use块然后由本地进程真正去执行。很多时候 Spinner 卡住不是模型没回复而是工具执行永远没有结束。最典型的是 Bash 工具。比如你让 Claude 启动一个本地服务或者运行一个监控命令像npm run dev、tail -f xxx.log这类命令根本不会自己退出。Claude Code 作为子进程执行它们时工具调用会一直挂起界面看起来就是停在执行中转圈。其次是文件读写被占用比如某些编辑器锁定了文件、git 索引被锁、权限弹窗在等待输入都会让工具调用无法完成。再常见一点的是长命令执行过程中你切走了终端焦点某些操作系统会给后台任务降权CPU 时间片不够命令就慢得出奇。判断这类问题其实不难看输出区有没有一个[bash]或[edit]标签再看命令本身是不是不会自行结束的类型。如果是那你已经找到了卡顿的真凶。处理方式也不是只能干等具体操作在后面 3.3 里详细说。3. 排查方案实战一套能用到最后的定位流程3.1 第一步开启 verbose让不可见变为可见我处理 Claude Code 卡顿的第一原则不要靠猜先把日志打开。Claude Code 提供--verbose或-v启动参数开启后会在终端里打印更多调试信息同时把运行日志写入本地目录。macOS/Linux 下通常在~/.claude/logs/Windows 下在%USERPROFILE%\.claude\logs\里按日期归档。你可以用tail -f实时跟进日志文件tail -f ~/.claude/logs/$(date %Y-%m-%d).log一份能用的日志应该能回答这些问题请求发给了哪个端点、请求体里带了多少输入 token、SSE 事件序列走到哪一步、HTTP 状态码是什么、工具执行有没有返回。比如你会看到类似下面的片段[DEBUG] Request to API: modelclaude-sonnet-4-20250514, input_tokens12642, max_tokens4096 [DEBUG] Stream event: message_start [DEBUG] Stream event: content_block_delta (text, 15 chars) [DEBUG] Tool use: bash npm run dev [DEBUG] Tool result: timeout, command did not exit after 90s有了这种日志排查就不再是盲猜。我的建议是平时就记住日志目录在哪或者干脆配个别名快速跳过去。别等卡了之后才临阵磨枪那时你大概率已经慌得忘了自己在等什么。3.2 第二步三种分诊状态三种完全不同的处理方式拿到日志后先做一次快速分诊把问题归入三类假死、慢响应、工具阻塞。假死的特征是界面完全无响应按 Esc、CtrlC、输入/status都没反应这个状态下优先怀疑终端渲染层或进程事件循环卡死处理方式是重启终端或杀掉进程。慢响应的特征是日志显示请求已发出但迟迟没有message_start或者在消息生成中途出现了大段间隔这个要向 TTFB 和上下文体积两个方向排查。工具阻塞的特征是日志尾部停在某个 Tool use 事件上始终没有对应的 Tool result这个要找的是那个还没退出的子进程。我个人经验里超过 70% 的Spinner 卡住最后都落在假死和工具阻塞这两类上真正常见的模型生成慢反而没那么多。很多人一卡就怪模型慢属于典型的归因错误。分诊完成之后处理动作完全不同假死要重开终端慢响应要查网络和上下文工具阻塞要去杀进程。如果连分诊都不做就直接重启下一次大概率还会卡在同一个地方。3.3 第三步对症下药的三套处理方案先说网络与请求阶段。先用前面 2.1 里的 curl 命令测各阶段耗时。如果延迟高试一下切换网络环境比如从公司 Wi-Fi 切到手机热点看看有没有改善。如果改善明显那基本可以确认是链路问题同时还排查一下本地安全软件是不是在做流量过滤。临时抢救做法是把超时心理预期放宽到三到五分钟但这不是根治只是给你时间去确认问题真正要落地的还是优化链路质量。再说上下文膨胀。如果日志里 input_tokens 已经到了几万这个会话必须瘦身。我常用的操作顺序是先用/compact让 Claude 把历史对话压缩成摘要如果压缩完还是卡就把当前任务复制到新建会话里继续平时也要注意别让 Claude 一口气 Read 一堆大文件读完立刻把它忘掉或者直接用/clear切断上下文。最重要的是改变使用习惯长任务拆成多个短任务每个会话只聚焦一件事从根上避免上下文膨胀。我在实际项目里最大的一个改善就是改掉了一个会话用到天荒地老的习惯换成按功能点切会话之后卡顿率明显下降。最后说工具阻塞。先判断这个命令是不是会自行结束的类型如果不会下次让 Claude 改成后台执行把输出写到日志文件再跟随而不是直接挂前台。其次在另一个终端里查进程ps aux | grep -E node|bash找到可疑残留进程直接终止。再检查当前目录有没有.git/index.lock是否有文件被编辑器占用。处理完之后用/status或者发一个简单的测试消息确认 Claude Code 已经恢复事件循环。记得前面提过的教训按 CtrlC 不一定能杀掉真正的子进程要杀就杀干净别留尾巴。3.4 第四步用配置把卡顿概率降下来排查完当前这一次更值钱的是通过配置减少未来卡顿的频率。我的用户级配置文件在~/.claude/settings.json里面我常用的优化项是这样{ model: claude-sonnet-4-20250514, permissionMode: acceptEdits, includeCoAuthoredBy: false }把 model 调成速度更快的系列而不是默认的顶配推理模型。日常重构和写测试用快模型复杂架构设计才用顶配这个区分能大幅缩短每次 Spinner 的时间。permissionMode 设为acceptEdits可以减少权限确认带来的交互等待但前提是你得信任当前仓库团队公共仓库或者来路不明的代码慎用。includeCoAuthoredBy 关掉可以减少不必要的元信息 token也符合不少团队的干净提交要求。环境变量层面我通常还会设置export ANTHROPIC_API_KEY你的密钥 export ANTHROPIC_MODELclaude-sonnet-4-20250514 export ANTHROPIC_SMALL_FAST_MODELclaude-haiku-4-xANTHROPIC_SMALL_FAST_MODEL专门用来指定后台辅助任务使用的小模型比如给会话起标题、做上下文总结这类轻量活。如果你看到某些操作卡了很久却不涉及主对话生成那很可能就是这个辅助模型在拖后腿给它换个更快的模型体验立马上来。如果你是用 cc switch 这类工具接的第三方兼容端点调用 DeepSeek、Qwen、GLM 等模型那要注意别把超时参数设得太小。这类服务端在高峰期推理速度参差不齐对流式接口的支持也不一样Spinner 卡顿的概率天然高一些。我的建议是先用最简单的纯文本问答验证连通和延迟再开工具调用别一上来就跑重活。4. 高频问题速查表与避坑笔记4.1 一张表对号入座快速定位常见现象我把这几年遇到的各种卡住现象整理成了一张速查表每次都先对号入座再决定下一步动作。现象最常见根因优先排查动作Spinner 一直转没有任何文字输出请求未拿到首包verbose 日志 curl 测 TTFB文字输出到一半停住再没动静流式断流或 API 限流看日志里有无 429/529出现 [bash] 后长时间不返回工具命令不会退出查子进程、.git/index.lock界面能操作但输出频繁卡顿终端渲染层问题换新版 Windows Terminal / iTerm2换一个网络环境就明显变好链路质量差优化网络调整重试策略长会话末尾特别容易卡上下文膨胀/compact切新会话命令执行后没有任何反应权限确认被忽略检查是否有等待确认的交互日志显示流式正常但界面不更新字体/字符集渲染问题更换终端字体开启字体回退这张表不能覆盖所有情况但能覆盖我遇到过的绝大多数。剩下的那些基本要靠日志里的具体事件来推。4.2 我踩过的几个坑希望你直接绕过去第一条别把 CtrlC 当万能解药。在工具调用阶段按 CtrlC有时只会中断 Claude Code 本轮的工具执行不会杀掉真正在后台跑的子进程。你以为结束了其实子进程还在占用资源下一个请求继续叠加整体越来越卡。正确做法是先ps定位残留进程再把它终止掉。第二条不要同时开五六个 Claude Code 会话做并行任务。虽然工具本身支持多开但每个会话都带着独立的上下文和请求队列API 并发一高限流和过载是必然的。我的原则是主任务一个窗口辅助任务最多一个再多就得排队排队的体感就是卡。第三条Windows 用户别忽略杀毒软件和终端版本。我把终端升级到新版 Windows Terminal、把工作目录加入杀软排除列表之后流畅度提升不止一个档次。这类优化不起眼但很多时候它就是卡和不卡的分界线。另外如果你的 Windows 提示 Claude Code 与 64 位系统不兼容优先检查安装包是不是下载成了错误架构重新下载对应版本通常能解决。第四条别在同一个会话里又写代码又查日志又改配置。Claude Code 的上下文是按会话隔离的混在一起只会让每个请求都背着大量无关内容。我现在的习惯是一个会话只干一件事最多加一个辅助子任务这样 Spinner 的转圈时间能压到一个让人舒服的区间。4.3 补充第三方模型接入时兼容性比速度更值得关注如果你走的是第三方兼容接口路线除了前面的通用排查还得额外关注三点。第一工具调用的格式是否和 Claude 协议完全兼容很多模型对 function calling 的支持很勉强表面上接上了一跑工具就挂。第二是否支持流式输出不支持的话会表现为等很久然后一次性倒出一大段哪怕网络没问题体验也非常像卡死。第三上下文窗口通常比官方小输入一长就直接报错而不是正常生成。遇到 Spinner 空转先确认这三点再改别的配置顺序不要反。我在本地环境接入其他模型实测的体感是开源模型的推理速度和稳定性跟官方接口有明显差距但作为日常辅助够用。把期望值调整好就不至于觉得卡到完全不能用。同时给这类接入单独准备一套更长超时的配置能少很多无意义的报错。最后分享一个我坚持了很久的习惯每天结束工作前我会把当天所有 Claude Code 会话里值得留存的命令和结论整理到项目文档里然后关掉所有会话第二天从干净状态开始。这样做既避免了上下文膨胀也让每次开工都思路清晰。如果你也被 Spinner 折磨过不妨先从开 verbose 记日志和定期清会话这两个小习惯试起。我的体会是Claude Code 本身是套好工具大多数卡住其实是状态不可见带来的焦虑状态一旦可见问题就真的解决了一半。
返回列表