Cursor 拖图为什么这么慢?我写了一个几百行的 skill,把图片“上传“绕到了本地

发布时间:2026/6/26 18:17:52
Cursor 拖图为什么这么慢?我写了一个几百行的 skill,把图片“上传“绕到了本地 深入 Cursor 的上下文机制、vision prefill 物理代价、Agent 模式的 token 消耗路径以及一个极简 skill 如何用文件系统绕过 LLM attachment 模式。TL;DRCursor 聊天里拖 10 张截图卡 60 秒通常不是网络慢而是模型 vision prefill 宿主 attachment 机制叠加后的结果图片一旦作为 attachment 进入对话后续轮次通常会继续携带这批视觉输入token 和首字延迟持续累加我写了一个极简 skill 叫img2md把图片从 “attachment 上下文驻留” 切换到 “本地文件 按需 Read”双模式触发「上传图片」走快速暂存就停「上传图片生成 markdown」才走完整 OCR当前实现只有5 个文件SKILL.md、Cursor 触发规则和 3 个脚本脚本约 500 行规则文档另约 300 行真正能优化的是工作流不是技术不要拖图输入路径口径说明本文的耗时和 token 数是我在自己机器、自己的 Cursor 配置、同一批截图上的观测值不是通用 benchmark。Cursor、模型供应商、账号套餐、图片尺寸、网络、缓存命中率都会改变绝对数字。本文真正想证明的是一个结构性判断把图片作为可丢弃的文件路径处理通常比把图片作为聊天 attachment 常驻上下文更稳定、更便宜、更可控。文中把图片 attachment 简化描述为「进入 prompt / 粘性层」。不同宿主的内部实现未必真的把图片以同一种 base64 字符串拼进文本 prompt但只要它在后续请求里继续作为模型可见的视觉输入存在工程代价就是类似的视觉 token 要被计费、prefill 要等待、上下文要变重。一、痛点是怎么发现的一个真实的早晨我习惯把屏幕上看到的内容书的章节截下来喂给 Cursor 让它转成我自己的笔记 markdown。两三张图的时候没什么感觉一切都很顺。直到某天我截了一篇文章的 12 张连续滚动截图全部拖进 Cursor 输入框敲下「帮我转成 markdown」回车。然后我等了47 秒才看到第一个字。接下来更糟。我跟它对话 5 轮让它修订标题、调整层级、补段落每一轮我都得等差不多 30 秒才看到回复开始。任务做完打开 Cursor 的 usage 面板一看——这一次对话烧了6 万 token而我感觉自己只问了 5 个简单问题。这不对劲。从我做的事情看12 张图 一段 markdown 输出 5 轮文字修订模型工作量按理说不该这么贵、这么慢。二、Cursor 内部每次按下回车到底发生了什么要理解为什么卡、为什么贵必须先看清 Cursor 的请求机制。很多人有个朴素的想象模型像人一样「记住」了聊天内容下次直接调用记忆。完全不是这样。LLM 本质是 stateless 的每一次你按回车Cursor 实际上做的事情是把从这次会话开头到现在的所有内容打包成一个巨大的 prompt把这个完整 prompt 整个发给 Anthropic / OpenAI 的 API模型从头读一遍整个 prompt然后开始输出输出完毕追加进历史作为下一轮 prompt 的一部分所以「记忆」其实是每一轮重新喂一遍历史。模型没有 RAM只有 prompt。Cursor 每次请求的 prompt 构成一次 API 请求的 prompt 并不只是你说的那句话而是多层叠加的结果固定层每轮相对稳定约 5,000–10,000 token系统提示Cursor 内置的角色定义和行为规则约 2,000 tokenCursor Rules你在.cursorrules或.mdc文件里写的项目规则每条规则 200–500 token工具 schemaRead、Write、Bash、Search 等工具的 JSON schema 定义约 3,000–5,000 token。每增加一个工具就多一段 schema动态层随对话时间线性增长文件 contextCursor 自动识别的相关文件当前打开的文件、import 链、mention 的文件。一个中型项目打开 3 个文件这一层就可能达到 5,000–20,000 token对话历史所有历史轮次的消息 每次工具调用的结果。随着对话轮次增加线性膨胀。当总长超过 context window 时Cursor 会从最早的历史开始截断粘性层图片 attachment——核心痛点你拖进来的图片会以宿主可转发给模型的多模态 attachment 形式保留在会话里直到你新开会话或手动删除。后续轮次通常仍会把它作为模型可见输入携带过去本轮输入你这次说的话约 100 tokenAgent 模式的内部循环Cursor 的 Agent 模式Composer Agent比普通 Chat 贵得多因为它有一个内部循环用户发一句话模型可能需要调用多次工具才能完成任务。每一次工具调用都是一次完整的 API 请求prompt 比上一次更大因为工具结果被追加进了历史。一句「帮我把这个组件重构一下」背后可能是Read 当前文件API 请求 1发现需要看 importRead 另一个文件API 请求 2Write 修改API 请求 3检查有没有 TypeScript 报错Bash 跑 tscAPI 请求 4修复报错API 请求 55 次 API 请求每次 prompt 都比上次更大你感受到的是等了一会但实际上烧了 5 次完整的 prefill 成本。Attachment 的粘性代价现在你理解了 prompt 的组成拖图很慢的根因就很清楚了一旦你拖进去一张图这张图就进了粘性层会在当前会话里持续影响后续请求直到新开会话或移除 attachment第 1 轮prompt 大小 固定层 历史(0) 图片×10 用户消息第 2 轮prompt 大小 固定层 历史(第1轮) 图片×10 用户消息第 3 轮prompt 大小 固定层 历史(前2轮) 图片×10 用户消息……每一轮那 10 张图都可能继续成为模型输入的一部分——即使你的新问题跟图毫无关系比如「再短一点」「换个标题」。这就是聊天框 attachment 模式的核心 cost把一次性输入变成了持续性输入。Vision prefill 的物理代价以 Anthropic 的图片 token 估算口径为例常见截图约 1500–2000px 长边经常落在千级 token/张。10 张大截图很容易变成上万视觉 token相当于把一大段长文本塞进每次请求的输入里。模型在生成第一个输出 token 之前必须完成prefill——把整个 prompt 跑一遍前向传播建立所有 token 的 attention 状态。Prefill 时间正比于 prompt 长度对视觉 token 尤其敏感。我的观测数字Claude Sonnet 级别12 张滚动截图那批数据的同类图片图片数量大致 prefill 时间你感受到的首字延迟0 张纯文本几百 token 0.5 秒瞬时2 张3–5 秒5–8 秒5 张8–15 秒12–20 秒10 张25–45 秒30–50 秒30 张经常超时N/A如果 attachment 在后续轮次仍被携带这个延迟就会反复出现。5 轮对话可能变成 5 次多图 prefill。Prompt caching 救不了多少Anthropic 提供 prompt caching连续两次请求的 prompt 前缀完全相同就可以复用缓存省掉重复的 input token 费用。听起来很美但实际场景里经常 miss你加一条新消息历史部分发生变化前缀就不再完全匹配Cursor 内部 prompt 组装会插入动态内容时间戳、文件修改时间等导致前缀漂移Cache TTL 是 5 分钟稍微停顿一下就过期了Prompt cache 主要优化重复前缀的计费和部分服务端处理成本它不是「把这轮视觉输入变成免费、零延迟」的开关。你感受到的首字延迟仍然会受当前请求体量影响我观察自己的几次多图对话cache hit rate 经常在 60% 以下。即便命中也不能把多图请求变成纯文本请求的交互手感。Cursor 容易烧 token 的 6 个加速器汇总下来和直接调 API 相比Cursor 用户面对的是 6 个叠加的 token 加速器机制原因节省手段Attachment 持久性拖入的图片每轮都在改用文件路径 skill文件 context 自动注入打开的文件、import 自动进 prompt精准 关闭 Auto-contextAgent 工具调用循环每次工具调用 一次新 API 请求一次只做一件事减少工具调用次数工具 schema 本身所有工具的定义都在 prompt 里减少不必要的 Cursor 插件Thinking 模式思考输出按 output 价格计费非推理任务关闭失败重试工具调用失败自动重试prompt 再次膨胀写更精确的 prompt 减少失败率单看每一条都合理叠加起来一次「看起来很简单」的对话可能悄无声息地烧掉数万 token。三、设计目标skill 能解决什么不能解决什么理解了上面的原理我才能清醒地想哪些问题 skill 能解决哪些是 skill 改不了的Skill 的边界卡顿 / 烧钱环节谁负责Skill 能管吗拖图 → Cursor UI 生成缩略图Cursor 前端❌上传至 Cursor 中继服务器Cursor 客户端❌中继转发至模型 APICursor 后端❌Vision prefill 的计算时间模型层物理限制❌每轮 attachment 重复 prefill模型协议本身❌图片已在本地硬盘后的暂存、重命名Skill 工具层✅引导用户改用文件路径而非 attachmentSkill 设计 trigger✅Skill 跑在 agent 循环里在 prefill 完成之后才被调用。你看到 skill 启动的那一刻慢的部分早就发生过了。Skill 没有任何办法加速 Cursor 前端的上传或模型的 prefill——这些是宿主层和物理层的事。但 skill 能做一件结构性的事把工作流从拖图 attachment切换到路径 按需 Read。关键 insight图片到达模型的两条路径路径 Aattachment拖入对话框图片以宿主的多模态 attachment / payload 形式进入模型输入进入粘性 context跟随每一轮 prefill每轮 token 成本 图片完整 token 数无论这轮你是否用它路径 B文件路径 skill 的 Read 工具图片以文件路径字符串形式在 context 里几十 byte模型只在真正需要看图的那一轮调用 Read 工具后续轮次不再 Read 图片不进 contexttoken 成本归零多张图可以一次 batch 并行 Read且每张只 Read 一次路径 B 的优势是结构性的图片变成了一次性消耗品而不是持续性负担。img2mdskill 的所有设计都围绕这一个 insight 展开。四、设计思想少量文件能做什么最终的 skill 只有 5 个文件~/.cursor/skills/img2md/ ├── SKILL.md # 给 agent 的指令一切的入口 ├── cursor/img2md.mdc # Cursor IDE 的触发规则 └── scripts/ ├── intake.sh # 把图片 cp 到 inbox 并命名为 NN.ext ├── embed.py # 把 !-- EMBED/CROP -- 标记物化为真实图片 └── log.py # JSONL 日志可选截至这版3 个脚本约 500 行SKILL.md约 300 多行Cursor 触发规则约 50 行。真正执行逻辑仍然很薄bash Python 标准库只有CROP模式需要 Pillow。这个口径比「400 行代码」更诚实也更能说明重点复杂度主要在 agent 行为约束而不是在脚本流水线。设计原则 1极简少即是多第一个版本v6我做得很复杂子 agent 分发、多引擎 OCR 融合macOS Vision PaddleOCR 智谱 GLM-4V、空间 stitching、内容寻址的 hints 缓存、Chunk 规划器……600 多行 Python复杂的并发控制。跑了几次之后发现这些复杂性全是 self-imposed 的。子 agent 分发并不快——子 agent 也要 prefill整体反而更慢多引擎融合的准确率提升在 LLM vision 足够强的今天价值接近零Stitching 去重逻辑写了 300 行但模型直接看相邻两张图自己就会处理重叠缓存层经常 invalidate反而增加了调试成本最让我清醒的一个观察这一切的总耗时比直接让 Cursor 读图慢得多因为我手工拼装了一个比 LLM 内部更低效的流水线。v9 我把这些全砍了。一个主 agent 直接看所有图、直接写 markdown没有任何中间产物。脚本流水线从复杂多阶段退回到 3 个小脚本速度反而快 3–5 倍。经验在 LLM agent 这个世界里你能托付给模型的事比你想象的多能用脚本优化的事比你想象的少。设计原则 2双模式解耦暂存和OCR最近一次迭代v9.4加了双模式触发这是被真实使用场景逼出来的。最初我只考虑了图片转 markdown这一个场景。但后来发现我有时只是想把一批截图快速暂存好让 Cursor 去写代码根据 UI 截图复刻界面而不是生成 markdown。Cursor 拖图同样慢但 skill 之前非得写 markdown 才肯退出显得很愚蠢。intake.sh本质上是个独立工具——它是一个本地 cp 循环 命名规范化器。OCR 只是它的可选下游。把两者绑死等于限制了 skill 的复用。所以 v9.4 拆成两个模式用户说的话触发模式动作“上传图片” / “上传图片生成代码” / 只输入路径Mode A快速暂存intake.sh→ 报$INBOX路径 →停等下一句指令“上传图片生成 markdown” / “OCR 这些图片” / “img2md”Mode B暂存 OCRintake.sh→ Read 所有图 → Write.md→embed.py→ 报告判断逻辑一条消息里有没有markdown/md/OCR/转文字。有 → Mode B没有 → Mode A。Mode A 是安全默认值——只是本地 cp不会产生错误的.md文件后续 Cursor 可以从$INBOX直接读图做任何事。设计原则 3用文件路径绕过 attachment整个 skill 的物理价值都在intake.sh这段逻辑上# 核心逻辑简化版TOTAL_IN${#INPUTS[]}if((TOTAL_IN1000));thenPAD_W4elif((TOTAL_IN100));thenPAD_W3elsePAD_W2fiforsrcin${INPUTS[]};dopad$(printf%0${PAD_W}d$i)cp$src$CURRENT/$pad.$exti$((i1))done就是个cp循环加几个工程细节自动 zero-padding、归档轮转、project 隔离。没有任何 OCR、没有任何 LLM 调用。它做的事是 Cursor 拖拽上传很难做到的让图片先停在本地文件系统里而不是一开始就进入 prompt 的粘性层。用户说「上传图片目录~/Downloads/」Cursor 收到的 prompt 只是一段几百字符的文字。首轮 prefill 接近纯文本请求intake.sh只做本地复制随后回报 INBOX 路径后续是否 Read 图片由下一步任务决定。设计原则 4Fidelity rule —— 禁止想当然这一条跟性能无关但跟产品质量有关。OCR 任务对模型来说是个特别危险的情境它看得见原文于是会自然产生我能写得更好的冲动。模型常见的违规行为每一条都是真实发生过的把引号里的字改掉感觉省了不少→感觉省时间了给原本无标签的 bullet 加分类标签ROI 量化、度量缺失把无序 bullet 改成有序的1. 2. 3.漏一句、合并两段、在节末凭空加总结/承接句同义词替换、调换词序走了 6 个 Phase→6 阶段的增减标点中文——没有数据→——没有数据。这些都是「改得更通顺」的好意但在「OCR 转录」这个语境下全是 bug——用户要的是与原图字符一致的 markdown不是模型的二次创作。v9.3 加了三层防御强禁止表SKILL.md 顶部 13 类禁止行为每条配一个 source→bad 的具体例子Pre-Write checklist写文件前自检 11 项bullet 数量、引号内容、段落终止句字符等Post-Write self-verify写完后重新 Read 原图随机挑 2 段做人工 diffbrief 报告里必须出现SELF_VERIFY: checked S, found V, fixed V缺这行视为协议违规效果paraphrase 违规率从 v9.2 的「一节文字里 12 处违规」降到 v9.3 的接近零。设计原则 5把失败显式化而不是假装没有失败专业的工具设计不能只描述 happy path。img2md现在保留了几个很朴素但关键的失败出口intake.sh找不到目录、目录里没有图片、所有输入都缺失时直接退出不创建空结果上一批current/会先归档到archive/避免新批次覆盖旧批次默认只保留最近 30 批磁盘紧张时可用IMG2MD_MAX_ARCHIVE调小文件名使用自动 zero-padding100 张以上会变成001.png这类宽度保证ls排序和阅读顺序一致embed.py是幂等的没有 marker 时是 no-opmarker 出错时保留原 HTML comment不破坏 markdown 主体CROP依赖 Pillow但只有实际出现 crop marker 才需要导入缺依赖时降级为保留 marker 和错误报告log.py只做 best-effort JSONL 日志失败不会阻断主流程这类设计看起来不酷但它决定了工具能不能长期使用失败时要留下可修复的现场而不是半写文件、吞掉错误、或者让 agent 凭感觉继续往下编。设计原则 6隐私和数据边界要说清楚这个 skill 不是“本地 OCR”。Mode A 只是本地暂存不把图片交给模型但 Mode B 一旦进入 OCRagent 会 Read 图片图片内容仍然会作为视觉输入发送给所选模型供应商。它绕开的只是 Cursor 聊天 attachment 的常驻路径不是模型推理本身。因此它适合处理“我本来就准备发给模型看的截图”不适合处理不允许进入第三方模型的敏感图片。真正需要离线 OCR 的场景应该换成本地 OCR 引擎或者把 Mode B 禁用只使用 Mode A 做本地文件整理。五、架构演进史教训汇编倒过来看 9 个版本最有价值的反而是那些被我删掉的东西。v1–v5探索期最早是命令行工具用 Vision/Paddle 做本地 OCR识别率一般需要人工校对。核心问题是本地 OCR 在中文/混排上准确率不够让 LLM 直接看图反而更准。v6复杂巅峰引入 LLM vision 作为最终决策者本地 OCR 退化成hints。同时引入子 agent fan-out、多引擎融合、空间 stitching、chunk 规划器。最复杂的一版也是最慢的一版。v7–v8开始砍v7 的草稿就叫lightweight redesign——直接砍 60% 的代码。v8 实现了大部分简化。v9极简回归砍掉所有中间表示hints、sections、manifest主 agent 直接看图直接写 md。v9.2 几乎是这个 skill 的正确形态。v9.3补 fidelity 漏洞发现 v9.2 在 paraphrase 上失守加了三层防御机制。v9.4双模式把暂存和OCR解耦成正交工具。这是产品视角的一次升级技术上没有大改动但对用户体验是质变。教训清单工程复杂性是负债你写的每一行代码都要在未来的某次需求变更里付出维护成本LLM 能做的事远比你想象的多图片去重、版式识别、内容理解让模型直接看图反而更好可用性 准确率v6 的99% 准确率没人用v9 的95% 准确率 10 倍速度才有人用触发匹配决定一切SKILL.md 的description字段是 skill 唯一的营销文案写不好就不会被调用少加抽象多删代码每次想加新功能时先问有没有可以一起删的六、效果对比同一个场景12 张滚动截图转 markdown。为了避免把体感当结论我用的是同一批图片、同一个输出目标、同一个模型档位做对比。记录口径很简单新开会话清空历史干扰记录从回车到第一个输出 token 出现的时间也就是用户真实感受到的首字延迟记录任务完成后的 usage 面板 token 数每组至少跑两次剔除明显的网络异常或服务端排队异常只比较同一批图片在「拖入聊天框」和「路径 skill」两条路径下的差异这不是严格实验室 benchmark但足够回答本文的问题慢点到底来自 OCR 本身还是来自图片进入上下文的方式。阶段拖图模式路径 A文件路径模式路径 B skill上传 / 暂存30–50 秒上传 中继 转发 100ms本地 cp首轮 prefill30–45 秒1–2 秒prompt 只有文字Skill 内部 Read 处理25–35 秒25–35 秒总耗时首轮85–130 秒27–37 秒后续每轮修订标题等可能再次携带图片 prefill30–45 秒接近纯文本轮次图不在 context除非再次 Read5 轮对话总 token 消耗~60,000 token~12,000 token在这批样本上速度提升约 3–4 倍token 消耗降低约 5 倍。但这些数字的根本来源不是 skill 的优化——而是 skill 把用户引导到了一条结构性更优的工作流。同样的模型、同样的图片、同样的任务只是图片到达模型的路径变了。七、如何最省 token 使用 Cursor基于上面对 Cursor 内部机制的理解这里整理出按影响力排序的节省策略高优先级影响 50–80%1. 不拖图用文件路径 skill这是影响最大的单点优化。从路径 A 切换到路径 Btoken 消耗立刻下降 5 倍以 12 张图为例。操作很简单macOSCmd Shift 5把截图存到固定目录如~/Screenshots/对 Cursor 说「上传图片目录~/Screenshots/」skill 秒级完成暂存2. 任务完成即开新会话这是比任何优化都管用的手段——直接清空所有粘性 context 和对话历史。Cursor 的 context 是单向增长的不存在聊着聊着会变短的情况唯一的办法是开新会话。经验法则一个任务 一个会话任务做完就关。下一个任务重新开不要把多个不相关的任务拼在同一个会话里。3. 精准 文件不用 codebasecodebase会让 Cursor 扫描整个仓库并注入大量相关文件每次请求额外带来 10,000–50,000 token 的文件 context。除非真的需要全局搜索否则精确ComponentA.tsx utils.ts比codebase省很多。中优先级影响 20–40%4. 截图前先压缩如果有时必须拖图比如临时看一张图先把图压缩再拖macOS 预览 → 导出 → JPEG 80% 品质分辨率缩到 1200px一张 4MB 的 PNG 压缩后变成 400KB对应的 token 数同比减少 ~80%5. 关闭 Cursor 的 Auto-contextCursor 默认会自动检测相关文件并注入 context。不同版本的设置入口会变化但思路是一样的降低自动注入的激进程度改为尽量手动文件。对 token 消耗通常有稳定影响。6. 一次 prompt 只做一件事每增加一个需求就多一轮工具调用prompt 就再膨胀一次。「帮我重构这个组件、顺便加单测、再把 README 更新一下」听起来是一句话实际是 3 个独立任务触发很长的工具调用链。拆开做每个任务一个新会话整体消耗反而更少。低优先级影响 5–15%7. 精简 .cursorrules / .mdc每条 Cursor Rule 都会进入固定层持续消耗 token。检查一下你的.cursorrules或img2md.mdc等文件把从未被用到的规则删掉。一般项目里 30–50% 的规则是当时加了但后来没用上的。8. 简单任务选小模型Cursor 支持切换模型。Haiku 的价格约为 Sonnet 的 1/10速度更快。重命名变量、格式化代码、写简单的 utility 函数等任务Haiku 完全胜任不需要用 Sonnet 或 Opus。9. 非推理任务关闭 Thinking 模式如果开启了 Thinking 模式Extended thinking模型先输出一段思考过程这段思考按 output token 价格计费比 input 贵 3–5 倍。大部分日常编程任务不需要 Thinking关掉能节省 20–40% 的 output 成本。八、另一条解Claude Code CLI 为什么更准、更省写完这个 skill 之后我有个反向感受与其在 Cursor 里堆 skill 和 rule 绕开它的开销不如直接换工具。我现在做不依赖 IDE 的任务写脚本、批量改文件、写文档、做 OCR几乎全部移到了 Claude Code CLI。Claude Code 是 Anthropic 推出的命令行 agent。安装方式以官方文档为准安装后在任意目录敲claude就进入。表面上看跟 Cursor 一样都是和模型对话写代码但底层 prompt 组装方式差很多。工作原理少了一整个 IDE chrome 层Cursor 是 VSCode fork 模型层每一次 prompt 里都包含 IDE 状态当前打开的文件、光标位置、recent files、import 链分析、Codebase indexing 结果。这些是好用的但它们默认就在 prompt 里无论你这次问题是否需要它们。Claude Code 是纯 CLI agent它的认知模型只有 3 件事当前工作目录pwd是它的边界不会越界扫别的目录CLAUDE.md当前目录以及上级目录的CLAUDE.md文件是项目级 system prompt由你显式写没有 IDE 自动塞进来的隐式内容本轮对话你说的话 它调用过的工具结果没有 IDE 自动注入文件没有 attachment 机制图片必须以路径方式传入比如分析 ~/Desktop/a.png 这张图没有 tab 补全产生的隐式消息。为什么更准确1. Context 边界由你显式控制不会被 IDE 偷偷扩张Cursor 里你打开了 5 个文件每次请求就可能带上这 5 个文件。中型项目 import 链一展开就是 1–2 万 token 的背景噪音——模型要花注意力区分哪些是相关的、哪些只是恰好打开了。Claude Code 不会自动 Read 任何文件你说一句话就只有这句话。它需要看文件时主动调用 Read 工具这一刻你是知道它在读什么的。2. 工具调用更直接Cursor 的 Read/Write 工具是包了一层 IDE 的要触发 diff 视图、文件 watcher 之类。Claude Code 直接调系统的文件系统工具结果回来就是文件内容没有中间层。失败率明显低重试次数少整体决策链更短。3. 没有粘性 attachment每轮都是新鲜的这是和本文主题最相关的一点。Cursor 拖图后图片容易在当前会话里持续存在Claude Code 的常规用法是用文件路径传入 → 模型按需 Read → 用完即丢。结构上就是本文路径 B 的工作流不需要 skill 绕一圈。4. CLAUDE.md 让重复说明只说一次我在~/.claude/CLAUDE.md里写了一段「作图规范」颜色、d2 语法、命名规则。每次进 Claude Code 它都自动加载这段我再也不用每次重申画图用 d2、配色用这套调色板。在 Cursor 里同样的事情要靠.cursorrules但效果不如直接读 CLAUDE.md 来得稳定。为什么更省 token在我的一次对比里同一个任务让 agent 改一个 200 行的 Python 脚本跑测试修 bugCursor Agent 模式吃掉 ~45,000 tokenClaude Code 大概 ~12,000 token差 3–4 倍。具体来源开销项CursorClaude Code系统提示~2,000 token含 IDE 集成相关~1,200 token精简Cursor Rules / CLAUDE.md每条规则 200–500 token且经常加冗余规则你写多少就是多少普遍更紧凑工具 schema内置工具多搜索、编辑、终端、补全等工具更少更聚焦Read/Edit/Bash/Grep/Glob/Task自动注入文件打开的文件 import 链 5k–20k默认接近 0通常需要显式 Read图片 attachment拖入后容易持续携带10 张图可带来上万视觉 token常规路径是文件路径天然接近路径模式历史累积IDE 会话长倾向于一直聊下去CLI 天然一任务一会话结束就exit最后一条最被低估。Cursor 的会话是 IDE 里的一个标签页关掉的代价很高会丢失 composer 状态所以大家倾向于在同一个会话里做完一整天的工作。结果就是粘性 context 越攒越大。Claude Code 用完一退出下次重新进就是干净的——这个 ergonomics 上的差别带来的 token 节省比任何技术优化都大。几个最常用的 Claude Code 命令# 进入当前目录的 agent 会话claude# 一次性 prompt不进入交互模式claude-p解释这个仓库的目录结构# 接着上一次会话继续claude-c# 用某个特定模型具体 model id 以官方文档为准claude--modelmodel-id# 跳过权限确认用于自动化脚本谨慎使用claude --dangerously-skip-permissions# 调用某个 skill会话内/img2md 上传图片目录 ~/Downloads//init会让 agent 帮你扫描当前项目并生成一份CLAUDE.md草稿——非常推荐每个项目跑一次相当于一次性建立项目级 system prompt。Claude Code 不是 Cursor 的替代品公平地说需要可视化 diff、tab 补全、悬浮文档的工作前端联调、复杂重构Cursor 仍然更顺手需要 agent 跑较多步骤、自动决策、批处理任务的工作数据处理、文档生成、脚本编写、OCR、批量改名Claude Code 又快又省我现在的分工是写交互式前端代码用 Cursor写脚本、文档、blog、做数据处理用 Claude Code。本文这个 img2md skill 同时塞在~/.cursor/skills/和~/.claude/skills/两边也是因为两个工具我都在用。九、什么时候适合写 skill写完 img2md 之后我对哪些问题适合 skill有了更清楚的认知适合 skill 的问题反复发生、可流程化每次都要做一样的事写成 skill 就是一个命令能用本地工具绕开 LLM context 开销文件操作、目录管理、本地脚本能搞定的事工作流可被规则清晰描述模型能按 SKILL.md 一步步执行不需要动态决策需要在 agent 行为里加硬约束如 fidelity rule把禁止 X写进 skill 比每次对话都强调更有效不适合 skill 的问题需要改宿主 UIskill 跑在 agent 工具层碰不到前端一次性问题写 skill 的成本可能比手动做更高复杂跨 session 状态skill 是无状态的复杂状态用 memory 或数据库更好需要持续运行的后台服务skill 是 invoke-and-return不适合做 daemon一个判断公式如果你每周至少做 3 次这件事且这件事可以用50 行脚本 一段清晰的指令文档完成 → 值得写成 skill十、给 LLM agent 工具设计者的几点思考1. Stateless 才是常态attachment 是反模式只要可能就让信息以可丢弃的方式进入 context。文件路径 Read 工具几乎总是优于把内容直接塞进 prompt。思考信息是否需要在每轮都存在而不是能不能加进去。2. 文件系统是 LLM 最便宜的 memoryinbox/project/current/这一个目录就承担了 skill 的所有中间状态。不需要数据库不需要缓存层——ls就能查cp就能改rm就能清。LLM 应用里有大量的中间产物可以用本地文件系统替代内存或 KV store。3. Skill description 是触发匹配的全部我改过 6 次 SKILL.md 的description字段每次都是因为某种说法下不被触发或不该触发时被错误触发。这个字段是 skill 唯一的入口——写不好就形同虚设。策略上正例和反例都要写。仅写什么时候触发不够必须写什么时候不要触发。4. 删代码比加代码更难也更有价值v6 → v9 砍掉了 200 行 Python。被砍掉的每一段当时都是为了某个边界情况设计的。事后看那些边界情况要么从没发生要么模型自己处理得比脚本更好。每次想加一个新模块时先问能不能让模型直接做5. 用户真实痛点 vs 工程师想象的需求我以前以为用户要的是「OCR 准确率」。后来发现用户要的是「不要让我等」和「不要让我重复操作」。前者是工程问题后者是产品问题。多数时候后者更重要而解决产品问题往往需要更少的代码而不是更多。结语这个 skill 看起来很小——5 个文件脚本约 500 行做的事一句话说得清。但它背后是对「LLM 上下文物理代价」「attachment 与文件路径的结构差异」「极简主义 vs 工程癖好」的一系列认知迭代。如果用一句话总结这次工程经验真正的优化不在算法层在工作流层。Cursor 拖图慢没有任何算法能解决但绕开它的方式很简单——告诉模型图片在那个目录里而不是把图片放进对话框。Skill 不过是把这个朴素的工作流变化固化成一个一句话能调用的工具而已。完。