这是 Claude Code 的一种自主运行模式:没人发消息时,Claude 也会自己找事做。没人说话时 Claude 自己找活干

核心行为:

  1. 自己驱动对话 — 不等用户下指令,会主动探索、执行、推进任务
  2. 周期性唤醒 — 系统会发 <tick> 提示,让模型检查有没有事可做
  3. 没活就 Sleep — 没事时会调用 SleepTool 休眠,等下一次 tick
  4. 用户可随时接管 — 按 Esc 会暂停主动模式;你下次输入时会恢复

激活方式:

  • 启动参数:--proactive
  • 环境变量:CLAUDE_CODE_PROACTIVE
  • 斜杠命令:/proactive

Prompts:

src/constants/prompts.ts   getProactiveSection

prompt: 

自主工作
你在自主运行。你会收到 <${TICK_TAG}> 提示来保持你在各轮次之间的活跃——只需将其视为“你醒着,接下来做什么?”每个 <${TICK_TAG}> 中的时间都是用户当前的本地时间。用这个来判断一天中的时间——来自外部工具(Slack、GitHub 等)的时间戳可能处于不同的时区。

单个消息中可能包含多个批量的 tick。这是正常的——只需处理最新的一个。绝对不要在回复中回显或重复 tick 的内容。

节奏把控
使用 ${SLEEP_TOOL_NAME} 工具来控制你在操作之间的等待时长。在等待慢速进程时睡久一点,在积极迭代时睡短一点。每次唤醒都会消耗一次 API 调用,但提示缓存会在不活动 5 分钟后过期——请平衡好这一点。

如果你在某个 tick 上没有有用的事情可做,你必须调用 ${SLEEP_TOOL_NAME}。 绝不要只回复状态消息,比如“仍在等待”或“无事可做”——那样会浪费一次轮次并白白消耗 token。

首次唤醒
在新会话的第一次 tick 时,简要地向用户打个招呼,并询问他们想做什么。不要在未得到指示的情况下擅自开始探索代码库或进行更改——等待指令。

后续唤醒该做什么
寻找有用的工作。一个优秀的小伙伴在面对模糊不清的情况时不会就此止步——他们会调查、降低风险、增进理解。问问自己:我还不知道什么?什么可能会出问题?在认定事情完成之前,我想验证什么?

不要向用户发送垃圾信息。如果你已经问过某件事而对方尚未回复,就不要再问了。不要叙述你打算做什么——直接去做即可。

如果某个 tick 到达时你没有有用的操作可做(没有要读的文件、没有要运行的命令、没有要做的决策),立即调用 ${SLEEP_TOOL_NAME}。不要输出文本叙述你在空闲——用户不需要看到“仍在等待”之类的消息。

保持响应性
当用户积极与你互动时,频繁查看并回复他们的消息。把实时对话视作结对编程——保持紧密的反馈循环。如果你感觉到用户在等你(比如他们刚发了一条消息、终端处于聚焦状态),优先做出回应,而不是继续后台工作。

倾向于行动
凭你的最佳判断行事,而不是事事征求确认。

读文件、搜索代码、探索项目、运行测试、检查类型、运行 linter——所有这些都无需询问。

做出代码更改。当你到达一个合适的里程碑时进行提交。

如果你在两种合理方案之间拿不准,选一个继续推进。你随时可以调整方向。

保持简洁
保持文本输出简短且高层面。用户不需要了解你的思考过程或实现细节的逐条播报——他们能看到你的工具调用。将文本输出聚焦于:

需要用户输入的决定

在自然里程碑处的高层面状态更新(例如“PR 已创建”“测试通过”)

改变计划的错误或障碍

不要逐一叙述每个步骤、列出你读过的每个文件,或解释常规操作。如果能用一句话说清,就不要用三句。

终端焦点
用户上下文中可能包含一个 terminalFocus 字段,指示用户的终端当前是聚焦还是未聚焦。用这个来校准你的自主程度:

未聚焦:用户不在。倾向于高度自主行动——做决策、探索、提交、推送。仅在遇到真正不可逆或高风险的操作时才暂停。

聚焦:用户正在观看。更具协作性——抛出选择、在提交大规模更改前征询意见,并保持输出简洁以便实时跟进。{BRIEF_PROACTIVE_SECTION && briefToolModule?.isBriefEnabled() ? `\n\n{BRIEF_PROACTIVE_SECTION}` : ''}

主动模式不是一种新的输入方式,而是改变了谁在驱动对话:

普通模式 主动模式

你输入 → Claude 回复

Claude 自己发起工作循环

你主导

模型主导,你随时可插话

场景 是否需要你先输入

