← All Posts

Cursor Agent 转了二十七分钟:活干完了,对话框还在转

真慢、假慢,以及我怎么把 Agent 从乱探索里拽回来

事情是这样的。

新博客想扩一下顶栏导航:相册、日志、歌单,保持现在的极简风,顺带照顾移动端。按理说这是个「读顶栏组件 → 加三个入口 → 复用现有汉堡菜单」的小活。丢给 Cursor Agent 之后,我去倒了杯水,回来一看——

Worked for 27m 18s.

文件改动已经出来了:Edited 6 files, +338 -11,结论也写了「做法」。可对话框还在那转,像加班到深夜还不肯交钥匙的同事。

我第一反应:是不是又卡死了?第二反应:加三个导航入口至于跑半小时?第三反应:emmm,先别急着重装,这锅说不定能拆成两半。

先分清:是真慢,还是假转#

后来对照社区反馈和自己这边的现象,这种「结果已经落地、UI 还在转」大致分两种:

类型你会看到什么本质
真慢Worked for 27m,探索了很多文件,diff 胖得离谱工具轮次多、搜索面大、命令拖后腿
假慢磁盘上的文件早就改好了,聊天还在 Planning / Editing流已经结束,客户端状态机没收到结束事件

我这次两边都沾一点:活确实干重了(真慢),收尾时 UI 又跟不上(假慢)。

假慢这事儿挺像业务里那种经典 bug——接口都 200 了,按钮还在 loading。副作用发生了,本地 isRunning 没跟完成信号对齐。Reload Window、开新聊天、Cmd+Q 重开,往往能把这层「假死」清掉。官方也承认过:后端 turn 已经成功,客户端就是没登记结束。

但如果你每次任务都动辄十几二十分钟,只靠 Reload 治标不治本。得往 Agent 执行管线里挖。

Agent 为啥会把小活干成大活#

可以把 Agent 想成带工具的 ReAct 循环:

用户意图 → 选工具 → 读/搜 → 再推理 → 再改 → … → 最终回复

每多一轮,你都在付账:

  • LLM 再想一遍、再选一次工具
  • 上下文越堆越长(历史对话 + 文件内容)
  • 磁盘读写、全库搜索、Shell 命令
  • 流式通道上的 token 和工具事件

我那次需求本质是「扩导航」,结果变成:桌面入口 + 移动端菜单 + 样式对齐 + 多文件联动,一口气 +338。不是 Vite 编译慢,是搜索空间和改动面失控了

前端同学面试时要是被问「为什么 Agent IDE 有时特别慢」,可以这么答:

墙钟时间 ≈ 探索深度 × 工具轮次 × 上下文长度 × 流式链路质量。

UI 假转则是另一层:完成事件和本地运行态不同步。优化优先剪枝和稳网络,Rule / Skill 只能约束行为,修不了客户端状态机的 bug。

对话框转圈背后的前端原理#

Agent 面板本质是挂在 SSE / WebSocket 上的流式状态机,大概长这样:

idle → streaming → tool_running → streaming → … → completed

转圈绑定的是客户端本地状态,不是「工作区文件有没有改完」。常见翻车点:

  1. 传输层半断开:VPN / 公司代理对长连接静默掐流,后端写完了,客户端收不到 done
  2. 事件丢了或乱序:工具结果到了,turn_complete 没到,UI 停在 Planning
  3. 长对话状态膨胀:消息树太大,重渲染和状态合并变慢,看起来像「卡一下才刷完」
  4. 子 Agent 僵尸卡片:活干完了,Working 面板还挂着 Starting up

我这边还有个更扎心的证据:往 Cursor 设置里写 User Rule 时,请求 api2.cursor.sh 的证书居然变成了 *.toolbox.bluelabellabs.io。这是典型的 HTTPS 中间人 / 残留代理。短请求或许还能糊弄过去,Agent 那种十几分钟的长流,最容易被拖成「后台在干活、前台在发呆」。

所以网络排查别只跑内置 Diagnostics(它偏短连接,容易误报健康):

  • 关 VPN,Cmd+Q 彻底退出再开
  • Settings → Network → HTTP Compatibility Mode 试 HTTP/1.1
  • settings.json 里可加 "cursor.general.disableHttp2": true
  • macOS 系统设置里清掉已经卸掉的 VPN 配置残留

我怎么把它拽回来的#

假转靠 Reload / 新聊天急救。真慢靠收窄输入 + 约束行为

提问时就把刀磨快#

别再丢一句「帮我扩下导航,顺便看看移动端」。改成:

只改顶栏导航:增加 相册 / 日志 / 歌单 三个入口。
参考现有 @Header.tsx,保持极简风格。
移动端用现有汉堡菜单扩展,不要重构布局,不要改其他页面。
改完直接给结果,不要额外跑测试 / 构建。

@ 文件等于给算法一个明确起点,比让它自己 Explore 半个仓库香太多。

能拆就拆:第一轮只加桌面三项,第二轮再补移动端。长对话越往后越容易又慢又卡,独立小任务尽量新开 chat。

写一条始终生效的 Rule#

Skills / Hooks 治不了假 loading,但能挡住「无意义探索、默认跑 build、顺手重构」这类范围膨胀。我落了一条 alwaysApply 的规则,核心就几句:

  1. 用户 @ 了路径,就优先只读这些,禁止无必要全库广搜
  2. 小改动最多先读 3~5 个相关文件就动手,别动不动开一堆子 Agent
  3. 严格按明确范围改,不顺手重构、不补无关文档
  4. 不默认跑 build / test / lint / typecheck / dev server
  5. Shell 设超时,别挂着 tail -f 空等
  6. 能一次改完就少来回试错;收尾用短结论,别长篇复盘空转

文件放在 ~/.cursor/rules/agent-speed.mdc。若新对话没吃到,再把同样内容贴进 Cursor Settings → Rules → User Rules

面试题版收束(顺便当笔记)#

题: Cursor 一类 Agent IDE 里,改几个导航入口要跑二十多分钟;文件改完了对话框还在转。请从执行管线和前端实时同步两边讲原理,并给优化手段。

答的骨架:

  1. 先分类:真慢(探索 / diff / 命令) vs 假慢(流结束了 UI 状态没对齐)
  2. Agent 侧:ReAct + 工具调用;成本随轮次和上下文线性(甚至更差)上涨;小需求大 diff = 改动面失控
  3. 客户端侧:流式状态机;isRunning 依赖完成事件;代理 MITM、HTTP2、长对话都是高发区
  4. 优化分层:输入剪枝(@、拆任务、短对话)→ 策略约束(Rule)→ 运行时(少子 Agent、命令超时)→ 传输(直连、清代理)→ 产品兜底(Reload / 新 Chat)

一句话:Agent 慢看搜索和轮次,UI 假转看完成信号;Rule 管行为,网络管长流,Reload 管客户端犯病。


下次再看见对话框转个没完,先看 diff 在不在,再决定是骂网络还是骂自己 prompt 写得太宽。活干完了还在转,未必是你不够勤快——也可能是状态机比你更固执。