Skip to content

转载声明:本文翻译转载自 Affaan Mustafa(@affaanmustafa)的文章《The Longform Guide to Everything Claude Code》。

原文链接:https://x.com/affaanmustafa/article/2014040193557471352

Claude Code 深度指南(长篇版)

在《Claude Code 速查指南》中,我涵盖了基础设置:技能与命令、钩子、子代理、MCP、插件,以及构成高效 Claude Code 工作流骨干的配置模式。那是一份设置指南和基础设施说明。

这篇长篇指南则深入探讨那些将高效会话与浪费时间的会话区分开来的技巧。如果你还没读过速查指南,请先回去配置好你的设置。以下内容假设你已经配置好了技能、代理、钩子和 MCP,并且它们正常工作。

本文的主题包括:Token 经济学、记忆持久化、验证模式、并行化策略,以及构建可复用工作流的复合效应。这些是我经过 10 多个月的日常使用提炼出来的模式,它们决定了你是在第一个小时内就被上下文腐化困扰,还是能维持数小时的高效会话。

速查指南和长篇指南中涵盖的所有内容都可以在 GitHub 上找到。


跨会话共享记忆

对于跨会话共享记忆,最好的方法是使用一个技能或命令来总结和检查进度,然后保存到 .claude 文件夹中的 .tmp 文件,并在会话结束前持续追加内容。第二天它可以以此为上下文,从上次停下的地方继续。为每个会话创建一个新文件,这样就不会将旧上下文污染到新工作中。最终你会积累一大堆会话日志——定期备份或清理不需要的会话对话。

Claude 创建一个总结当前状态的文件。检查它,如果需要可以要求修改,然后重新开始。对于新对话,只需提供文件路径。这在碰到上下文限制需要继续复杂工作时特别有用。这些文件应包含:

  • 哪些方法有效(有证据可验证)
  • 尝试过但无效的方法
  • 尚未尝试的方法以及待办事项

战略性清除上下文

一旦计划确定并清除了上下文(现在是 Claude Code 计划模式的默认选项),你就可以基于计划工作。这在积累了大量探索性上下文但已不再与执行相关时非常有用。对于战略性压缩,禁用自动压缩。在逻辑间隔点手动压缩,或创建一个技能来为你执行或根据定义的条件建议压缩。

bash
#!/bin/bash
# Strategic Compact Suggester
# 在 PreToolUse 上运行,在逻辑间隔建议手动压缩
#
# 为什么手动优于自动压缩:
# - 自动压缩在任意时间点发生,经常在任务中途
# - 战略性压缩通过逻辑阶段保留上下文
# - 在探索后、执行前压缩
# - 在完成里程碑后、开始下一个前压缩
COUNTER_FILE="/tmp/claude-tool-count-$$"
THRESHOLD=${COMPACT_THRESHOLD:-50}

# 初始化或递增计数器
if [ -f "$COUNTER_FILE" ]; then
  count=$(cat "$COUNTER_FILE")
  count=$((count + 1))
  echo "$count" > "$COUNTER_FILE"
else
  echo "1" > "$COUNTER_FILE"
  count=1
fi

# 达到阈值工具调用后建议压缩
if [ "$count" -eq "$THRESHOLD" ]; then
  echo "[StrategicCompact] $THRESHOLD tool calls reached - consider /compact if transitioning phases" >&2
fi

将它挂载到 Edit/Write 操作的 PreToolUse 上——当你积累了足够的上下文需要压缩时,它会提醒你。


高级:动态系统提示注入

我采纳并正在试用的一种模式是:不仅仅将所有内容放在 CLAUDE.md(用户范围)或 .claude/rules/(项目范围,每次会话都加载),而是使用 CLI 标志动态注入上下文。

bash
claude --system-prompt "$(cat memory.md)"

这让你能更精确地控制何时加载什么上下文。你可以根据正在做的工作在每个会话中注入不同的上下文。

为什么这比 @ file 引用更重要:

当你使用 @ file.md 或将内容放在 .claude/rules/ 中时,Claude 在对话过程中通过 Read 工具读取——它作为工具输出进入。当你使用 --system-prompt 时,内容在对话开始前被注入到实际的系统提示中。

