“有一次我让Claude Code做一次中等复杂的重构。七八分钟过去,终端还在滚动输出。我看不出它卡在哪儿。Bash没报错,模型还在产出内容——就是慢。它是在几十次重读同一个文件吗?是在等某个命令的IO?还是陷入死循环了?”

这位开发者的吐槽,几乎每个重度依赖AI编程助手的人都感同身受。终端的输出永远是“过去时”:一行行滚过去,然后消失。任务跑完,你仍然说不出这几分钟到底花在哪里了。直到他试了cctrace。

打开网易新闻 查看精彩图片

同一个任务跑完后,他打开cctrace生成的瀑布时间线。“一眼看过去:一个Bash工具调用卡了将近两分钟,在这之前和之后都是快速Read调用批次,中间还夹了十几次工具返回结果。问题从‘完全没头绪’变成‘啊,就是它’。”cctrace只做一件简单的事:把一次完整的AI编程代理(agent)会话,转成一份你可以真正阅读的瀑布时间线。

cctrace 是为了解决一个具体的痛点而生的:当Claude Code或Codex这类AI代理跑一个不简单的任务时,终端看起来一直很忙,但你根本说不出——哪个工具调用耗时最长?是Read啃了一堆文件,还是bash在等命令完成?模型什么时候在思考,什么时候是真的卡住了?它什么时候派出了子代理(subagent),代理层叠了多少层深度?一句对话跑了五分钟,墙上钟的时间到底耗在哪里?终端给不了这些答案。Claude Code没有内置的剖析器。转录文件(transcript)确实有数据,但那是逐行JSON,你需要手工关联;ccglass记录又是另一个格式;进程级事件又是另一码事。三类来源,散落四处,看都看不全。

cctrace的办法很直接:在启动代理之前,在外面包一层。一行命令——cctrace claude -- claude——就搞定了。它会同时盯住三个数据源:代理进程本身(进程层)、对转录文件的写入(转录层)、以及ccglass跟踪记录(ccglass层)。三路信号全部灌进一个统一的事件/会话模型里。随后,一个启发式预处理步骤会把跨来源的相关事件关联起来,给每条关联打上四档置信度标签:exact(精确匹配)、likely(很可能)、possible(可能)、unknown(未知)。

接着cctrace启动一个本地网页服务器,默认只监听127.0.0.1:43179这个地址,命令行会打印URL,你用浏览器打开,就能看到瀑布时间线。没有后台守护进程,没有遥测——所有数据都只写入本地磁盘上的JSONL文件。用完就关,数据留在自己机子上。

打开瀑布时间线,你会看到事件按请求轮次(request turn)组织在左侧,所有事件——用户输入、模型回复、工具调用、工具返回结果——全部平铺在同一条时间轴上。顶部有整个会话的密度概览图,你能一眼看到最拥挤的那一段,直接点过去。水平拖动缩放时间,纵向滚动浏览其余部分,想细看哪个事件,点一下就能展开详情:参数和输出、持续时长(起止时间戳)、关联ID(以及四档置信度标签),还有原始事件JSON。原来那句“为什么这个工具调用这么慢?”或者“哪个子代理卡了最久?”都能在这种单一视图里直接找到答案。

这样的设计本质上就是把散落在不同角落里的调试信息,揉进一张可交互的图中。开发者不再需要对着滚动几千行的终端屏幕使劲回忆,也不需要手工拼凑JSON日志。一个会话跑下来,时间流中的所有停顿、并发、等待,全都摊在时间轴上,视觉上的突兀就是问题所在的位置。

cctrace并没有引入任何新魔法,它只是用一种更符合人类理解的方式,把已经存在但在日常使用中被淹没的数据重新组织。本地、无后台、不联网,也意味着你可以把它插在CI或者调试环境里,跑完一个任务后扫一眼瀑布图,快速定位卡顿源头。下次再遇到“终端还在滚,就是不知道在干嘛”的场景,或许那一眼瀑布图,就能让你把骂娘的话换成一句“原来如此”。