Appearance
Thariq 的两篇指南解决了 Claude Code 使用中两个最容易出错的维度:一是随着上下文增长如何正确管理 session(什么时候 continue/rewind/compact/clear/subagent),二是如何写出真正好用的 Skill(不只是 markdown 文件,而是包含脚本、资产、hooks 的文件夹)。这是 Anthropic 内部用了几百个 Skill 后提炼出的经验。
Thariq 实战经验:Session 管理、上下文控制与 Skill 工程
作者背景
Thariq(@trq212)是 Claude Code 团队成员,在 Anthropic 内部大量使用和构建 Claude Code 工具链。2026 年 3—4 月间,他分享了两篇详细的实操指南:一篇关于 Session/Context 管理,一篇关于 Skills 的系统性工程实践。
第一部分:Session 管理与 1M 上下文的正确打开方式
什么是 Context Rot(上下文腐烂)
1M token 上下文窗口意味着 Claude 能看到海量历史,但这是把双刃剑:
Context Rot:随着上下文增长,模型注意力分散到更多 token 上,旧的、无关的内容开始干扰当前任务,模型性能下降。
对于 1M 上下文模型,Context Rot 通常在 300k–400k tokens 左右变得明显,但具体取决于任务类型,不是硬性规律。
每次模型 turn 结束都是一个分叉点
Claude 完成一个 turn 后,你有 5 种选择,而不只是"继续说话":
Claude 完成 turn
│
├─ Continue(继续)
│ → 上下文全部保留
│
├─ Rewind(双击 Esc / /rewind)
│ → 保留指定点之前的内容,丢弃之后的
│
├─ Compact(/compact)
│ → 模型把对话压缩成摘要,替换历史
│
├─ Clear(/clear)
│ → 清空,你写 brief 重新开始
│
└─ Subagent(委托)
→ 子任务在独立上下文中执行,只有结论返回每种方式携带的旧上下文量不同:
| 方式 | 携带的旧上下文 |
|---|---|
| Continue | 全部(什么都不丢) |
| Rewind | 指定点之前的内容 |
| Compact | 有损压缩摘要(Claude 决定保留什么) |
| Clear + Brief | 仅你手写的 brief |
| Subagent | 只有最终结论返回父 session |
何时用哪种方式:决策规则
Continue(继续)
- 同一任务,上下文中的内容仍然相关
- 不要重新获取已有的文件读取结果
Rewind(双击 Esc 或 /rewind)—— 最被低估的操作
错误做法(纠正):
用户: "不对,试试方法 B"
→ 上下文 = 文件读取 + 失败的方法 A + 纠正 + 方法 B
↑ 污染正确做法(Rewind):
回到"文件读取完成"那一步之后
→ 重新提示:"不用方法 A,foo 模块没有暴露那个接口,直接用方法 B"
→ 上下文 = 文件读取 + 一次有信息量的提示 + 方法 BRewind 的最佳使用场景:
- Claude 读了 5 个文件,然后尝试了一个方法,但行不通
- 不要说"这不对,换个方式",而是回到文件读取完成后的状态,带着学到的信息重新提示
辅助技巧:先让 Claude"从这里总结",得到一段"失败经验备忘录",然后 Rewind 并把这段摘要带入新提示。
Compact(/compact <hint>)—— 中途减重
适合:
- 任务进行到一半,session 被大量调试/探索产生的噪音撑大
- 不想从头开始,但上下文开始影响质量
- 主动调用,不要等到 autocompact 触发(autocompact 触发时 context rot 最严重,模型最不聪明)
指导 compact:
/compact focus on the auth refactor, drop the test debuggingBad Compact 预防:当 session 包含多个不相关线索时,compact 可能丢掉你等会还需要的信息。提前告诉 Claude 你接下来想做什么,它会在摘要里保留相关内容。
Clear + Brief(/clear)—— 高精度重启
适合:
- 开始一个真正新的任务
- 从 100K 探索中找到了 1 个关键事实,下一步对精确性要求高
- 你自己决定什么信息进入新上下文,而不是信任 Claude 的摘要
Brief 写法示例:
我们在重构 auth 中间件。
约束条件:不能改变 JWT 签名算法。
重要文件:src/auth/middleware.ts, src/auth/types.ts
已排除方案:使用 passport.js(依赖冲突)
当前目标:让 refresh token 逻辑支持 sliding expirySubagent(委托子任务)
判断标准:我将来会需要这些中间工具调用的输出,还是只需要最终结论?
- 20 次文件读取 + 12 次 grep + 3 个死胡同 → 垃圾,用 subagent 隔离
- 最终结论 → 返回父 session
何时明确指示 subagent:
# 验证
"启动一个 subagent,根据以下 spec 文件验证这次工作的结果"
# 跨库研究
"启动一个 subagent,读取那个代码库,总结它如何实现 auth 流程,然后你按同样方式实现"
# 文档生成
"启动一个 subagent,根据我的 git 变更写这个功能的文档"Session 管理一览表
| 情境 | 操作 | 理由 |
|---|---|---|
| 同一任务,上下文仍有价值 | Continue | 不要重建已有的信息 |
| Claude 走了一条错路 | Rewind(双击 Esc) | 保留有用的文件读取,丢掉失败尝试,带信息重新提示 |
| 任务进行中但 session 被调试噪音撑大 | /compact <hint> | 低代价;Claude 决定保留什么;用 hint 引导 |
| 开始新任务 | /clear | 零 context rot;你控制什么信息进入新上下文 |
| 下一步会产生大量只需要结论的中间输出 | Subagent | 中间噪音留在子 context;只有结论返回 |
第二部分:Skill 工程——Anthropic 内部的实战经验
Skill 不只是 Markdown 文件
"一个常见误解是 Skills 只是 markdown 文件。最有意思的地方在于它们是文件夹,可以包含脚本、资产、数据等——agent 可以发现、探索、操作这些内容。"
.claude/skills/
└── my-skill/
├── SKILL.md # 主入口,包含触发说明
├── references/
│ └── api.md # 详细 API 参考(按需读取)
├── scripts/
│ └── validate.ts # 可调用的脚本
└── examples/ # 示例代码9 种 Skill 类型
Anthropic 内部梳理了几百个 Skill,发现它们集中在 9 个类别,最好的 Skill 只专注其中一个:
| 类型 | 说明 | 示例 |
|---|---|---|
| 1. 库与 API 参考 | 内部库或难用的外部库的正确用法、gotchas | billing-lib, frontend-design |
| 2. 产品验证 | 测试和验证代码是否正确工作 | signup-flow-driver, checkout-verifier |
| 3. 数据获取与分析 | 连接数据和监控系统 | funnel-query, grafana |
| 4. 业务流程自动化 | 把重复工作流变成一条命令 | standup-post, weekly-recap |
| 5. 代码脚手架与模板 | 生成框架样板代码 | new-migration, create-app |
| 6. 代码质量与审查 | 执行代码规范,运行 review | adversarial-review, code-style |
| 7. CI/CD 与部署 | 抓取、推送、部署代码 | babysit-pr, deploy-<service> |
| 8. Runbooks | 从报警/错误 → 多工具调查 → 结构化报告 | oncall-runner, log-correlator |
| 9. 基础设施运维 | 日常维护,带防护栏的危险操作 | dependency-management, cost-investigation |
9 条写 Skill 的最佳实践
1. 不要陈述显而易见的内容
Claude 已经了解大量通用编程知识。Skill 应该把 Claude 推出它的默认思维模式——填充它不知道的、项目特有的、反常识的内容。
示例:frontend-design skill 的价值在于告诉 Claude 不要用 Inter 字体和紫色渐变——这是迭代出来的,不是从头写的。
2. 建立 Gotchas 部分
Skill 中信息密度最高的部分是 Gotchas。这些应该来自 Claude 实际遇到的失败,随着使用积累更新。
markdown
## Gotchas
- 不要直接调用 `db.query()`,必须通过 `dbClient.execute()` 包装器
- JWT refresh 在 staging 环境有 5 分钟缓存,别被假阳性迷惑
- 迁移文件命名必须用 `YYYYMMDD_description` 格式,否则 runner 忽略3. 用文件系统做渐进披露(Progressive Disclosure)
把 SKILL.md 当作入口,详细内容拆到独立文件。告诉 Claude 有哪些文件,它会在合适的时候读取:
markdown
## 参考资料
详细的函数签名在 `references/api.md`
使用示例在 `examples/` 目录
常见错误处理脚本在 `scripts/handle-errors.ts`4. 不要框死 Claude(避免 Railroading)
给目标和约束,而不是逐步骤的指令。Skills 要复用,过于具体的步骤会在不同情境下失效:
markdown
# 不好:
Step 1: 运行 lint
Step 2: 检查 TypeScript 编译
Step 3: ...
# 好:
目标:确保代码符合团队规范。
约束:不要修改测试文件。不要改变公共 API 签名。5. 想清楚初始化流程
需要用户配置的 Skill,推荐用 config.json 存储配置,首次运行时自动检测:
markdown
## 初始化
启动时检查 `config.json` 是否存在。
如果不存在,用 AskUserQuestion 工具询问用户:
- 仓库路径
- 目标环境(staging/production)
然后将配置保存到 `config.json`。6. description 字段是写给模型看的
Claude Code 启动时会扫描所有 Skill 的 description,决定"这个请求有没有对应的 Skill"。
description 不是摘要,而是触发条件:
yaml
# 不好:
description: 这个 Skill 帮助你审查代码
# 好:
description: 当用户要求审查代码、检查代码质量、或在提交前检查问题时调用7. 用文件系统存储记忆
Skill 可以用文件系统持久化数据:
.claude/skills/my-skill/
├── SKILL.md
└── logs/
└── run-history.jsonl # 执行历史(追加写入)注意:升级 Skill 时 skills/ 目录可能被清除。需要跨版本持久化的数据使用 ${CLAUDE_PLUGIN_DATA} 目录。
8. 在 Skill 中提供脚本
给 Claude 代码比给 Claude 指令更强大——有了脚本,Claude 把 turn 用在"组合这些工具做什么",而不是"重新写这些脚本":
scripts/
├── fetch-metrics.ts # 已经实现的数据获取逻辑
├── format-report.ts # 报告格式化
└── validate-schema.ts # Schema 校验9. 按需 Hooks(On-Demand Hooks)
Skill 可以注册只在被调用时激活的 Hook,session 结束时自动注销:
markdown
## Hooks
当此 Skill 被调用时,激活以下 hooks:
PreToolUse(Bash):
- 如果命令包含 `rm -rf`、`DROP TABLE`、`kubectl delete`,
阻断并提示用户确认
(示例:/careful Skill 注册这个 hook,只在你需要"小心模式"时生效)其他实用例子:
/freeze— 限制 Edit/Write 只能操作特定目录/log-all— 记录所有 bash 命令到日志文件
分发与规模化
| 方式 | 适合 |
|---|---|
检入 repo(.claude/skills/) | 小团队、少数几个 repo |
| 内部 Plugin 市场 | 大团队、多 repo、需要选择性安装 |
市场管理建议:
- 不设置中心化审核团队
- 先在 GitHub sandbox 目录放置,发布到 Slack 征集反馈
- 有足够使用量后,提 PR 进入市场
- 发布前确认没有重复 Skill,避免功能碎片化
Skill 使用量监控:通过 PreToolUse Hook 记录 Skill 调用日志,找出哪些 Skill 触发率低于预期。
Skill 组合
目前没有原生的依赖管理,但可以在 SKILL.md 中引用其他 Skill:
markdown
## 依赖
此 Skill 依赖:
- `file-uploader` Skill(请确保已安装)
- 使用时 Claude 会自动调用它如果被依赖的 Skill 已安装,Claude 会自动调用。
FAQ
Q: 1M 上下文意味着不需要担心 context rot 了吗?
A: 不是。1M 上下文让你可以做更长的任务,但 300k–400k tokens 后仍会出现性能下降。规则是:任务新了就开新 session,不要因为"反正 context 够用"而让无关内容积累。
Q: Rewind 和 Compact 怎么选?
A: Rewind 用于"Claude 走错了路"——你想保留文件读取,丢掉错误尝试;Compact 用于"任务还在继续,但上下文被调试噪音撑大了"。两者不是互相替代的,而是针对不同情境。
Q: Skill 的 description 写多长合适?
A: 1–2 句话。目的是让模型能精确匹配"何时调用",不需要解释 Skill 做了什么——Claude 读了 SKILL.md 后自然知道。
Q: 什么时候该做成 Skill,什么时候用 CLAUDE.md 规则就够了?
A: CLAUDE.md 适合"全局行为规范"(总是/从不做某事);Skill 适合"具体工作流"(当用户要求 X 时执行 Y 步骤)。如果某个操作需要多个步骤、依赖外部工具、或需要按需激活 Hook,就做成 Skill。
Q: 为什么不能让 Skill 之间有强依赖?
A: 因为 Claude Code 目前没有内置的 Skill 包管理系统,安装顺序和版本都不受控。用软引用(在 SKILL.md 中提到"依赖 X Skill")让 Claude 自动调用已安装的同名 Skill,是目前最稳定的组合方式。