区别在于指令层级。系统提示内容的权威性高于用户消息,用户消息的权威性高于工具结果。对于大多数日常工作来说,这个差异是微小的。但对于严格的行为规则、项目特定约束或你绝对需要 Claude 优先处理的上下文——系统提示注入确保了它被适当地加权。

实用设置

一种有效的做法是利用 .claude/rules/ 作为基线项目规则,然后为特定场景创建 CLI 别名:

bash
# 日常开发
alias claude-dev='claude --system-prompt "$(cat ~/.claude/contexts/dev.md)"'

# PR 审查模式
alias claude-review='claude --system-prompt "$(cat ~/.claude/contexts/review.md)"'

# 研究/探索模式
alias claude-research='claude --system-prompt "$(cat ~/.claude/contexts/research.md)"'
  • dev.md 专注于实现
  • review.md 专注于代码质量/安全
  • research.md 专注于行动前的探索

同样,对于大多数情况,使用 .claude/rules/context1.md 和直接将内容追加到系统提示之间的差异是微小的。CLI 方法更快(无需工具调用)、更可靠(系统级权威)、且稍微更节省 token。但这是一个小优化,对很多人来说可能得不偿失。


高级:记忆持久化钩子

有一些大多数人不知道或知道但没有真正利用的钩子可以帮助记忆:

SESSION 1                          SESSION 2
──────────                         ──────────
[Start]                            [Start]
    │                                  │
    ▼                                  ▼
┌──────────────┐              ┌──────────────┐
│ SessionStart │ ◄── reads ───│ SessionStart │◄── 加载之前的
│    Hook      │  nothing yet │    Hook      │    上下文
└──────┬───────┘              └──────┬───────┘
       │                              │
       ▼                              ▼
   [Working]                      [Working]
       │                          (有信息的)
       ▼                              │
┌──────────────┐                      ▼
│ PreCompact   │──► 保存状态     [继续...]
│    Hook      │   压缩前
└──────┬───────┘


  [Compressed]


┌──────────────┐
│  Stop Hook   │──► 持久化到 ──────────►
│ (session-end)│   ~/.claude/sessions/
└──────────────┘
  • PreCompact 钩子:在上下文压缩发生前,将重要状态保存到文件
  • SessionComplete 钩子:会话结束时,将学习成果持久化到文件
  • SessionStart 钩子:新会话开始时,自动加载之前的上下文

钩子配置:

json
{
  "hooks": {
    "PreCompact": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/pre-compact.sh"
      }]
    }],
    "SessionStart": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/session-start.sh"
      }]
    }],
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/session-end.sh"
      }]
    }]
  }
}

这些脚本的功能:

  • pre-compact.sh:记录压缩事件,用压缩时间戳更新活跃会话文件
  • session-start.sh:检查最近的会话文件(最近 7 天),通知可用的上下文和已学习的技能
  • session-end.sh:用模板创建/更新每日会话文件,跟踪开始/结束时间

将这些链接在一起实现无需手动干预的跨会话持续记忆。这建立在第一篇文章中的钩子类型(PreToolUse、PostToolUse、Stop)之上,但专门针对会话生命周期。


持续学习

我们讨论过以更新代码地图的形式进行持续记忆更新,但这同样适用于其他方面,比如从错误中学习。如果你不得不多次重复一个提示,而 Claude 遇到相同的问题或给了你之前听过的回答,这就适用于你。

最可能你需要发出第二个提示来"重新引导"并校准 Claude 的方向。这适用于任何此类场景——那些模式必须被追加到技能中。

你可以通过简单地告诉 Claude 记住它或将其添加到你的规则中来自动完成这个操作,或者你可以有一个专门做这件事的技能。

问题:浪费 token、浪费上下文、浪费时间,你的皮质醇水平飙升,因为你沮丧地对 Claude 大喊不要做你已经在之前会话中告诉它不要做的事情。

解决方案:当 Claude Code 发现非琐碎的东西——一种调试技术、一个变通方案、某个项目特定的模式——它将该知识保存为新技能。下次类似问题出现时,技能会被自动加载。

为什么用 Stop 钩子而不是 UserPromptSubmit? UserPromptSubmit 在你发送的每条消息上运行——这开销很大,给每个提示增加延迟,坦率地说对此目的是杀鸡用牛刀。Stop 在会话结束时运行一次——轻量级,不会在会话中拖慢你,并且评估完整会话而非零散片段。

