OFFICIAL SOURCE ANALYSIS

KAIROS 概述与激活

Anthropic 的龙虾计划:定位、Feature Flag 体系、从 --assistant 到 Daemon 模式的完整激活链路。

1. KAIROS 是什么——定位与战略意义

在 Claude Code 的源码中,KAIROS 是一个 feature flag 的名字。但如果你只把它当作一个 boolean 开关来理解,你就错过了它的全部含义。KAIROS 是 Anthropic 对 AI 编程助手形态的一次范式级跃迁——从「你问我答」的被动模式,跃入「AI 自主工作、主动汇报」的全新模式。

代号来源:Kairos(希腊语 "关键时刻")

Kairos(希腊语:καιρός)在古希腊哲学中是一个与 Chronos(线性时间)相对的概念。Chronos 是钟表上的刻度,而 Kairos 是「恰到好处的时机」——一个质变的瞬间。Anthropic 选择这个代号绝非偶然:它暗示着 AI 编程助手正处在一个 Kairos 时刻——从被动工具到主动伙伴的转型拐点。

在 Anthropic 内部,KAIROS 也被称为 Assistant Mode。从源码可以看到,--assistant 是它的 CLI 激活参数,assistantModule 是它的运行时模块名。但「Assistant」这个词太温和了——KAIROS 的真正能力远超一个「助手」。

从 Chat 到 Code 到 Claw 的进化路线

Andrej Karpathy 曾在公开场合描述过 AI 编程工具的三阶段进化模型,这个模型精准地预测了 KAIROS 的出现:

Karpathy 的三阶段模型
阶段模式比喻代表产品
Chat你问,AI 答自己开车,GPS 导航ChatGPT, Claude.ai
Code你导航,AI 写代码坐副驾,你指方向Claude Code, Cursor, Copilot
ClawAI 自主工作,你审核躺后排睡觉KAIROS, OpenClaw

如果 Chat 模式是「你在开车,AI 是 GPS」,Code 模式是「你坐副驾指路,AI 在开车」,那么 Claw 模式就是「你躺在后排睡觉,AI 把你送到目的地,中途有事拍拍你」。KAIROS 正是 Claude Code 从 Code 阶段向 Claw 阶段跃迁的核心系统。

战略意义:后提示词时代的押注

传统的 AI 编程助手有一个本质限制:用户必须持续提供输入,AI 才能持续工作。每次交互都是一个「提示词 → 回复」的原子操作。这意味着用户需要时刻在线、持续思考下一步该让 AI 做什么。

KAIROS 彻底打破了这个模式。它让 Claude Code 变成一个可以在后台持续运行的 Daemon 进程,通过心跳机制(Tick)自主检查是否有工作要做,通过 Brief 工具主动向用户汇报进展,通过 Push Notification 在用户离开终端时发送通知。用户可以关掉笔记本盖子去喝咖啡,回来时发现 AI 已经完成了三个 PR、修了两个 bug、还给你发了一条总结。

核心洞察:KAIROS 的本质是将 Claude Code 从「同步工具」变为「异步员工」。这不只是一个产品功能的升级——它重新定义了人机协作的范式。在 KAIROS 模式下,AI 不再是你手中的锤子,而是你团队里的一名(不知疲倦的)工程师。

KAIROS vs OpenClaw 的对标关系

OpenClaw 是社区对 Claw 模式的开源实现——它试图在 Claude Code 之外复刻主动代理的能力。而 KAIROS 是 Anthropic 原生的、深度集成在 Claude Code 内部的实现。两者的目标相似,但路径截然不同:

维度KAIROSOpenClaw
定位官方原生实现,深度集成社区逆向实现,外部包装
激活方式Feature Flag + GrowthBook 灰度开源直接可用
心跳机制TICK_TAG XML + SleepTool外部定时器 + 消息注入
记忆系统Auto Dream 整合 + memdir外部记忆文件
编排能力Coordinator Mode(原生 Worker 系统)Agent 嵌套调用
安全模型Trust Dialog + Hooks + Classifier依赖用户自行配置

2. Feature Flag 体系——构建时的条件编译

KAIROS 不是一个单一开关——它是一个由多个 Feature Flag 组成的分层门控体系。理解这个体系是理解 KAIROS 的前提。Claude Code 使用 Bun 的构建时条件编译(Dead Code Elimination, DCE),在编译阶段根据 feature flag 的值决定是否将某段代码包含在最终产物中。这意味着在没有开启 KAIROS 的构建中,所有 KAIROS 相关代码根本不存在于 bundle 中——不是运行时跳过,而是编译时删除。

完整的 Feature Flag 清单

