经过前面20多章的源码分析,我们了解了Claude Code的每一个细节。但"知道怎么做"不等于"知道为什么"。

本章提炼六条核心原则——驾驭工程(Harness Engineering)的智慧,它们不仅适用于Claude Code,也适用于任何AI Agent系统的构建。

原则一:提示词即控制面

定义:用系统提示词段落引导模型行为,而非用代码逻辑硬编码限制。

为什么重要

AI模型的能力在快速迭代。如果为每种行为都写代码检测,你永远追不上模型能力的变化速度。

Claude Code的实践

极简主义指令

"Don't create helpers, utilities, or abstractions for one-time operations.
Don't design for hypothetical future requirements. The right amount of
complexity is what the task actually requires..."

这段文本不是代码注释——是发送给模型的实际指令。Claude Code没有在代码层面检测模型是否过度工程化(技术上几乎不可能),而是通过自然语言直接告诉模型"不要这么做"。

工具提示词的例子

  • BashTool的Git安全协议完全由提示词文本表达
  • “绝不跳过hooks、绝不amend、优先指定文件git add”
  • 如果某天允许amend,只需删除一行提示词,无需触碰执行逻辑

适用边界

  • 用代码处理:结构性约束(权限、token预算)
  • 用提示词处理:行为性约束(风格、策略、偏好)

反模式:行为硬编码

为每种不希望的模型行为编写检测器和拦截器,最终得到一个庞大的规则引擎,永远追不上模型能力的变化速度。

原则二:缓存感知设计是刚需

定义:每次提示词变更都有以cache_creationtoken计量的成本,系统设计必须将缓存稳定性作为一等约束。

动态边界标记

export const SYSTEM_PROMPT_DYNAMIC_BOUNDARY =
  '__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__'

将系统提示词分为两个区域:

  • 边界前:跨用户共享内容,可全局缓存
  • 边界后:用户/会话特定内容,不缓存

缓存中断检测

追踪近20个字段的前后状态变化:

  • systemHash:系统提示词哈希
  • toolsHash:工具Schema哈希
  • cacheControlHash:缓存控制哈希
  • perToolHashes:每个工具的哈希
  • betas:Beta Header列表

任何一个字段变化都可能触发缓存失效。

Beta Header锁存机制

极端案例:一旦发送过某个beta header,就永远继续发送,即使功能已关闭。

原因:取消发送改变请求签名,导致约50-70K token的缓存前缀失效。

日期记忆化

如果会话跨越午夜,模型看到的日期会"过期"——但这是有意为之,因为日期字符串变化会打断缓存前缀。

反模式:提示词频繁变动

Agent列表曾内联在系统提示词中,占全球cache_creationtoken的10.2%。解决方案是将其移至system-reminder消息——这部分在缓存段之外。

原则三:失败关闭,显式开放

定义:系统默认值应选择最安全的选项,只有在显式声明后才允许危险操作。

工具默认值

const TOOL_DEFAULTS = {
  isEnabled: () => true,
  isConcurrencySafe: () => false,  // 默认不可并发
  isReadOnly: () => false,          // 默认可能写入
  // ...
}

这意味着新工具默认不可并发执行。当isConcurrencySafe抛出异常时,catch块也返回false——保守方向的兜底。

权限模式

从最严格到最宽松:

default → acceptEdits → plan → bypassPermissions → auto → dontAsk

系统默认使用default——用户必须主动选择更宽松的模式。

YOLO拒绝追踪

连续3次或总计20次被分类器拒绝后,系统自动回退到用户手动确认。

核心思想:在自动化决策不可靠时,回退到人类决策。

反模式:默认开放,出事再关

工具默认可并发执行,某个有副作用的工具在并行执行中产生竞态条件——这种bug极难复现和诊断。

原则四:A/B测试一切

定义:行为变更先在内部用户群体中验证,通过数据确认后再扩展到所有用户。

89个Feature Flag

Claude Code有89个Feature Flag,其中相当一部分用于A/B测试。

ant-only门控

process.env.USER_TYPE === 'ant'
  ? [ /* 内部功能 */ ]
  : []

注释中的典型表述:

// @[MODEL LAUNCH]: capy v8 thoroughness counterweight
// (PR #24302) — un-gate once validated on external via A/B

流程:先在内部验证,确认有效后通过A/B测试推广给外部用户。

GrowthBook集成

tengu_*前缀的Feature Flag通过远程配置服务器控制,支持按百分比灰度。

两种缓存策略:

  • _CACHED_MAY_BE_STALE:可能过期
  • _CACHED_WITH_REFRESH:带刷新

这体现了"缓存感知的A/B测试"——flag值的切换不应导致缓存失效。

反模式:Big Bang发布

直接将行为变更推送给所有用户。在AI Agent领域,行为变更的影响通常不是"崩溃"而是"不够好"或"太激进"——需要量化度量和对照组才能发现。

原则五:先观察再修复

定义:在尝试修复问题之前,先建立可观测性基础设施来理解问题的全貌。

缓存中断检测系统

这个系统不修复任何问题——它的全部职责是观察和报告

调用前

  • recordPromptState()记录近20个字段的快照

调用后

  • checkResponseForCacheBreak()对比前后状态,识别哪个字段变化
  • 翻译为人类可读原因——“system prompt changed”、“TTL likely expired”
  • createPatch()输出前后提示词状态对比