安装方法:

bash
# 克隆到 skills 文件夹
git clone https://github.com/affaan-m/everything-claude-code.git ~/.claude/skills/everything-claude-code

# 或者只获取持续学习技能
mkdir -p ~/.claude/skills/continuous-learning
curl -sL https://raw.githubusercontent.com/affaan-m/everything-claude-code/main/skills/continuous-learning/evaluate-session.sh > ~/.claude/skills/continuous-learning/evaluate-session.sh
chmod +x ~/.claude/skills/continuous-learning/evaluate-session.sh
json
{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
          }
        ]
      }
    ]
  }
}

Stop 钩子在你的会话结束时触发——脚本分析会话中值得提取的模式(错误解决方案、调试技术、变通方案、项目特定模式等),并将它们保存为可复用技能到 ~/.claude/skills/learned/

使用 /learn 手动提取

你不必等到会话结束。该仓库还包括一个 /learn 命令,你可以在会话中刚解决了非琐碎问题时运行。它会提示你立即提取模式,起草技能文件,并在保存前要求确认。

会话日志模式

该技能期望 .tmp 文件中的会话日志。模式是:~/.claude/sessions/YYYY-MM-DD-topic.tmp——每个会话一个文件,包含当前状态、已完成项目、阻塞项、关键决策和下次会话的上下文。

其他自我改进记忆模式

一种方法涉及对会话日志进行反思,提炼用户偏好——本质上是建立一本关于什么有效什么无效的"日记"。每次会话后,反思代理提取什么顺利、什么失败、你做了什么纠正。这些学习成果更新一个在后续会话中加载的记忆文件。

另一种方法让系统每 15 分钟主动建议改进,而不是等你发现模式。代理审查最近的交互,提出记忆更新建议,你批准或拒绝。随着时间推移,它从你的批准模式中学习。


Token 优化

我从价格敏感的用户或作为高级用户经常遇到限制问题的人那里收到了很多问题。在 token 优化方面有几个技巧。

主要策略:子代理架构

主要优化你使用的工具和设计为将最便宜的足够完成任务的模型分配工作的子代理架构来减少浪费。你有几个选择——你可以尝试试错法并随着时间适应。一旦你了解了什么是什么,你可以委托给 Haiku 而不是 Sonnet,委托给 Sonnet 而不是 Opus。

基准测试方法(更复杂)

另一种更复杂的方法是让 Claude 设置一个基准测试,你有一个定义明确的目标和任务的仓库,以及一个定义明确的计划。在每个 git worktree 中,让所有子代理都使用同一个模型。在完成任务时记录日志——理想情况下在你的计划和任务中。你至少需要使用每个子代理一次。

完成一整轮并从 Claude 计划中勾选任务后,停止并审计进度。你可以通过比较 diff、创建在所有 worktree 中统一的对单元、集成和 E2E 测试来实现。这将根据通过的用例与失败的用例给你一个数字基准。如果所有测试在所有 worktree 上都通过,你需要添加更多测试边缘情况或增加测试的复杂性。这是否值得取决于这对你的真正重要性。

模型选择快速参考

默认使用 Sonnet 完成 90% 的编码任务。在以下情况升级到 Opus:首次尝试失败、任务跨越 5 个以上文件、架构决策或安全关键代码。在以下情况降级到 Haiku:任务重复、指令非常清晰,或在多代理设置中用作"工作者"。

坦率地说,Sonnet 4.5 目前处于一个奇怪的位置,每百万输入 token 3 美元,每百万输出 token 15 美元,与 Opus 相比节省约 66.7%,绝对来说这是一个不错的节省,但相对而言对大多数人来说微不足道。Haiku 和 Opus 的组合最有意义,因为 Haiku 与 Opus 相比有 5 倍的成本差异,而与 Sonnet 相比只有 1.67 倍的价格差异。

在你的代理定义中,指定模型:

yaml
---
name: quick-search
description: Fast file search
tools: Glob, Grep
model: haiku # Cheap and fast
---

工具特定优化

考虑 Claude 最频繁调用的工具。例如,用 mgrep 替换 grep——在各种任务中,与传统 grep 或 ripgrep(Claude 默认使用的)相比,平均 token 减少约一半。

后台进程