KAIROS Feature Flag 矩阵
Flag 名称作用依赖关系对应 GrowthBook Gate
KAIROS 主开关。控制 Assistant Mode 的整体可用性:assistantModule 的条件 require、--assistant 参数解析、kairosEnabled 计算、Daemon 模式初始化等 无(顶层) tengu_kairos
KAIROS_BRIEF Brief 工具(SendUserMessage)独立开关。允许在不开启完整 KAIROS 的情况下单独使用 Brief 工具 独立于 KAIROS tengu_kairos_brief
KAIROS_CHANNELS MCP Channel 推送通知。允许 MCP 服务器通过 notifications/claude/channel 向 Claude 发送频道消息 独立或与 KAIROS 联合 tengu_harbor
KAIROS_GITHUB_WEBHOOKS GitHub PR 事件订阅。允许通过 subscribe_pr_activity 工具监听 PR 的 review comments、CI 结果等事件 通常与 KAIROS 配合
KAIROS_PUSH_NOTIFICATION 推送通知。允许 Claude 向用户设备发送推送通知(如系统通知、邮件等) 需 KAIROS 激活
COORDINATOR_MODE Worker 编排系统。启用后 Claude 切换为协调者角色,不直接写代码,而是编排多个 Worker 并行完成任务 独立 flag
PROACTIVE 主动模式。允许 Claude 主动检查任务、发现问题并采取行动,而非等待用户指令 独立或与 KAIROS 联合
PROACTIVE_MODE 扩展主动功能。在 PROACTIVE 基础上增加更多主动行为的能力范围 需 PROACTIVE

Bun 构建时 DCE 机制

Claude Code 使用 import { feature } from 'bun:bundle' 进行构建时条件编译。这是 Bun 提供的编译时宏——在构建阶段,feature('KAIROS') 会被替换为字面量 truefalse,然后 Bun 的 tree-shaking 引擎会将 dead code 路径完全移除。

// 源码中的写法
import { feature } from 'bun:bundle'

const assistantModule = feature('KAIROS')
  ? require('./assistant/index.js')
  : null;

// 当 KAIROS=false 时,编译产物中:
// - require('./assistant/index.js') 被完全移除
// - assistantModule 被替换为 null
// - 所有依赖 assistantModule 的代码路径被 DCE 消除
// - assistant/ 目录下的模块不会出现在 bundle 中

这意味着 KAIROS 的代码对非 KAIROS 用户完全不可见——不增加 bundle 体积,不影响启动性能,不暴露实现细节。这是一种比运行时 if/else 更彻底的隔离方式。

GrowthBook 运行时灰度

构建时 DCE 控制的是「代码是否存在」,而 GrowthBook 控制的是「代码是否执行」。即使 KAIROS flag 在构建时被启用(代码存在于 bundle 中),运行时还需要通过 GrowthBook gate 的检查:

GrowthBook Gate用途缓存策略
tengu_kairos控制 Assistant Mode 运行时激活磁盘缓存 + 延迟 GrowthBook 初始化(最多 5 秒)
tengu_kairos_brief控制 Brief 工具的独立使用权限5 分钟刷新缓存
tengu_harbor控制 MCP Channel 通知的运行时激活缓存可能过期
tengu_onyx_plover控制 Auto Dream 记忆整合的调度参数缓存可能过期
tengu_scratch控制 Scratchpad(跨 Worker 共享目录)缓存可能过期

环境变量覆盖

对于开发和测试场景,多个 KAIROS 子功能支持环境变量覆盖,绕过 GrowthBook gate:

# Brief 工具强制启用(同时授予 entitlement,跳过 GB gate)
CLAUDE_CODE_BRIEF=1

# Coordinator Mode 启用
CLAUDE_CODE_COORDINATOR_MODE=1

# Proactive Mode 启用
CLAUDE_CODE_PROACTIVE=1

# Agent SDK Daemon 模式(等价于 --assistant)
# 由 Agent SDK 在启动子进程时自动设置
实践提示:如果你想在本地体验 KAIROS 的部分功能,最简单的方式是设置 CLAUDE_CODE_BRIEF=1 来启用 Brief 工具,或 CLAUDE_CODE_COORDINATOR_MODE=1 来进入 Coordinator 模式。完整的 Assistant Mode 需要 --assistant 参数且通过 GrowthBook gate。

3. 激活流程——从 --assistant 到 Daemon 模式

KAIROS 的激活不是一个简单的 boolean 切换——它是一个经过多层门控、条件检查、状态初始化的复杂启动链。理解这个链条是理解整个 KAIROS 运行时行为的关键。以下是从 main.tsx 源码中提取的完整激活流程。

