我花了两天时间拆解 SayCraft 的全链路性能数据。结论和我预想的不一样。
17 分钟里,97% 的时间花在哪
拿一个真实会议(meeting 5U0DM3fWzqr)的 Langfuse trace 做分析。总耗时 1029 秒,大约 17 分钟。trigger-classifier 花了 0.48 秒,coordinator 决策花了 24 秒左右。剩下的 97%——全在沙箱里 Claude Code 写代码。
这个数字一出来,我之前想优化触发器和协调器的念头就可以放下了。收益太小。
压力测试:20 个 follow-up 的真实数据
为了验证不是个例,我跑了一轮压力测试,连续 20 个 follow-up 请求。结果更夸张:
- Claude 编码(10 个前台 session):3569 秒,占 wallclock 的 99%
- Coordinator 全部决策加一起:229 秒,6.4%
- tsgo 类型检查:29 次,每次约 5.5 秒,共 159 秒
这里有个教训。之前让 subagent 估算各环节耗时,它给 subagent 自己算了 345 秒——比实测高出一倍。数字是它编的,不是量的。从那以后我只看 trace 数据,不看估算。
Coordinator 的长上下文表现
我们用 kimi-k2.5 跑 coordinator。17 轮对话下来,input token 从 8132 涨到 10312,几乎是线性增长。每轮耗时 5 到 18 秒,单轮成本稳定在 0.006 到 0.009 美元,没有随轮次上升的趋势。
这让我放心了。kimi-k2.5 在长上下文场景下没有退化,成本也没有失控。coordinator 这一层不需要动。
沙箱里的工具调用浪费
既然 97% 的时间在 coder 端,我就钻进去看它到底在干什么。发现了一堆低效操作:
npx tsgo 每次调用多花约 30 秒在查找开销上。改成直接调用 ./node_modules/.bin/tsgo,这个收益是确定的。还有一次拼写错误,npx tscgo(多了个 c),白白浪费 5 秒等报错。
同一个文件连续两次 Edit,明明可以合并成一次。先 Read 一个文件再整体 Write 覆盖,那个 Read 完全没用,出现了 4 次,浪费约 20 秒。每个 section 的 commit 拆成了 tsgo 和 git add && commit 两个独立的 Bash 调用,也应该合并。
单个看都是小事。但 coder 在沙箱里跑几十分钟,这些小浪费乘以调用次数就不小了。
TypeScript 编译器的三代
这个值得单独说。tsc 是基础的 TypeScript 编译器,项目一大就慢得离谱。tsc --incremental 做了增量编译,只重新检查变更文件,好一些。tsgo 是 Go 语言重写的版本,速度提升 10 倍。
我们在沙箱里把 tsc 换成 tsgo,每次类型检查从约 55 秒降到约 5.5 秒。29 次调用,省下将近 1400 秒。这是整个优化里回报最大的一项。
定价数据的坑
优化成本的时候踩了两个坑。
第一个:阿里百炼上的 deepseek-v4-pro 定价是每百万 token 12 元人民币,折合下来比 DeepSeek 官网贵了 4 倍。同一个模型,不同渠道价差这么大,不比不知道。
第二个更隐蔽。Langfuse 里旧的 qwen-turbo 定价记录,把人民币 0.3 元直接当成 0.3 美元存了。汇率差 7 倍,成本报表看着吓人,其实是数据录入错误。我把 9 条定价记录全部重建了。
成本优化的前提是成本数据本身是对的。听起来像废话,但我确实在错误数据上做了好几天分析才发现。
我的结论
SayCraft 的性能瓶颈极度集中:沙箱内的 Claude Code 编码占了绝对大头。优化策略也因此很明确——减少 coder 的无效调用,用更快的工具(tsgo 替代 tsc),合并重复操作。触发器和协调器的优化优先级很低。
还有一个方法论上的收获:不要相信 AI 对自己性能的估算。它会编数字,而且编得很有说服力。只有 trace 数据是真的。
SayCraft 是一个用对话构建 Web 应用的工具。如果你感兴趣,可以在 saycraft.ai 试试。