在适用时,如果你不需要 Claude 处理整个输出并实时流式传输,可以在 Claude 之外运行后台进程。这可以通过 tmux 轻松实现。获取终端输出然后仅总结或复制你需要的部分。这将节省大量输入 token——Opus 4.5 每百万 token 5 美元(输入),输出每百万 token 25 美元。

模块化代码库的收益

拥有更模块化的代码库,具有可复用的工具、函数、钩子等——主文件在数百行而不是数千行——既有助于 token 优化成本,又有助于第一次就正确完成任务,两者是相关的。如果你不得不多次提示 Claude,你就在消耗 token,特别是当它在很长的文件上反复阅读时。你会注意到它需要做很多工具调用来完成文件读取。在中间过程中,它让你知道文件很长并会继续读取。在这个过程中的某个环节,Claude 可能会丢失一些信息。而且停止并重新读取会消耗额外的 token。这可以通过拥有更模块化的代码库来避免。

root/
├── docs/              # 全局文档
├── scripts/           # CI/CD 和构建脚本
├── src/
│   ├── apps/          # 入口点 (API, CLI, Workers)
│   │   ├── api-gateway/  # 路由请求到模块
│   │   └── cron-jobs/
│   │
│   ├── modules/       # 系统核心
│   │   ├── ordering/  # 自包含的"订单"模块
│   │   │   ├── api/         # 面向其他模块的公共接口
│   │   │   ├── domain/      # 业务逻辑与实体(纯)
│   │   │   ├── infrastructure/  # DB、外部客户端、仓储
│   │   │   ├── use-cases/   # 应用逻辑(编排)
│   │   │   └── tests/       # 单元和集成测试
│   │   │
│   │   ├── catalog/   # 自包含的"目录"模块
│   │   │   ├── domain/
│   │   │   └── ...
│   │   │
│   │   └── identity/  # 自包含的"认证/用户"模块
│   │       ├── domain/
│   │       └── ...
│   │
│   ├── shared/        # 每个模块都使用的代码
│   │   ├── kernel/    # 基类 (Entity, ValueObject)
│   │   ├── events/    # 全局事件总线定义
│   │   └── utils/     # 深度通用辅助函数
│   │
│   └── main.ts        # 应用引导
├── tests/             # 端到端 (E2E) 全局测试
├── package.json
└── README.md

精简代码库 = 更便宜的 Token

这可能是显而易见的,但你的代码库越精简,token 成本就越低。使用技能持续清理代码库、通过重构来识别死代码至关重要。在某些时候,我喜欢通览整个代码库,寻找突出或看起来重复的内容,手动拼凑那个上下文,然后连同重构技能和死代码技能一起喂给 Claude。

系统提示瘦身(高级)

对于真正关注成本的人:Claude Code 的系统提示占用约 18k token(200k 上下文的约 9%)。这可以通过补丁减少到约 10k token,节省约 7,300 token(静态开销的 41%)。如果你想走这条路,参见 YK 的指南。个人我不做这个。


评估与 Harness 调优

根据项目,你会想要使用某种形式的可观测性和标准化。

可观测性方法

一种方法是将 tmux 进程挂接到跟踪思维流并在技能触发时输出。另一种方法是使用 PostToolUse 钩子记录 Claude 具体执行了什么以及确切的更改和输出。

基准测试工作流

与在没有技能的情况下要求同样的事情并检查输出差异来基准测试相对性能:

[Same Task]

   ┌────┴────┐
   ▼         ▼
┌────────┐ ┌────────┐
│Worktree│ │Worktree│
│  A     │ │  B     │
│有技能  │ │无技能  │
└───┬────┘ └───┬────┘
    │          │
    ▼          ▼
[Output A] [Output B]
    │          │
    └─────┬────┘

      [git diff]


   ┌──────────────┐
   │比较日志、     │
   │token 使用、   │
   │输出质量       │
   └──────────────┘

分叉对话,在其中一个中启动一个没有技能的新 worktree,最后拉出 diff,看看记录了什么。这与持续学习和记忆部分相关联。

评估模式类型

更高级的评估和循环协议在此进入。分为基于检查点的评估和基于 RL 任务的持续评估。

基于检查点的评估

  • 在工作流中设置显式检查点
  • 在每个检查点根据定义的标准验证
  • 如果验证失败,Claude 必须在继续之前修复
  • 适用于有清晰里程碑的线性工作流