claude --proactive(空会话,无 -p

不需要 — 系统会自动发第一个 <tick> 唤醒模型

claude --proactive -p "修这个 bug"

需要这一次 — CLI 把 prompt 当初始消息自动提交

Resume 已有会话

不需要 — 从历史继续,直接进自主循环

Headless --print 模式

通常需要 stdin 或 -p(除非 resume)

完全零输入也能启动:

Proactive 的设计就是:没人说话时,系统自己注入 <tick> 驱动循环。

Headless 路径(print.ts)在 turn 结束、队列为空时会调度 tick:

    if (proactiveModule?.isProactiveActive() && !proactiveModule.isProactivePaused()) {
      if (peek(isMainThread) === undefined && !inputClosed) {
        scheduleProactiveTick!()
        return
      }
    }

交互 REPL 则通过 useProactive hook 在空闲时提交 tick(ant 构建)。

所以:开 --proactive 后,不必先打字,循环会自动跑起来。

但第一次唤醒的行为是「问候 + 等方向」,不是立刻乱改代码:

系统提示对第一次 tick 有专门约束:

## First wake-up

On your very first tick in a new session, greet the user briefly and ask what they'd like to work on. Do not start exploring the codebase or making changes unprompted — wait for direction.

同时 main.tsx 还会追加:

Start by briefly greeting the user.

也就是说:

  • 技术上:不需要你输入,模型会被 tick 唤醒
  • 行为上:第一次应该先打招呼、问你想做什么,不会一上来就扫仓库、改文件
  • 第二次及以后的 tick:才会真正自主找活干、探索、执行
如果你给了初始输入,会跳过「空等」阶段:
      initialMessage: inputPrompt ? {
        message: createUserMessage({
          content: String(inputPrompt)
        })
      } : null,

这时流程是:

  1. 你的 prompt 作为第一轮用户消息
  2. 模型直接回应你的任务
  3. 之后进入 tick → 工作 → Sleep 循环

useProactive 还会在 initialMessage 处理完之前抑制 tick,避免和用户首条消息抢跑。

和「完全无人值守」的区别:

即使进了自主循环,也不是完全不管:

  • 你随时可打字接管
  • Esc 会 pauseProactive(),暂停 tick
  • 第一次 tick 会等你给方向(新会话)
  • Resume / compaction 后会直接从摘要继续,不再问候

Proactive 不强制你先输入 — 空启动会自动 tick 并问候;但给了初始输入(-p 或第一条消息)会更快进入工作状态。第一次唤醒偏保守(先问再做),之后才是典型的自动工作模式。

输入框里也能看到相关状态,比如 footer 会显示下一次 proactive tick 的倒计时(ProactiveCountdown)。

ps: 在 BriefTool 里,proactive 表示模型主动发起的消息(比如后台任务完成、发现问题需要问你),而不是回复你刚问的问题。

主动模式有几个重要限制,所以和「完全无人值守的自动化脚本」不完全一样:
  1. 模型自己决定干什么 — 不是按固定脚本跑,而是根据上下文自己判断下一步
  2. 可以随时被接管 — 按 Esc 会暂停;你发消息会恢复控制权
  3. 没事会 Sleep — 不是一直狂跑,没活就休眠省电/省 token
  4. 出错会阻塞 — API 异常时会暂停 tick,避免死循环
和其他「自动」功能的区别:

仓库里还有别的自动化能力,不要混在一起:

  • 主动模式(Proactive) — 主对话线程自主循环
  • Cron 定时任务 — 到点触发特定任务
  • AutoDream — 晚上自动整理记忆
  • 后台任务 — 长时间命令丢到后台跑

主动模式是其中最核心的那种:整个 REPL 会话进入「我自己找活干」状态。

与主流程的关系:命令队列

Proactive 不绕过主流程,而是复用统一的命令队列(messageQueueManager):

用户交互:暂停与恢复

  • Esc:pauseProactive() + abort 当前 query,用户拿回控制权
  • 下次输入:resumeProactive(),tick 循环恢复
  • 终端失焦:userContext 注入 terminalFocus: 'unfocused',模型知道用户没在盯着
  • API 错误:contextBlocked = true,防止 tick → 错误 → tick 死循环
  • Compaction 后:清除 contextBlocked,tick 恢复

与其他子系统的协作:

子系统 与 Proactive 的关系

Cron 定时任务

也通过队列 isMeta: true 注入;Assistant 模式绕过 isLoading 门控,避免 tick→Sleep 饿死调度器

BriefTool

status: 'proactive' 标记模型主动发起的消息;主动模式下 Brief 提示段由 getProactiveSection() 统一提供

Compaction

压缩后专用提示:继续工作,不要重新问候

Bridge / Remote

远程消息走队列 skipSlashCommands: true;与 proactive tick 共用同一队列

Messages UI

主动模式关闭 terminal progress bar;tick 消息不渲染

总结:

Proactive 是在主查询循环外围加的一层「自主驱动器」:用模块级状态控制开关,用系统提示教模型如何自主工作,用 <tick> + 命令队列在无用户输入时注入唤醒信号,用 Sleep 工具在无活干时节流,用 paused / contextBlocked / 优先级队列保证用户随时可接管、错误不会死循环。它没有独立的事件循环,完全寄生在现有的 enqueue → drain → query → tool loop 主流程上。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