少烧 Token,多干活
同一个任务,糟糕的用法可能比熟练用法多消耗 5–10 倍 token。这份分享拆解 token 都花在哪、有哪些立竿见影的优化技巧,以及如何量化定位自己的浪费点。
0Token 到底花在哪
很多人以为「token 消耗 = 我打的字 + AI 回复的字」。实际上在 agent 类工具里,真正烧 token 的是上下文(context)每一轮都要重新发送。
下图:每一轮你只敲了几个字(绿色),但真正发出去的是整段历史的累积重发(橙色越来越长)。这就是为什么长会话越聊越贵——成本几乎随轮数平方增长。
四大消耗源
| 消耗源 | 说明 | 是否可优化 |
|---|---|---|
| 系统提示 + 工具定义 | 每轮固定开销,含工具 schema、CLAUDE.md / AGENTS.md | 可缓存(cache) |
| 读取的文件内容 | 读大文件、整目录、重复读同一文件 | ✅ 重点优化 |
| 工具返回结果 | 巨量 grep 命中、整个 npm install 日志、大 JSON | ✅ 重点优化 |
| 累积的对话历史 | 跑题、反复试错、长会话不清理 | ✅ 重点优化 |
1控制上下文窗口
这是省 token 收益最大的一类技巧,核心是「只让模型看到它真正需要的东西」。
1.1 任务做完就清空:/clear
换一个不相关的任务时,立刻 /clear(或直接开一个新会话)。否则前一个任务读过的所有文件、跑过的所有命令,会在新任务里继续被当作输入反复发送。
✗ 浪费
修完 bug A,不清理,接着在同一会话里改 feature B、写文档 C…… 到第 3 个任务时,前两个任务的几十个文件还在每轮重发。✓ 省 token
每个独立任务/clear 一次。会话保持「短而专注」,输入 token 始终维持在低位。1.2 主动压缩:/compact
当一个任务确实很长、又必须延续上下文时,用 /compact 把历史总结成摘要,丢掉冗长的中间过程(大段文件内容、试错记录),只保留结论。比放任它自动压缩更可控。
/compact 只保留最终方案和改动的文件列表 —— 可以给 compact 附带指令,告诉它该留什么。1.3 精准读文件:先定位,后精读
读文件是会话里最容易失控的 token 大头。原则就一句:先用搜索把范围缩到具体函数,再只读真正需要的那几十行,别让整文件、整目录无差别地灌进上下文。
✗ 浪费
「帮我看看这个项目」这种没边界的需求,逼它做地毯式探索、Read 一大批文件;或你直接 @ 一个几千行的大文件 / @目录,把整份内容一次灌进来 —— 几千行的文件,一次就两三万 token 起步。✓ 省 token
给它一个明确目标,比如「只看login.ts 里的 parseUser() 函数」。剩下交给它:会自己先 grep 定位、再用 Read 区间(offset/limit)精读那几十行 —— 不用你手动敲命令。Read 也最多 2000 行(超出要 offset 续读),不会无限吞。所以真正要你把关的,是别用 @ 亲手把大文件 / 整目录塞进去 —— 正是下面要讲的。关键认知:@文件 会把「整份内容」直接注入
DeepSeek Harness 支持在输入里用 @ 引用文件(输入 @ 自动补全路径),例如 @src/auth/login.ts。但要分清它到底干了什么:
✓ @ 省的是「搜索成本」
你知道代码在哪,直接 @ 指给它 —— AI 不用满仓库 grep 翻找,省下十几次工具调用和大段命中输出。✗ @ 不帮你「省内容」
@文件 会在你发消息那一刻,就把整个文件内容原样塞进上下文(不是让 AI 自己挑着读)。文件多大,就吞多少 token。- 小文件 / 配置文件 → 放心
@,整份也就几百 token,准确又省事。 - 几千行的大文件 → 别整份
@,直接点名「读parseUser()函数」,剩下交给它定位精读。 @目录→ 会带上文件清单、甚至多个文件,范围越大越要克制。
1.4 善用子代理 / 子任务隔离上下文
DeepSeek Harness 有原生子代理(subagent):在独立的上下文里跑搜索/调研类脏活,只把结论返回主会话。「翻 100 个文件找用法」这种会污染主上下文的活,丢给子代理,主会话只收到一句总结。
- DeepSeek Harness:内建
subagent/subagent_fork工具,可并行派发多个独立子任务,各自汇总;更大规模的编排用 Agent Teams 工作流。
但它不是免费的:每开一个子代理都自带固定开销(独立的系统提示 + 工具定义,几百到几千 token),子代理内部那几轮也会重发它自己读到的脏数据。所以「总 token」是涨是降取决于场景,而不是「总更高」:
✓ 净赚
大范围探索 / 一次性调研,且后面还有很多轮对话 —— 隔离省下的「反复重发」远大于那份开销。✗ 净亏
琐碎小事、一两轮就结束 —— 隔离没省下多少,却白交一份开销,直接做反而更省。1.5 用文件做「中转」,而不是把内容塞进对话
对话历史是「只进不出」的:任何塞进去的东西都会在之后每一轮重发。而文件是「按需读取」的:写进文件后它不占上下文,要用时再读、用完就过。所以凡是「体积大、又不需要全程跟着对话」的内容,都应该落到文件、而不是留在聊天里。
典型场景
| 场景 | 别这样 | 改成 |
|---|---|---|
| 分析大日志 | 把几千行日志贴进对话让它看 | 让它把日志写文件,再 grep/区间读关键片段 |
| 中间产物 / 调研结论 | 长篇结论堆在对话里,后面一直重发 | 让它写成 NOTES.md / findings.md,需要时再读 |
| 多步任务的计划 | 计划只停留在对话,/compact 后可能丢失 | 写成 PLAN.md / TODO 文件,跨轮次稳定可查 |
| 大段数据 / 接口返回 | 整个 JSON 灌进上下文 | 存文件,用 jq 等只取需要的字段 |
为什么省 token
- 不重发:内容在文件里,对话历史保持精简,后续每一轮的输入都更小。
- 可按需、可局部:下次只读需要的那几行(配合 1.3 的区间读取),而不是整坨重新载入。
- 能复用、抗压缩:
/compact或/clear会丢掉对话里的细节,但写进文件的内容不会丢——新会话直接读文件即可恢复上下文,省去重新生成。
findings.md,先别在对话里展开」「把这次的计划存成 PLAN.md,之后按它执行」——主动引导 AI 把大产物外置,是长任务里最容易被忽视、却很有效的省 token 手段。1.6 把垃圾目录挡在上下文外:沙箱权限 / deny 规则
DSH 的文件沙箱默认只放行 workspace-write(工作区内读写,其余需审批)。在此基础上还能用 deny 规则禁止读取某些路径,从源头不让 node_modules、dist、生成物、lockfile 这类垃圾被整份读进上下文。
# 文件访问 deny 规则(gitignore 风格 glob)
deny: [
"Read(node_modules/**)",
"Read(dist/**)",
"Read(**/*.lock)"
]
命中的路径 AI 读不到,也就不会在地毯式探索里把它们的大段内容灌进来 —— 既防误读,又省下本不该花的 token。(注意:DSH 不会自动套用你的 .gitignore,要挡就得显式写 deny。)1.7 临时插一句问题:side-question(不进历史)
对话历史是「只进不出、每轮重发」的(呼应 1.5)。聊到一半想顺手问个无关小问题(「这个缩写啥意思」「这段顺便解释下」),直接问会把这段一问一答永久焊进历史,之后每一轮都陪着它重发。若工具提供 /btw 这类「side question」,它不进对话历史、复用现有缓存、单独答一次 —— 问完不污染主线,长任务里尤其值。
2让工具调用更省
工具返回结果是仅次于文件读取的「隐形大户」。一条命令的输出会 100% 进入上下文。
2.1 给命令加过滤,别让 AI 看「全量输出」
✗ 浪费
npm install # 上千行日志
cat huge.log # 整个日志吞进来
grep -r "foo" . # 几千行命中✓ 省 token
npm install 2>&1 | tail -5
grep -rn "foo" src/ | head -30
rg "foo" --count # 只要数量
2>&1?很多人不解 DSH 为何老在命令后加 2>&1。原因:很多工具(npm、编译器、测试框架……)把报错和警告打到 stderr(标准错误),正常信息打到 stdout(标准输出),二者是两条独立的流。而 | tail / | grep 这类管道默认只接 stdout。2>&1 的意思是「把 stderr(文件描述符 2)重定向并入 stdout(文件描述符 1)」,这样两条流合成一条,再一起喂给 tail 截断。不加的话,恰恰是最关键的报错会绕过 tail 直接刷屏 / 或干脆丢失 —— 既没省到 token,又漏看了错误。所以「截断 + 2>&1」要配套使用。顺序也有讲究:
cmd 2>&1 | tail 才对;写成 cmd | tail 2>&1 是错的(那只是把 tail 自己的 stderr 并进去,没用)。head/tail/--count 截断」。用 rg(ripgrep) 代替 grep -r,更快且默认更克制。- 事前(
PreToolUse):拦下 Bash 命令、用updatedInput给已知啰嗦的命令(npm test/build…)自动补上| tail,命令压根不会产出整坨。 - 事后(
PostToolUse):用updatedToolOutput替换掉模型看到的结果 —— 超过 N 行就只回传头尾 + 一句「已省略 X 行」,作为兜底。
2.2 测试别全量跑、别贴全量输出
调一个失败用例时,只跑那一个测试(pytest path::test_x / jest -t "name"),而不是整个测试套件把几千行输出塞回来。失败信息让它 tail 关键部分即可。
2.3 警惕 MCP 工具的「工具定义膨胀」
每接入一个 MCP server,它的所有工具 schema 都会进系统提示,每轮都发。装了一堆用不上的 MCP,等于给每轮对话加了固定税。
2.4 全局 vs 局部:装在哪,就在哪付费
MCP server 和 Skill 都能装在全局(~/.dsh/,所有会话都加载)或项目局部(工作区 / 项目配置,仅该项目加载)。原则一句话:装在哪,就在哪每轮付费。所以——「几乎每个项目都用」的才放全局,专用的放进对应项目,免得在用不上它的仓库里也白交税。
| 类型 | 启动时进 context 的 | 每轮 token 成本 | 该克制的真正理由 |
|---|---|---|---|
| MCP | 工具 schema(或 deferred 模式下的名字)+ server instructions | 重 —— 真·每轮固定税,且进缓存前缀 | 省 token(少装、局部装都对) |
| Skill | 只有「名字 + 一行描述」;正文 /调用 时才加载 | 很轻 —— 实测全部 Skills 合计仅 ~1.6k | 不是省 token,而是避免选择污染 |
2.5 一次多个独立操作并行发
多个互不依赖的读取/搜索/命令,让 AI 在一条消息里并行调用,而不是一问一答来回好几轮。原理回到第 0 节:每多一轮,整个对话历史就重发一遍。所以轮数本身就是成本——把能并行的合并成一轮,省的是那些被反复重发的历史 token。
✗ 串行(4 轮)
读a.ts → 等结果再读
b.ts → 等结果再
git log → 等结果再跑测试 → 等结果
每一轮都重发前面所有历史。
✓ 并行(1 轮)
同一条消息里同时发起:读
a.ts、读 b.ts、git log、跑测试历史只重发一次,还更快。
4 轮
1 轮
什么能并行、什么不能
- 能并行:彼此没有依赖的操作 —— 同时读几个文件、几处搜索、查 git 状态 + 跑 lint 等。
- 不能并行:后一步依赖前一步结果的 —— 比如「先搜出文件名,再读那个文件」必须串行;硬并行只会拿到半截信息再补一轮,反而更费。
@ 一次指多个文件,一轮就能把信息凑齐。3吃满 Prompt Cache
DeepSeek Harness(DeepSeek API)支持 prompt caching:相同的上下文前缀命中缓存后,价格通常只有正常输入的 ~10%。用好缓存几乎是「免费」省 token。
✓ 命中
✗ 之后全失效
3.1 别在会话中途改动「靠前的稳定内容」
- 频繁编辑
CLAUDE.md/AGENTS.md会让整段缓存失效 —— 调稳定后再固定下来。 - 会话中途增删 MCP / 工具,会冲掉工具定义缓存。
3.2 连续追问比「攒一大批改完重开」更划算
在同一会话里连续交互,前缀稳定、缓存持续命中;反复 /clear 重开会让每次都重新建缓存(首轮无折扣)。所以是权衡:跨任务要清,同任务内则尽量连续。
/compact 救不回缓存 —— 它把历史换成摘要,前缀整个变了,缓存照样失效。它真正省的是回来那次重建的体量:先把 100k 压到 20k 再走,回来全价重算的只是 20k。所以「上下文已经很长 + 要离开较久」时,走之前先 compact;上下文还小就别为了走特地 compact,那次总结本身也要花钱。3.3 反直觉:会话中途切模型,可能更贵
每个模型有自己独立的缓存。聊到一半(比如已经 100k token)想「换个便宜模型答个简单问题」省钱 —— 结果常常更贵:换过去那一刻整个前缀缓存命不中,要按全价给新模型重建一遍,重建的钱往往超过让原模型直接答省下的那点。同一会话内尽量别来回切模型;真要用不同模型,不如开一个专门的新会话。
<system-reminder> 这类信息总是追加在消息末尾、而不是塞回开头。4把任务说清楚(减少试错轮数)
最贵的浪费是「方向错了」:AI 读了一堆文件、改了半天,结果不是你要的,推倒重来 —— 前面所有 token 全打水漂,还得重新读一遍。
4.1 一开始就给足约束
✗ 模糊
「优化一下这个函数」→ AI 猜你要啥,读一堆文件,方向跑偏,来回 4 轮。
✓ 明确
「parseUser() 里的正则在空输入时会抛错,只改这个边界处理,别动函数签名」→ 一轮命中。
4.2 指明文件 / 范围,省掉「搜索成本」
你知道在哪就直接说 src/auth/login.ts,别让 AI 满仓库搜。一句路径,省下十几次工具调用和大段命中输出。
4.3 复杂任务先让它「出计划」再动手
用 plan 模式 / 先要方案,确认方向对了再执行。比「边做边发现不对」省得多。计划阶段的 token 很便宜,返工的 token 很贵。
4.4 用项目记忆文件固化重复约束
把「用 pnpm 不用 npm」「测试放 __tests__」这类每次都要交代的规则写进 CLAUDE.md / AGENTS.md,避免每个会话重复打字解释(而且它在缓存前缀里,几乎免费)。
CLAUDE.md,DeepSeek Harness 还会把会话历史自动持久化到本地(jsonl / sqlite 会话存储),配合记忆文件体系沉淀「构建命令、踩过的坑、确认过的偏好」。它对 token 友好的关键在于 —— 启动时只加载记忆文件的索引与摘要,具体内容按需才读,记得再多也不会一上来就撑爆上下文;和 CLAUDE.md(你写、每次全量加载)互补。4.5 主动用 ! 喂精准信息,省掉一轮工具往返
与其让 AI 自己琢磨「该跑哪条命令」再发一轮工具调用,不如你直接把结果喂给它。在输入框打 ! 进入 shell 模式,!git status / !npm test 2>&1 | tail 的输出会直接进上下文,AI 拿现成的精准信息接着干 —— 少一轮「它猜命令 → 你确认 → 它再读」的往返(呼应 4.2「给精准信息」、2.5「省轮数」)。
!… | tail,呼应 2.1)—— ! 省的是「轮数 / 让它搜的成本」,不是免去截断。5进阶:用代码索引省掉「探索开销」(CodeGraph)
前面那些技巧靠 /clear、控工具、给足约束这些手动办法压低开销,但有一类开销很难靠话术消掉:在陌生代码库里「找代码」这件事本身 —— AI 为了回答「这个功能是怎么实现的」,要反复 grep / glob / Read 一层层摸,每次工具调用的命中和文件内容都进上下文。CodeGraph 这类「代码索引」工具,就是冲着这块开销来的。
它怎么省 token
CodeGraph 通过 MCP 接入 DeepSeek Harness / Cursor 等 agent,把整个代码库预先建成一张语义知识图谱(符号关系、调用图、代码结构,存在本地 SQLite)。之后 AI 一次查询图谱就能拿到入口、相关符号和代码片段 —— 把原本几十次 grep/read 的「探索往返」压成几个工具调用,常常零文件读取就给出答案。
官方 benchmark(7 个真实开源库 · Opus 4.8 · 2026-06)
| 代码库 | 语言 · 规模 | Token | 工具调用 | 花费 |
|---|---|---|---|---|
| VS Code | TS · ~10k 文件 | 少 64% | 少 81% | 便宜 18% |
| Django | Python · ~3k | 少 60% | 少 77% | 便宜 8% |
| Alamofire | Swift · ~110 | 少 64% | 少 58% | 便宜 40% |
| OkHttp | Java · ~645 | 少 54% | 少 50% | 便宜 25% |
方法:同一个架构类问题,headless CLI 模式对每个库跑「带索引 vs 不带索引」各 4 次取中位数。
什么时候值得上
- 库越大越划算:VS Code 这种万级文件,工具调用直接砍 81%;小库主要省在单价。
- 探索 / 问架构类任务收益最大:「X 功能怎么跑通的」「改这里会影响谁」(影响分析)。纯改一行的小活用不上。
- 100% 本地:只用 SQLite,无 API key、不外传代码,对公司内代码合规友好。
- 局限:只在 AI 直接查图谱时有用;若它仍把活甩给子代理去读文件,反而成了额外开销 —— 所以它的 MCP 指令会引导 AI 直接作答(呼应 1.4 子代理的「用对场景才划算」)。
# 1. 装 CLI(macOS/Linux,自带运行时,无需 Node)
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
# 2. 接入你的 agent(自动检测 DeepSeek Harness / Cursor…)
codegraph install
# 3. 在项目里建索引
cd your-project && codegraph init -i
支持 20+ 语言;文件改动靠原生 OS 事件(FSEvents/inotify)自动增量同步,基本零维护。
6省「输出 token」(caveman,冷门,看情况)
前面所有技巧(含 CodeGraph)省的都是输入侧:上下文、历史、工具结果。这是第三条、也最少被提的轴 —— 输出 token。caveman 是个跨 agent 的 skill,用 /caveman 让模型改用「电报体」作答(丢虚词、留干货、用短句),只压缩输出、不影响它的思考。官方基准称输出平均省 ~65%(22%~87% 不等)。
- 输入才是大头:日常编码里,文件 / 历史 / 工具结果(输入)远大于模型回话(输出)。砍输出对总账单的影响,通常远不如前面那些省输入的技巧。
- 有可读性代价:电报体会牺牲解释的清晰度,团队协作 / 需要留档说明时不一定划算。
- 真正适合的场景:输出特别啰嗦、又只你自己看的活(大批量解释、长篇总结),且你确实在为输出 token 买单时,才值得开。
7典型浪费案例(对号入座)
案例 A:「万能长会话」
DeepSeek Harness 一整天不关会话,从 bug 修到需求、再到写周报。到下午每一句的输入都是几十万 token。
解法:任务切换即 /clear;长任务中途 /compact。
案例 B:「让 AI 自己找」
「这个报错怎么回事」却不贴报错、不给文件,AI 只能全仓库翻。
解法:贴上报错栈 + 相关文件路径,把搜索成本降到零。
案例 C:「全量输出回灌」
跑 build/test 不截断,几千行日志全进上下文,而且接下来每轮都重发。
解法:| tail、只跑单个用例、让它先看摘要再决定要不要细看。
案例 D:「读整个文件改一行」
改一个常量,AI 把 2000 行文件整读进来。
解法:定位行号区间精读;明确告诉它改哪。
案例 E:「MCP 全家桶」
装了十几个 MCP,大半用不上,但每轮都在为它们的工具定义付费。
解法:按项目裁剪启用的 MCP。
案例 F:「方向性返工」
没说清需求,AI 写完一大坨发现不对,推倒重来三次。这是单次成本最高的浪费。
解法:先对齐方案 / plan 模式,再动手。
8实战演练(端到端操作示例)
前面是原则,这一节是可照着敲的完整操作。每个演练都给出「散弹做法 vs 精准做法」的真实流程和 token 对比。(其中的 token 数为量级示意。)
8.1 修一个线上 bug:散弹 → 精准
需求:「登录接口偶尔返回 500」。同一个 bug,两种开法差出近 10 倍 token。
✗ 散弹(~85k token)
你:登录有时候会 500,帮我看看
AI:(开始全仓库探查)
→ Grep "login" 全库 命中 240 行
→ Read src/routes/auth.ts (整文件 1.8k 行)
→ Read src/services/user.ts (整文件 1.2k 行)
→ Read src/db/pool.ts (整文件)
→ 又读了 6 个相关文件…
→ 「能贴一下报错吗?」 ← 绕一圈又回来问你
方向全靠猜,读进十几个整文件,最后还得问你要报错。✓ 精准(~9k token)
你:登录偶发 500,报错栈如下,
只看 @src/services/user.ts 的
getUserByToken(),别动签名:
TypeError: Cannot read 'id' of null
at getUserByToken (user.ts:88)
at authMiddleware (auth.ts:41)
AI:(直接定位)
→ Read user.ts:70-100 只读 30 行
→ 第 88 行 token 过期时 query
返回 null 未判空 → 修复
报错栈 + @ 指文件 + 限定函数 = 一轮命中,零搜索。@ 把范围锁到单个文件;③ 用「只改 X,别动 Y」划定边界,杜绝顺手乱改引发的返工。8.2 长会话该清了吗:用 /context 做决策
不要凭感觉,敲 /context 看构成再决定。下面是一个「该动手了」的典型画面:
看到这个画面,按情况二选一:
场景:已经换任务了
消息里大半是上一个任务读过的文件/日志,跟现在要做的事无关。/clear # 直接清空,从干净的上下文重开
# 需要延续的结论,先让它写进 NOTES.md场景:还在同一个长任务
历史都相关、不能丢,但中间过程(大段文件、试错)很冗余。/compact 只保留最终方案、改动的
文件列表和待办,丢掉中间读过的
文件全文和调试输出
# 540k → 通常能压到 30~60k/clear;占比高但全相关 → 带指令的 /compact。底部状态栏的百分比可以让你不用反复敲命令。8.3 分析一大坨日志:走文件中转,别贴进对话
需求:「这个 5000 行的崩溃日志,帮我找出根因」。
✗ 贴进对话(~70k,且每轮重发)
你:(把 5000 行日志整段粘贴进来)
帮我看看崩在哪
→ 5000 行一次性进上下文 ≈ 65k token
→ 之后每追问一句,这 65k
都跟着重发,越聊越贵✓ 文件中转(~4k)
你:日志在 @logs/crash-0601.log,
先别全读。按这个步骤:
① grep -n "ERROR\|FATAL" 看有几处
② 只读第一个 FATAL 前后 40 行
③ 告诉我根因
AI:→ grep 命中 3 处 FATAL
→ Read 该文件 1180-1220 行
→ OOM in image resizegrep/区间读关键几十行。对话历史保持精简,后续每一轮的输入都小 —— 这正是第 1.5 节「文件做中转」的实战形态。8.4 跨文件批量改:子代理探查 + PLAN.md 落地
需求:「把全项目的 moment 换成 dayjs」—— 涉及几十个文件,是最容易把上下文撑爆的活。
# ① 探查交给子代理,主会话不被原始输出污染
你:用一个 subagent 搜出所有 import 了 moment 的文件,
只返回「文件路径 + 用到的 moment API」清单,别贴文件全文。
子代理(独立上下文里翻了 40+ 文件)→ 只回主会话一张表:
src/a.ts → moment().format()
src/b.ts → moment().add(), .diff()
…共 23 个文件、5 种 API
# ② 把计划落到文件,抗 /compact、可跨轮次执行
你:把这张清单和替换方案写进 PLAN.md,按文件分组、能勾选。
# ③ 按 PLAN.md 分批改,每改几个就 /compact 一次
你:按 PLAN.md 改前 5 个文件,改完更新勾选状态。
(改完)/compact 只留 PLAN.md 进度和约定,继续下一批。
- 子代理隔离:40 个文件的原始内容留在子上下文,主会话只收到一张 23 行的表(呼应 1.4)。
- 计划外置到
PLAN.md:进度写在文件里,/compact//clear都冲不掉,随时能接着干(呼应 1.5 / 4.4)。 - 分批 + 阶段性 compact:避免「23 个文件的改动全堆在一个会话里反复重发」。
8.5 在陌生大库里问架构:探索 → 查图谱(CodeGraph)
需求:刚接手一个万级文件的项目,「扩展进程(extension host)是怎么和主进程通信的?」—— 典型的"问架构"任务,也是第 5 节 CodeGraph 最擅长的场景。下面是 VS Code 仓库上「带索引 vs 不带索引」的真实对比(数字取自官方 benchmark,同一模型 4 次中位数)。
✗ 不带索引(~1.79M token · 21 次工具调用 · $0.83)
你:extension host 怎么和主进程通信?
AI:(全靠在文件系统里摸)
→ Grep "extension host" 全库 命中几百行
→ Glob **/extHost*.ts 列一堆候选
→ Read extHost.ts (整文件)
→ Read mainThread*.ts (整文件)
→ 又 grep/read 了十几次…
→ 9 次 Read + 11 次 grep/bash
才拼出调用链
预算几乎全花在「发现该读哪个文件」上,整文件反复灌进上下文。✓ 带索引(~640k token · 4 次工具调用 · $0.68)
你:extension host 怎么和主进程通信?
(项目已 codegraph init -i)
AI:(直接问图谱)
→ codegraph_explore
"extension host ↔ main
process communication"
→ 一次返回:入口符号 + 调用链
+ 关键代码片段(RPC 协议、
proxy/序列化层),零文件读取
→ 直接作答
一次图谱查询替代 20 次 grep/read:token −64%、工具调用 −81%、还更快。codegraph init -i 建好索引(一次性);② 问"怎么实现/谁调用了它/改这里影响谁"这类探索型问题时,直接让 AI 走 codegraph_explore / 影响分析,而不是放它去 grep;③ 之后真要改代码,再配合 1.3 区间精读那几个命中文件 —— 探索用图谱,精读用 Read,两段各省各的。@ 指文件(1.3)更快。索引的价值在"不知道在哪"的探索阶段;已经定位到了就回归普通精读。9如何发现自己在哪浪费
优化的前提是能看见。下面是几种量化 / 定位手段。
9.1 会话诊断三件套:/context · /usage · /cost
三个命令对应三种视角,配合着看才完整:
| 命令 | 看什么 | 用来定位 |
|---|---|---|
/context | 当前会话的上下文里「装了什么」:系统提示 / 工具 / MCP / Skills / 消息各占多少 | 谁在占满窗口 —— 哪个大户该清 |
/usage | 你的套餐 / 账户配额用掉多少:限额、剩余量、距离重置还有多久 | 「最近整体烧太快」的宏观信号 |
/cost | 当前会话累计 花费 & token 用量 | 单次会话是不是异常贵 |
/context 的一次真实输出
- 「消息」占了一半以上,而且会随对话变长持续上涨 —— 涨到逼近窗口上限,就是该
/compact或/clear的时刻。 - 工具 / MCP 是「固定税」(这里合计 ~36k),每轮都在付。用不上的 MCP 就该裁(呼应 2.3);好在按需加载(deferred)能把一部分推迟到真正用时再算。
- 系统提示 / Skills 很小,基本不用操心 —— 别把优化精力花在这。
另外,与其每次手动敲 /context,不如把用量常驻状态栏,让它实时显示、随时扫一眼就知道。
- 怎么配:跑
/statusline让它按你的描述自动生成脚本;或在settings.json里写statusLine(type: "command")指向一个脚本。 - 懒得自己写?用现成的:claude-hud 是个开箱即用的状态栏,直接显示上下文用量、本会话花费、模型、git 分支等,装上就有,不用自己拼脚本。
- 能显示什么:脚本会收到 JSON,含
context_window.used_percentage(已用百分比)、total_input_tokens、模型名、git 分支等,可以拼成一个带进度条的实时条。 - 零成本:状态栏脚本本地跑、不消耗 API token,纯白赚的可见性。
/compact//clear」的判断(呼应 8.2)不用敲命令,瞄一眼百分比就有数。9.2 /insights:从「单次体检」升级到「习惯诊断」
前面三件套看的是「当下这一次」(这个会话装了啥、花了多少、配额还剩多少)。/insights 换一个视角:它会分析你跨多个会话的使用情况,生成一份报告,告诉你常在哪些项目区域工作、习惯怎么和 AI 交互、卡点(friction)出在哪。
| 命令 | 时间尺度 | 回答的问题 |
|---|---|---|
/context / /cost | 当前会话 | 这一次装了啥、花了多少 |
/usage | 当前配额周期 | 套餐额度还剩多少 |
/insights | 跨会话的长期趋势 | 我反复在哪些模式上卡壳 / 浪费 |
/context 帮你救一个已经臃肿的会话;/insights 帮你发现系统性的坏习惯 —— 比如「总在让 AI 满仓库搜本可以直接 @ 指的文件」「长会话从不 /clear」这类反复出现的卡点。把根因式的浪费(前面 5、6 节那些案例)一次性改掉,比每次事后补救更省。
/insights 偏向工作流 / 交互模式的复盘,不是逐 token 的精确账本 —— 要精确数字仍看 /cost 与控制台 Usage(8.4)。两者互补:/insights 指方向,账单核数字。9.3 看 Cache 命中率
关注用量里的 cache read vs. input 比例。理想状态是大量 token 走 cache read(便宜)。如果 cache 命中很低,说明你在频繁让前缀失效(中途改 CLAUDE.md、反复重开、间隔太久缓存过期)。
9.4 API:用账单与用量后台
- OpenAI / Anthropic 控制台的 Usage 页可按天、按模型看 token 走势,定位「哪天哪类任务突然暴涨」。
- API 响应里的
usage字段(input_tokens/output_tokens/cache_*_tokens)是最精确的逐请求账本。
9.5 自检三连问
- 这个会话里,是不是混了好几个不相关任务?(→ 早该 clear)
- 上下文里是不是塞着大段我已经不需要的文件/日志?(→ compact)
- 我有没有让 AI 去搜本可以直接告诉它的东西?(→ 给路径/贴报错)
9.6 给团队的可观测建议
若用 API/SDK 自建 agent,把每次请求的 usage 落日志,做个看板按「任务类型 / 用户 / 是否命中缓存」聚合。浪费往往集中在少数几种模式上,量化后一目了然。
判断口诀:一次性、个人探索、明显吞量大的活 → 走个人账号;池子留给短平快、人人都要用的协作场景。
10速查清单(贴墙版)
| 场景 | 该做什么 |
|---|---|
| 切换到不相关任务 | /clear / 开新会话 |
| 同一任务越聊越长 | /compact 总结,丢中间过程 |
| 知道改哪个文件 | 直接给路径,别让它搜 |
| 有报错 | 贴报错栈,别让它复现/猜 |
| 跑命令/测试 | | tail、只跑单测、要 --count |
| 读大文件 | 先定位行号,区间精读 |
| 大范围调研/搜索 | 丢给 subagent,只收结论 |
| 复杂改动 | 先出 plan,对齐再执行 |
| 反复交代的规则 | 写进 CLAUDE.md / AGENTS.md |
| MCP 一大堆 | 只留用得上的 |
| 怀疑在烧 token | /cost + /context 体检 |
| 临时问个无关小问题 | side-question(/btw),不进对话历史 |
| 手上已有现成信息 | ! 直接喂(记得截断),省一轮工具往返 |
| 老忘记截断输出 | 配 PreToolUse/PostToolUse hook 自动截 |
| 垃圾目录老被读进来 | 沙箱 deny 加 Read(...) 规则 |
| 想随时盯用量 | /statusline 把上下文 % 常驻状态栏 |
命令与折扣比例以官方文档为准;不同版本可能略有差异。