持续评估

  • 每 N 分钟或重大更改后运行
  • 完整测试套件、构建状态、代码检查
  • 立即报告回归
  • 在继续之前停止并修复
  • 适用于长时间运行的会话、探索性重构或维护

决定因素是你工作的性质。基于检查点适用于有清晰阶段的功能实现。持续适用于探索性重构或没有清晰里程碑的维护。

我想说通过一些干预,验证方法足以避免大多数技术债。让 Claude 在完成任务后通过运行技能和 PostToolUse 钩子来验证有助于此。持续的代码地图更新也有帮助,因为它保留了变更日志以及代码地图如何随时间演变,作为仓库本身之外的真相来源。通过严格的规则,Claude 会避免创建随意的 .md 文件弄得一团糟,以及相似代码的重复文件和留下死代码的荒原。

评分器类型

  • 基于代码的评分器:字符串匹配、二进制测试、静态分析、结果验证。快速、便宜、客观,但对有效变化脆弱。
  • 基于模型的评分器:评分标准、自然语言断言、成对比较。灵活且能处理细微差别,但不具确定性且更昂贵。
  • 人工评分器:主题专家审查、众包判断、抽查抽样。黄金标准质量,但昂贵且缓慢。

关键指标

pass@k:k 次尝试中至少有一次成功

k 值通过率
k=170%
k=391%
k=597%

k 越高 = 成功概率越高

pass^k:k 次尝试必须全部成功

k 值通过率
k=170%
k=334%
k=517%

k 越高 = 越难(一致性)

当你只需要它工作且任何验证反馈就够时使用 pass@k。当一致性至关重要且你需要近乎确定性的输出一致性(在结果/质量/风格方面)时使用 pass^k

构建评估路线图

  1. 尽早开始——从真实失败中获取 20-50 个简单任务
  2. 将用户报告的失败转换为测试用例
  3. 编写明确的任务——两位专家应达成相同结论
  4. 构建平衡的问题集——测试行为应该和不应该发生的情况
  5. 构建稳健的 harness——每次试验从干净环境开始
  6. 评估代理产生了什么,而不是它采取的路径
  7. 阅读多次试验的记录
  8. 监控饱和度——100% 通过率意味着需要添加更多测试

并行化策略

在多 Claude 终端设置中分叉对话时,确保分叉和原始对话中的操作范围定义明确。在代码更改方面争取最小重叠。选择彼此正交的任务以防止干扰的可能性。

我的偏好模式

个人而言,我更喜欢让主聊天处理代码更改,而我做的分叉用于我对代码库及其当前状态的问题,或研究外部服务(如拉取文档、搜索 GitHub 寻找有帮助的开源仓库),或其他有帮助的通用研究。

关于任意终端数量

Boris(Claude Code 的创建者,传奇人物)有一些关于并行化的建议,我有些同意有些不同意。他建议过像本地运行 5 个 Claude 实例和 5 个上游实例这样的事情。我建议不要设置像这样的任意终端数量。添加终端和添加实例应该是出于真正的必要性和目的。如果你能用脚本完成任务,就用脚本。如果你能在主聊天中让 Claude 在 tmux 中启动一个实例并在单独的终端中流式传输,就那样做。

你的目标应该是:用最少的可行并行化完成最多的事情。

对于大多数新手,我甚至建议远离并行化,直到你掌握了只运行单个实例并在其中管理一切的技巧。我不是在提倡限制自己——我是在说要小心。大多数时候,甚至我也总共只使用 4 个终端左右。我发现通常用 2 或 3 个 Claude 实例就能完成大部分事情。

扩展实例时

如果你确实要开始扩展实例并且有多个 Claude 实例处理彼此重叠的代码,使用 git worktree 并为每个实例制定非常明确的计划是必须的。此外,为了避免在恢复会话时对哪个 git worktree 用于什么感到困惑(除了树的名称),使用 /rename <name> 命名为你的所有聊天命名。

使用 Git Worktree 进行并行工作

bash
# 为并行工作创建 worktree
git worktree add ../project-feature-a feature-a
git worktree add ../project-feature-b feature-b
git worktree add ../project-refactor refactor-branch

