深度拆解 Claude Code:12 个可复用的 Agentic Harness 设计模式¶
Ch04.090 深度拆解 Claude Code:12 个可复用的 Agentic Harness 设计模式¶
📊 Level ⭐⭐ | 16.4KB |
entities/claude-code-agentic-harness-design-patterns.md
Claude Code Agentic Harness Design Patterns
记忆与上下文¶
这五个模式其实是一条逐步演进的路径:一开始只是给 Agent 一份固定的 ** 规则文件 ** ,然后按目录去限制这些规则的 ** 作用范围 ** ,再把记忆做成 ** 分层结构 ** ,接着在后台 ** 做清理 ** ,最后在上下文快满的时候对对话本身 ** 做压缩 ** 。
1. 持久化指令文件模式(Persistent Instruction File Pattern)¶
没有持久化指令文件时,每个 Agent 会话都像从零开始。同样的约定、命令和边界,需要一遍遍重复,甚至第几次对话还会犯和第一次一样的错误。 这个模式的做法其实很直接:放一个项目级的配置文件,每次会话自动加载。里面写清楚构建命令、测试方式、架构规则、命名约定这些内容。文件跟着代码仓库走,而不是靠人每次复制粘贴。 ** 适用场景 ** :需要在多个会话里反复处理同一个代码库。 ** 权衡点 ** :有维护成本。这个文件需要跟着项目一起更新,一旦过时,反而会误导 Agent,还不如没有。
2. 作用域上下文组装模式(Scoped Context Assembly Pattern)¶
一个指令文件在小项目里够用,但项目一大就容易出问题:要么越写越长,最后没人看;要么写得太泛,对具体目录又没什么用。 这个模式的思路是把指令拆到不同作用域里:组织级、用户级、项目根目录、父目录、子目录。Agent 会根据当前所在的位置,动态加载对应的规则。这样既能保持全局一致,又能允许局部有差异。 另外,通过导入的方式,可以把大的指令集拆开管理,避免重复。 ** 适用场景 ** :Monorepo、多语言项目,或者不同目录有不同规范的代码库。 ** 权衡点 ** :可读性会变差。规则分散在多个文件里后,很难一眼看清 Agent 实际加载了哪些内容,不同作用域之间也可能出现冲突。
3. 分层记忆模式(Tiered Memory Pattern)¶
如果一个 Agent 什么都用同一种方式记住,最后往往什么都记不好。 把所有记忆都塞进上下文,每次会话都会浪费 token,还容易撞上窗口限制,重要信息反而被淹没。 这个模式的做法是把记忆分层:一个精简的索引始终放在上下文里(比如控制在几百行以内),和当前任务相关的内容按需加载,完整的历史记录则留在磁盘上,需要时再去查。 ** 适用场景 ** :需要跨多次会话保留偏好、决策或状态的 Agent。 ** 权衡点 ** :实现会更复杂。需要想清楚信息该放哪一层,什么时候上升或下沉,以及怎么保证索引和实际数据是同步的。
4. 记忆整合模式(Dream Consolidation Pattern)¶
即使做了分层,记忆用久了还是会「变乱」:重复内容越来越多,旧信息和新信息打架,索引也会慢慢膨胀。 这个模式的思路是加一个后台整理机制,在空闲时定期做清理:去重、删旧、重组结构,让记忆保持干净、可用。可以理解为给 Agent 做一次「垃圾回收」。 像泄露代码里提到的 autoDream ,就是在做类似的事情:合并重复、处理冲突、控制索引规模。 ** 适用场景 ** :Agent 会长期运行、持续积累记忆,而且不方便靠人工去维护。 ** 权衡点 ** :整理本身也要消耗 token,而且不一定完全准确。如果清理太激进,可能会把有用的信息一起删掉。
5. 渐进式上下文压缩模式(Progressive Context Compaction Pattern)¶
对话一长,很快就会碰到上下文窗口的上限。要么早期内容被挤掉,要么任务直接做不下去,这两种情况都挺难受。 这个模式的做法是「 ** 分层压缩 ** 」:新的对话尽量保留细节,稍旧的内容做轻量总结,再往前的就逐步压缩,甚至折叠成很短的摘要。 可以理解为越久远的信息,保留得越粗。像源码里提到的几层压缩,本质上也是这个思路,只是做得更细。 ** 适用场景 ** :对话轮次比较多(比如 20~30 轮以上)的任务。 ** 权衡点 ** :压缩一定是有损的。信息在一轮轮总结中会丢失,如果后面又需要这些细节,Agent 可能会「编」而不是承认不知道。
工作流与编排¶
这一组模式的核心其实就是一个词: ** 分离 ** 。 把读取和写入拆开,把「查资料」和「改代码」的上下文拆开,把顺序执行和并行执行也拆开。这样做的好处是,随着任务变复杂,系统不会越来越乱。 大多数 Agent 的默认做法是把这些事情混在一起,刚开始可能没问题,但任务一多,质量就很容易下降。
6. 探索-规划-行动循环模式(Explore-Plan-Act Loop Pattern)¶
如果一上来就让 Agent 改代码,很容易出问题:理解不完整,改错文件,漏掉依赖,或者直接忽略现有的实现方式。 这个模式的做法是把流程拆成三步,而且权限逐步放开:
- • 先探索,只读代码、查信息、摸清结构
- • 再规划,和用户对齐思路
- • 最后再动手改代码 本质上就是先搞清楚,再决定怎么做,最后再执行。 ** 适用场景 ** :不熟悉的代码库,或者涉及多个文件的复杂修改。 ** 权衡点 ** :会慢一点。多了探索和规划这两步,小任务会显得有点「流程过重」。
7. 上下文隔离子智能体模式(Context-Isolated Subagents Pattern)¶
会话一长,所有东西都会堆在同一个上下文里:调研内容、规划讨论、代码修改、日志输出,全混在一起。等真正开始改代码时,很多无关信息已经在干扰判断了。 这个模式的做法是把任务拆给不同的子 Agent,每个都有自己的上下文和权限:
- • 做调研的只负责看和分析,不能改代码
- • 做规划的只负责设计方案
- • 真正执行的才有完整工具权限 每个子 Agent 只接触自己需要的信息,避免被「流噪声」影响。 适用场景 :长会话、多阶段流程,或者不同阶段对上下文要求差异很大的任务。 权衡点 :需要额外协调。主 Agent 要决定每一步传什么信息,传少了会丢细节,传多了又回到上下文污染的问题。
深度分析¶
1. 这 12 个模式本质是一个协同系统,不是独立技巧¶
原文分四类介绍,但细看会发现它们有隐含的依赖链:记忆分层(模式 3)是上下文压缩(模式 5)的前提,因为没有分层索引就不知道该压缩什么;上下文隔离子 Agent(模式 7)是分支-合并并行(模式 8)的骨干,没有隔离上下文就没有干净的并行副本;渐进式工具扩展(模式 9)和命令风险分类(模式 10)共同构成权限体系的内外层;确定性生命周期钩子(模式 12)则为所有其他模式提供可靠性底座。Bilgin Ibryam 的分类更像是一种视图组织,而不是独立的建筑砌块。理解这点后,在实现时可以按依赖顺序引入,而不是一股脑堆砌。
2. "系统兜底" vs "模型负责" 的边界是贯穿全篇的核心张力¶
原文在多个模式里都隐隐戳到了这个分界线:模式 4 的记忆整合如果纯靠模型判断,清理可能出错,所以需要系统介入;模式 5 的压缩有损,但系统可以做更保守的压缩策略;模式 10 的命令风险分类本质是不信任模型的实时判断,需要规则引擎前置;模式 12 更是直接挑明:凡是「不能出错、不能漏」的事情,都不该交给模型记。这不是否定模型能力,而是一种务实的分工哲学——Harness Engineering 框架 称之为「硬约束 vs 软约束」的区分。许多 Agent 框架失败的原因,恰恰是在应该用系统兜底的地方过度依赖提示词。
3. 模式 4(Dream Consolidation)揭示了长程 Agent 的一个普遍困境¶
原文提到 autoDream 在后台做记忆整合,但实际上这个过程有一个根本矛盾:负责「整理记忆」的 Agent 也需要上下文来理解哪些记忆是重要的、哪些是冗余的——但它的上下文同样会受到记忆膨胀的影响。这形成了一个递归困境:记忆太多导致整理困难,但整理本身又需要消耗上下文。Claude Code 的解法可能是让这个过程非常轻量(只处理索引层而不是全量记忆),但这个细节原文没有展开。对比 OpenSquilla 的 Dream Consolidation 实现,会发现两者都承认这个整合步骤是必须的,但也都承认整合本身有成本。这是一个长程 Agent 的 open problem,没有银弹。
4. 分支-合并并行模式(模式 8)的实现复杂度被低估了¶
原文只提了一句「用 git worktree 在独立副本里工作」,但真正落地的复杂度远不止此:合并时的冲突消解需要一个有权决定保留什么的协调层;不同分支的 Agent 可能有不同的上下文和记忆状态,合并后如何保持一致性;如果某个分支超时或失败,主 Agent 如何感知并决定是否回退。这些问题在 Claude Code 的代码库里可能有具体答案,但原文只描述了概念层面的思路。这意味着模式 8 适合在相对独立的子任务上使用(比如批量重命名、跨文件单点修改),而不太适合高度耦合的逻辑改动。
5. 这些模式的出现频率与当前 Agent 框架的成熟度之间存在错位¶
Bilgin Ibryam 能从 Claude Code 源码里提炼出这 12 个模式,说明生产级 Agent 已经广泛使用它们。但大多数开源 Agent 框架(比如 LangChain Agents、AutoGPT)只实现了其中少数几个(主要是模式 1 和 6)。这种错位的后果是:社区里大量关于「Agent 太不可靠」的抱怨,往往不是模型的问题,而是 Harness 缺失的问题。Harness Engineering 系统化框架 试图把这个领域的共识整理成可操作的检查清单,12 个模式可以视为这个清单的源码级证据。
实践启示¶
1. 用生命周期钩子实现「强制门禁」,不要放在提示词里¶
凡是「每次改代码后必须格式化」「每次提交前必须跑测试」这类硬性要求,不要写在 System Prompt 中——模型会跳过。正确的做法是:找到 Agent 生命周期的关键节点(工具调用前后、目录切换时、会话结束时),在 Harness 层面挂上确定性钩子。 中的「完成门禁」概念即此:系统检查不通过,模型无法继续下一步。这比任何提示词都可靠。
2. 渐进式工具扩展要从「最小可用集」开始,而不是「功能开关」¶
模式 9 的关键不是「工具数量多不多」,而是「第一次给什么」。建议的做法是:统计过去 100 次任务中工具使用频率,把前 20% 设为默认,其余按需加载。这样 Agent 在大多数场景下不会被选择焦虑困扰,而罕见需求也能得到满足。一个反模式是:默认开启所有工具让 Agent 自己判断——这相当于让 Agent 做它不擅长的事情(风险评估)。
3. 在 Monorepo 中优先实现目录级的上下文组装,而不是全局指令文件¶
模式 2(Scoped Context Assembly)比模式 1(Persistent Instruction File)更适合中大型项目。具体落地路径:先在项目根目录放一份全局 .claude/instructions,然后在 packages/、tools/、docs/ 等子目录各放一份局部的。Agent 进入某目录时,系统自动 import 父目录的规则再加上本地覆盖。这样既保证全局一致性,又允许局部有合理差异。对比 该文的另一个版本 中的 monorepo 实践,这条路径已经被验证过。
4. 对话超过 20 轮时主动触发渐进压缩,不要等窗口上限¶
模式 5 的实现有一个细节陷阱:很多系统等到上下文快满了才开始压缩,结果压缩本身需要消耗上下文空间,导致压缩过程 itself 触发窗口上限。正确的做法是设置一个保守的触发阈值(比如上下文用了 60%),就开始对更早的内容做轻量总结。这个触发点应该由系统判断,而不是模型判断——模型没有能力在关键时刻主动承认自己「上下文快不够了」。
5. 并行分支要用「结果等权合并」而非「最后一个分支结果覆盖」¶
模式 8 的合并策略决定了并行化是否真的带来质量提升。一个常见错误是用时间戳取最后一个分支的结果,这实际上把并行变成了串行的随机选择。正确的设计是:每个分支返回「修改摘要 + 置信度」,主 Agent 在合并层做一次跨分支的对比消解,决定最终保留什么。如果多个分支对同一处代码都有修改,系统应该自动发起一次「合并协调」而非直接覆盖。这个协调层的存在是 Fork-Join 模式区别于简单并行的关键。
关联阅读¶
Related¶
AI Coding 入门指南