激活决策树

               用户启动 claude --assistant
                        |
                        v
          +---------------------------+
          | feature('KAIROS') = true? |
          +---------------------------+
            |                    |
          true                 false
            |                    |
            v                    v
    +----------------+     [KAIROS 代码
    | 条件 require   |      不存在于 bundle]
    | assistantModule|
    | kairosGate     |
    +----------------+
            |
            v
    +-------------------------+
    | options.assistant = true |----> markAssistantForced()
    | (来自 --assistant 参数)   |      设置强制激活标记
    +-------------------------+
            |
            v
    +-----------------------------+
    | assistantModule              |
    |   .isAssistantMode() = true? |
    +-----------------------------+
      |              |
    true           false
      |              |
      v              v
  +----------------+  [正常 REPL 模式]
  | 检查 --agent-id |
  +----------------+
    |           |
  有 agent-id  无 agent-id
  (是 Teammate) (是 Leader)
    |           |
    v           v
  [跳过 KAIROS  +---------------------------+
   Leader 初始化] | checkHasTrustDialogAccepted |
                +---------------------------+
                  |               |
                已接受           未接受
                  |               |
                  v               v
          +------------------+  [打印警告,
          | kairosGate       |   禁用 KAIROS]
          | .isKairosEnabled |
          +------------------+
            |            |
          true         false
          (或 forced)    |
            |            v
            v         [正常模式]
    +----------------------------------+
    | kairosEnabled = true             |
    | setKairosActive(true)            |
    | options.brief = true             |
    | initializeAssistantTeam()        |
    +----------------------------------+
            |
            v
    +----------------------------------+
    | fullRemoteControl = true         |
    | Bridge 启动                       |
    | REPL 变为 viewer/messenger 客户端 |
    | Daemon 开始 agentic loop         |
    +----------------------------------+

逐步拆解

Step 1: CLI 解析 --assistant 参数 main.tsx:3842

在 Commander.js 注册的命令选项中,--assistant 被定义为一个隐藏选项(hideHelp()),用于 Agent SDK daemon 调用场景。它不出现在 claude --help 的输出中。

program.addOption(
  new Option('--assistant', 'Force assistant mode (Agent SDK daemon use)')
    .hideHelp()
);

这个参数主要被 Agent SDK 在启动 Claude Code 子进程时使用。普通用户不需要手动传递它——它是机器到机器的接口。

Step 2: feature('KAIROS') 构建时检查 main.tsx:80-81

在 main.tsx 的顶层作用域中,KAIROS 相关模块通过条件 require 引入:

const assistantModule = feature('KAIROS')
  ? require('./assistant/index.js') as typeof import('./assistant/index.js')
  : null;
const kairosGate = feature('KAIROS')
  ? require('./assistant/gate.js') as typeof import('./assistant/gate.js')
  : null;

如果构建时 KAIROS flag 为 false,这两个模块均为 null,后续所有依赖它们的代码路径都会被短路。

Step 3: isAssistantMode() — GrowthBook gate 检查 main.tsx:1058

assistantModule.isAssistantMode() 是运行时的灰度检查。它查询 GrowthBook 的 tengu_kairos gate,决定当前用户是否有权使用 Assistant Mode。这个检查支持磁盘缓存——如果缓存命中返回 true,则立即通过;否则触发 GrowthBook SDK 的延迟初始化(最多 5 秒网络超时)。

重要的例外:--assistant 参数(daemon 模式)会调用 markAssistantForced(),完全跳过 GrowthBook gate。这是因为 Agent SDK daemon 进程在启动前已经完成了权限检查——不需要让子进程再查一次。

Step 4: Trust Dialog 检查 main.tsx:1067

即使 GrowthBook gate 通过,KAIROS 仍然需要用户已经接受了当前目录的 Trust Dialog。这是一个安全措施:KAIROS 模式下 AI 拥有远超普通模式的自主权(可以主动修改文件、执行命令),必须确保用户对当前工作目录的信任已明确授予。

如果 Trust Dialog 未接受,终端会打印黄色警告:Assistant mode disabled: directory is not trusted.

Step 5: 初始化链 main.tsx:1076-1087

一旦所有门控通过,kairosEnabled 被设置为 true,触发以下初始化序列:

kairosEnabled = true setKairosActive(true) options.brief = true initializeAssistantTeam()
kairosEnabled = assistantModule.isAssistantForced()
  || (await kairosGate.isKairosEnabled());

if (kairosEnabled) {
  const opts = options as { brief?: boolean };
  opts.brief = true;                               // 强制启用 Brief
  setKairosActive(true);                            // 全局状态标记
  assistantTeamContext = await assistantModule
    .initializeAssistantTeam();                     // 预置 in-process team
}

注意 options.brief = true——KAIROS 模式强制启用 Brief 工具。在 KAIROS 下,所有用户可见的输出都必须通过 SendUserMessage,而不是裸文本。

Step 6: fullRemoteControl 与 Daemon 启动 main.tsx:2916
const fullRemoteControl = remoteControl
  || getRemoteControlAtStartup()
  || kairosEnabled;

当 kairosEnabled 为 true 时,fullRemoteControl 也为 true。这激活了 Bridge(WebSocket 远程控制桥接),让 REPL 从传统的本地终端模式切换为远程 Daemon 模式。在这个模式下:

  • REPL 本身变为 viewer/messenger 客户端——它显示 AI 的输出、转发用户输入,但不直接驱动 agentic loop
  • 真正的推理和工具调用运行在 Daemon 进程中,通过 Bridge 与 viewer 通信
  • 用户可以关闭终端然后重新连接——Daemon 持续运行