W
AI-Wiki
ENTITY

summary-hook.js

定义与身份

summary-hook.jsclaude-mem 五阶段 Hook 生命周期中 Stop 阶段对应的脚本,由 hooks 配置在 Stop 生命周期事件中调用。它不是会话结束后的清理器,而是会话进行中的摘要生成器,用于在 Claude 停止时生成当前会话的阶段性摘要。

在配置中,它通过如下命令路径执行: node ${CLAUDE_PLUGIN_ROOT}/scripts/summary-hook.js

原始源码与构建产物的映射为: src/hooks/summary-hook.tsplugin/scripts/summary-hook.js

在 Hook 生命周期中的位置

summary-hook.js 对应 Stop 事件,属于 Hooks architecture 摘要 中第 4 个执行环节,位于 PostToolUse 之后、SessionEnd 之前。其触发条件是 Claude 停止,而不是用户真正关闭会话。

这意味着它生成的是“检查点式”摘要,而不是“终局总结”。原文明确强调:

  • 由 Stop lifecycle event 触发
  • 从 v4.2.0+ 开始,一个 session 可以有多份 summary
  • 这些 summary 是 checkpoints,不是 endings
  • 使用 Claude Agent SDK 做 AI 压缩

hooks 配置

Stop 阶段的配置形式如下:

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "${CLAUDE_PLUGIN_ROOT}/scripts/summary-hook.js"
      }]
    }]
  }
}

这说明 summary-hook.js 是由 hooks 配置直接挂到 Stop 阶段的命令型脚本。

角色职责

summary-hook.js 的职责不是保存单次工具调用,也不是结束会话清理,而是处理“结构化摘要”的生成与持久化。原文给出的处理流程有 4 步:

  1. 从数据库收集当前会话的 observations
  2. 将这些内容发送给 Claude Agent SDK 做摘要生成
  3. 处理返回结果并提取结构化 summary
  4. 将结果写入 session_summaries

因此,它在系统中的角色更接近会话级压缩器:把前面由 save-hook.js 持续沉淀的 observation,压缩成可检索、可延续使用的会话摘要。

摘要结构

summary-hook.js 处理的不是任意自由文本,而是结构化摘要。原文示例中的 summary 结构如下:

<summary>
  <request>User's original request</request>
  <investigated>What was examined</investigated>
  <learned>Key discoveries</learned>
  <completed>Work finished</completed>
  <next_steps>Remaining tasks</next_steps>
  <files_read>
    <file>path/to/file1.ts</file>
    <file>path/to/file2.ts</file>
  </files_read>
  <files_modified>
    <file>path/to/file3.ts</file>
  </files_modified>
  <notes>Additional context</notes>
</summary>

从这个结构可以看出,摘要至少覆盖以下信息维度:

  • request:用户原始请求
  • investigated:本轮检查过什么
  • learned:得到的关键发现
  • completed:已经完成的工作
  • next_steps:剩余待办
  • files_read:读过的文件列表
  • files_modified:修改过的文件列表
  • notes:补充上下文

这也是它区别于普通日志或 observation 队列的关键点:输出是面向后续恢复和理解的结构化会话状态。

关键信息

  • 调用阶段:Stop
  • 调用方式:hooks 中的 command
  • 命令路径:${CLAUDE_PLUGIN_ROOT}/scripts/summary-hook.js
  • 源码映射:src/hooks/summary-hook.tsplugin/scripts/summary-hook.js
  • 核心依赖:Claude Agent SDK
  • 持久化位置:session_summaries
  • 摘要语义:阶段性 checkpoint,而非会话结束总结
  • 版本边界:v4.2.0+ 支持同一 session 产生多份 summaries

细节与边界

1. 它在会话中途运行,不等于结束流程

Stop 触发的是 Claude 停止,而不是 SessionEnd。因此 summary-hook.js 生成摘要时,会话可能仍会继续,后续仍可能继续产生 observation、继续生成新的 summary。

2. 一个会话可以有多份摘要

原文明确给出 “Multiple summaries per session (v4.2.0+)”。这意味着系统设计上不假定每个 session 只有一条最终摘要,而是允许随着会话推进反复生成多个检查点。

3. 它依赖 observation,而不是直接监听工具输出

在职责描述里,它首先是“从数据库收集 session observations”。也就是说,summary-hook.js 主要消费前序链路已落库的数据,而不是像 save-hook.js 那样直接处理单次工具事件。

4. 输出去向是数据库,不是上下文注入或日志显示

在 Hook Timing 表中,Summary 一行对应:

  • Timing:Worker triggered
  • Blocking:No
  • Timeout:120s
  • Output Handling:Database

这说明它的结果主要写数据库,而不是像 SessionStart 那样注入 hookSpecificOutput.additionalContext,也不是仅写 stderr 日志。

5. 它是非阻塞的,超时为 120 秒

虽然 Stop 阶段会触发摘要生成,但该流程在时序表中被标记为非阻塞(No),并且超时时间是 120 秒。这表明摘要生成被设计成尽量不阻塞主交互流程。

6. 摘要生成由 worker 触发链路承接

时序表把 Summary 的 Timing 标成 “Worker triggered”,说明即便 Stop 是生命周期事件,实际摘要执行与 Worker Service Architecture 存在直接关系,不是单纯前台同步脚本输出。

与相邻脚本的分工

save-hook.js 的区别

save-hook.js 属于 PostToolUse,负责在每次工具使用后,把 observation 排队送入后续处理流程;summary-hook.js 则消费这些 observation,生成会话级结构化摘要并写入 session_summaries。前者偏事件采集,后者偏会话压缩。

cleanup-hook.js 的区别

cleanup-hook.js 属于 SessionEnd,职责是把 session 标记为 completed 并执行优雅清理;summary-hook.js 不负责完成态标记,也不负责结束 worker,而是负责在会话过程中生成摘要。

version-check.js 的区别

version-check.js 属于 Setup 阶段,负责安装版本检查与提示;summary-hook.js 不参与安装检查,也不处理启动前校验。

在整体架构中的意义

summary-hook.jsProgressive Enhancement 思路中的关键组成部分:系统不是等到会话彻底结束才总结,而是在 Stop 节点持续形成结构化 checkpoint。这样做有几个直接意义:

  • 降低长会话上下文膨胀问题
  • 为后续恢复会话提供更清晰的阶段摘要
  • 让 worker 可以基于已积累 observation 持续压缩信息
  • 避免把“总结”完全推迟到结束时才进行

相关条目