--debug 更会说话了:子代理 frontmatter 拼错、慢钩子一眼看出
自己写子代理、配钩子,最烦的往往不是写,而是「它为什么没生效」「为什么每轮都卡一下」。CLI 2.1.296 对 --debug 输出做了两处改进,正好对着这两个问题:
- 自定义子代理文件里不认识的 frontmatter 字段会被点名,并附上可能拼错的提示;
- 命令钩子跑完会留下一行,写明命令、来源插件、结果和耗时,慢钩子一查就知道。
先把调试日志打开
两种方式(按 CLI 参考文档):
# 写到默认位置:~/.claude/debug/<session-id>.txt
claude --debug
# 写到你指定的文件,同时隐式开启调试模式
claude --debug-file /tmp/claude-debug.log注意 --debug 不会把日志打印到终端,要去日志文件里看。还可以按类别过滤,比如 --debug='mcp,startup'——过滤只在 = 写法下生效,用空格隔开会变成「开调试但不过滤」。
改进一:子代理 frontmatter 拼错会被点名
子代理就是 .claude/agents/ 或 ~/.claude/agents/ 里的 Markdown 文件,靠开头的 YAML frontmatter 声明 name、description、tools、model 等。字段名拼错,比如把 tools 写成 tool,过去往往没有任何提示——那一项设置就悄悄不生效,你只觉得子代理「不太听话」。
2.1.296 起,--debug 会列出自定义 agent 文件里无法识别的 frontmatter 字段,并对疑似拼写错误给出提示。排查子代理行为异常时,先开调试跑一次,搜一下这个文件名,往往就能找到原因。
顺带记一下官方文档列出的「子代理文件被跳过」的几种情况,它们同样只在调试日志里能看到:
- 没有
name:被当成放在旁边的说明文档; - 开头的
---不在第一行:被视为没有 frontmatter; name以-开头、包含:,或超过 256 个字符:跳过并在调试日志写错误;- 有
name但没有description:跳过并写明原因; - YAML 解析失败:整份文件不读,跳过并记录解析错误。
想在开会话之前检查,可以对目录跑 claude plugin validate .claude/agents(2.1.233 起),它会找出 frontmatter 解析不了的文件;但只检查你指定的目录,也不会标出「能解析但没 name」的文件。
子代理还有不少新字段,比如前两天介绍的 autoCompactWindow,新字段写错也能靠这个功能尽早发现。
改进二:每个命令钩子都留下耗时
钩子多了以后,偶尔会有一个特别慢:每次提交提示、每次工具调用都要等它。以前想找出是谁,得自己往脚本里加计时。
2.1.296 起,工具事件、UserPromptSubmit、SessionStart、Stop 等事件上的命令钩子结束时,无论它输出了什么,都会在调试日志里留下一行 Hooks:。按官方文档的例子,格式大致是:
Hooks: PostToolUse:Write [.claude/hooks/log-write.sh] finished with status 0 (31ms)拆开看:
PostToolUse:Write:事件名,冒号后是匹配到的工具名或其他匹配值;- 方括号里:钩子执行的命令;来自插件的还会写明插件;
finished with status 0:怎么结束的;(31ms):耗时。
结束方式除了正常退出,还可能是 timed out after <N>ms、cancelled、moved to the background 或 failed to start。Notification、SessionEnd、PreCompact 等少数事件上的命令钩子,会留下不带耗时的 completed with status 行。
找慢钩子的办法很直接:
grep "Hooks:" /tmp/claude-debug.log扫一眼括号里的毫秒数,最大的那个就是元凶。看到 failed to start 或 timed out,也可以结合 onFailure: "block" 想清楚:这个钩子失败时,是该放行还是该拦截。
需要更细的匹配信息(比如每个 matcher 命中多少钩子),可以再设 CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose。
小结
- 2.1.296 起,
--debug会点名子代理文件里不认识的 frontmatter 字段,并提示可能的拼写错误。 - 命令钩子结束时会记录事件、命令、插件、结果和耗时,
grep "Hooks:"就能定位慢钩子或启动失败的钩子。 - 调试日志不打印到终端:用
--debug看~/.claude/debug/<session-id>.txt,或用--debug-file指定路径。
升级后用 claude --version 确认 ≥ 2.1.296。