关于 context-surfing
Context Surfing 是供 Agent 在大型、长时间或易偏离的任务中选择使用的执行技能。它以任务和项目文件为依据监测上下文质量,并在需要退出稍后续做时生成交接记录。
主要功能
- 01以任务和项目上下文为执行依据
- 02监测矛盾和推理偏移
- 03对弱偏移信号执行恢复流程
- 04退出时生成结构化交接文件
- 05可选用 Entire CLI 检查持久状态
适用场景
- 01管理长时间任务中的上下文压力
- 02上下文质量下降时交接工作
- 03根据记录的状态恢复多会话任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pskoett/ pskoett-ai-skills --skill context-surfing安装后在 Claude Code 中输入/context-surfing确认已加载。
附带文件scripts/handoff-checker.sh
详细介绍
Context Surfing
安装
gh skill install pskoett/pskoett-skills context-surfing
使用 Agent Skills CLI 的备用方式:
npx skills add pskoett/pskoett-skills/skills/context-surfing
Agent 驾驭着上下文峰值的浪潮。浪潮到达顶点时,它就提交更改。检测到偏移时,它会干净利落地退出——保存状态、交接工作,让下一次会话接住下一波浪潮。
不翻船。不留下僵尸会话。只进行有意图、高保真的执行。
心智模型
把上下文想象成海浪:
- 划入浪区 = 加载意图框架、计划和初始上下文。能量正在积聚。
- 浪峰 = 上下文完全连贯。Agent 清楚自己正在做什么,以及原因。此时适合执行。
- 浪肩 = 上下文开始变平。仍可乘浪前进,但输出密度正在下降。
- 浪头闭合 = 发生偏移。出现矛盾、含糊其辞、反复犹豫或幻觉细节。即将翻船。
这项技能的任务:只要浪况良好,就继续乘浪;在浪头闭合前退出。
生命周期位置
[plan-interview (optional)] → [initial intent frame] → [session-context]
→ [finalize approach] → [context-surfing ACTIVE during execution]
→ [verify-gate] → [simplify-and-harden] → [self-improvement]
Context Surfing 是一层可选的执行层,适用于上下文压力显著的工作。只有当任务规模较大、运行时间较长、涉及多个会话、明确要求监控上下文,或存在具体偏移风险时,它才会在意图捕获与完成后审查之间包裹执行过程。
与 intent-framed-agent 的关系
启用 context-surfing 后,两个技能在执行期间都会生效。它们监控不同的失败模式:
- intent-framed-agent 监控范围偏移——我做的事情对吗?当工作偏离所述目标时,它会触发结构化的意图检查。
- context-surfing 监控上下文质量偏移——我是否仍有能力把事情做好?当 Agent 自身的连贯性下降(出现幻觉、矛盾、含糊其辞)时,它会触发。
二者互为补充,并非重复。Agent 可能始终没有偏离目标,但上下文质量却在下降(例如,它做的事情是对的,却开始幻觉出一些细节)。反过来,即使上下文质量完美,也可能发生范围偏移(Agent 有意追逐岔路)。intent-framed-agent 的意图检查会与 context-surfing 的浪潮监控同时持续运行。
**优先级规则:**如果两个技能同时触发(同时发生意图检查和偏移退出),以 context-surfing 的退出为先。上下文质量下降会使范围检查不可靠——先解决上下文问题,再在下一次会话中恢复范围监控。
**节奏区分:**意图检查在范围边界触发——“接触新的区域/文件前、开始新的逻辑工作单元前、当前操作感觉偏题时”(intent-framed-agent/SKILL.md)。Context-surfing 的提交前锚定检查则在产生副作用的操作时触发——特定工具调用、写入、提交、提交级输出。不要在同一个节拍中同时运行两者:如果刚刚触发的意图检查已顺利完成,那么同一工作单元内的下一个产生副作用的操作无需再次进行锚定检查——你已经重新校准了方向。
何时使用完整流程
并非每项任务都需要流程中的所有技能。应根据任务复杂度匹配流程深度:
| 任务类型 | 要使用的技能 |
|---|---|
| 微小任务(重命名、修正错字) | 无——直接完成 |
| 小型任务(孤立的错误修复、单文件更改) | verify-gate + simplify-and-harden |
| 中型任务(已知区域中的功能、多文件更改) | intent-framed-agent + session-context + verify-gate + simplify-and-harden |
| 大型任务(复杂重构、新架构、不熟悉的代码库) | 完整流程 |
| 长期任务(跨多个会话、上下文压力较高) | 完整流程,并将 context-surfing 作为关键技能 |
此表与 skill-pipeline 的任务分类一致,后者是权威的路由来源。
拿不准时,就从轻量流程开始。如果在任务中途发现偏移或质量问题,再添加相应技能。
激活
当任务规模较大或耗时较长、工作跨越多个会话、用户明确要求监控上下文,或具体行为表明存在偏离风险时,激活此技能。仅有意图框架和计划本身并不足以触发激活;普通的中等规模任务不要自动激活。
激活时,加载最精简且有用的锚点:
- 用户当前的任务及最新的范围变更
- 适用的 Agent 指令文件
- 已批准的意图框架和计划(如有)
- 先前的交接文件(如为恢复任务)
- Entire 中当前会话的状态(如有)
如果不存在意图框架和计划(独立模式),则使用用户最初的任务描述与项目上下文文件作为工作波次锚点。这已足够——技能会平稳降级,而非灾难性失效。
Entire CLI 集成
Entire CLI(github.com/entireio/cli)提供持久化会话状态,作为偏离检查和交接文件的外部事实依据。
激活时,检测 Entire:
entire status 2>/dev/null
- 如果检测成功,且当前主机适配器支持相关生命周期事件,Entire 会通过钩子被动捕获这些受支持的事件。不要仅凭
entire status推断完整的对话记录或检查点覆盖情况。使用entire status和entire explain --session <id>检查可用状态,并明确记录主机支持范围中不受支持的部分。 - 如果不可用或运行失败,应记录此可选集成不可用及其具体原因,然后继续,不使用该集成。改用意图框架和计划文件作为工作波次锚点。不要将可选遥测功能失败视为拒绝委派或违反策略的理由,也不要反复重试或催促安装。
工作波次锚点不是靠记忆维持的,而是由所有可用的外部持久化制品构成——每次偏离检查都直接读取这些制品,绝不依赖重构的记忆。
交接成为学习信号
当上下文巡航在偏离后退出时写入交接文件,受支持的主机适配器也可能在 Entire 中捕获相关的 Stop / SessionEnd 事件。在既定周期中,learning-aggregator --deep 只读取实际可用的对话记录覆盖内容,并提取:
- 哪些偏离信号最常触发交接 → 潜在的会话设计问题
- 有多少会话以偏离退出告终,与顺利完成的会话数量 → 会话健康基线
- 偏离发生时缺失了哪些上下文制品 → 可考虑纳入项目指令文件的候选内容
采用结构化交接文件(.context-surfing/handoff-<slug>-<timestamp>.md)并设置可预测的章节标题,便于解析。你无需做任何特别操作——只要保持交接格式一致即可。
- 完整流程: 意图框架 + 计划文件 + Entire CLI 会话状态
- 部分流程: 已存在的意图框架或计划,以及适用的指令文件
- 独立模式: 用户最初的任务描述 + 适用的指令文件
独立模式下的锚点较弱,因为可用于交叉核对的制品较少,但锚点始终存在。弱锚点胜过没有锚点。
项目上下文文件
执行前,确定完成任务所需的最少常驻上下文。 默认情况下,不要扫描或加载所有根目录中的 Markdown 文件。
激活时始终加载
- 适用的 Agent 指令文件,例如
AGENTS.md、CLAUDE.md或.github/copilot-instructions.md - 用户当前的任务及最新的范围变更
- 已批准的计划/意图制品(如有)
- 恢复任务时选定的交接文件
按需加载(与当前任务相关时)
- 用于了解项目用途或结构的
README.md - 当前指令或任务指定的特定根目录 Markdown 文件
skills/、docs/、.learnings/或类似目录中的.md文件- 与此技能同时调用的其他技能所对应的
SKILL.md文件
上下文文件规则
- 它们始终是波次锚点的一部分。 如果输出与项目的
.md文件相矛盾,这就是偏移信号——应将其视为强信号。 - 如果任务的领域或范围发生变化,请重新阅读这些文件。 不要假设自己在 20 步之后仍记得准确。
- 在交接文件中列出它们的关键约束。 下一个会话也需要重新加载这些文件——请注明哪些文件处于启用状态,以及会话期间是否有更新。
- **如果会话期间修改了
.md文件,**请在交接文件的“已修改的上下文文件”部分明确标出,以便下一个会话重新阅读,而不是依赖交接摘要。
偏移检测
持续监控这些信号。强信号会触发立即退出——当前波次即将结束。弱信号会先触发恢复协议——也许还可以挽回。
这些信号同样适用于你自己的推理链,而不只是输出内容——检查你的思路,而不只是检查文本。 偏移会先在推理轨迹中产生,之后才显现在文字中;锚点的职责是约束推理,而不只是事后审查输出。在执行有副作用的操作之前进行推理层面的检查,严格来说先于事后的输出层面检查。
强信号(立即退出)
- Agent 违背自己已经作出并确认的决定
- Agent 坚持某个细节,而锚点与之矛盾,且无法调和
- Agent 重新提出计划中已明确解决的范围问题
弱信号(触发恢复)
- 回复越来越长,却没有变得更有用
- 含糊措辞增多:“视情况而定”“可能是”“或许可以考虑”
- Agent 在任务进行中途切换方案,但用户并未明确要求
- 对原始意图的引用变得模糊或经过改述,不再准确
- Agent 提出本应已经知道答案的澄清问题
- 输出开始重新解释任务,而不是执行任务
- 出现新的、缺乏依据且需要对照锚点核实的细节
不属于偏移
- 范围内的正常迭代和完善
- 询问原始上下文中没有的真正新信息
- 简化之前的输出(这说明波次正在推进,而非失控)
监控悖论
上下文退化的 Agent 最不可能察觉到自身的退化。强信号(幻觉、矛盾)恰恰是受损 Agent 会漏掉的信号——因为它已不再拥有识别矛盾所需的上下文。
这是自我监控固有的局限。通过外部依据来缓解:
-
提交前锚点检查。 在执行任何会产生副作用的操作(写入文件、提交、会改变状态的外部工具调用、用户可见的提交级输出)之前,在你的推理链中内联执行以下检查:
- 从新近读取的内容中逐字引用相关锚点行——不能凭记忆。如果存在意图框架,就打开并从中引用。如果存在计划文件,就引用相关部分。在独立模式下,引用用户最初的任务描述。
- 用一行说明待执行的操作。
- 确认该操作可追溯至所引用的行。
- 如果无法明确追溯,不要只是“停止”——进入下方的恢复协议。不指定下一步分支就“停止”,默认会选择成本最低的做法,而这通常意味着悄无声息地继续。
锚点可变性: 如果会话中途修改了上下文文件,提交前检查应使用该文件的最新版本,而不是激活时的快照。重新读取,不依赖记忆。
-
将 Entire CLI 日志用作外部记忆。 如果可以使用 Entire,在做出重要决定之前,回读自己的会话日志。记录下来的状态比回忆中的状态更可靠。
-
把用户视为偏移传感器。 如果用户表达困惑、询问“你为什么要这么做?”或将你引向别处——无论你自己的判断如何,都应将其视为强信号。
弱信号(犹豫、冗长)恰恰因为属于行为表现而非事实,更容易被自己察觉。留意这些早期预警信号。
恢复协议(波形重新锚定)
当弱信号累积时,不要立即退出——先尝试重新锚定。只要能够重新建立依据,波峰仍然可以驾驭。
步骤 1:暂停并重新读取
停止生成输出。重新读取所有可用的波形锚点资料:
- 如果存在意图框架,打开并逐字阅读(不要依赖你对它的记忆)
- 如果存在计划文件,打开并阅读相关部分
- 在独立模式下,重新阅读用户最初的任务描述和项目上下文文件
- 如果可以使用 Entire CLI,回读你的会话日志
将你当前正在做的事情与这些资料所述的应做事项进行比较。
第 2 步:协调
- 如果不一致已消除——你能从锚点清晰地追溯到当前工作——继续执行。弱信号只是噪声,并非偏离。
- 如果仍不确定——在升级给用户之前,先启动
context-monitor子 Agent,获取冷上下文的第二意见。(context-monitor定义于插件包中的plugin/agents/context-monitor.md;如果你的环境中没有该文件,则启动一个具备相同任务说明的通用只读子 Agent。)向它说明意图框架(或计划,或原始任务描述)、你当前的下一步行动,以及观察到的具体弱信号。全新的上下文是摆脱监控悖论的唯一可靠途径:你自己重新阅读时仍处于可能已退化的同一上下文中,而context-monitor则会在冷上下文中阅读这些材料。 - 如果
context-monitor返回“状态良好”或“仅有弱信号”——整合它的修正意见并继续执行。 - 如果
context-monitor返回“检测到严重偏离”,或你在阅读报告后仍无法协调——升级给用户。坦诚说明情况:"我注意到有些偏离。以下是我目前的进展与计划要求的对比——以下是context-monitor的发现——我应该如何继续?" - 如果用户帮你重新校准——整合用户的澄清并继续执行。重新锚定成功。
- 如果用户无法解决问题,或原始意图已发生根本变化——执行退出协议。
重新锚定限制
同一次偏离事件最多允许一次本地重新锚定和一次冷上下文检查。如果仍无法解决,则升级处理或退出。强信号会绕过恢复流程,立即触发退出。
顺势推进
上下文状态良好时:
- 坚定执行。 不要犹豫,也不要重新争论已做出的决定。计划就是计划。
- 在产生副作用的操作之前运行提交前锚点检查。 检查流程见“监控悖论”部分(逐字引用 → 说明待执行操作 → 验证可追溯性 → 失败时进入恢复协议,不要只“停下来”)。此检查是执行期间把关上下文质量的主要措施,不是可有可无的步骤。范围层级的检查由
intent-framed-agent负责,并在不同节点触发(检查频率如何区分,请参阅“与 intent-framed-agent 的关系”)。 - 跟踪完成情况。 随工作进展记录已完成、进行中和待处理的事项,而不是等到退出时再记录。如果 Entire CLI 可用,就用它记录会话;如果不可用,则在输出中持续更新状态。必要时,这些记录可用于交接。
- 抵制范围蔓延。 如果出现有趣但超出范围的事项,记录下来(记在 Entire CLI 或输出中),不要继续追查。
退出协议(波次收尾)
强信号触发,或恢复协议未能重新锚定时,执行干净退出。不要试图硬撑。
第 1 步:停止执行
立即暂停任务执行。不要再输出可能因上下文退化而出错的内容。
第 2 步:编写交接文件
创建名为 .context-surfing/handoff-[slug]-[timestamp].md 的文件(如果 .context-surfing/ 目录不存在,则创建该目录)。将 .context-surfing/ 添加到 .gitignore 中——交接文件是会话产物,不属于项目历史。
结构:
# Context Surf Handoff
## Session Info
- Task: [task name / slug]
- Started: [timestamp]
- Ended: [timestamp]
- Exit reason: [what drift signal was detected]
## Intent Frame (if available — read verbatim, do not reconstruct)
[copy directly from the intent-framed-agent artifact, or "N/A — standalone session" if none exists]
## Plan (if available — read verbatim, do not reconstruct)
[copy directly from the plan-interview artifact, or "N/A — standalone session" if none exists]
## Original Task Description (standalone fallback)
[copy the user's original task description if no intent frame or plan exists]
## Completed Work (from Entire CLI session state or running output log)
[pull directly from CLI log or structured output — do not reconstruct from memory]
## In Progress at Exit (from Entire CLI session state or running output log)
[what the session log shows as active at the moment of exit]
[include any partial outputs if useful]
## Pending Work (from plan-interview output — cross-reference session log to confirm what's genuinely not done)
[remaining tasks from the plan, in order]
## Drift Notes
[what specifically triggered the exit — be precise, this helps the next session replan intelligently]
## Active Context Files
[list all .md files loaded during this session — root level and any skill/docs files consulted]
## Modified Context Files
[any .md files that were changed during this session — next session must re-read these, not trust the handoff summary]
## Scope Notes (Out-of-Band)
[anything interesting discovered that's outside scope — flagged for the next session to decide on]
## Recommended Re-entry Point
[where the next session should pick up, and any replanning it should do before continuing]
第 3 步:通知用户
简短清晰地说明:
"上下文波次已结束。我已将会话状态保存到
.context-surfing/[filename]。下一次会话应加载该文件,并从[重新进入点]继续。只有当交接记录中存在未解决的要求或实质性的范围变更时,才需要重新规划。以下是触发退出的原因:[用一句话说明偏离信号]。"
不要过度解释。详情已记录在交接文件中。
移交至下一会话
下一会话应当:
- 开始任何操作前,完整阅读移交文件
- 如果移交文件表明已批准的计划和意图框架仍然完整且未发生变化,则沿用它们
- 仅当移交文件记录了未解决的需求、重大的范围变更或已失效的计划时,才运行
plan-interview - 在独立模式下,根据任务描述和偏移记录重新校准
- 从建议的重新进入点继续
- 仅在成功重新进入后,才将移交标记为已处理
这并非失败。这是系统正常运作的表现。干净地退出,比苟延残喘直到完成的僵尸会话能产出更好的整体结果。
会话结束(自然完成)
当任务在状态良好的执行波次中完成(无需因偏移而退出)时:
- 确认所有计划事项均已完成(或者在独立模式下,确认已满足原始任务描述)
- 在简短摘要中记录会话结束(可选,不必编写完整的移交文件)
- 发出已准备好进行 simplify-and-harden 的信号——流水线中的下一项技能将从这里开始
顺利完成时无需移交文件——只需提供产出和一句状态说明。
与其他技能的互操作性
此技能使用的内容
- 来自 plan-interview(可选): 计划文件(
docs/plans/plan-NNN-<slug>.md)。如有此文件,可增强执行波次的锚点。 - 来自 intent-framed-agent(可选): 意图框架产物。如有此产物,可增强执行波次的锚点。
- 来自用户(始终可用): 原始任务描述。在缺少上游产物时,用作独立执行波次的锚点。
- 来自 Entire CLI(可选): 用于进度跟踪和外部记忆的会话状态。
此技能生成的内容
- 供 simplify-and-harden 使用: 自然完成时发出“已就绪”信号。simplify-and-harden 会从已完成的工作继续。
- 供下一会话使用(因偏移而退出时): 在
.context-surfing/中生成一个包含完整状态的移交文件,以便恢复会话。 - 用于自我改进: 会话中观察到的偏移模式若重复出现,可记录为经验。
流水线位置
plan-interview(可选,用于梳理需求)intent-framed-agent(初始执行约定 + 范围偏移监控)session-context(在最终确定方案前,参考前序会话的证据)context-surfing(可选,用于对大型、长时间运行或明确依赖上下文的执行进行上下文质量监控)verify-gate(机器验证:编译 + 测试 + lint)simplify-and-harden(完成后的质量/安全审查)self-improvement(记录重复模式并将持久规则固化)
钩子集成
在会话开始时启用自动移交检测,确保不会悄然忽略此前上下文退出时留下的移交文件。
设置(Claude Code)
添加到 .claude/settings.json。将命令指向技能的安装位置(通过 gh skill install / npx skills add 安装时为 .claude/skills/context-surfing/,此仓库中使用 vendor 副本时为 skills/context-surfing/;插件包会自动通过 ${CLAUDE_PLUGIN_ROOT} 路径注册此钩子):
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/skills/context-surfing/scripts/handoff-checker.sh"
}]
}]
}
}
Codex CLI 也通过 <repo>/.codex/hooks.json 支持相同的 SessionStart 事件(实验性功能,需在 config.toml 中启用 codex_hooks = true);脚本的标准输出也会作为开发者上下文添加到其中。
此操作会在会话开始时检查 .context-surfing/ 中是否存在待处理的移交文件。
成功重新进入后,创建相邻的
handoff-<slug>-<timestamp>.md.consumed 标记文件,避免未来会话重复显示
同一提醒。此标记属于会话状态,存放在已忽略的
.context-surfing/ 目录中。
Copilot / Chat 回退方案
对于不支持钩子的 Agent,请在会话开始时手动检查:
ls .context-surfing/handoff-*.md 2>/dev/null
原则
乘上浪峰,而非横渡整片海洋。 与其进行一场漫长且逐渐失真的会话,不如选择一场更短、保真度更高的会话。
退出并非失败。 收尾浪潮是一项功能。及早发现它,才是真正的本领。
交接文件就是连续性的保障。 它不是额外的文档负担,而是让下一场会话一开始就像这场会话一样敏锐的关键。
绝不隐瞒退出。 始终明确告知用户上下文已退出,以及原因。在上下文质量下降时悄无声息地继续,是最糟糕的结果。