# 每个 worktree 获得自己的 Claude 实例
cd ../project-feature-a && claude

好处:

  • 实例之间没有 git 冲突
  • 每个都有干净的工作目录
  • 容易比较输出
  • 可以在不同方法间基准测试相同任务

级联方法

运行多个 Claude Code 实例时,用"级联"模式组织:

  • 在右边的新标签页中打开新任务
  • 从左到右扫描,从最旧到最新
  • 保持一致的方向流
  • 根据需要检查特定任务
  • 一次最多关注 3-4 个任务——超过这个,心智负担增长速度比生产力更快

从头开始:两实例启动模式

从头开始时,实际的基础很重要。这应该是显而易见的,但随着代码库复杂度和规模增加,技术债也会增加。管理它非常重要,如果你遵循一些规则并不那么困难。

两实例启动模式

对于我自己的工作流管理(不是必须的但有帮助),我喜欢用 2 个打开的 Claude 实例启动一个空仓库。

实例 1:脚手架代理

  • 搭建脚手架和基础工作
  • 创建项目结构
  • 设置配置(CLAUDE.md、规则、代理——速查指南中的所有内容)
  • 建立约定
  • 搭建骨架

实例 2:深度研究代理

  • 连接到你所有的服务、网络搜索等
  • 创建详细的 PRD
  • 创建架构 mermaid 图
  • 编译来自实际文档的参考

启动设置:左终端用于编码,右终端用于提问——使用 /rename/fork

你最初需要的最低限度就够了——这比每次都使用 Context7 或喂入链接让它抓取或使用 Firecrawl MCP 站点更快。当你在某事中已经深陷其中,Claude 明显在语法上出错或使用过时的函数或端点时,所有这些方法都有效。

llms.txt 模式

如果可用,你可以在许多文档参考上找到 llms.txt,方法是到达它们的文档页面后加上 /llms.txt。这会给你一个干净的、LLM 优化的文档版本,你可以直接喂给 Claude。


哲学:构建可复用模式

我完全认同的一个洞察:"早期,我花时间构建可复用工作流/模式。构建很繁琐,但随着模型和代理 harness 改进,这产生了疯狂的复合效应。"

值得投资的:

  • 子代理(速查指南)
  • 技能(速查指南)
  • 命令(速查指南)
  • 规划模式
  • MCP 工具(速查指南)
  • 上下文工程模式

为什么它会复合:"最好的部分是所有这些工作流都可以转移到 Codex 等其他代理。" 一旦构建,它们跨模型升级工作。对模式的投资 > 对特定模型技巧的投资。

子代理上下文问题

子代理的存在是为了通过返回摘要而不是转储所有内容来节省上下文。但编排器拥有子代理缺少的语义上下文。子代理只知道字面查询,不知道请求背后的目的/推理。摘要经常遗漏关键细节。

比喻:"你的老板派你去开会并要求一份摘要。你回来给了他一个概要。十有八九,他会有后续问题。你的摘要不会包含他需要的一切,因为你没有他拥有的隐式上下文。"

迭代检索模式

┌─────────────────┐
│   ORCHESTRATOR  │
│  (has context)  │
└────────┬────────┘
         │ dispatch with query + objective

┌─────────────────┐
│   SUB-AGENT     │
│ (lacks context) │
└────────┬────────┘
         │ returns summary

┌─────────────────┐    ┌─────────────┐
│   EVALUATE      │──no─►│ FOLLOW-UP   │
│  Sufficient?    │       │  QUESTIONS  │
└────────┬────────┘    └──────┬──────┘
         │ yes               │
         ▼                   │ sub-agent
      [ACCEPT]          fetches answers
         │                   │
         ◄───────────────────┘
                         (max 3 cycles)

修复方法是让编排器:

  • 评估每个子代理的返回
  • 在接受之前提出后续问题
  • 子代理回到源,获取答案,返回
  • 循环直到足够(最多 3 个循环以防止无限循环)

传递目标上下文,而不仅仅是查询。分派子代理时,包含特定查询和更广泛的目标。这有助于子代理在摘要中优先包含什么。

编排器顺序阶段模式

Phase 1: RESEARCH (use Explore agent)
- 收集上下文
- 识别模式
- 输出: research-summary.md

Phase 2: PLAN (use planner agent)
- 阅读 research-summary.md
- 创建实现计划
- 输出: plan.md

