:让 Claude Code / Gemini CLI 的 Agent 感知并安全应对上下文耗尽)
get-shit-done 上下文窗口监控Context Window Monitor让 Claude Code / Gemini CLI 的 Agent 感知并安全应对上下文耗尽【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done本指南讲解 get-shit-doneGSD仓库中“上下文窗口监控”后置工具钩子post-tool hook的完整机制。它解决一个真实痛点状态栏statusline能把上下文用量展示给人类用户但 Agent 自身对上下文限制毫无感知直到撞上硬墙被迫中断。读完本文你将掌握该监控钩子在 Claude CodePostToolUse与 Gemini CLIAfterTool下的注册方式、35%/25% 两级阈值与防抖策略、桥接 JSON 数据格式以及它与/gsd-pause-work状态保存命令的联动原理并能在自己的 settings 中手工配置、验证与排障。要解决的问题上下文耗尽 中途“失忆”的 Agent大上下文Long Context模式下会话越长可用窗口越少。GSD 的状态栏钩子 hooks/gsd-statusline.js 会在终端下方绘制一条 10 段的进度条和百分比绿→黄→橙→红色骷髅头这段信息是给用户看的但驱动工作的Agent并不会因此停下来——它不知道上下文快要用完了。后果是当剩余上下文跌破极限时Agent 会继续执行任务直到被强制压缩或中断而此时它可能正处理到一半尚未把执行状态写入文件。等新一轮对话恢复时它丢失了对“做到哪一步”的记忆长任务往往需要人工补述才能继续。GSD 的上下文监控钩子正是为弥合“用户知道、Agent 不知道”这一信息差而设计让 Agent 在自己的对话流里收到结构化警告自主选择收尾并保存状态。整体架构与数据流监控功能由两个钩子配合完成形成“写入桥接文件 → 读取桥接文件 → 注入警告”的闭合链路。架构示意出自 docs/ko-KR/context-monitor.mdStatusline Hookgsd-statusline.js | 写入 v /tmp/claude-ctx-{session_id}.json ^ 读取 | Context Monitorgsd-context-monitor.jsPostToolUse / AfterTool | 注入 v additionalContext —— Agent 在对话中收到警告具体分四步statusline 钩子写入指标每次渲染时hooks/gsd-statusline.js 把上下文指标写入/tmp/claude-ctx-{session_id}.json。每次工具调用后监控钩子读取上下文监控钩子 hooks/gsd-context-monitor.js 在每一次工具执行完毕后被触发Claude Code 为PostToolUseGemini CLI 为AfterTool读取该桥接文件。低于阈值时注入警告当剩余上下文百分比跌落到阈值之下钩子以hookSpecificOutput.additionalContext的形式返回一段警告文本。Agent 在对话流中收到并响应该文本会像一条新消息一样出现在 Agent 的上下文中Agent 据此收尾当前任务、停止新工作或提示用户暂停。桥接文件两个钩子之间的“信使”两个钩子进程彼此独立通过位于系统临时目录的 JSON 文件解耦注无论运行在哪个 CLI 上文件名前缀统一为claude-ctx-。这个桥接文件是一个纯 JSON 对象{ session_id: abc123, remaining_percentage: 28.5, used_pct: 71, timestamp: 1708200000 }字段含义字段含义说明session_id会话标识既用于命名桥接文件claude-ctx-{session_id}.json也用于命名防抖哨兵文件见下文remaining_percentage剩余上下文百分比取自运行时的原始值不做归一化used_pct已用上下文百分比必须与 Claude Code 原生/context报告口径一致详见后文 #2451 精度说明timestamp写入时刻Unix 秒供监控钩子做“过期数据”判断两级阈值Normal / WARNING / CRITICAL监控钩子依据剩余上下文比例做判定源码中以常量形式固化于 hooks/gsd-context-monitor.jsconst WARNING_THRESHOLD 35; // 剩余 35% 触发 const CRITICAL_THRESHOLD 25; // 剩余 25% 触发 const STALE_SECONDS 60; // 忽略超过 60 秒的过期指标 const DEBOUNCE_CALLS 5; // 两次警告之间的最小工具调用间隔级别剩余比例Agent 应执行的动作Normal 35%不注入任何警告WARNING≤ 35%收尾当前工作不要启动新的复杂任务CRITICAL≤ 25%立即停止并保存状态提示执行/gsd-pause-work注意源码判断是remaining WARNING_THRESHOLD则直接静默退出因此 35% 是一个“含端点”的触发边界。实际注入的警告文本GSD 判定差异监控钩子会先探测当前工作目录是否存在.planning/STATE.md据此区分“GSD 工程内”与“普通工程”两种语境拼装不同文案GSD 工程内 · CRITICALCONTEXT CRITICAL: Usage at {used_pct}%. Remaining: {remaining}%. Context is nearly exhausted. Do NOT start new complex work or write handoff files — GSD state is already tracked in STATE.md. Inform the user so they can run /gsd:pause-work at the next natural stopping point.非 GSD 工程 · CRITICAL... Inform the user that context is low and ask how they want to proceed. Do NOT autonomously save state or write handoff files unless the user asks.GSD 工程内 · WARNINGCONTEXT WARNING: ... Avoid starting new complex work. If not between defined plan steps, inform the user so they can prepare to pause.两种语境的差异很关键在 GSD 工程内CRITICAL 会引导用户到pause-work状态保存命令且刻意不写手写交接文件state 已由 STATE.md 跟踪在普通工程内则保持克制绝不替用户擅自杀青或写文件。注入格式与运行时兼容警告最终以 JSON 形式输出到 stdoutconst output { hookSpecificOutput: { hookEventName: process.env.GEMINI_API_KEY ? AfterTool : PostToolUse, additionalContext: message } };钩子通过检测环境变量GEMINI_API_KEY自动切换事件名——这保证同一份钩子脚本既可作为 Claude Code 的PostToolUse钩子、也可作为 Gemini CLI 的AfterTool钩子工作参见 docs/ko-KR/CONFIGURATION.md 中关于GEMINI_API_KEY的说明。防抖Debounce避免警告刷屏每次工具调用都可能触发一次监控若不加以抑制反复警告会污染 Agent 的上下文。因此钩子为每个会话维护一个独立的“哨兵”文件/tmp/claude-ctx-{session_id}-warned.json记录callsSinceWarn距上次警告的工具调用数、lastLevel上次警告级别与criticalRecorded本次 CRITICAL 会话是否已做过状态记录见下文。防抖规则如下hooks/gsd-context-monitor.js首次警告总是立即触发firstWarn标记为 true 时跳过防抖检查后续警告需要间隔至少 5 次工具调用warnData.callsSinceWarn DEBOUNCE_CALLS则只更新计数、不输出警告级别上升WARNING → CRITICAL时绕过防抖立即触发severityEscalated判断保证最危险的时刻不被“静音”。与 GSD 状态保存的集成CRITICAL 时自动留痕GSD 的/gsd-pause-work命令实现见 commands/gsd/pause-work.md用于保存执行状态对应的恢复命令为/gsd-resume-work见 commands/gsd/resume-work.md。WARNING 消息“建议”在自然的暂停点使用该命令保存状态CRITICAL 消息则“指示”立即保存。除了提示用户之外监控钩子还提供了一层自动兜底源码中对应 issue #1974 的机制当满足CRITICAL 活动 GSD 工程 该会话尚未记录过三个条件时钩子以“fire-and-forget”方式异步拉起gsd-tools.cjs state record-session --stopped-at context exhaustion at {used_pct}% (日期)把“上下文耗尽”这一刻作为 breadcrumb 写进.planning/STATE.md的Stopped At字段便于之后通过/gsd-resume-work定位崩溃瞬间。几点实现细节值得注意仅触发一次criticalRecorded哨兵标记会持久化到-warned.json后续同一 CRITICAL 会话的防抖周期不会重复覆盖“崩溃时刻”的记录路径解析使用__dirname而非硬编码~/.claude/钩子通过path.join(__dirname, .., get-shit-done, bin, gsd-tools.cjs)定位 CLI 工具使同一脚本在 Claude Code、Gemini CLI、OpenCode 等多个运行时上都能工作状态记录本身带保护整段逻辑被 try/catch 包裹状态记录失败绝不影响钩子主流程。阈值之上的精度工程#2451 原始值与归一化的取舍若告警数值与 Claude Code 原生/context显示不一致会造成误导。历史上曾出现过约 13 个百分点的“虚高”issue #2451Claude Code 默认为 autocompact 预留约 16.5% 的缓冲statusline 内部为了绘制进度条会对“可用上下文”做缓冲归一化即usableRemaining (remaining - 16.5%) / (100% - 16.5%) * 100。修复后tests/bug-2451-context-monitor-over-report.test.cjs 予以回归锁定的关键原则是进度条使用缓冲归一化后的used用于状态栏展示桥接文件的used_pct必须写原始值Math.round(100 - remaining)保证监控钩子警告文案里的百分比与用户手动输入/context看到的口径一致允许 ±1 的舍入差。此外用户可通过环境变量CLAUDE_CODE_AUTO_COMPACT_WINDOW以 token 数为单位自定义 autocompact 缓冲大小statusline 会按(acw / total_tokens) * 100动态换算缓冲占比避免在提前压缩配置下仪表不准。安装与注册自动与手工两种方式两个钩子都会在运行npx get-shit-done-cc安装时自动注册到当前编辑器的设置文件中Statusline负责写入桥接文件注册为statusLinesettings.json 中的statusLine键Context Monitor负责读取桥接文件注册为PostToolUse钩子Gemini 为AfterTool。手工注册Claude Code如需手工写入编辑~/.claude/settings.json以下示例沿用了韩文文档的简洁写法{ statusLine: { type: command, command: node ~/.claude/hooks/gsd-statusline.js }, hooks: { PostToolUse: [ { hooks: [ { type: command, command: node ~/.claude/hooks/gsd-context-monitor.js } ] } ] } }英文原版文档 docs/context-monitor.md 补充了一个跨平台建议手工注册时最好使用当初运行安装器的 Node 可执行文件绝对路径例如/usr/local/bin/node /Users/me/.claude/hooks/gsd-context-monitor.js在 Windows PowerShell 中若该路径带引号命令前需加前缀。手工注册Gemini CLIGemini CLI 的事件名是AfterTool而非PostToolUse配置文件为~/.gemini/settings.json{ hooks: { AfterTool: [ { hooks: [ { type: command, command: node ~/.gemini/hooks/gsd-context-monitor.js } ] } ] } }可选开关hooks.context_warnings监控警告并非强制常开。在工程的.planning/config.json中可显式关闭源码读取路径见 hooks/gsd-context-monitor.js 中对config.hooks?.context_warnings的探测{ hooks: { context_warnings: false } }该键默认值为true见 docs/CONFIGURATION.md 中 Hook Settings 一节。关闭后监控钩子读到配置即静默退出不注入任何警告但 statusline 的上下文仪表仍正常显示——两者互不阻塞。完整配置参考可见 docs/ko-KR/USER-GUIDE.md 中示例配置片段。安全性设计宁可沉默绝不阻塞监控钩子是一类“注入型”工具必须做到高度容错其安全性原则原文档归纳 源码佐证全程 try/catch出错静默退出输入解析、文件读写、JSON 解析任何一步异常都会走catch后process.exit(0)不向 CLI 报“hook error”绝不阻塞工具执行监控器崩溃或超时都不应中断 Agent 工作流。为此脚本对 stdin 设有10 秒超时保护stdinTimeout若 stdin 迟迟不关闭例如 Windows/Git Bash 管道问题或 Claude Code 输出较大时的慢管道钩子会在 10 秒后自行退出避免因挂起被宿主强杀而报错对应 issue #775/#1162 的教训statusline 侧则是 3 秒超时超过 60 秒的过期指标被忽略now - metrics.timestamp STALE_SECONDS时直接退出防止陈旧的上下文数据引发误报缺失桥接文件被优雅处理当没有claude-ctx-{session_id}.json时典型场景是子代理 subagent、全新会话钩子静默退出——子代理的执行同样会触发PostToolUse但它们没有自己的 statusline 写入必须有这一层兜底session_id 注入防护session_id会被拼入文件路径因此钩子在构造路径前会先校验凡含/、\或..的会话 ID 一律静默拒绝防止恶意会话 ID 把读写引到临时目录之外hooks/gsd-statusline.js 与监控钩子两侧都做了同一校验。测试与证据索引上述行为均有仓库内测试回归锁定可作为深入阅读的起点tests/bug-2451-context-monitor-over-report.test.cjs验证桥接文件used_pct写入原始值100 - remaining而非缓冲归一化值并验证 WARNING/CRITICAL 消息中的百分比与 Claude Code 原生报告口径一致误差 ≤1。测试通过构造 stdin payload 直接驱动 hooks/gsd-statusline.js 与监控钩子展示了两个钩子的真实输入输出契约。tests/bug-1974-context-exhaustion-record.test.cjs验证 CRITICAL 活动 GSD 工程时criticalRecorded哨兵被写入、state record-session会把“context exhaustion at X%”写入 STATE.md同时验证无.planning/STATE.md时不拉起子进程、WARNING 级不触发记录、以及__dirname路径解析不依赖~/.claude/硬编码。钩子完整注册清单、事件时机与 35%/25% 阈值在 docs/ARCHITECTURE.md 与 docs/INVENTORY.md 的钩子表中均有登记可交叉核对当前版本行为。小结与故障排查要点把上下文监控想象成一道“给 Agent 看的最后防线”statusline 让用户看见水位context monitor 让 Agent 自己在撞墙前收到信号/gsd-pause-work提供落盘能力CRITICAL 自动记录则是无用户在场时的兜底保险丝。日常使用中如遇到以下现象可按下述方向排查现象可能原因与对策Agent 从没收到过警告检查 settings 中PostToolUse/AfterTool是否注册、.planning/config.json是否把hooks.context_warnings设为false警告中的百分比与/context不一致确认安装的是修复 #2451 后的钩子版本手工安装时注意钩子脚本版本要与仓库最新一致大输出场景偶发“hook error”钩子已有 10 秒 stdin 超时兜底多见于旧版本或管道异常升级安装即可长会话反复收到同级别警告这是防抖未达 5 次工具调用间隔的正常抑制行为级别上升进入 CRITICAL会立即穿透子代理会话无警告正常——子代理通常没有独立的 statusline 写入桥接文件属预期静默如需阅读该模块的最新权威英文描述与其余译文日语、葡萄牙语等平行文档可对照 docs/context-monitor.md 与 docs/ko-KR/context-monitor.md两个钩子的实现本体则统一位于 hooks/gsd-statusline.js 与 hooks/gsd-context-monitor.js。【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考