数据驱动的可观测性

/** Per-tool schema hash. Diffed to name which tool's description changed
 * when toolSchemasChanged but added=removed=0 (77% of tool breaks per
 * BQ 2026-03-22). AgentTool/SkillTool embed dynamic agent/command lists. */
perToolHashes: Record<string, number>

这里引用了具体的BigQuery查询日期和百分比数据(77%)。团队在用数据驱动可观测性的粒度设计——不是随意追踪所有字段,而是基于生产数据发现"大多数工具Schema变化来自某个特定工具的描述变动",然后有针对性地添加per-tool哈希。

YOLO调试能力

CLAUDE_CODE_DUMP_AUTO_MODE=1提供完整的输入/输出导出能力,让开发者精确理解"分类器为什么拒绝了这个操作"。

反模式:凭直觉修复

看到缓存命中率下降就回滚最近修改,但实际原因可能是Beta Header切换、TTL过期、或MCP工具列表变化。

原则六:锁存以求稳定

定义:一旦进入某个状态,就不再摇摆——状态抖动比次优状态更有害。

Beta Header锁存

afkModeHeaderLatchedfastModeHeaderLatchedcacheEditingHeaderLatched

会话中首次发送某个Beta Header后,后续所有请求继续发送,即使功能已关闭。

原因:取消发送改变请求签名,导致缓存前缀失效。

缓存TTL资格锁存

should1hCacheTTL()在会话中只执行一次,结果被锁存。

自动压缩熔断器

// Stop trying autocompact after this many consecutive failures.
// BQ 2026-03-10: 1,279 sessions had 50+ consecutive failures
// (up to 3,272) in a single session, wasting ~250K API calls/day globally.
const MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3

连续3次失败后锁存到"停止压缩"状态。

注释中的BigQuery数据(1,279个会话、250K API调用/天)提供了充分的工程理由。

反模式:状态抖动

每次请求都重新计算配置,导致状态在不同值之间切换。在缓存系统中意味着缓存键不断变化,命中率趋近于零。

六条原则的关系

原则1: 提示词即控制面
原则2: 缓存感知设计(提示词变更有成本)
原则6: 锁存以求稳定(避免缓存抖动)

原则1: 提示词即控制面
原则3: 失败关闭(安全默认值)
原则4: A/B测试一切(验证后再开放)
原则5: 先观察再修复(数据驱动决策)
原则2: 缓存感知设计

提示词即控制面出发:

  • 既然行为主要由提示词控制,提示词变更就需要缓存感知设计来控制成本
  • 需要锁存以求稳定来防止抖动
  • 行为的安全边界由失败关闭保障
  • 从关闭到开放的过渡需要A/B测试验证
  • 出现问题时,先观察再修复确保理解全貌后再行动
  • 观察结果反馈到缓存感知设计中

实战:如何应用这些原则

提示词即控制面

  • 创建行为配置文件(类似CLAUDE.md),让行为调整不需要代码变更
  • 用自然语言表达行为期望,代码只处理结构性约束

缓存感知设计

  • 在引入提示词缓存前,先设计缓存边界
  • 区分跨用户共享内容和会话级内容

失败关闭

  • 审查你的默认值
  • 对每个配置项问:如果用户不设置它,系统的行为是最安全的还是最危险的?

A/B测试

  • 为关键行为变更设计灰度方案
  • 即使只有两个用户群体(内部/外部),也比全量发布安全

先观察再修复

  • 在修复之前添加日志
  • 缓存命中率下降或模型行为异常时,先记录完整上下文,再尝试修复

锁存以求稳定

  • 识别系统中的"锁存点"
  • 哪些状态在会话生命周期中不应该变化?提前设计稳定性机制

模式提炼

模式1:提示词驱动行为控制

  • 解决的问题:如何引导AI模型行为而不与模型能力迭代产生耦合
  • 核心做法:用自然语言提示词表达行为期望,用代码仅处理结构性约束
  • 前置条件:模型具备足够的指令跟随能力

模式2:缓存前缀稳定化

  • 解决的问题:提示词缓存因微小变动频繁失效
  • 核心做法:静态/动态边界分离 + 日期记忆化 + Header锁存 + Schema缓存
  • 前置条件:使用支持前缀缓存的API

模式3:失败关闭默认值

  • 解决的问题:新增组件引入安全或并发风险
  • 核心做法:所有属性默认为最安全值,显式声明才能解锁
  • 前置条件:有明确的"安全"和"不安全"定义

总结

六条驾驭工程原则:

原则核心做法反模式
提示词即控制面用提示词表达行为期望行为硬编码
缓存感知设计将缓存稳定性作为一等约束提示词频繁变动
失败关闭默认最安全,显式开放默认开放,出事再关
A/B测试一切内部验证→灰度→全量Big Bang发布
先观察再修复建立可观测性再修复凭直觉修复
锁存以求稳定状态一旦进入不再摇摆状态抖动

这些原则的共同主题是:在AI Agent系统中,控制行为的最佳方式不是编写更多代码,而是设计更好的约束

理解这些原则,你就能:

  • 构建更稳定、更可维护的AI Agent系统
  • 在快速迭代的AI领域保持系统的可控性
  • 将Claude Code的工程智慧应用到自己的项目中

下篇咱们聊聊上下文管理——AI编码的核心能力。