Phase 3: IMPLEMENT (use tdd-guide agent)
- 阅读 plan.md
- 先写测试
- 实现代码
- 输出: code changes

Phase 4: REVIEW (use code-reviewer agent)
- 审查所有更改
- 输出: review-comments.md

Phase 5: VERIFY (use build-error-resolver if needed)
- 运行测试
- 修复问题
- 输出: done 或 loop back

关键规则:

  1. 每个代理获得一个清晰的输入并产生一个清晰的输出
  2. 输出成为下一阶段的输入
  3. 永远不要跳过阶段——每个都增加价值
  4. 在代理之间使用 /clear 保持上下文新鲜
  5. 将中间输出存储在文件中(不仅仅是内存)

代理抽象层级

第一层:直接增益(易于使用)

  • 子代理——防止上下文腐化和临时专业化的直接增益。效果约为多代理的一半,但复杂度低得多
  • 元提示——"我花 3 分钟提示一个 20 分钟的任务。" 直接增益——提高稳定性并验证假设
  • 一开始多问用户——通常是增益,虽然你需要在计划模式中回答问题

第二层:高技能门槛(更难用好)

  • 长时间运行的代理——需要理解 15 分钟任务与 1.5 小时与 4 小时任务的形状和权衡。需要一些调整,显然是非常长的试错过程
  • 并行多代理——方差很高,只对高度复杂或良好分割的任务有用。"如果 2 个任务各需要 10 分钟,而你花任意时间提示或者更糟的合并更改,那是适得其反的"
  • 基于角色的多代理——"模型演进太快,除非套利非常高,否则硬编码的启发式规则不适用。" 难以测试
  • 计算机使用代理——非常早期的范式,需要磨合。"你让模型做它们一年前绝对不是设计来做的事情"

要点:从第一层模式开始。只有在掌握了基础并有真正需求时才晋升到第二层。


MCP 替代策略

一些 MCP 是可替代的,会释放你的上下文窗口。方法如下。

对于版本控制(GitHub)、数据库(Supabase)、部署(Vercel、Railway)等 MCP——这些平台大多数已经有强大的 CLI,MCP 本质上只是在包装它们。MCP 是一个不错的包装器,但需要付出代价。

要让 CLI 像 MCP 一样运行而不实际使用 MCP(以及随之而来的减少上下文窗口),考虑将功能打包到技能和命令中。将 MCP 暴露的工具剥离出来,把它们变成命令。

例如:与其一直加载 GitHub MCP,不如创建一个包装 gh pr create/gh-pr 命令,加上你偏好的选项。与其让 Supabase MCP 消耗上下文,不如创建直接使用 Supabase CLI 的技能。功能相同,便利性类似,但你的上下文窗口被释放用于实际工作。

自从我发布原文以来的过去几天,Boris 和 Claude Code 团队在记忆管理和优化方面取得了很多进展,主要是 MCP 的延迟加载,这样它们不再从一开始就消耗你的窗口。之前我会建议尽可能将 MCP 转换为技能,通过以下两种方式卸载执行 MCP 的功能:在当时启用它(不太理想,因为需要离开并恢复会话)或拥有使用 MCP 的 CLI 类似物的技能(如果存在)并让技能成为它的包装器——本质上是让它充当伪 MCP。

有了延迟加载,上下文窗口问题基本解决了。但 token 使用和成本并没有以同样的方式解决。CLI + 技能方法仍然是一种 token 优化方法,效果可能与使用 MCP 相当或接近。此外,你可以通过 CLI 而不是在上下文中运行 MCP 操作,这显著减少了 token 使用,特别适用于重型 MCP 操作如数据库查询或部署。


参考资源

  • Anthropic:《Demystifying evals for AI agents》(2026 年 1 月)
  • Anthropic:《Claude Code Best Practices》(2025 年 4 月)
  • Fireworks AI:《Eval Driven Development with Claude Code》(2025 年 8 月)
  • YK:《32 Claude Code Tips》(2025 年 12 月)
  • Addy Osmani:《My LLM coding workflow going into 2026》
  • 子代理上下文协商模式
  • 代理抽象层级
  • 复合效应哲学
  • RLanceMartin:Session Reflection Pattern
  • 自我改进记忆系统

Last updated: