Chris Olah(Anthropic 联合创始人)说:像 Claude 这样的生成式 AI 系统是"生长"出来的,而不是"构建"出来的。研究人员设定引导条件,但涌现出的具体结构和能力并不总是可预测的。

这带来了一个挑战:Agent harness 编码了关于"Claude 独自无法做什么"的假设,但随着 Claude 能力增强,这些假设会变得过时。

Anthropic 工程团队总结了三个关键设计原则。

1. 用 Claude 已经知道的工具

建议用 Claude 非常熟悉的工具来构建应用。

2024 年底,Claude 3.5 Sonnet 仅凭 bash 工具和文本编辑器工具,就在 SWE-bench Verified 上达到了 49%——当时的最先进水平。Claude Code 同样基于这些工具。bash 工具不是为构建 Agent 设计的,但它是一个 Claude 知道怎么用、而且会越用越好的工具。

Claude 可以把这些通用工具组合成解决不同问题的模式——Agent Skills、程序化工具调用、memory 工具,都是从 bash 和文本编辑器工具构建出来的。

2. 持续问"什么可以停做?"

Agent harness 编码了关于 Claude 能力边界的假设。随着 Claude 变强,这些假设应该被持续检验。

让 Claude 自己编排动作

常见假设:每个工具结果都要流回 Claude 的 context window 来决定下一步行动。但如果结果只需要传给下一个工具,或者 Claude 只需要输出的一小部分,把它处理成 tokens 是缓慢、昂贵且不必要的。

给 Claude 一个代码执行工具(如 bash)可以解决这个问题:它让 Claude 写代码来表达工具调用和它们之间的逻辑,而不是由 harness 决定每个工具结果都要被当作 tokens 处理。只有代码执行的结果才会进入 Claude 的 context window。

Orchestration 决策从 harness 转移到了模型。由于代码是 Claude 编排动作的通用方式,一个强编码模型也是一个强通用 Agent。Claude 在非编码评估上也表现出色——在 BrowseComp benchmark 上,给 Opus 4.6 过滤自己工具输出的能力,准确率从 45.3% 提升到 61.6%。

让 Claude 自己管理上下文

常见的假设是 system prompts 应该手工写满任务特定指令。问题在于:预加载的 prompts 无法跨很多任务高效扩展,每个加入的 token 都在消耗 Claude 的注意力预算。

给 Claude 调用 skills 的能力解决了这个问题:每个 skill 的 YAML frontmatter 是一个简短描述,预加载到 context window,提供 skill 内容的概览。如果任务需要,Claude 可以调用文件读取工具来渐进式获取完整的 skill 内容。

Context editing 则相反——提供了一种选择性移除过时或无关上下文的方式,比如旧的工具结果或思考块。

Claude 也正在变得更好的是:知道什么时候该 fork 一个新的 context window 来隔离处理特定任务。

让 Claude 自己持久化上下文

长周期运行的 Agent 会超出单个 context window 的限制。常见假设是记忆系统应该依赖模型外围的检索基础设施。但 Anthropic 的做法是给 Claude 简单的方式让它自己选择要持久化什么内容。

Compaction 让 Claude 总结过去的 context 以保持长周期任务的连续性。几个版本迭代下来,Claude 在选择记住什么上变得更好。在 BrowseComp 上,Sonnet 4.5 在不同压缩预算下准确率都维持在 43%;而 Opus 4.5 扩展到了 68%,Opus 4.6 达到了 84%。

Memory folder 是另一种方式——让 Claude 把上下文写入文件,之后按需读取。在 BrowseComp-Plus 上,给 Sonnet 4.5 加上 memory folder 准确率从 60.4% 提升到 67.2%。

3. 谨慎设置边界

Agent harness 在 Claude 周围提供结构,以强制执行 UX、成本或安全边界。

设计上下文以最大化缓存命中

Messages API 是无状态的。Claude 看不到之前轮次的对话历史。这意味着 harness 需要在每轮把新的上下文和所有过去的操作、工具描述、指令一起打包给 Claude。

Prompts 可以根据断点(breakpoint)被缓存。缓存的 token 成本是基础输入 token 的 10%,以下是几个最大化缓存命中的原则:

原则说明
静态在前,动态在后把稳定内容(system prompt、tools)放在前面
用 messages 而非编辑 prompt<system-reminder> 而非编辑 prompt
不要切换模型切换模型会使缓存失效,如果需要更便宜的模型,用 subagent
谨慎管理 toolsTools 放在缓存前缀中,增删都会使缓存失效;动态发现用 tool search
更新断点对多轮应用,把断点移到最后一条消息以保持缓存新鲜

用声明式工具处理 UX、可观测性或安全边界

Claude 不一定知道应用程序的安全边界或 UX 表面。将动作升级为专用工具,让 harness 获得特定类型的钩子,可以拦截、门控、渲染或审计。

需要安全边界的动作是天然的专用工具候选。可逆性通常是好标准,难以逆转的操作(如外部 API 调用)可以加上用户确认。写入类工具可以包含新鲜度检查,防止覆盖自上次读取后已变化的文件。

专用工具也适用于需要向用户呈现动作的场景——比如渲染成弹窗显示问题、给用户多个选项、或者阻塞 agent 循环直到用户提供反馈。

在可观测性方面,当动作是类型化的工具时,harness 获得结构化的参数,可以记录、追踪和回放。

是否把动作升级为专用工具,应该持续重新评估。

核心教训

随着 Claude 能力边界的扩展,harness 中的假设需要持续被重新检验。当假设变得过时时,活水就会变成死重(dead weight)——而这会反过来成为 Claude 性能的瓶颈。

要定期问自己:什么可以停做?