SpyBara
Go Premium

Documentation 2026-10-09 23:02 UTC to 2026-10-10 08:02 UTC

19 files changed +504 −156. View all changes and history on the product overview
2026
Sat 10 09:00 Fri 9 23:02 Thu 8 22:58 Wed 7 23:59 Tue 6 23:59 Mon 5 23:58 Sun 4 23:58 Sat 3 23:57 Fri 2 22:59 Thu 1 23:59
Details

124 124 

125未启用部分消息时,你会接收除 `StreamEvent` 之外的所有消息类型。常见类型包括 `SystemMessage`(会话初始化)、`AssistantMessage`(完整内容块)、`ResultMessage`(最终结果)和一个紧凑边界消息,指示何时压缩了对话历史记录(TypeScript 中为 `SDKCompactBoundaryMessage`;Python 中为带有子类型 `"compact_boundary"` 的 `SystemMessage`)。125未启用部分消息时,你会接收除 `StreamEvent` 之外的所有消息类型。常见类型包括 `SystemMessage`(会话初始化)、`AssistantMessage`(完整内容块)、`ResultMessage`(最终结果)和一个紧凑边界消息,指示何时压缩了对话历史记录(TypeScript 中为 `SDKCompactBoundaryMessage`;Python 中为带有子类型 `"compact_boundary"` 的 `SystemMessage`)。

126 126 

127<h3 id="handle-a-stream-that’s-cut-off">

128 处理被中断的流

129</h3>

130 

131如果流在消息中途被中断,例如当您中断该轮次或连接断开时,您仍会在该轮次结束前收到该消息的 `message_stop`。被中断的文本块或思考块也会收到其 `content_block_stop`。被中断的工具调用则不会,因此如果 `message_stop` 到达时某个工具调用的块仍处于打开状态,请将该调用的输入视为不完整。

132 

133在 Claude Code v2.1.290 之前,被中断的流可能会在没有 `message_stop` 的情况下结束轮次,因此您根据流事件渲染的回复可能会一直显示为进行中。TypeScript Agent SDK 从 v0.3.290 起捆绑 Claude Code v2.1.290 或更高版本,Python Agent SDK 则从 v0.2.164 起捆绑。如果轮次结束后回复仍显示为进行中,请更新 SDK。

134 

127<h2 id="stream-tool-calls">135<h2 id="stream-tool-calls">

128 流式传输工具调用136 流式传输工具调用

129</h2>137</h2>

Details

1588 1588 

1589请通过 `agent_id` 将子代理的消息与其任务事件进行匹配,而不是将消息的 `parent_tool_use_id` 与任务事件的 `tool_use_id` 配对。当某个工具调用恢复子代理时,任务事件携带的是该调用的 `tool_use_id`,而消息保留的是最初启动该子代理的工具调用的 `parent_tool_use_id`,因此两者不再匹配。1589请通过 `agent_id` 将子代理的消息与其任务事件进行匹配,而不是将消息的 `parent_tool_use_id` 与任务事件的 `tool_use_id` 配对。当某个工具调用恢复子代理时,任务事件携带的是该调用的 `tool_use_id`,而消息保留的是最初启动该子代理的工具调用的 `parent_tool_use_id`,因此两者不再匹配。

1590 1590 

1591Claude Code 在该轮的第一条助手消息上设置 `user_message_uuid` 和 `user_message_uuids`,条件在 [`user_message_uuid`](#user_message_uuid) 中。当 Claude Code 重新运行被重启中断的轮时,重新运行的携带这些字段的助手消息也携带 [`resume_reason`](#resume_reason)。1591Claude Code 会在满足 [`user_message_uuid`](#user_message_uuid) 中所述条件时,在该轮次的第一条助手消息上设置 `user_message_uuid` 和 `user_message_uuids`。当该轮次是继续一个被重启中断的轮次时,携带这些字段的助手消息还会携带 [`resume_reason`](#resume_reason)。

1592 1592 

1593`timestamp` 是消息内容在生成它的进程上完成生成的 ISO 8601 时间。该值来自该机器的时钟,因此仅用于显示,不要按它排序消息。一个 API 轮可以产生多条共享 `message.id` 的助手消息,每条都有自己的 `timestamp`。当字段不存在时,回退到您收到消息的时间。1593`timestamp` 是消息内容在生成它的进程上完成生成的 ISO 8601 时间。该值来自该机器的时钟,因此仅用于显示,不要按它排序消息。一个 API 轮可以产生多条共享 `message.id` 的助手消息,每条都有自己的 `timestamp`。当字段不存在时,回退到您收到消息的时间。

1594 1594 


1631 1631 

1632设置 `inline_pastes` 可告知 Claude Code `message.content` 中哪些部分是用户粘贴的而非键入的,每次粘贴对应一个字符串。提示词文本保留在用户放置的位置。Claude Code 可能会在原位用 `<pasted_content>` 标签包裹每个列出的粘贴内容,以便 Claude 区分粘贴的材料和用户自己的话。只有提示词最后一个文本块中的粘贴内容会被包裹。需要 TypeScript Agent SDK v0.3.280 或更高版本。1632设置 `inline_pastes` 可告知 Claude Code `message.content` 中哪些部分是用户粘贴的而非键入的,每次粘贴对应一个字符串。提示词文本保留在用户放置的位置。Claude Code 可能会在原位用 `<pasted_content>` 标签包裹每个列出的粘贴内容,以便 Claude 区分粘贴的材料和用户自己的话。只有提示词最后一个文本块中的粘贴内容会被包裹。需要 TypeScript Agent SDK v0.3.280 或更高版本。

1633 1633 

1634每个粘贴字段都有大小限制:

1635 

1636* `pasted_content`:如果条目数加上其中的内容块数超过 1,000,Claude Code 会忽略整个字段。

1637* `inline_pastes`:Claude Code 使用前 100 个非空条目,并忽略其余条目。

1638 

1634设置 `shouldQuery`、`client_composed` 或 `priority` 可以改变 Claude Code 处理您所发送消息的方式:1639设置 `shouldQuery`、`client_composed` 或 `priority` 可以改变 Claude Code 处理您所发送消息的方式:

1635 1640 

1636* `shouldQuery`:设置为 `false` 以将消息附加到会话记录中而不触发助手轮。消息被保留并合并到下一条触发轮的用户消息中。使用此方法注入上下文,例如您在带外运行的命令的输出,而无需在模型调用上花费。1641* `shouldQuery`:设置为 `false` 以将消息附加到会话记录中而不触发助手轮。消息被保留并合并到下一条触发轮的用户消息中。使用此方法注入上下文,例如您在带外运行的命令的输出,而无需在模型调用上花费。


1775* `ttft_stream_ms`:直到第一个 `message_start` 流事件(响应流打开时)的时间(毫秒)。低于 `ttft_ms`;两者之间的差距是流式传输第一条消息所花费的时间。仅在成功分支上存在。1780* `ttft_stream_ms`:直到第一个 `message_start` 流事件(响应流打开时)的时间(毫秒)。低于 `ttft_ms`;两者之间的差距是流式传输第一条消息所花费的时间。仅在成功分支上存在。

1776* `user_message_uuid`:您发送的消息的 `uuid`,该轮回答了该消息。请参阅 [`user_message_uuid`](#user_message_uuid) 了解哪些结果携带它。1781* `user_message_uuid`:您发送的消息的 `uuid`,该轮回答了该消息。请参阅 [`user_message_uuid`](#user_message_uuid) 了解哪些结果携带它。

1777* `user_message_uuids`:您发送的每条消息的 `uuid`,Claude Code 在该轮中回答了这些消息。请参阅 [`user_message_uuids`](#user_message_uuids)。1782* `user_message_uuids`:您发送的每条消息的 `uuid`,Claude Code 在该轮中回答了这些消息。请参阅 [`user_message_uuids`](#user_message_uuids)。

1778* `resume_reason`:Claude Code 在重启中断该轮次后重新运行它的原因。出现在两个分支上。请参阅 [`resume_reason`](#resume_reason)。1783* `resume_reason`:本轮次为何是继续一个被重启中断的轮次。在两个分支上都存在。请参阅 [`resume_reason`](#resume_reason)。

1779* `local_command`:轮分派的命令的名称,在轮由命令完成而不进入 Agent 循环的成功结果上,例如 `/compact`。名称折叠为小写字母和下划线,因此 `/reload-plugins` 报告 `reload_plugins`。MCP 服务器提供的命令和内置 `/mcp` 报告 `mcp`。您自己定义的命令报告 `custom`。参数从不包含。在进入 Agent 循环的每个轮上不存在,在运行无命令的发送上不存在。需要 Agent SDK v0.3.268 或更高版本。1784* `local_command`:轮分派的命令的名称,在轮由命令完成而不进入 Agent 循环的成功结果上,例如 `/compact`。名称折叠为小写字母和下划线,因此 `/reload-plugins` 报告 `reload_plugins`。MCP 服务器提供的命令和内置 `/mcp` 报告 `mcp`。您自己定义的命令报告 `custom`。参数从不包含。在进入 Agent 循环的每个轮上不存在,在运行无命令的发送上不存在。需要 Agent SDK v0.3.268 或更高版本。

1780* `request_sent_wall_ms`:Claude Code 分派 API 请求的纪元毫秒,用于与服务器端时间戳的连接。仅与 [`user_message_uuid`](#user_message_uuid) 一起存在,在成功结果上,其中 `is_error` 为 false,且轮发送了 API 请求。1785* `request_sent_wall_ms`:Claude Code 分派 API 请求的纪元毫秒,用于与服务器端时间戳的连接。仅与 [`user_message_uuid`](#user_message_uuid) 一起存在,在成功结果上,其中 `is_error` 为 false,且轮发送了 API 请求。

1781* `first_content_frame_ms`:直到第一个 `content_block_start` 或 `content_block_delta` 流事件的时间(毫秒),计算思考块作为内容。仅在成功分支上存在,当 `is_error` 为 false 时。需要 Agent SDK v0.3.260 或更高版本。1786* `first_content_frame_ms`:直到第一个 `content_block_start` 或 `content_block_delta` 流事件的时间(毫秒),计算思考块作为内容。仅在成功分支上存在,当 `is_error` 为 false 时。需要 Agent SDK v0.3.260 或更高版本。


1825 1830 

1826* **您发送的常规消息**,意思是没有 `isSynthetic: true` 的消息:轮在其整个运行中回答该消息。当您一起发送多条消息时,Claude Code 可以将它们合并为一轮,该字段然后仅携带最后一条消息的 `uuid`。要将回复与任何合并的消息匹配,请使用 [`user_message_uuids`](#user_message_uuids)。1831* **您发送的常规消息**,意思是没有 `isSynthetic: true` 的消息:轮在其整个运行中回答该消息。当您一起发送多条消息时,Claude Code 可以将它们合并为一轮,该字段然后仅携带最后一条消息的 `uuid`。要将回复与任何合并的消息匹配,请使用 [`user_message_uuids`](#user_message_uuids)。

1827* **您发送的带有 `isSynthetic: true` 的消息**:轮最初回答该消息。如果 Claude Code 在工具调用之间拾取您的常规消息,轮从那时起回答拾取的消息。回显合成消息的 `uuid` 需要 Agent SDK v0.3.265 或更高版本;早期版本在合成轮上不回显任何内容。1832* **您发送的带有 `isSynthetic: true` 的消息**:轮最初回答该消息。如果 Claude Code 在工具调用之间拾取您的常规消息,轮从那时起回答拾取的消息。回显合成消息的 `uuid` 需要 Agent SDK v0.3.265 或更高版本;早期版本在合成轮上不回显任何内容。

1828* **Claude Code 生成的、用于在 [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](/docs/zh-CN/env-vars) 下重新运行被中断轮的提示词**:当被中断轮的最后一个提示词是您发送的常规消息时,无论它是打开轮还是 Claude Code 在轮期间拾取它,重新运行最初回答该消息。[`resume_reason`](#resume_reason) 可将重新运行的帧与被中断尝试的帧区分开。当最后一个提示词不是您的常规消息时,重新运行最初不回答您的任何消息。如果 Claude Code 在工具调用之间拾取您的常规消息,轮从那时起回答拾取的消息。回显被中断轮的提示词需要 Agent SDK v0.3.268 或更高版本。1833* **Claude Code 在 [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](/docs/zh-CN/env-vars) 下为继续被中断的轮次而生成的提示词**:当被中断轮次的最后一个提示词是您发送的常规消息时(无论它是开启了该轮次,还是 Claude Code 在轮次期间接收的),继续的轮次起初回答该消息。[`resume_reason`](#resume_reason) 可将继续轮次的帧与被中断尝试的帧区分开来。当最后一个提示词不是您的常规消息时,继续的轮次起初不回答您的任何消息。如果 Claude Code 在工具调用之间接收了您的一条常规消息,则从那时起该轮次回答被接收的消息。回显被中断轮次的提示词需要 Agent SDK v0.3.268 或更高版本。

1829* **Claude Code 自己生成的任何其他提示词**:轮最初不回答您的任何消息,其帧不携带回显。如果 Claude Code 在工具调用之间拾取您的常规消息,轮从那时起回答该消息。拾取回显需要 Agent SDK v0.3.265 或更高版本;早期版本在这些轮上不回显任何内容。1834* **Claude Code 自己生成的任何其他提示词**:轮最初不回答您的任何消息,其帧不携带回显。如果 Claude Code 在工具调用之间拾取您的常规消息,轮从那时起回答该消息。拾取回显需要 Agent SDK v0.3.265 或更高版本;早期版本在这些轮上不回显任何内容。

1830 1835 

1831Claude Code 在三种帧上回显回答的消息的 `uuid`:1836Claude Code 在三种帧上回显回答的消息的 `uuid`:


1857 `resume_reason`1862 `resume_reason`

1858</h4>1863</h4>

1859 1864 

1860Claude Code 在重启后重新运行该轮的原因。Claude Code 在它在 [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](/docs/zh-CN/env-vars) 下重新运行的轮上设置此字段,以便您可以将重新运行的回复和结果与被中断尝试的区分开。需要 Agent SDK v0.3.268 或更高版本。1865本轮次为何是继续一个被重启中断的轮次。Claude Code 会在 [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](/docs/zh-CN/env-vars) 下继续被中断轮次的轮次上设置此字段,以便您将继续轮次的回复和结果与被中断尝试的回复和结果区分开来。需要 Agent SDK v0.3.268 或更高版本。

1861 1866 

1862Claude Code 在两种帧上设置该字段:1867Claude Code 在两种帧上设置该字段:

1863 1868 

1864* **重新运行的结果**:在成功和错误分支上,无论结果是否携带 `user_message_uuid`。1869* **继续轮次的结果**:在 success 和 error 分支上均设置,无论结果是否携带 `user_message_uuid`。

1865* **重新运行的回复帧**:那些携带 [`user_message_uuid`](#user_message_uuid) 的帧。1870* **继续轮次的回复帧**:携带 [`user_message_uuid`](#user_message_uuid) 的那些帧。

1866 1871 

1867该值是一个简短的小写标记,指明该轮次被重新运行的原因,例如 `interrupted_turn`。1872其值是一个简短的小写标记,例如 `interrupted_turn`。

1868 1873 

1869<h4 id="queued_turn_count">1874<h4 id="queued_turn_count">

1870 `queued_turn_count`1875 `queued_turn_count`


2029};2034};

2030```2035```

2031 2036 

2032Claude Code 在轮的第一个非 ping 流事件上设置 `user_message_uuid` 和 `user_message_uuids`,并在轮回答的消息改变时再次设置,条件在 [`user_message_uuid`](#user_message_uuid) 中。当 Claude Code 重新运行被重启中断的轮时,重新运行的携带这些字段的流事件也携带 [`resume_reason`](#resume_reason)。2037Claude Code 会在满足 [`user_message_uuid`](#user_message_uuid) 中所述条件时,在该轮次的第一个非 ping 流事件上设置 `user_message_uuid` 和 `user_message_uuids`,并在轮次所回答的消息发生变化时再次设置。当该轮次是继续一个被重启中断的轮次时,携带这些字段的流事件还会携带 [`resume_reason`](#resume_reason)。

2033 2038 

2034<h3 id="sdkcompactboundarymessage">2039<h3 id="sdkcompactboundarymessage">

2035 `SDKCompactBoundaryMessage`2040 `SDKCompactBoundaryMessage`


3558| - | - | - |3563| - | - | - |

3559| `script` | `string` | 内联工作流脚本。必须以 `export const meta = { name, description }` 作为字面量开头,后跟使用 `agent()`、`parallel()`、`pipeline()` 和 `phase()` 的脚本主体。`meta` 中的可选 `phases` 数组在进度视图中将 Agent 分组到命名阶段下 |3564| `script` | `string` | 内联工作流脚本。必须以 `export const meta = { name, description }` 作为字面量开头,后跟使用 `agent()`、`parallel()`、`pipeline()` 和 `phase()` 的脚本主体。`meta` 中的可选 `phases` 数组在进度视图中将 Agent 分组到命名阶段下 |

3560| `name` | `string` | 内置工作流的名称或保存在 `.claude/workflows/` 中的工作流名称。解析为脚本 |3565| `name` | `string` | 内置工作流的名称或保存在 `.claude/workflows/` 中的工作流名称。解析为脚本 |

3561| `scriptPath` | `string` | 磁盘上工作流脚本文件的路径。优先于 `script` 和 `name`。Claude Code 持久化每次调用的脚本并在结果中返回路径,因此您可以编辑该文件并使用相同的 `scriptPath` 重新调用以进行迭代 |3566| `scriptPath` | `string` | 磁盘上工作流脚本文件的路径,例如先前运行返回的 `scriptPath`。优先于 `script` 和 `name`。当会话的工具不包含 `Read` 时,Claude Code 会以错误拒绝 `scriptPath` |

3562| `args` | `unknown` | 输入值,作为全局 `args` 暴露给脚本,用于参数化的命名工作流,例如研究问题或文件路径列表。将数组和对象作为实际 JSON 值传递,而不是作为 JSON 编码的字符串 |3567| `args` | `unknown` | 输入值,作为全局 `args` 暴露给脚本,用于参数化的命名工作流,例如研究问题或文件路径列表。将数组和对象作为实际 JSON 值传递,而不是作为 JSON 编码的字符串 |

3563| `resumeFromRunId` | `string` | 要恢复的先前 `Workflow` 调用的运行 ID。具有未更改输入的已完成 `agent()` 调用通常返回缓存的结果;其余的实时运行。[暂停后恢复](/docs/zh-CN/workflows#resume-after-a-pause)涵盖哪些已完成的调用会重新运行。仅限同一会话 |3568| `resumeFromRunId` | `string` | 要恢复的先前 `Workflow` 调用的运行 ID。具有未更改输入的已完成 `agent()` 调用通常返回缓存的结果;其余的实时运行。[暂停后恢复](/docs/zh-CN/workflows#resume-after-a-pause)涵盖哪些已完成的调用会重新运行。仅限同一会话 |

3564| `title` | `string` | 被忽略;脚本的 `meta` 块设置标题 |3569| `title` | `string` | 被忽略;脚本的 `meta` 块设置标题 |

chrome.md +3 −4

Details

129 VS Code 会话中的权限提示129 VS Code 会话中的权限提示

130</h3>130</h3>

131 131 

132在 VS Code 会话中,Claude Code 是否在浏览器操作前询问您,取决于该会话连接到您浏览器的方式:132在 VS Code 会话中,当 Claude Code 在浏览器操作前询问您时,提示会以卡片形式显示在聊天面板中。当该操作针对您尚未允许的网站时,该卡片还会提供允许该网站的选项。

133 133 

134* **您键入了 `@browser`**:扩展程序会批准 Claude Code 原本会询问您的每个浏览器操作。134在因 [Enabled by default](#enable-chrome-by-default) 已开启而在启动时连接到您浏览器的会话中,在 Manual、Edit automatically、Auto 和 Bypass permissions 模式下,对于您尚未允许的网站,Claude Code 会在浏览器操作前询问您。在 Auto 和 Bypass permissions 模式下,这一行为持续到您在该会话中键入 `@browser` 为止。

135* **[Enabled by default](#enable-chrome-by-default) 设置在启动时建立了连接**:在 Manual、Edit automatically、Auto 和 Bypass permissions 模式下,对于您尚未允许的网站,Claude Code 会在浏览器操作前询问您,直到您在该会话中键入 `@browser`。

136 135 

137<h3 id="browser-tools-in-plan-mode">136<h3 id="browser-tools-in-plan-mode">

138 Plan Mode 中的浏览器工具137 Plan Mode 中的浏览器工具

139</h3>138</h3>

140 139 

141在[计划模式](/docs/zh-CN/permission-modes#analyze-before-you-edit-with-plan-mode)中,在 Claude 记录 GIF、打开新标签页或运行快捷方式之前会出现权限提示,但在您键入了 [`@browser`](#permission-prompts-in-vs-code-sessions) 的 VS Code 会话中除外。在交互式 CLI 会话中,如果[可用绕过权限模式](/docs/zh-CN/permission-modes#skip-all-checks-with-bypasspermissions-mode)且[功能标志获取](/docs/zh-CN/env-vars#features-that-need-feature-flag-fetching)已关闭,这些调用将在没有提示的情况下运行。140在[计划模式](/docs/zh-CN/permission-modes#analyze-before-you-edit-with-plan-mode)中,在 Claude 记录 GIF、打开新标签页或运行快捷方式之前会出现权限提示。在交互式 CLI 会话中,如果[可用绕过权限模式](/docs/zh-CN/permission-modes#skip-all-checks-with-bypasspermissions-mode)且[功能标志获取](/docs/zh-CN/env-vars#features-that-need-feature-flag-fetching)已关闭,这些调用将在没有提示的情况下运行。

142 141 

143当 `tabs_context_mcp` 调用设置 `createIfEmpty` 时也会提示,包含任何这些操作的 `browser_batch` 调用也是如此。142当 `tabs_context_mcp` 调用设置 `createIfEmpty` 时也会提示,包含任何这些操作的 `browser_batch` 调用也是如此。

144 143 

Details

981 * **混合键**:同时包含 `code` 和 `cli`(或其早期写法 `settings`)的文件会使网关在启动时停止。请在一次编辑中将所有块放在同一个键下。981 * **混合键**:同时包含 `code` 和 `cli`(或其早期写法 `settings`)的文件会使网关在启动时停止。请在一次编辑中将所有块放在同一个键下。

982</Warning>982</Warning>

983 983 

984策略的 Claude Code 设置(例如拒绝读取 `.env` 文件的规则)放在 `cli` 或 `code` 键下的块中。两个键接受相同的内容。键决定设置在哪里被执行:984策略的 Claude Code 设置(例如拒绝读取 `.env` 文件的规则)放在 `cli` 或 `code` 键下的块中。`code` 是推荐的键,`cli` 是旧版键。两个键接受相同的内容。键决定了设置在何处强制执行:

985 985 

986* **`cli`**:终端、VS Code 和 JetBrains 扩展以及 Agent SDK。在 `cli` 下,Claude Desktop 的 Code 标签页获得的是[派生设置](#claude-desktop-overlay),因此诸如 `Read(./.env)` 之类的限定规则在那里不会阻止用户。986* **`cli`**:终端、VS Code 和 JetBrains 扩展以及 Agent SDK。在 `cli` 下,Claude Desktop 的 Code 标签页获得的是[派生设置](#claude-desktop-overlay),因此诸如 `Read(./.env)` 之类的限定规则在那里不会阻止用户。

987* **`code`**:相同的位置,并且也可以覆盖 Claude Desktop 的 Code 标签页。987* **`code`**:相同的位置,并且也可以覆盖 Claude Desktop 的 Code 标签页。

988 988 

989需要决定的是这些设置是否也应覆盖 Code 标签页。如果不需要,无需做任何更改。使用 `cli` 的文件会照常工作;如果网关在带有 [`desktop`](#claude-desktop-overlay) 键的策略中发现 `cli`,它会在启动时发出警告但仍会启动。要覆盖 Code 标签页,请切换到推荐的 `code` 键。989使用 `cli` 的文件照常工作;如果网关在带有 [`desktop`](#claude-desktop-overlay) 键的策略中发现 `cli`,会在启动时发出警告,但仍会启动。请切换到 `code`,以便设置也能涵盖 Code 标签页。

990 990 

991切换之前,请阅读[在 Code 标签页中应用 `code` 设置](#apply-code-settings-in-the-code-tab)。策略需要 `desktop` 键,用户的机器也需要进行设置后这些设置才会在那里生效,并且 Claude Desktop 中的网页搜索会被关闭。991切换之前,请阅读[在 Code 标签页中应用 `code` 设置](#apply-code-settings-in-the-code-tab)。策略需要 `desktop` 键,用户的机器也需要进行设置后这些设置才会在那里生效,并且 Claude Desktop 中的网页搜索会被关闭。

992 992 

Details

277 277 

278当线程的模型支持时,线程在[自动模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode)中运行,因此大多数工具调用无需询问你即可运行。当线程需要你的批准时,提示在该线程内,线程等待你在那里回答。在项目对话中告诉 Claude 继续不会到达它。278当线程的模型支持时,线程在[自动模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode)中运行,因此大多数工具调用无需询问你即可运行。当线程需要你的批准时,提示在该线程内,线程等待你在那里回答。在项目对话中告诉 Claude 继续不会到达它。

279 279 

280每个批准涵盖该提示,或如果你选择更广泛的选项,则涵盖该线程的其余部分。要让每个线程运行某些命令而不询问,或阻止某些命令,请将[权限规则](/docs/zh-CN/permissions)添加到存储库的`.claude/settings.json`。云线程仅在具有一个存储库的项目中应用它们;请参阅[线程从你的存储库中获取什么](#what-threads-pick-up-from-your-repositories)。在具有多个存储库的项目中,没有存储库的权限规则到达云线程,因此你依赖自动模式和你在每个线程内给出的批准。280每次批准仅涵盖该提示,或者如果您选择更广泛的选项,则涵盖该线程的其余部分。

281 

282要让每个线程无需询问即可运行某些命令,或阻止某些命令,请将[权限规则](/docs/zh-CN/permissions)添加到仓库的 `.claude/settings.json` 中。请确认项目中的云线程是否会应用这些规则:

283 

284* **一个仓库**:云线程会应用这些规则。请参阅[线程从您的仓库中获取哪些内容](#what-threads-pick-up-from-your-repositories)。

285* **多个仓库,Anthropic 托管的环境**:任何仓库的权限规则都不会传达到云线程,因此您需要依赖自动模式以及您在每个线程内给出的批准。

286* **多个仓库,自托管环境**:请参阅[哪个仓库的设置适用](/docs/zh-CN/self-hosted-environments-configuration#repository-settings-in-sessions-with-several-repositories)。

281 287 

282<h3 id="run-a-thread-on-your-own-computer">288<h3 id="run-a-thread-on-your-own-computer">

283 在你自己的计算机上运行线程289 在你自己的计算机上运行线程


381 线程从您的仓库中获取什么387 线程从您的仓库中获取什么

382</h3>388</h3>

383 389 

384每个云线程会克隆项目中的每个仓库,并从所有仓库加载 `CLAUDE.md` 和 skill。权限规则、hook 和 `env` 仅来自线程启动目录中的 `.claude/settings.json`:当项目只有一个仓库时,该目录位于仓库内;当有多个仓库时,该目录位于各克隆的上层,此时不会读取任何仓库的该文件来获取这些内容。390每个云线程会克隆项目中的每个仓库,并从所有仓库加载 `CLAUDE.md` 和 skill。权限规则、hook 和 `env` 仅来自线程启动目录中的 `.claude/settings.json`。

385 391 

386| 在每个仓库中 | 一个仓库 | 多个仓库 |392| 在每个仓库中 | 一个仓库 | 多个仓库 |

387| :- | :- | :- |393| :- | :- | :- |

388| `CLAUDE.md` | 在线程启动时加载 | 在线程启动时从每个仓库加载 |394| `CLAUDE.md` | 在线程启动时加载 | 在线程启动时从每个仓库加载 |

389| `.claude/` 下的 skill、Agent 和命令 | 加载 | 从每个仓库加载 |395| `.claude/` 下的 skill、Agent 和命令 | 加载 | 从每个仓库加载 |

390| 在 `.claude/settings.json` 中启用的插件 | 不加载。请改为在 **Project settings > Plugins** 中添加该插件 | 不加载。请改为在 **Project settings > Plugins** 中添加该插件 |396| 在 `.claude/settings.json` 中启用的插件 | 不加载。请改为在 **Project settings > Plugins** 中添加该插件 | 不加载。请改为在 **Project settings > Plugins** 中添加该插件 |

391| 在 `.claude/settings.json` 中定义的权限规则、hook 和 `env` | 适用于线程,但[任何云端会话都不遵循](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)的 `env` 键除外 | 不适用 |397| 在 `.claude/settings.json` 中定义的权限规则、hook 和 `env` | 适用于线程,但[任何云端会话都不遵循](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)的 `env` 键除外 | 在 Anthropic 托管环境中不适用。对于自托管环境,请参阅[哪个仓库的设置适用](/docs/zh-CN/self-hosted-environments-configuration#repository-settings-in-sessions-with-several-repositories) |

392 398 

393在有多个仓库的项目中,每个克隆都作为[附加目录](/docs/zh-CN/memory#load-from-additional-directories)附加到线程,并启用了 `CLAUDE.md` 加载,这就是为什么即使线程在它们的上层启动,每个仓库的 `CLAUDE.md` 和 skill 仍会在启动时加载。在这样的项目中,请将常规规则放在项目说明中,并通过[云环境](#choose-an-environment-for-threads)为线程提供环境变量。399在有多个仓库的项目中,请将常规规则放在项目说明中,并通过[云环境](#choose-an-environment-for-threads)为线程提供环境变量。

394 400 

395<h3 id="choose-an-environment-for-threads">401<h3 id="choose-an-environment-for-threads">

396 为线程选择环境402 为线程选择环境


406 412 

407云线程不具备仅安装在您机器上的 skill、MCP 服务器、插件和工具。Claude 通过 [Remote Control](/docs/zh-CN/remote-control) 在您机器上运行的线程会使用那里安装的内容。要让这些内容对云线程可用:413云线程不具备仅安装在您机器上的 skill、MCP 服务器、插件和工具。Claude 通过 [Remote Control](/docs/zh-CN/remote-control) 在您机器上运行的线程会使用那里安装的内容。要让这些内容对云线程可用:

408 414 

409* skill、子代理和命令:将它们提交到您已添加到项目的仓库,例如位于 `.claude/skills/<skill-name>/SKILL.md` 的 skill。每个云线程会克隆项目中的每个仓库,并从每个仓库加载 `.claude/skills/`、`.claude/agents/` 和 `.claude/commands/`,因此提交到一个仓库的 skill 在每个云线程中都可用。云线程还会加载您为 claude.ai 账户启用的 skill。415* skill、子代理和命令:将它们提交到您已添加到项目的仓库,例如位于 `.claude/skills/<skill-name>/SKILL.md` 的 skill。每个云线程会克隆项目中的每个仓库,并从每个仓库加载 `.claude/skills/`、`.claude/agents/` 和 `.claude/commands/`,因此提交到一个仓库的 skill 在每个云线程中都可用。云线程还会加载[您为 claude.ai 账户启用的 skill](/docs/zh-CN/skills#skills-in-cowork-and-cloud-sessions)。

410* 插件:在 **Project settings > Plugins** 中添加它们;它们会加载到每个新云线程中。仓库在其 `.claude/settings.json` 中声明的插件[不会在云线程中加载](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)。416* 插件:在 **Project settings > Plugins** 中添加它们;它们会加载到每个新云线程中。仓库在其 `.claude/settings.json` 中声明的插件[不会在云线程中加载](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)。

411* MCP 服务器:云线程从您 claude.ai 账户上的连接器获取 MCP 工具,这些连接器是您在 [claude.ai/customize/connectors](https://claude.ai/customize/connectors) 或通过 **Project settings > Environment** 中的 **Manage connectors** 链接一次性连接的 MCP 服务器。每个云线程都可以使用所有这些连接器,无需按项目设置。项目对话本身没有连接器,因此请将需要连接器的工作作为任务发送给云线程。在只有一个仓库的项目中,云线程还会从该仓库的 [`.mcp.json`](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup) 加载 MCP 服务器。[连接器如何到达 Claude Code](/docs/zh-CN/mcp#how-connectors-reach-claude-code) 列出了云端会话的规则以及关闭连接器的设置。417* MCP 服务器:云线程从您 claude.ai 账户上的连接器获取 MCP 工具,这些连接器是您在 [claude.ai/customize/connectors](https://claude.ai/customize/connectors) 或通过 **Project settings > Environment** 中的 **Manage connectors** 链接一次性连接的 MCP 服务器。每个云线程都可以使用所有这些连接器,无需按项目设置。项目对话本身没有连接器,因此请将需要连接器的工作作为任务发送给云线程。在只有一个仓库的项目中,云线程还会从该仓库的 [`.mcp.json`](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup) 加载 MCP 服务器。[连接器如何到达 Claude Code](/docs/zh-CN/mcp#how-connectors-reach-claude-code) 列出了云端会话的规则以及关闭连接器的设置。

412* 命令行工具和包:在环境的[设置脚本](/docs/zh-CN/cloud-environments#setup-scripts)中安装它们。418* 命令行工具和包:在环境的[设置脚本](/docs/zh-CN/cloud-environments#setup-scripts)中安装它们。

Details

108| `--maintenance` | 在会话之前使用 `maintenance` 匹配器运行 [Setup hook](/docs/zh-CN/hooks#setup)(仅限 print 模式) | `claude -p --maintenance "query"` |108| `--maintenance` | 在会话之前使用 `maintenance` 匹配器运行 [Setup hook](/docs/zh-CN/hooks#setup)(仅限 print 模式) | `claude -p --maintenance "query"` |

109| `--max-budget-usd` | 一旦 API 调用的估算支出达到此金额,即停止运行(仅限 print 模式)。Claude Code 根据其[客户端成本估算](/docs/zh-CN/agent-sdk/cost-tracking#estimates-not-billing)检查上限,该估算可能与您的账单不同。来自[子代理](/docs/zh-CN/sub-agents)的支出计入上限。支出可能超过上限,因此请[预留余量](/docs/zh-CN/agent-sdk/agent-loop#budget-headroom)。当您使用 `--continue` 或 `--resume` 返回对话时,[从早期运行恢复的](/docs/zh-CN/agent-sdk/cost-tracking#accumulate-costs-across-multiple-calls)总数不计入上限。一旦支出达到上限,生成另一个子代理会失败并显示 `Budget limit reached`,Claude Code 会停止仍在运行的后台子代理;上限执行行为需要 Claude Code v2.1.217 或更高版本 | `claude -p --max-budget-usd 5.00 "query"` |109| `--max-budget-usd` | 一旦 API 调用的估算支出达到此金额,即停止运行(仅限 print 模式)。Claude Code 根据其[客户端成本估算](/docs/zh-CN/agent-sdk/cost-tracking#estimates-not-billing)检查上限,该估算可能与您的账单不同。来自[子代理](/docs/zh-CN/sub-agents)的支出计入上限。支出可能超过上限,因此请[预留余量](/docs/zh-CN/agent-sdk/agent-loop#budget-headroom)。当您使用 `--continue` 或 `--resume` 返回对话时,[从早期运行恢复的](/docs/zh-CN/agent-sdk/cost-tracking#accumulate-costs-across-multiple-calls)总数不计入上限。一旦支出达到上限,生成另一个子代理会失败并显示 `Budget limit reached`,Claude Code 会停止仍在运行的后台子代理;上限执行行为需要 Claude Code v2.1.217 或更高版本 | `claude -p --max-budget-usd 5.00 "query"` |

110| `--max-turns` | 限制 Agent 轮次数(仅限 print 模式)。达到限制时以错误退出。默认无限制。使用 `--input-format stream-json` 时,当限制结束某一轮次时仍在排队的消息会保持排队,并以其自己的限制启动新轮次 | `claude -p --max-turns 3 "query"` |110| `--max-turns` | 限制 Agent 轮次数(仅限 print 模式)。达到限制时以错误退出。默认无限制。使用 `--input-format stream-json` 时,当限制结束某一轮次时仍在排队的消息会保持排队,并以其自己的限制启动新轮次 | `claude -p --max-turns 3 "query"` |

111| `--mcp-config` | 从 JSON 文件或字符串加载 MCP 服务器(空格分隔)。当您使用 `-p` 传递此标志时,Claude Code 在运行第一轮之前等待仍待处理的服务器连接,最多等待 [`MCP_TIMEOUT`](/docs/zh-CN/env-vars) 启动超时时间,默认 30 秒;具有[缓存工具列表](/docs/zh-CN/mcp#managing-your-servers)的服务器跳过等待并在首次使用时连接。等待需要 Claude Code v2.1.221 或更高版本 | `claude --mcp-config ./mcp.json` |111| `--mcp-config` | 从 JSON 文件或字符串加载 MCP 服务器(空格分隔)。当您使用 `-p` 传递此标志时,Claude Code 在运行第一轮之前等待仍待处理的服务器连接,最多等待 [`MCP_TIMEOUT`](/docs/zh-CN/env-vars) 启动超时时间,默认 30 秒;具有[缓存工具列表](/docs/zh-CN/mcp#managing-your-servers)的服务器跳过等待并在首次使用时连接。在[自托管环境](/docs/zh-CN/self-hosted-environments-configuration#connection-timing)中,则改为适用较短的等待时间。等待需要 Claude Code v2.1.221 或更高版本 | `claude --mcp-config ./mcp.json` |

112| `--model` | 使用[模型别名](/docs/zh-CN/model-config#model-aliases)(如 `sonnet`、`opus`、`haiku` 或 `fable`)或模型的完整名称为当前会话设置模型。覆盖 [`model`](/docs/zh-CN/settings-reference#model) 设置和 [`ANTHROPIC_MODEL`](/docs/zh-CN/model-config#environment-variables) | `claude --model claude-sonnet-5` |112| `--model` | 使用[模型别名](/docs/zh-CN/model-config#model-aliases)(如 `sonnet`、`opus`、`haiku` 或 `fable`)或模型的完整名称为当前会话设置模型。覆盖 [`model`](/docs/zh-CN/settings-reference#model) 设置和 [`ANTHROPIC_MODEL`](/docs/zh-CN/model-config#environment-variables) | `claude --model claude-sonnet-5` |

113| `--name`, `-n` | 为会话设置显示名称,显示在 `/resume` 和终端标题中。您可以使用 `claude --resume <name>` 恢复命名会话。在交互式会话中,如果此机器上的另一个活动会话已使用该名称,Claude Code 会改为应用[其变体](/docs/zh-CN/sessions#name-your-sessions)。<br /><br />[`/rename`](/docs/zh-CN/commands) 在会话中途更改名称,并且还会在提示栏上显示它 | `claude -n "my-feature-work"` |113| `--name`, `-n` | 为会话设置显示名称,显示在 `/resume` 和终端标题中。您可以使用 `claude --resume <name>` 恢复命名会话。在交互式会话中,如果此机器上的另一个活动会话已使用该名称,Claude Code 会改为应用[其变体](/docs/zh-CN/sessions#name-your-sessions)。<br /><br />[`/rename`](/docs/zh-CN/commands) 在会话中途更改名称,并且还会在提示栏上显示它 | `claude -n "my-feature-work"` |

114| `--no-chrome` | 为此会话禁用 [Chrome 浏览器集成](/docs/zh-CN/chrome) | `claude --no-chrome` |114| `--no-chrome` | 为此会话禁用 [Chrome 浏览器集成](/docs/zh-CN/chrome) | `claude --no-chrome` |

Details

314| 在您的仓库的 `.claude/settings.json` 中声明的插件和市场 | 否 | 云端会话不会安装仓库在 [`enabledPlugins`](/docs/zh-CN/settings-reference#enabledplugins) 下启用的插件,包括来自它在 [`extraKnownMarketplaces`](/docs/zh-CN/settings-reference#extraknownmarketplaces) 下列出的市场的插件 |314| 在您的仓库的 `.claude/settings.json` 中声明的插件和市场 | 否 | 云端会话不会安装仓库在 [`enabledPlugins`](/docs/zh-CN/settings-reference#enabledplugins) 下启用的插件,包括来自它在 [`extraKnownMarketplaces`](/docs/zh-CN/settings-reference#extraknownmarketplaces) 下列出的市场的插件 |

315| 您组织的[服务器托管设置](/docs/zh-CN/server-managed-settings) | 是,除了在 [Claude Tag](https://claude.com/docs/claude-tag/overview) 会话中 | 在会话启动时从 Anthropic 的服务器获取。请参阅[使用入口覆盖范围](/docs/zh-CN/model-config#surface-coverage)了解 `availableModels` 在云端会话中如何强制执行。通过 MDM 或托管设置文件部署到您设备的设置不适用,因为会话在 Anthropic 管理的 VM 上运行;在[自托管环境](/docs/zh-CN/self-hosted-environments)中,会话也会读取运行器镜像中的托管设置文件,根据 [Claude Code 如何组合托管来源](/docs/zh-CN/managed-settings#how-claude-code-combines-managed-sources) |315| 您组织的[服务器托管设置](/docs/zh-CN/server-managed-settings) | 是,除了在 [Claude Tag](https://claude.com/docs/claude-tag/overview) 会话中 | 在会话启动时从 Anthropic 的服务器获取。请参阅[使用入口覆盖范围](/docs/zh-CN/model-config#surface-coverage)了解 `availableModels` 在云端会话中如何强制执行。通过 MDM 或托管设置文件部署到您设备的设置不适用,因为会话在 Anthropic 管理的 VM 上运行;在[自托管环境](/docs/zh-CN/self-hosted-environments)中,会话也会读取运行器镜像中的托管设置文件,根据 [Claude Code 如何组合托管来源](/docs/zh-CN/managed-settings#how-claude-code-combines-managed-sources) |

316| 您的用户 `~/.claude/CLAUDE.md` | 否 | 位于您的机器上,不在仓库中。请参阅[添加个人偏好而无需提交到仓库](#add-personal-preferences-without-committing-to-the-repo) |316| 您的用户 `~/.claude/CLAUDE.md` | 否 | 位于您的机器上,不在仓库中。请参阅[添加个人偏好而无需提交到仓库](#add-personal-preferences-without-committing-to-the-repo) |

317| 您的用户 `~/.claude/skills/`、`~/.claude/agents/`、`~/.claude/commands/` | 否 | 位于您的机器上,不在仓库中。请改为将它们提交到仓库的 `.claude/` 目录。云端会话会自动加载您在 claude.ai 上启用的 skill |317| 您的用户 `~/.claude/skills/`、`~/.claude/agents/`、`~/.claude/commands/` | 否 | 位于您的机器上,不在仓库中。请改为将它们提交到仓库的 `.claude/` 目录。云端会话会自动加载[您在 claude.ai 上启用的 skill](/docs/zh-CN/skills#skills-in-cowork-and-cloud-sessions) |

318| 仅在您的用户设置中启用的插件 | 否 | 用户作用域的 `enabledPlugins` 位于您机器上的 `~/.claude/settings.json` |318| 仅在您的用户设置中启用的插件 | 否 | 用户作用域的 `enabledPlugins` 位于您机器上的 `~/.claude/settings.json` |

319| 您使用 `claude mcp add` 在默认本地作用域或用户作用域添加的 MCP 服务器 | 否 | 这些写入您机器上的 `~/.claude.json`,而不是仓库。请使用 `claude mcp add --scope project` 添加服务器,它会写入仓库的 [`.mcp.json`](/docs/zh-CN/mcp#project-scope),并提交该文件。具有一个仓库的会话会加载它 |319| 您使用 `claude mcp add` 在默认本地作用域或用户作用域添加的 MCP 服务器 | 否 | 这些写入您机器上的 `~/.claude.json`,而不是仓库。请使用 `claude mcp add --scope project` 添加服务器,它会写入仓库的 [`.mcp.json`](/docs/zh-CN/mcp#project-scope),并提交该文件。具有一个仓库的会话会加载它 |

320| 您的仓库的 `.claude/settings.json` `env` 块中的传输变量,例如 `NODE_EXTRA_CA_CERTS` 和 [mTLS 客户端证书变量](/docs/zh-CN/network-config#mtls-authentication) | 否 | 托管环境管理会话的 API 连接,因此 Claude Code 忽略这些键,并在会话的调试日志中记录每个被忽略的键 |320| 您的仓库的 `.claude/settings.json` `env` 块中的传输变量,例如 `NODE_EXTRA_CA_CERTS` 和 [mTLS 客户端证书变量](/docs/zh-CN/network-config#mtls-authentication) | 否 | 托管环境管理会话的 API 连接,因此 Claude Code 忽略这些键,并在会话的调试日志中记录每个被忽略的键 |

env-vars.md +1 −1

Details

340| `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION` | [WebSearch](/docs/zh-CN/tools-reference#session-search-limit) 调用次数上限(默认:200)。当 Claude 达到上限后,后续 WebSearch 调用会返回一条通知,告知它使用已收集的信息继续。接受任意正整数,没有最大值限制。其他值会被忽略并应用默认值,因此该上限可以提高,但不能关闭。需要 Claude Code v2.1.212 或更高版本 |340| `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION` | [WebSearch](/docs/zh-CN/tools-reference#session-search-limit) 调用次数上限(默认:200)。当 Claude 达到上限后,后续 WebSearch 调用会返回一条通知,告知它使用已收集的信息继续。接受任意正整数,没有最大值限制。其他值会被忽略并应用默认值,因此该上限可以提高,但不能关闭。需要 Claude Code v2.1.212 或更高版本 |

341| `CLAUDE_CODE_MCP_ALLOWLIST_ENV` | 设置为 `1` 可在启动 stdio MCP 服务器时仅提供安全的基线环境加上服务器配置的 `env`,而不是继承您的 shell 环境 |341| `CLAUDE_CODE_MCP_ALLOWLIST_ENV` | 设置为 `1` 可在启动 stdio MCP 服务器时仅提供安全的基线环境加上服务器配置的 `env`,而不是继承您的 shell 环境 |

342| `CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS` | 仍在运行的 MCP 工具调用在经过多长时间(毫秒)后[转为后台任务](/docs/zh-CN/mcp#automatic-backgrounding-of-long-tool-calls)(默认:120000,即 2 分钟)。设置为 `0` 可关闭自动转入后台。需要 Claude Code v2.1.212 或更高版本 |342| `CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS` | 仍在运行的 MCP 工具调用在经过多长时间(毫秒)后[转为后台任务](/docs/zh-CN/mcp#automatic-backgrounding-of-long-tool-calls)(默认:120000,即 2 分钟)。设置为 `0` 可关闭自动转入后台。需要 Claude Code v2.1.212 或更高版本 |

343| `CLAUDE_CODE_MCP_STARTUP_WAIT_MS` | [非交互](/docs/zh-CN/headless)会话的第一轮等待仍在连接中的 MCP 服务器的时长(毫秒),用于替代默认的[首轮等待](/docs/zh-CN/agent-sdk/mcp#connection-timing)。设置后,该等待涵盖所有待连接的服务器。设置为 `0` 可跳过等待。无论该值如何,[`--permission-prompt-tool`](/docs/zh-CN/cli-reference#cli-flags) 服务器都会保留其自身的 `MCP_TIMEOUT` 等待。需要 Claude Code v2.1.274 或更高版本 |343| `CLAUDE_CODE_MCP_STARTUP_WAIT_MS` | [非交互](/docs/zh-CN/headless)会话的第一轮等待仍在连接的 MCP 服务器的时长(毫秒),用于替代默认的[首轮等待](/docs/zh-CN/agent-sdk/mcp#connection-timing)。设置后,等待会涵盖所有待连接的服务器;在[自托管环境](/docs/zh-CN/self-hosted-environments-configuration#connection-timing)中,它只改变等待持续的时长。设置为 `0` 可跳过等待。无论该值如何,[`--permission-prompt-tool`](/docs/zh-CN/cli-reference#cli-flags) 服务器都会保持其自身的 `MCP_TIMEOUT` 等待。需要 Claude Code v2.1.274 或更高版本 |

344| `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT` | MCP 工具调用的空闲超时时间(毫秒)。当 stdio、HTTP、SSE、WebSocket 或 [claude.ai 连接器](/docs/zh-CN/mcp#use-mcp-servers-from-claude-ai) MCP 服务器在这段时间内既没有发送响应也没有发送进度通知时,工具调用会报错中止,而不是等待整体的 `MCP_TOOL_TIMEOUT`。覆盖各传输方式的默认值:网络服务器为 300000(5 分钟),stdio 服务器为 1800000(30 分钟)。设置为 `0` 可禁用空闲检查。低于 1000 的值会被提高到一秒,且该值的上限为生效的 `MCP_TOOL_TIMEOUT`。`.mcp.json` 中至少为 1000 的单服务器 `timeout` 会将该服务器的空闲窗口提高到至少等于 `timeout` 值。不适用于 IDE 服务器或 SDK 进程内服务器。需要 Claude Code v2.1.187 或更高版本。在 v2.1.203 之前,stdio 服务器不受空闲超时限制 |344| `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT` | MCP 工具调用的空闲超时时间(毫秒)。当 stdio、HTTP、SSE、WebSocket 或 [claude.ai 连接器](/docs/zh-CN/mcp#use-mcp-servers-from-claude-ai) MCP 服务器在这段时间内既没有发送响应也没有发送进度通知时,工具调用会报错中止,而不是等待整体的 `MCP_TOOL_TIMEOUT`。覆盖各传输方式的默认值:网络服务器为 300000(5 分钟),stdio 服务器为 1800000(30 分钟)。设置为 `0` 可禁用空闲检查。低于 1000 的值会被提高到一秒,且该值的上限为生效的 `MCP_TOOL_TIMEOUT`。`.mcp.json` 中至少为 1000 的单服务器 `timeout` 会将该服务器的空闲窗口提高到至少等于 `timeout` 值。不适用于 IDE 服务器或 SDK 进程内服务器。需要 Claude Code v2.1.187 或更高版本。在 v2.1.203 之前,stdio 服务器不受空闲超时限制 |

345| `CLAUDE_CODE_MESSAGING_SOCKET` | 由 Claude Code 设置,而非由您设置:在绑定了[收件箱套接字](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)的会话中,Claude Code 在绑定套接字时会将该套接字的路径导出给 hook 和 Bash 命令。在启动时即开启消息功能的会话中,Claude Code 会在任何 hook 运行之前绑定套接字。本机上的其他会话会将消息投递到此路径。每个会话导出自己的套接字,而不是从父会话继承的套接字,到达该套接字的消息会经过该会话的[入站控制](/docs/zh-CN/cross-session-messaging#control-inbound-messages)。设置中的 `env` 块无法设置此变量。需要 Claude Code v2.1.224 或更高版本 |345| `CLAUDE_CODE_MESSAGING_SOCKET` | 由 Claude Code 设置,而非由您设置:在绑定了[收件箱套接字](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)的会话中,Claude Code 在绑定套接字时会将该套接字的路径导出给 hook 和 Bash 命令。在启动时即开启消息功能的会话中,Claude Code 会在任何 hook 运行之前绑定套接字。本机上的其他会话会将消息投递到此路径。每个会话导出自己的套接字,而不是从父会话继承的套接字,到达该套接字的消息会经过该会话的[入站控制](/docs/zh-CN/cross-session-messaging#control-inbound-messages)。设置中的 `env` 块无法设置此变量。需要 Claude Code v2.1.224 或更高版本 |

346| `CLAUDE_CODE_MESSAGING_TOKEN` | 由 Claude Code 设置,而非由您设置:在绑定了[收件箱套接字](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)的会话中,Claude Code 会将此会话专属令牌与 `CLAUDE_CODE_MESSAGING_SOCKET` 一起导出给 hook 和 Bash 命令。向该套接字发送消息的脚本可以将 `{"type":"auth","token":"<token>"}` 作为第一行发送,以证明它属于该会话。在原生 Windows 上,Claude Code 要求发送此行,并会关闭任何未以有效认证行开头的连接。[自有子进程规则](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)说明了 Claude Code 何时会检查该令牌。每个会话导出自己的令牌,绝不会使用从父会话继承的令牌。设置中的 `env` 块无法设置此变量。需要 Claude Code v2.1.228 或更高版本 |346| `CLAUDE_CODE_MESSAGING_TOKEN` | 由 Claude Code 设置,而非由您设置:在绑定了[收件箱套接字](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)的会话中,Claude Code 会将此会话专属令牌与 `CLAUDE_CODE_MESSAGING_SOCKET` 一起导出给 hook 和 Bash 命令。向该套接字发送消息的脚本可以将 `{"type":"auth","token":"<token>"}` 作为第一行发送,以证明它属于该会话。在原生 Windows 上,Claude Code 要求发送此行,并会关闭任何未以有效认证行开头的连接。[自有子进程规则](/docs/zh-CN/cross-session-messaging#the-sessions-inbox-socket)说明了 Claude Code 何时会检查该令牌。每个会话导出自己的令牌,绝不会使用从父会话继承的令牌。设置中的 `env` 块无法设置此变量。需要 Claude Code v2.1.228 或更高版本 |

errors.md +46 −9

Details

247| `Windows reported an error (EBADF) when Claude Code read this session's transcript file` | [命令行错误](#windows-reported-an-error-ebadf) |247| `Windows reported an error (EBADF) when Claude Code read this session's transcript file` | [命令行错误](#windows-reported-an-error-ebadf) |

248| `Cannot switch renderers in this session` | [命令行错误](#cannot-switch-renderers-in-this-session) |248| `Cannot switch renderers in this session` | [命令行错误](#cannot-switch-renderers-in-this-session) |

249| `Cannot switch renderers while work is running in the background` | [命令行错误](#cannot-switch-renderers-in-this-session) |249| `Cannot switch renderers while work is running in the background` | [命令行错误](#cannot-switch-renderers-in-this-session) |

250| `Claude Code couldn't restart` | [命令行错误](#claude-code-couldnt-restart) |

250| `Couldn't open Claude Desktop` | [命令行错误](#couldnt-open-claude-desktop) |251| `Couldn't open Claude Desktop` | [命令行错误](#couldnt-open-claude-desktop) |

251| `Failed to open Claude Desktop. Please try opening it manually.` | [命令行错误](#couldnt-open-claude-desktop) |252| `Failed to open Claude Desktop. Please try opening it manually.` | [命令行错误](#couldnt-open-claude-desktop) |

252| `Couldn't read your Zed keymap` / `Couldn't back up your Zed keymap` / `Couldn't update your Zed keymap` | [命令行错误](#terminal-setup-left-your-zed-keymap-unchanged) |253| `Couldn't read your Zed keymap` / `Couldn't back up your Zed keymap` / `Couldn't update your Zed keymap` | [命令行错误](#terminal-setup-left-your-zed-keymap-unchanged) |


334| `Session isn't responding` / `Press enter again to restart this session — it isn't responding` | [后台会话错误](#session-isnt-responding) |335| `Session isn't responding` / `Press enter again to restart this session — it isn't responding` | [后台会话错误](#session-isnt-responding) |

335| `Session <id> was stopped while the respawn was in flight` | [后台会话错误](#session-was-stopped-while-the-respawn-was-in-flight) |336| `Session <id> was stopped while the respawn was in flight` | [后台会话错误](#session-was-stopped-while-the-respawn-was-in-flight) |

336| `This session was running agent '<name>', which is no longer available` | [后台会话错误](#session-agent-no-longer-available) |337| `This session was running agent '<name>', which is no longer available` | [后台会话错误](#session-agent-no-longer-available) |

338| `This session restarted <time> after its next /loop wakeup was due, so that wakeup will not fire` | [后台会话错误](#restarted-after-its-next-loop-wakeup-was-due) |

337| `CLAUDE_CODE_PROCESS_WRAPPER: launcher ...` | [后台会话错误](#claude_code_process_wrapper-launcher-errors) |339| `CLAUDE_CODE_PROCESS_WRAPPER: launcher ...` | [后台会话错误](#claude_code_process_wrapper-launcher-errors) |

338| `EUNKNOWN: unknown error, uv_spawn` | [后台会话错误](#eunknown-when-starting-a-background-session) |340| `EUNKNOWN: unknown error, uv_spawn` | [后台会话错误](#eunknown-when-starting-a-background-session) |

339| `EACCES: permission denied, posix_spawn` | [后台会话错误](#eacces-when-starting-a-background-session) |341| `EACCES: permission denied, posix_spawn` | [后台会话错误](#eacces-when-starting-a-background-session) |


439| :- | :- | :- |441| :- | :- | :- |

440| [`CLAUDE_CODE_MAX_RETRIES`](/docs/zh-CN/env-vars) | 10 | 重试尝试次数。从 v2.1.186 开始上限为 15;从 v2.1.199 开始 `CLAUDE_CODE_RETRY_WATCHDOG` 提高默认值并移除上限。降低它以在脚本中更快地显示故障。 |442| [`CLAUDE_CODE_MAX_RETRIES`](/docs/zh-CN/env-vars) | 10 | 重试尝试次数。从 v2.1.186 开始上限为 15;从 v2.1.199 开始 `CLAUDE_CODE_RETRY_WATCHDOG` 提高默认值并移除上限。降低它以在脚本中更快地显示故障。 |

441| [`CLAUDE_CODE_RETRY_WATCHDOG`](/docs/zh-CN/env-vars) | 未设置 | 在 CI 作业等无人值守会话中设置为 `1`,以无限期重试 `429` 和 `529` 容量错误,而不是在 `CLAUDE_CODE_MAX_RETRIES` 尝试后失败。当标准速度请求获得报告支出限制或耗尽使用额度的 `429` 时,Claude Code 立即失败,即使来自 [gateway spend cap](#spend-limit-reached) 的也是如此,该上限按计划重置。在 v2.1.239 之前,看门狗无限期重试这些。对于快速模式请求,请参阅 [Handle rate limits](/docs/zh-CN/fast-mode#handle-rate-limits)。在 v2.1.199 或更高版本上,它还为其他瞬时错误(例如服务器错误、超时和断开连接)提高默认重试计数至 300,大约三小时的退避,如果您明确设置该变量,则移除 `CLAUDE_CODE_MAX_RETRIES` 的 15 上限。 |443| [`CLAUDE_CODE_RETRY_WATCHDOG`](/docs/zh-CN/env-vars) | 未设置 | 在 CI 作业等无人值守会话中设置为 `1`,以无限期重试 `429` 和 `529` 容量错误,而不是在 `CLAUDE_CODE_MAX_RETRIES` 尝试后失败。当标准速度请求获得报告支出限制或耗尽使用额度的 `429` 时,Claude Code 立即失败,即使来自 [gateway spend cap](#spend-limit-reached) 的也是如此,该上限按计划重置。在 v2.1.239 之前,看门狗无限期重试这些。对于快速模式请求,请参阅 [Handle rate limits](/docs/zh-CN/fast-mode#handle-rate-limits)。在 v2.1.199 或更高版本上,它还为其他瞬时错误(例如服务器错误、超时和断开连接)提高默认重试计数至 300,大约三小时的退避,如果您明确设置该变量,则移除 `CLAUDE_CODE_MAX_RETRIES` 的 15 上限。 |

444| [`CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS`](/docs/zh-CN/env-vars) | 未设置 | 设置 `CLAUDE_CODE_RETRY_WATCHDOG` 时,每个 API 请求在等待 `429` 和 `529` 错误上所花费的最长时间(毫秒)。未设置时,等待时间没有限制。需要 Claude Code v2.1.295 或更高版本。 |

442| [`CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`](/docs/zh-CN/env-vars) | 500 | 当 API 以 `529` 过载错误拒绝请求时,该请求各次重试之间退避的起始延迟(毫秒)。当 API 容量已满时,可将其提高(最高 32000),以便在更长的时间窗口内分散重试。当 `CLAUDE_CODE_RETRY_WATCHDOG` 设置为 `1`,或被拒绝的请求是在[快速模式](/docs/zh-CN/fast-mode#handle-rate-limits)下发送时,此变量无效。需要 Claude Code v2.1.292 或更高版本。 |445| [`CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS`](/docs/zh-CN/env-vars) | 500 | 当 API 以 `529` 过载错误拒绝请求时,该请求各次重试之间退避的起始延迟(毫秒)。当 API 容量已满时,可将其提高(最高 32000),以便在更长的时间窗口内分散重试。当 `CLAUDE_CODE_RETRY_WATCHDOG` 设置为 `1`,或被拒绝的请求是在[快速模式](/docs/zh-CN/fast-mode#handle-rate-limits)下发送时,此变量无效。需要 Claude Code v2.1.292 或更高版本。 |

443| [`API_TIMEOUT_MS`](/docs/zh-CN/env-vars) | 600000 | 每个请求的超时(毫秒)。为慢速网络或代理提高它。它还限制 Claude Code 等待响应头的时间,在 [No response from API](#no-response-from-api) 中描述。 |446| [`API_TIMEOUT_MS`](/docs/zh-CN/env-vars) | 600000 | 每个请求的超时(毫秒)。为慢速网络或代理提高它。它还限制 Claude Code 等待响应头的时间,在 [No response from API](#no-response-from-api) 中描述。 |

444| [`CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`](/docs/zh-CN/env-vars) | 未设置 | 超时的[非流式请求](#streaming-response-ended-before-any-complete-data-was-received)的重新发送次数限制。达到该限制时,请求失败。生成时间超过超时时间的 Claude 响应在每次重新发送时都会再次超时,因此请设置较低的数值(例如 `0`)以更快地失败。在本地会话中,每次非流式尝试在 300 秒后超时;当您为 `API_TIMEOUT_MS` 设置正值时,则在该值指定的时间后超时。需要 Claude Code v2.1.285 或更高版本。 |447| [`CLAUDE_CODE_NONSTREAMING_TIMEOUT_RETRIES`](/docs/zh-CN/env-vars) | 未设置 | 超时的[非流式请求](#streaming-response-ended-before-any-complete-data-was-received)的重新发送次数限制。达到该限制时,请求失败。生成时间超过超时时间的 Claude 响应在每次重新发送时都会再次超时,因此请设置较低的数值(例如 `0`)以更快地失败。在本地会话中,每次非流式尝试在 300 秒后超时;当您为 `API_TIMEOUT_MS` 设置正值时,则在该值指定的时间后超时。需要 Claude Code v2.1.285 或更高版本。 |


3412 3415 

3413对于任何[注入动态上下文](/docs/zh-CN/skills#when-an-injected-command-fails)的 skill,Claude Code 都会显示相同的错误,注入的命令失败会中止该 skill 的调用。还有两条相关字符串会在命令运行之前就触发:3416对于任何[注入动态上下文](/docs/zh-CN/skills#when-an-injected-command-fails)的 skill,Claude Code 都会显示相同的错误,注入的命令失败会中止该 skill 的调用。还有两条相关字符串会在命令运行之前就触发:

3414 3417 

3415* `Shell command permission check failed for pattern "..."`:该命令的权限检查未允许它运行。[注入命令的权限检查](/docs/zh-CN/skills#permission-checks-on-injected-commands)介绍了在每种权限模式下哪些结果会导致中止,以及如何使用 `allowed-tools` 预先批准命令3418* `Shell command permission check failed for pattern "..."`:该命令的权限检查未允许它运行。[注入命令的权限检查](/docs/zh-CN/skills#permission-checks-on-injected-commands)介绍了在各权限模式下哪些结果会导致中止,以及如何使用 `allowed-tools` 预先批准命令

3416* ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found``:该 skill 的 frontmatter 要求使用 bash,但机器上没有 bash。请安装 Git for Windows,或将 frontmatter 改为 `shell: powershell`。请参阅[注入命令的运行方式](/docs/zh-CN/skills#how-injected-commands-run)3419* ``Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found``:该 skill 的 frontmatter 要求在没有 bash 的机器上使用 bash。请安装 Git for Windows,或将 frontmatter 改为 `shell: powershell`。请参阅[注入命令的运行方式](/docs/zh-CN/skills#how-injected-commands-run)

3417 3420 

3418**解决方法:**3421**解决方法:**

3419 3422 


3562 3565 

3563* **您没有传入基础分支**:Claude Code 与仓库的默认分支进行了比较,并建议您显式传入基础分支,如上例所示3566* **您没有传入基础分支**:Claude Code 与仓库的默认分支进行了比较,并建议您显式传入基础分支,如上例所示

3564* **您传入的基础分支已存在于您的克隆中**:提示为 ``Make sure <branch> exists locally or on origin (try `git fetch origin <branch>`)``3567* **您传入的基础分支已存在于您的克隆中**:提示为 ``Make sure <branch> exists locally or on origin (try `git fetch origin <branch>`)``

3565* **您传入的基础分支不在您的克隆中**:Claude Code 在比较前已从 origin fetch 了该分支。提示为 ``<branch> was fetched from origin but shares no history with HEAD. If another branch is your real base, pass it explicitly (`/code-review ultra <branch>`)``;当 Claude Code 无法判断您的克隆是否为浅克隆时,它会改为建议 `git fetch --unshallow origin`。在 v2.1.221 之前,对于每个被 fetch 的基础分支,提示都会建议 `git fetch --unshallow origin`,而在完整克隆上,该命令会以 `fatal: --unshallow on a complete repository does not make sense` 失败。3568* **您传入的基础分支不在您的克隆中**:Claude Code 在比较之前从 origin fetch 了该分支。提示内容为 ``<branch> was fetched from origin but shares no history with HEAD. If another branch is your real base, pass it explicitly (`/code-review ultra <branch>`)``;当 Claude Code 无法判断您的克隆是否为浅克隆时,它会改为建议 `git fetch --unshallow origin`。在 v2.1.221 之前,对于每个 fetch 过来的基础分支,提示都会建议 `git fetch --unshallow origin`,而在完整克隆上该命令会以 `fatal: --unshallow on a complete repository does not make sense` 失败。

3566 3569 

3567**解决方法:**3570**解决方法:**

3568 3571 


3816 3819 

3817* 在不带这些限制启动的会话中运行 `/tui fullscreen`,或运行 `/tui default` 切换回来。Claude Code 会在那里保存 [`tui` 设置](/docs/zh-CN/settings-reference#tui)3820* 在不带这些限制启动的会话中运行 `/tui fullscreen`,或运行 `/tui default` 切换回来。Claude Code 会在那里保存 [`tui` 设置](/docs/zh-CN/settings-reference#tui)

3818 3821 

3822<h3 id="claude-code-couldnt-restart">

3823 Claude Code couldn't restart

3824</h3>

3825 

3826Claude Code 正在重启,例如在您运行 [`/tui`](/docs/zh-CN/fullscreen#enable-fullscreen-rendering) 后切换到全屏渲染或从全屏渲染切换回来。它关闭了会话,但无法启动新进程,因此打印了以下消息并以状态 1 退出:

3827 

3828```text theme={null}

3829Claude Code couldn't restart. Your conversation is saved. Start Claude Code again and run /resume to pick it up.

3830```

3831 

3832当重启时没有可重新打开的对话,例如 `/tui` 是您在新会话中的第一个输入时,消息为 `Claude Code couldn't restart. Start Claude Code again.`

3833 

3834**解决方法:**

3835 

3836* 在 shell 中从同一目录再次运行 `claude`。如果消息表示您的对话已保存,请在新会话中运行 [`/resume`](/docs/zh-CN/sessions#resume-a-session) 并选择该对话

3837* 如果重启持续失败,请在 shell 中使用 [`claude --debug-file claude-debug.log`](/docs/zh-CN/cli-reference#cli-flags) 启动 Claude Code。如果从该会话重启失败,您启动时所在目录中的 `claude-debug.log` 会记录一行包含操作系统错误的 `Failed to relaunch:`。[报告问题](#report-an-error)时请附上该行

3838 

3819<h3 id="couldnt-open-claude-desktop">3839<h3 id="couldnt-open-claude-desktop">

3820 无法打开 Claude Desktop3840 无法打开 Claude Desktop

3821</h3>3841</h3>


4752 命令被 worktree 隔离检查阻止4772 命令被 worktree 隔离检查阻止

4753</h3>4773</h3>

4754 4774 

4755Claude 在[在 worktree 中隔离的会话](/docs/zh-CN/worktrees#how-claude-code-enforces-isolation)中运行了 Bash 或 Monitor 命令,Claude Code 因以下两个原因之一拒绝了它:4775Claude 在[在 worktree 中隔离的会话](/docs/zh-CN/worktrees#how-claude-code-enforces-isolation)中运行了 Bash、[PowerShell](/docs/zh-CN/tools-reference#powershell-tool) 或 [Monitor](/docs/zh-CN/tools-reference#monitor-tool) 命令,Claude Code 因以下原因之一拒绝了它:

4756 4776 

4757* 该命令将 git 指向主检出。4777* 该命令将在主检出或另一个 worktree 中运行。消息会说明其工作目录 `resolved to the shared checkout` 或 `is in a different worktree`。

4758* Claude Code 无法从命令文本验证该命令运行的任何 git 都保留在 worktree 内。从不命名 git 的命令仍然可能因此原因被拒绝,因为展开变量间接寻址(如 `${!name}`)或运行 Bash 函数替换(如 `${ command; }`)会产生在运行时本身可能是命令的值。4778* Bash 或 Monitor 命令将 git 指向主检出。

4779* Claude Code 无法从 Bash 或 Monitor 命令的文本验证该命令运行的任何 git 都保留在 worktree 内。从不命名 git 的命令仍然可能因此原因被拒绝,因为展开变量间接寻址(如 `${!name}`)或运行 Bash 函数替换(如 `${ command; }`)会产生在运行时本身可能是命令的值。

4759 4780 

4760消息的中间命名无法验证的内容:4781消息会说 `is isolated in the worktree <path>, but this command`,后跟原因,例如 Claude Code 无法验证其文本的命令:

4761 4782 

4762```text wrap theme={null}4783```text wrap theme={null}

4763This session is isolated in the worktree /path/to/worktree, but this command evaluates ${!x@P} arithmetically inside a construct too complex to verify, which can run a command hidden in a variable's value. Refusing to run it — a worktree-isolated session's git operations must target its own worktree. Split it into plain, separate commands and run them from /path/to/worktree.4784This session is isolated in the worktree /path/to/worktree, but this command evaluates ${!x@P} arithmetically inside a construct too complex to verify, which can run a command hidden in a variable's value. Refusing to run it — a worktree-isolated session's git operations must target its own worktree. Split it into plain, separate commands and run them from /path/to/worktree.


4765 4786 

4766**要做什么:**4787**要做什么:**

4767 4788 

4768* 通常什么都不做:Claude 读取消息并按照其最后一句要求的方式重写命令4789* **git 指向主检出,或命令文本无法验证**:什么都不用做。Claude 读取消息并按照其最后一句要求的方式重写命令。如果您要求的命令因其文本中的展开而持续被拒绝,请按字面拼写被标记的值,并从 worktree 内将 git 作为独立的纯命令运行

4769* 如果您要求的命令继续被拒绝,按字面拼写标记的值:用其值替换间接寻址或替换,并从 worktree 内作为其自己的纯命令运行 git

4770* 要有意对主检出采取行动,在会话外的终端中自己运行该命令4790* 要有意对主检出采取行动,在会话外的终端中自己运行该命令

4771 4791 

4772<h3 id="this-session-has-no-saved-transcript">4792<h3 id="this-session-has-no-saved-transcript">


4946* 或使用 `--agent <name>` 恢复,命名确实存在的 Agent,以改为作为该 Agent 运行会话4966* 或使用 `--agent <name>` 恢复,命名确实存在的 Agent,以改为作为该 Agent 运行会话

4947* 如果 Agent 是项目范围的,您还没有信任会话的原始目录,在那里运行一次 Claude Code,接受信任对话框,然后再次恢复4967* 如果 Agent 是项目范围的,您还没有信任会话的原始目录,在那里运行一次 Claude Code,接受信任对话框,然后再次恢复

4948 4968 

4969<h3 id="restarted-after-its-next-loop-wakeup-was-due">

4970 此会话在其下一次 /loop 唤醒到期后才重启

4971</h3>

4972 

4973[后台会话](/docs/zh-CN/agent-view)中的[自定节奏 `/loop`](/docs/zh-CN/scheduled-tasks#let-claude-choose-the-interval) 已停止。会话的进程在循环等待下一次唤醒时结束,而该唤醒在会话的[下一个进程](/docs/zh-CN/agent-view#the-supervisor-process)启动之前就已到期。错过的唤醒不会延迟触发。通知会说明会话重启时该唤醒已逾期多久:

4974 

4975```text theme={null}

4976This session restarted 12m after its next /loop wakeup was due, so that wakeup will not fire. The loop stays stopped until Claude schedules it again: reply to continue it.

4977```

4978 

4979在 v2.1.295 之前,循环在这种情况下会停止且不显示通知。

4980 

4981**要做什么:**

4982 

4983* 要继续循环,请[回复该会话](/docs/zh-CN/agent-view#peek-and-reply)并说明这一点,例如 `keep the loop running`。Claude 会连同您的回复一起读取通知,并可以安排下一次唤醒

4984* 如果您已不再需要该循环,则无需任何操作。它已经停止

4985 

4949<h3 id="claude_code_process_wrapper-launcher-errors">4986<h3 id="claude_code_process_wrapper-launcher-errors">

4950 CLAUDE\_CODE\_PROCESS\_WRAPPER 启动器错误4987 CLAUDE\_CODE\_PROCESS\_WRAPPER 启动器错误

4951</h3>4988</h3>

headless.md +43 −41

Details

89* **[Monitor](/docs/zh-CN/tools-reference#monitor-tool) 监视**:运行会等待,直到监视超时或 10 分钟上限结束等待,以先发生者为准。在等待期间,Claude 会继续响应监视报告的内容。默认情况下,监视在 Claude 启动后五分钟超时。89* **[Monitor](/docs/zh-CN/tools-reference#monitor-tool) 监视**:运行会等待,直到监视超时或 10 分钟上限结束等待,以先发生者为准。在等待期间,Claude 会继续响应监视报告的内容。默认情况下,监视在 Claude 启动后五分钟超时。

90* **待处理的唤醒**:在以文本形式而非通过 `--input-format stream-json` 传递提示词的运行中,如果 Claude 已安排 [自定节奏的 `/loop` 唤醒](/docs/zh-CN/scheduled-tasks#let-claude-choose-the-interval),运行会等待每次唤醒触发并执行其迭代,直到 [循环结束](/docs/zh-CN/scheduled-tasks#stop-a-loop),即使超过 10 分钟上限也是如此。90* **待处理的唤醒**:在以文本形式而非通过 `--input-format stream-json` 传递提示词的运行中,如果 Claude 已安排 [自定节奏的 `/loop` 唤醒](/docs/zh-CN/scheduled-tasks#let-claude-choose-the-interval),运行会等待每次唤醒触发并执行其迭代,直到 [循环结束](/docs/zh-CN/scheduled-tasks#stop-a-loop),即使超过 10 分钟上限也是如此。

91 91 

92当 stderr 是终端且运行已等待五秒时,Claude Code 会向 stderr 打印一行以 `Waiting for background work to finish` 开头的内容,并列出正在等待的工作。使用 [`json` 或 `stream-json` 输出](#get-structured-output) 时,该行仅在 stdout 不是终端时才会打印,因此您的脚本读取的 JSON 中永远不会包含它。

93 

92如果运行达到其 [`--max-budget-usd`](/docs/zh-CN/cli-reference#cli-flags) 上限,Claude Code 会停止剩余的后台工作,而不是继续等待。94如果运行达到其 [`--max-budget-usd`](/docs/zh-CN/cli-reference#cli-flags) 上限,Claude Code 会停止剩余的后台工作,而不是继续等待。

93 95 

94当后台工作启动新的轮次时,使用默认的 `text` 输出时运行会打印每一轮的结果,使用 `json` 输出时则打印最后一轮的结果。在 v2.1.295 之前,使用 `text` 输出时运行也只打印最后一轮的结果。96当后台工作启动新的轮次时,使用默认的 `text` 输出时运行会打印每一轮的结果,使用 `json` 输出时则打印最后一轮的结果。在 v2.1.295 之前,使用 `text` 输出时运行也只打印最后一轮的结果。


116 示例118 示例

117</h2>119</h2>

118 120 

119这些示例突出了常见的 CLI 模式。对于命名文件(如 `auth.py` 或 `build-error.txt`)的命令,请替换来自您自己项目的文件。在 CI 或其他脚本环境中,添加 [`--bare`](#start-faster-with-bare-mode) 以便 Claude Code 启动时不加载主机的 hooks、plugins、auto memory 或 `CLAUDE.md`。121这些示例突出了常见的 CLI 模式。对于命名文件(如 `auth.py` 或 `build-error.txt`)的命令,请替换为您自己项目中的文件。在 CI 或其他脚本环境中,添加 [`--bare`](#start-faster-with-bare-mode),以便 Claude Code 启动时不加载主机的 hook、插件、自动记忆或 `CLAUDE.md`。

120 122 

121<h3 id="pipe-data-through-claude">123<h3 id="pipe-data-through-claude">

122 通过 Claude 管道传输数据124 通过 Claude 管道传输数据


130cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt132cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt

131```133```

132 134 

133使用 `--output-format json`,响应有效负载包括 `total_cost_usd` 和按模型的成本分解,因此脚本调用者可以跟踪支出而无需查询 [使用情况仪表板](/docs/zh-CN/costs)。当您使用 `--continue` 或 `--resume` 继续较早的对话时,运行报告对话的整体总计,[包括较早运行的支出](/docs/zh-CN/agent-sdk/cost-tracking#accumulate-costs-across-multiple-calls)。两个数字都是 [客户端估计](/docs/zh-CN/agent-sdk/cost-tracking),可能与您的实际账单不同。135使用 `--output-format json` 时,响应的 JSON 数据包括 `total_cost_usd` 和按模型的成本分解,因此脚本调用者可以跟踪支出而无需查询 [使用情况仪表板](/docs/zh-CN/costs)。当您使用 `--continue` 或 `--resume` 继续较早的对话时,运行报告对话的整体总计,[包括较早运行的支出](/docs/zh-CN/agent-sdk/cost-tracking#accumulate-costs-across-multiple-calls)。两个数字都是 [客户端估计](/docs/zh-CN/agent-sdk/cost-tracking),可能与您的实际账单不同。

134 136 

135<Note>137<Note>

136 管道 stdin 的上限为 10MB。如果超过上限,Claude Code 会以清晰的错误和非零状态退出。要处理更大的输入,请将内容写入文件并在提示中引用文件路径,而不是管道传输它。138 管道 stdin 的上限为 10MB。如果超过上限,Claude Code 会以清晰的错误和非零状态退出。要处理更大的输入,请将内容写入文件并在提示词中引用文件路径,而不是管道传输它。

137</Note>139</Note>

138 140 

139如果 Claude Code 无法读取 stdin,例如因为启动它的进程断开了其端点,Claude Code 会向 stderr 打印警告并继续使用命令行中的提示。在 v2.1.211 之前,Windows 上不可读的 stdin 会导致会话崩溃或无输出地静默退出。141如果 Claude Code 无法读取 stdin,例如因为启动它的进程断开了其端点,Claude Code 会向 stderr 打印警告并继续使用命令行中的提示词。在 v2.1.211 之前,Windows 上不可读的 stdin 会导致会话崩溃或无输出地静默退出。

140 142 

141<h3 id="add-claude-to-a-build-script">143<h3 id="add-claude-to-a-build-script">

142 将 Claude 添加到构建脚本144 将 Claude 添加到构建脚本


172claude -p "Summarize this project" --output-format json174claude -p "Summarize this project" --output-format json

173```175```

174 176 

175要获得符合特定架构的输出,请使用 `--output-format json` 与 `--json-schema` 和 [JSON Schema](https://json-schema.org/) 定义。响应包括关于请求的元数据(会话 ID、使用情况等),结构化输出在 `structured_output` 字段中。177要获得符合特定 schema 的输出,请使用 `--output-format json` 与 `--json-schema` 和 [JSON Schema](https://json-schema.org/) 定义。响应包括关于请求的元数据(会话 ID、使用情况等),结构化输出在 `structured_output` 字段中。

176 178 

177此示例从 auth.py 中提取函数名称并将其作为字符串数组返回:179此示例从 auth.py 中提取函数名称并将其作为字符串数组返回:

178 180 


182 --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'184 --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'

183```185```

184 186 

185如果该值不是有效的 JSON Schema,`claude` 会以 `Error: --json-schema is not a valid JSON Schema` 退出,后跟验证器的诊断。Claude Code 接受使用 `format` 关键字的架构,例如 `"format": "email"`,但将 `format` 视为注释,不强制执行它。在 v2.1.205 之前,Claude Code 会静默忽略无效的架构并返回非结构化文本,并将任何包含 `format` 的架构视为无效。187如果该值不是有效的 JSON Schema,`claude` 会以 `Error: --json-schema is not a valid JSON Schema` 退出,后跟验证器的诊断。Claude Code 接受使用 `format` 关键字的 schema,例如 `"format": "email"`,但将 `format` 视为注释,不强制执行它。在 v2.1.205 之前,Claude Code 会静默忽略无效的 schema 并返回非结构化文本,并将任何包含 `format` 的 schema 视为无效。

186 188 

187<Tip>189<Tip>

188 使用 [jq](https://jqlang.org/) 之类的工具来解析响应并提取特定字段:190 使用 [jq](https://jqlang.org/) 之类的工具来解析响应并提取特定字段:


203 流式传输响应205 流式传输响应

204</h3>206</h3>

205 207 

206使用 `--output-format stream-json` 与 `--verbose` 和 `--include-partial-messages` 来接收生成的令牌。每一行都是代表一个事件的 JSON 对象:208使用 `--output-format stream-json` 与 `--verbose` 和 `--include-partial-messages` 来接收生成的 token。每一行都是代表一个事件的 JSON 对象:

207 209 

208```bash theme={null}210```bash theme={null}

209claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages211claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages


223对于具有回调和消息对象的编程流式传输,请参阅 Agent SDK 文档中的 [实时流式传输响应](/docs/zh-CN/agent-sdk/streaming-output)。225对于具有回调和消息对象的编程流式传输,请参阅 Agent SDK 文档中的 [实时流式传输响应](/docs/zh-CN/agent-sdk/streaming-output)。

224 226 

225<h4 id="follow-subagent-messages">227<h4 id="follow-subagent-messages">

226 跟踪 subagent 消息228 跟踪子代理消息

227</h4>229</h4>

228 230 

229来自[子代理](/docs/zh-CN/sub-agents)以及[在子代理中运行](/docs/zh-CN/skills#run-skills-in-a-subagent)的 skill 的消息在流中显示为 `assistant` 和 `user` 消息。其 `parent_tool_use_id` 字段表明每条消息属于哪次运行。来自主对话的消息在该字段中为 `null`。231来自[子代理](/docs/zh-CN/sub-agents)以及[在子代理中运行](/docs/zh-CN/skills#run-skills-in-a-subagent)的 skill 的消息在流中显示为 `assistant` 和 `user` 消息。其 `parent_tool_use_id` 字段表明每条消息属于哪次运行。来自主对话的消息在该字段中为 `null`。


257 处理 API 重试259 处理 API 重试

258</h4>260</h4>

259 261 

260当 API 请求因可重试错误而失败时,Claude Code 在重试前发出 `system/api_retry` 事件。在 v2.1.246 或更高版本上,当 `401` 或 `403` 拒绝 [`apiKeyHelper`](/docs/zh-CN/settings-reference#apikeyhelper) 凭证时,Claude Code 会静默进行前两次重试,没有事件,然后从第三次连续重试开始照常发出事件。静默重试仍然计入 `attempt`。您可以使用该事件在您自己的界面中显示重试进度。262当 API 请求因可重试错误而失败时,Claude Code 在重试前发出 `system/api_retry` 事件。在 v2.1.246 或更高版本上,当 `401` 或 `403` 拒绝 [`apiKeyHelper`](/docs/zh-CN/settings-reference#apikeyhelper) 凭据时,Claude Code 会静默进行前两次重试,没有事件,然后从第三次连续重试开始照常发出事件。静默重试仍然计入 `attempt`。您可以使用该事件在您自己的界面中显示重试进度。

261 263 

262| 字段 | 类型 | 描述 |264| 字段 | 类型 | 描述 |

263| - | - | - |265| - | - | - |


265| `subtype` | `"api_retry"` | 将其标识为重试事件 |267| `subtype` | `"api_retry"` | 将其标识为重试事件 |

266| `attempt` | 整数 | 当前尝试次数,从 1 开始 |268| `attempt` | 整数 | 当前尝试次数,从 1 开始 |

267| `max_retries` | 整数 | 针对此失败原因允许的总重试次数 |269| `max_retries` | 整数 | 针对此失败原因允许的总重试次数 |

268| `retry_delay_ms` | 整数 | 毫秒直到下一次尝试 |270| `retry_delay_ms` | 整数 | 距下一次尝试的毫秒数 |

269| `error_status` | 整数或 null | 失败尝试的 HTTP 状态代码,或 `null` 当尝试从 API 没有获得 HTTP 响应时 |271| `error_status` | 整数或 null | 失败尝试的 HTTP 状态代码,当尝试未从 API 获得 HTTP 响应时为 `null` |

270| `no_response` | 对象,可选 | 仅当失败的尝试 [未及时获得响应头](/docs/zh-CN/errors#no-response-from-api) 时存在。`waited_ms` 是该尝试等待的时间,`retry_wait_ms` 是重试将等待的时间。需要 Claude Code v2.1.261 或更高版本 |272| `no_response` | 对象,可选 | 仅当失败的尝试 [未及时获得响应头](/docs/zh-CN/errors#no-response-from-api) 时存在。`waited_ms` 是该尝试等待的时间,`retry_wait_ms` 是重试将等待的时间。需要 Claude Code v2.1.261 或更高版本 |

271| `error` | 字符串 | 错误类别:`authentication_failed`、`oauth_org_not_allowed`、`account_on_hold`、`billing_error`、`rate_limit`、`overloaded`、`invalid_request`、`model_not_found`、`server_error`、`max_output_tokens`、`cloud_credential_error` 或 `unknown` |273| `error` | 字符串 | 错误类别:`authentication_failed`、`oauth_org_not_allowed`、`account_on_hold`、`billing_error`、`rate_limit`、`overloaded`、`invalid_request`、`model_not_found`、`server_error`、`max_output_tokens`、`cloud_credential_error` 或 `unknown` |

272| `uuid` | 字符串 | 唯一事件标识符 |274| `uuid` | 字符串 | 唯一事件标识符 |


276 读取会话元数据278 读取会话元数据

277</h4>279</h4>

278 280 

279`system/init` 事件报告会话元数据,包括模型、工具、MCP 服务器和加载的 plugins。它是流中的第一个事件,除非启动事件在其之前:281`system/init` 事件报告会话元数据,包括模型、工具、MCP 服务器和加载的插件。它是流中的第一个事件,除非启动事件在其之前:

280 282 

281* `plugin_install` 事件,当设置了 [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/zh-CN/env-vars) 时。283* `plugin_install` 事件,当设置了 [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/zh-CN/env-vars) 时。

282* [`hook_started`、`hook_progress` 和 `hook_response` 事件](/docs/zh-CN/agent-sdk/typescript#sdkhookstartedmessage),当配置的 [`SessionStart`](/docs/zh-CN/hooks#sessionstart) 或 [`Setup`](/docs/zh-CN/hooks#setup) hook 运行时。这些事件在 hook 生成时流式传输。Claude Code v2.1.169 至 v2.1.203 在 hook 完成后以一个批次传递它们,仍然在 `system/init` 之前;v2.1.204 恢复了实时传递。284* [`hook_started`、`hook_progress` 和 `hook_response` 事件](/docs/zh-CN/agent-sdk/typescript#sdkhookstartedmessage),当配置的 [`SessionStart`](/docs/zh-CN/hooks#sessionstart) 或 [`Setup`](/docs/zh-CN/hooks#setup) hook 运行时。这些事件在 hook 生成时流式传输。Claude Code v2.1.169 至 v2.1.203 在 hook 完成后以一个批次传递它们,仍然在 `system/init` 之前;v2.1.204 恢复了实时传递。


284该事件还携带一个可选的 `capabilities` 字符串数组,命名此 Claude Code 版本实现的协议行为,例如 `interrupt_receipt_v1` 或 `interrupt_cancel_queued_v1`。检查它以进行功能检测,而不是比较版本字符串,并忽略您不认识的值。该字段需要 Claude Code v2.1.205 或更高版本,在早期版本中不存在。有关功能列表,请参阅 [`SDKSystemMessage`](/docs/zh-CN/agent-sdk/typescript#sdksystemmessage)。286该事件还携带一个可选的 `capabilities` 字符串数组,命名此 Claude Code 版本实现的协议行为,例如 `interrupt_receipt_v1` 或 `interrupt_cancel_queued_v1`。检查它以进行功能检测,而不是比较版本字符串,并忽略您不认识的值。该字段需要 Claude Code v2.1.205 或更高版本,在早期版本中不存在。有关功能列表,请参阅 [`SDKSystemMessage`](/docs/zh-CN/agent-sdk/typescript#sdksystemmessage)。

285 287 

286<h4 id="fail-ci-when-a-plugin-or-mcp-server-doesn’t-load">288<h4 id="fail-ci-when-a-plugin-or-mcp-server-doesn’t-load">

287 当 plugin 或 MCP 服务器未加载时使 CI 失败289 当插件或 MCP 服务器未加载时使 CI 失败

288</h4>290</h4>

289 291 

290使用 `system/init` 事件中的 plugin 字段来捕获未加载的 plugin:292使用 `system/init` 事件中的插件字段来捕获未加载的插件:

291 293 

292| 字段 | 类型 | 描述 |294| 字段 | 类型 | 描述 |

293| - | - | - |295| - | - | - |

294| `plugins` | 数组 | 成功加载的 plugins,每个都有 `name` 和 `path` |296| `plugins` | 数组 | 成功加载的插件,每个都有 `name` 和 `path` |

295| `plugin_errors` | 数组 | plugin 加载时错误,每个都有 `plugin`、`type` 和 `message`。包括不满足的依赖版本和 `--plugin-dir` 加载失败,例如缺失路径或无效存档。未加载的 plugin 从 `plugins` 中缺失。当没有错误时,该键被省略 |297| `plugin_errors` | 数组 | 插件加载时错误,每个都有 `plugin`、`type` 和 `message`。包括不满足的依赖版本和 `--plugin-dir` 加载失败,例如缺失路径或无效存档。未加载的插件不会出现在 `plugins` 中。当没有错误时,该键被省略 |

296 298 

297当 `--plugin-dir` 目录或存档本身加载失败时,其 `plugin_errors` 条目包括解析的绝对路径作为 `path`。使用它来判断哪个 `--plugin-dir` 值失败。`path` 字段需要 Claude Code v2.1.283 或更高版本。299当 `--plugin-dir` 目录或存档本身加载失败时,其 `plugin_errors` 条目包括解析的绝对路径作为 `path`。使用它来判断哪个 `--plugin-dir` 值失败。`path` 字段需要 Claude Code v2.1.283 或更高版本。

298 300 

299以相同的方式使用 MCP 服务器字段。当您使用 `-p` 传递 [`--mcp-config`](/docs/zh-CN/cli-reference#cli-flags) 时,Claude Code 在运行第一轮之前等待仍然待处理的服务器,最多等待 [`MCP_TIMEOUT`](/docs/zh-CN/env-vars) 启动超时,默认为 30 秒。具有 [缓存工具列表](/docs/zh-CN/agent-sdk/mcp#connection-timing) 的远程服务器跳过等待,在 `system/init` 中显示 `pending`,并在其第一次工具调用时连接。等待需要 Claude Code v2.1.221 或更高版本。301以相同的方式使用 MCP 服务器字段。当您使用 `-p` 传递 [`--mcp-config`](/docs/zh-CN/cli-reference#cli-flags) 时,Claude Code 在运行第一轮之前等待仍然待处理的服务器,最多等待 [`MCP_TIMEOUT`](/docs/zh-CN/env-vars) 启动超时时间,默认为 30 秒。具有 [缓存工具列表](/docs/zh-CN/agent-sdk/mcp#connection-timing) 的远程服务器跳过等待,在 `system/init` 中显示 `pending`,并在其第一次工具调用时连接。在 [自托管环境](/docs/zh-CN/self-hosted-environments-configuration#connection-timing) 中,改为适用较短的等待时间。等待需要 Claude Code v2.1.221 或更高版本。

300 302 

301Claude Code 在启动时验证每个 `--mcp-config` 条目并跳过验证失败的条目,例如没有 `type` 的 `url` 条目。运行继续并干净地退出,因此检查这些字段以捕获从未加载的服务器:303Claude Code 在启动时验证每个 `--mcp-config` 条目并跳过验证失败的条目,例如没有 `type` 的 `url` 条目。运行继续并干净地退出,因此检查这些字段以捕获从未加载的服务器:

302 304 

303| 字段 | 类型 | 描述 |305| 字段 | 类型 | 描述 |

304| - | - | - |306| - | - | - |

305| `mcp_servers` | 数组 | 会话中的 MCP 服务器,每个都有 `name` 和 `status` |307| `mcp_servers` | 数组 | 会话中的 MCP 服务器,每个都有 `name` 和 `status` |

306| `mcp_server_errors` | 数组 | `--mcp-config` 条目被配置验证跳过,每个都有 `name`、`type` 和 `message`。`type` 是跳过类别,例如 `unknown_type`、`url_missing_type`、`invalid_config` 或 `reserved_name`;将您不认识的值视为通用跳过。受影响的服务器从 `mcp_servers` 中缺失。当没有错误时,该键被省略,因此 CI 门可以在非空数组上失败。需要 Claude Code v2.1.219 或更高版本 |308| `mcp_server_errors` | 数组 | 被配置验证跳过的 `--mcp-config` 条目,每个都有 `name`、`type` 和 `message`。`type` 是跳过类别,例如 `unknown_type`、`url_missing_type`、`invalid_config` 或 `reserved_name`;将您不认识的值视为通用跳过。受影响的服务器不会出现在 `mcp_servers` 中。当没有错误时,该键被省略,因此 CI 门可以在数组非空时失败。需要 Claude Code v2.1.219 或更高版本 |

307 309 

308当您在终端中手动运行命令时,Claude Code 也会向 stderr 打印启动警告,例如 `Warning: 1 MCP server skipped due to invalid config:`,后跟每个跳过条目的原因。当您重定向 stderr 或当 CI 运行器或 SDK 主机等程序捕获它时,Claude Code 不打印警告,仅在 `mcp_server_errors` 字段中报告跳过的条目。警告需要 Claude Code v2.1.219 或更高版本。310当您在终端中手动运行命令时,Claude Code 也会向 stderr 打印启动警告,例如 `Warning: 1 MCP server skipped due to invalid config:`,后跟每个跳过条目的原因。当您重定向 stderr 或当 CI 运行器或 SDK 主机等程序捕获它时,Claude Code 不打印警告,仅在 `mcp_server_errors` 字段中报告跳过的条目。警告需要 Claude Code v2.1.219 或更高版本。

309 311 

310<h4 id="track-plugin-installs">312<h4 id="track-plugin-installs">

311 跟踪 plugin 安装313 跟踪插件安装

312</h4>314</h4>

313 315 

314当设置了 [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/zh-CN/env-vars) 时,Claude Code 在第一轮之前安装市场 plugins 时发出 `system/plugin_install` 事件。使用这些在您自己的 UI 中显示安装进度。316当设置了 [`CLAUDE_CODE_SYNC_PLUGIN_INSTALL`](/docs/zh-CN/env-vars) 时,Claude Code 在第一轮之前安装市场插件时发出 `system/plugin_install` 事件。使用这些事件在您自己的 UI 中显示安装进度。

315 317 

316| 字段 | 类型 | 描述 |318| 字段 | 类型 | 描述 |

317| - | - | - |319| - | - | - |

318| `type` | `"system"` | 消息类型 |320| `type` | `"system"` | 消息类型 |

319| `subtype` | `"plugin_install"` | 将其标识为 plugin 安装事件 |321| `subtype` | `"plugin_install"` | 将其标识为插件安装事件 |

320| `status` | `"started"`、`"installed"`、`"failed"` 或 `"completed"` | `started` 和 `completed` 括住整体安装;`installed` 和 `failed` 报告单个市场 |322| `status` | `"started"`、`"installed"`、`"failed"` 或 `"completed"` | `started` 和 `completed` 标记整体安装的开始和结束;`installed` 和 `failed` 报告单个市场 |

321| `name` | 字符串,可选 | 市场名称,在 `installed` 和 `failed` 上存在 |323| `name` | 字符串,可选 | 市场名称,在 `installed` 和 `failed` 上存在 |

322| `error` | 字符串,可选 | 失败消息,在 `failed` 上存在 |324| `error` | 字符串,可选 | 失败消息,在 `failed` 上存在 |

323| `uuid` | 字符串 | 唯一事件标识符 |325| `uuid` | 字符串 | 唯一事件标识符 |


327 自动批准工具329 自动批准工具

328</h3>330</h3>

329 331 

330使用 `--allowedTools` 让 Claude 使用某些工具而无需提示。列出 `Read` 和 `Edit` 让 Claude 读取和编辑文件而无需请求权限。列出 `Bash` 对 shell 命令执行相同操作,除了在 [auto 模式](/docs/zh-CN/permission-modes#how-auto-mode-evaluates-actions) 中启动的运行,其中 Claude Code 删除裸 `Bash` 条目作为广泛允许规则,auto 模式改为评估每个命令。此示例运行测试套件并修复失败,允许这三个工具:332使用 `--allowedTools` 让 Claude 使用某些工具而无需提示。列出 `Read` 和 `Edit` 让 Claude 读取和编辑文件而无需请求权限。列出 `Bash` 对 shell 命令执行相同操作,但在 [自动模式](/docs/zh-CN/permission-modes#how-auto-mode-evaluates-actions) 中启动的运行除外,此时 Claude Code 会将裸 `Bash` 条目作为宽泛的允许规则丢弃,改由自动模式评估每个命令。此示例运行测试套件并修复失败,列出了这三个工具:

331 333 

332```bash theme={null}334```bash theme={null}

333claude -p "Run the test suite and fix any failures" \335claude -p "Run the test suite and fix any failures" \

334 --allowedTools "Bash,Read,Edit"336 --allowedTools "Bash,Read,Edit"

335```337```

336 338 

337要为整个会话设置基线而不是列出单个工具,请传递 [权限模式](/docs/zh-CN/permission-modes)。对于不设置权限模式的运行,采用 [内置启动权限模式](/docs/zh-CN/permission-modes#which-mode-a-session-starts-in),可能是 `auto`,因此传递您想要的权限模式:339要为整个会话设置基线而不是列出单个工具,请传递 [权限模式](/docs/zh-CN/permission-modes)。对于不设置权限模式的运行,采用 [内置启动权限模式](/docs/zh-CN/permission-modes#which-mode-a-session-starts-in),可能是 `auto`,因此请传递您想要的权限模式:

338 340 

339* **`auto`**:传递 `--permission-mode auto` 以让分类器审查大多数操作而不是您341* **`auto`**:传递 `--permission-mode auto` 以让分类器代替您审查大多数操作

340* **`dontAsk`**:Claude Code 拒绝每个原本会提示的调用,这对于锁定的 CI 运行很有用。在 Manual 模式下无需批准的操作仍会运行,例如工作目录中的文件读取和 [只读命令集](/docs/zh-CN/permissions#read-only-commands),您的 `--allowedTools` 条目或 `permissions.allow` 规则涵盖的操作也是如此。`AskUserQuestion`、连接器工具 [您的组织设置为 `ask`](/docs/zh-CN/mcp#organization-controls-on-connector-tools) 和标记为 [`requiresUserInteraction`](/docs/zh-CN/mcp#require-approval-for-a-specific-tool) 的 MCP 工具即使当允许规则匹配时也被拒绝342* **`dontAsk`**:Claude Code 拒绝每个原本会提示的调用,这对于锁定的 CI 运行很有用。在 Manual 模式下无需批准的操作仍会运行,例如工作目录中的文件读取和 [只读命令集](/docs/zh-CN/permissions#read-only-commands),您的 `--allowedTools` 条目或 `permissions.allow` 规则涵盖的操作也是如此。`AskUserQuestion`、[您的组织设置为 `ask`](/docs/zh-CN/mcp#organization-controls-on-connector-tools) 的连接器工具和标记为 [`requiresUserInteraction`](/docs/zh-CN/mcp#require-approval-for-a-specific-tool) 的 MCP 工具即使在允许规则匹配时也会被拒绝

341* **`acceptEdits`**:Claude 写入文件而无需提示,Claude Code 自动批准常见的文件系统命令,例如 `mkdir`、`touch`、`mv` 和 `cp`。[任何模式都不自动批准的操作](/docs/zh-CN/permission-modes#actions-no-mode-auto-approves) 仍然适用。除了只读命令集,其他 shell 命令和网络请求仍然需要 `--allowedTools` 条目或 `permissions.allow` 规则。有关 `acceptEdits` 自动批准的内容,请参阅 [使用 acceptEdits 模式自动批准文件编辑](/docs/zh-CN/permission-modes#auto-approve-file-edits-with-acceptedits-mode)343* **`acceptEdits`**:Claude 写入文件而无需提示,Claude Code 自动批准常见的文件系统命令,例如 `mkdir`、`touch`、`mv` 和 `cp`。[任何模式都不自动批准的操作](/docs/zh-CN/permission-modes#actions-no-mode-auto-approves) 仍然适用。除了只读命令集,其他 shell 命令和网络请求仍然需要 `--allowedTools` 条目或 `permissions.allow` 规则。有关完整列表,请参阅 [`acceptEdits` 自动批准的内容](/docs/zh-CN/permission-modes#auto-approve-file-edits-with-acceptedits-mode)

342 344 

343此示例使用 `acceptEdits` 作为基线应用 lint 修复:345此示例使用 `acceptEdits` 作为基线应用 lint 修复:

344 346 


352 354 

353当没有人可用来回答权限提示时,传递 `--permission-prompts none`,例如在计划的作业中。当您的运行有权限主机时,该标志最重要:具有 [`canUseTool` 回调](/docs/zh-CN/agent-sdk/user-input) 的 Agent SDK 应用,或您使用 [`--permission-prompt-tool`](/docs/zh-CN/cli-reference#cli-flags) 传递的 MCP 工具。没有该标志,您的运行会等待该主机回答每个权限请求。355当没有人可用来回答权限提示时,传递 `--permission-prompts none`,例如在计划的作业中。当您的运行有权限主机时,该标志最重要:具有 [`canUseTool` 回调](/docs/zh-CN/agent-sdk/user-input) 的 Agent SDK 应用,或您使用 [`--permission-prompt-tool`](/docs/zh-CN/cli-reference#cli-flags) 传递的 MCP 工具。没有该标志,您的运行会等待该主机回答每个权限请求。

354 356 

355使用该标志,您的运行不会查询主机或等待它。任何会提示的内容都被拒绝,除非 `PermissionRequest` hook 允许它,Claude 被告知没有人可以批准请求且不要重试它,运行继续。在没有主机的 `-p` 运行中,这些请求无论如何都被拒绝,该标志也告诉 Claude 不要重试它们。权限规则、[`PermissionRequest` hooks](/docs/zh-CN/hooks#permissionrequest) 和您设置的权限模式仍然首先决定每个调用;Claude Code 仅拒绝其他任何内容都不解决的请求。357使用该标志,您的运行不会查询主机或等待它。任何会提示的内容都被拒绝,除非 `PermissionRequest` hook 允许它,Claude 被告知没有人可以批准请求且不要重试它,运行继续。在没有主机的 `-p` 运行中,这些请求无论如何都被拒绝,该标志也告诉 Claude 不要重试它们。权限规则、[`PermissionRequest` hook](/docs/zh-CN/hooks#permissionrequest) 和您设置的权限模式仍然首先决定每个调用;Claude Code 仅拒绝其他任何机制都无法解决的请求。

356 358 

357此示例在 [auto 模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode) 中运行无人值守任务。分类器照常审查每个操作,Claude Code 拒绝任何会回退到提示的内容:359此示例在 [自动模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode) 中运行无人值守任务。分类器照常审查每个操作,Claude Code 拒绝任何会回退到提示的内容:

358 360 

359```bash theme={null}361```bash theme={null}

360claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none362claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none


372 创建提交374 创建提交

373</h3>375</h3>

374 376 

375此示例审查暂存的更改并创建具有适当消息的提交:377此示例审查暂存的更改并创建具有适当提交信息的提交:

376 378 

377```bash theme={null}379```bash theme={null}

378claude -p "Look at my staged changes and create an appropriate commit" \380claude -p "Look at my staged changes and create an appropriate commit" \

379 --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"381 --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"

380```382```

381 383 

382`--allowedTools` 标志使用 [权限规则语法](/docs/zh-CN/settings-reference#permission-rule-syntax)。尾部的 ` *` 启用前缀匹配,因此 `Bash(git diff *)` 允许任何以 `git diff` 开头的命令。空格在 `*` 之前很重要:没有它,`Bash(git diff*)` 也会匹配 `git diff-index`。384`--allowedTools` 标志使用 [权限规则语法](/docs/zh-CN/settings-reference#permission-rule-syntax)。尾部的 ` *` 启用前缀匹配,因此 `Bash(git diff *)` 允许任何以 `git diff` 开头的命令。`*` 之前的空格很重要:没有它,`Bash(git diff*)` 也会匹配 `git diff-index`。

383 385 

384<Note>386<Note>

385 命令支持在 `-p` 模式下有所不同:387 命令支持在 `-p` 模式下有所不同:

386 388 

387 * 用户调用的 [skills](/docs/zh-CN/skills) 和自定义命令工作。在提示字符串中包含 `/skill-name`,Claude Code 会在运行前展开它。389 * 用户调用的 [skill](/docs/zh-CN/skills) 和自定义命令可以使用。在提示词字符串中包含 `/skill-name`,Claude Code 会在运行前展开它。

388 * 仅在终端界面中运行的内置命令,例如 `/login`,在 `-p` 模式下不可用。390 * 仅在终端界面中运行的内置命令,例如 `/login`,不可用。

389 * `/model`、`/effort`、`/fast`、`/color` 和 `/rename` 接受该值作为参数,例如 `/model sonnet`,`/mcp` 不带参数打印服务器状态的文本摘要。这些形式需要 Claude Code v2.1.205 或更高版本,并遵循每个命令的 [可用性说明](/docs/zh-CN/commands#all-commands)。391 * `/model`、`/effort`、`/fast`、`/color` 和 `/rename` 接受该值作为参数,例如 `/model sonnet`,`/mcp` 不带参数时打印服务器状态的文本摘要。这些形式需要 Claude Code v2.1.205 或更高版本,并遵循每个命令的 [可用性说明](/docs/zh-CN/commands#all-commands)。

390 * 要从 `-p` 调用更改设置,请将 `key=value` 传递给 `/config`,例如 `/config thinking=false`。392 * 要更改设置,请将 `key=value` 传递给 `/config`,例如 `/config thinking=false`。

391 * `/output-style <style>` 切换 [输出样式](/docs/zh-CN/output-styles),`/output-style` 单独列出它们。需要 Claude Code v2.1.269 或更高版本。393 * `/output-style <style>` 切换 [输出样式](/docs/zh-CN/output-styles),单独使用 `/output-style` 会列出它们。需要 Claude Code v2.1.269 或更高版本。

392</Note>394</Note>

393 395 

394<h3 id="customize-the-system-prompt">396<h3 id="customize-the-system-prompt">

395 自定义系统提示397 自定义系统提示词

396</h3>398</h3>

397 399 

398使用 `--append-system-prompt` 添加指令同时保持 Claude Code 的默认行为。此示例将 PR diff 传递给 Claude 并指示它审查安全漏洞。将其保存为 shell 脚本,例如 `review.sh`:400使用 `--append-system-prompt` 添加指令同时保持 Claude Code 的默认行为。此示例将 PR diff 传递给 Claude 并指示它审查安全漏洞。将其保存为 shell 脚本,例如 `review.sh`:


405 407 

406在脚本中,`"$1"` 代表您在命令行上传递的第一个参数。运行 `bash review.sh 123`,shell 将 `"$1"` 替换为 `123`,因此脚本获取 PR 123 的 diff。Claude Code 将审查打印为 JSON,文本在 `result` 字段中。408在脚本中,`"$1"` 代表您在命令行上传递的第一个参数。运行 `bash review.sh 123`,shell 将 `"$1"` 替换为 `123`,因此脚本获取 PR 123 的 diff。Claude Code 将审查打印为 JSON,文本在 `result` 字段中。

407 409 

408有关更多选项(包括 `--system-prompt` 以完全替换默认提示),请参阅 [系统提示标志](/docs/zh-CN/cli-reference#system-prompt-flags)。410有关更多选项(包括用于完全替换默认提示词的 `--system-prompt`),请参阅 [系统提示词标志](/docs/zh-CN/cli-reference#system-prompt-flags)。

409 411 

410<h3 id="continue-conversations">412<h3 id="continue-conversations">

411 继续对话413 继续对话

412</h3>414</h3>

413 415 

414使用 `--continue` 继续最近的对话,或使用 `--resume` 与会话 ID 继续特定对话。在 Claude Code v2.1.257 或更高版本上,当您传递 `--continue` 时,Claude Code 会打开已完成的 [后台会话](/docs/zh-CN/sessions#resume-a-session),但不会打开仍在运行的后台会话。此示例运行审查,然后发送后续提示:416使用 `--continue` 继续最近的对话,或使用 `--resume` 与会话 ID 继续特定对话。在 Claude Code v2.1.257 或更高版本上,当您传递 `--continue` 时,Claude Code 会打开已完成的 [后台会话](/docs/zh-CN/sessions#resume-a-session),但不会打开仍在运行的后台会话。此示例运行审查,然后发送后续提示词:

415 417 

416```bash theme={null}418```bash theme={null}

417# First request419# First request


429claude -p "Continue that review" --resume "$session_id"431claude -p "Continue that review" --resume "$session_id"

430```432```

431 433 

432您可以从不同的目录运行两个命令:Claude Code [按其 ID 查找会话](/docs/zh-CN/sessions#resume-a-session) 在此机器上的任何项目中。在 v2.1.223 之前,Claude Code 仅在当前项目目录及其 git worktrees 中查找 ID,因此您必须从同一目录运行两个命令。434您可以从不同的目录运行这两个命令:Claude Code 会在此机器上的任何项目中 [按其 ID 查找会话](/docs/zh-CN/sessions#resume-a-session)。在 v2.1.223 之前,Claude Code 仅在当前项目目录及其 git worktree 中查找 ID,因此您必须从同一目录运行两个命令。

433 435 

434代替会话 ID,您可以将 `--resume` 传递会话的 `.jsonl` [记录文件](/docs/zh-CN/sessions#where-transcripts-are-stored) 的绝对路径,Claude Code 继续存储在该文件中的对话。436您可以向 `--resume` 传递会话的 `.jsonl` [会话记录文件](/docs/zh-CN/sessions#where-transcripts-are-stored) 的绝对路径来代替会话 ID,Claude Code 会继续存储在该文件中的对话。

435 437 

436<h2 id="next-steps">438<h2 id="next-steps">

437 后续步骤439 后续步骤

Details

132运行器及其会话进行多种出站连接,不需要来自 Anthropic 的入站连接:132运行器及其会话进行多种出站连接,不需要来自 Anthropic 的入站连接:

133 133 

134* **控制平面**:运行器轮询 `api.anthropic.com` 以获取工作并发布设置进度和失败事件,全部出站 HTTPS。轮询充当运行器的心跳。134* **控制平面**:运行器轮询 `api.anthropic.com` 以获取工作并发布设置进度和失败事件,全部出站 HTTPS。轮询充当运行器的心跳。

135* **SCM 连接器**:可选的编排器 [SCM 连接器](/docs/zh-CN/self-hosted-environments-reference#scm-connector-flags)隧道是唯一的 WebSocket 连接。135* **Git**:运行器通过 HTTPS 或 SSH 从您的 git 主机克隆和推送,使用您的部署提供的凭据进行身份验证。请参阅[配置 git](/docs/zh-CN/self-hosted-environments-deploy#configure-git)了解各选项,包括每个会话铸造的凭据。使用 [Anthropic git 代理](/docs/zh-CN/self-hosted-environments-deploy#use-the-anthropic-git-proxy)时,github.com 上仓库的 git 流量改为经由 `api.anthropic.com` 传输。

136* **Git**:运行器通过 HTTPS 或 SSH 从您的 git 主机克隆和推送,使用您的部署提供的凭证进行身份验证;[配置 git](/docs/zh-CN/self-hosted-environments-deploy#configure-git)涵盖了选项,包括每个会话铸造的凭证和 [Anthropic git 代理](/docs/zh-CN/self-hosted-environments-deploy#use-the-anthropic-git-proxy),它通过 `api.anthropic.com` 路由 git。136* **会话子进程**:子 Claude Code 进程将会话的事件流保持到 `api.anthropic.com`,并为模型推理和会话期间运行的 git 命令进行自己的出站调用。在使用 [Anthropic 托管 git](/docs/zh-CN/self-hosted-environments-deploy#use-the-anthropic-git-proxy) 的会话中,子进程通过其打开到 `api.anthropic.com` 的 WebSocket 连接发送 github.com 的 `git` 和 `gh` 流量。

137* **会话子进程**:子 Claude Code 进程将会话的事件流保持到 `api.anthropic.com`,并为模型推理和会话期间运行的 git 命令进行自己的出站调用。请参阅[网络要求](/docs/zh-CN/self-hosted-environments-deploy#network-requirements)了解完整的出站列表。[上面的图](#how-self-hosted-environments-work)显示了这些路径,除了可选的 SCM 连接器。137* **SCM 连接器**:可选的编排器 [SCM 连接器](/docs/zh-CN/self-hosted-environments-reference#scm-connector-flags)不可用,因此其隧道不会打开。该隧道是到 `api.anthropic.com` 的 WebSocket 连接。

138 

139请参阅[网络要求](/docs/zh-CN/self-hosted-environments-deploy#network-requirements)了解完整的出站列表。[上面的图](#how-self-hosted-environments-work)显示了这些路径,但可选的 SCM 连接器和 Anthropic 托管的 git 连接除外。

138 140 

139默认情况下,模型推理使用 Anthropic API。控制平面将 API 端点传递给每个会话,会话使用 Anthropic 颁发的会话范围的 OAuth 令牌进行身份验证。如需改为将模型请求发送到您自己的云帐户,请参阅[将模型请求发送到 Bedrock 或 Agent Platform](/docs/zh-CN/self-hosted-environments-configuration#send-model-requests-to-bedrock-or-agent-platform)。141默认情况下,模型推理使用 Anthropic API。控制平面将 API 端点传递给每个会话,会话使用 Anthropic 颁发的会话范围的 OAuth 令牌进行身份验证。如需改为将模型请求发送到您自己的云帐户,请参阅[将模型请求发送到 Bedrock 或 Agent Platform](/docs/zh-CN/self-hosted-environments-configuration#send-model-requests-to-bedrock-or-agent-platform)。

140 142 

Details

31| 变量 | 描述 |31| 变量 | 描述 |

32| :- | :- |32| :- | :- |

33| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话 JWT,前缀为 `sk-ant-cc-`。其 `act` 声明标识会话创建者,并在创建会话的使用入口记录了创建者电子邮件时包含该电子邮件。该值是生成时的令牌;刷新通过子进程的 stdin 到达,因此包装脚本只看到初始值。请参阅 [Verify session identity](/docs/zh-CN/self-hosted-environments-identity)。 |33| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话 JWT,前缀为 `sk-ant-cc-`。其 `act` 声明标识会话创建者,并在创建会话的使用入口记录了创建者电子邮件时包含该电子邮件。该值是生成时的令牌;刷新通过子进程的 stdin 到达,因此包装脚本只看到初始值。请参阅 [Verify session identity](/docs/zh-CN/self-hosted-environments-identity)。 |

34| `CCR_SESSION_ACCOUNT_EMAIL` | 会话创建者的电子邮件,由运行器从令牌的 `act.email` 声明中预先提取,无需签名验证。适合用于标记,例如提交 trailer。当电子邮件控制凭据发放时,验证令牌并从中读取声明;请参阅 [Provision credentials scoped to the session creator](#provision-credentials-scoped-to-the-session-creator)。当令牌不包含创建者电子邮件时未设置。视为个人可识别信息。 |34| `CCR_SESSION_ACCOUNT_EMAIL` | 会话创建者的电子邮件,由运行器从令牌的 `act.email` 声明中预先提取,无需签名验证。适合用于标记,例如提交 trailer。当电子邮件控制凭据发放时,请改为验证令牌并从中读取声明。请参阅 [Provision credentials scoped to the session creator](#provision-credentials-scoped-to-the-session-creator)。当令牌不包含创建者电子邮件时未设置,例如在由您组织的服务身份创建的会话中。视为个人可识别信息。 |

35| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app`、`ios`、`claude_code_cli` 或 `scheduled_trigger`。Anthropic 在会话创建时记录该值一次,因此包装脚本和每个生命周期 hook 都看到相同的值。仅将其用于采用分析和标记,不用作授权信号。当会话没有记录或识别的使用入口时未设置,因此在 `set -u` 下将其引用为 `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}`。需要 Claude Code v2.1.229 或更高版本。 |35| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app`、`ios`、`claude_code_cli` 或 `scheduled_trigger`。Anthropic 在会话创建时记录该值一次,因此包装脚本和每个生命周期 hook 都看到相同的值。仅将其用于采用分析和标记,不用作授权信号。当会话没有记录或识别的使用入口时未设置。需要 Claude Code v2.1.229 或更高版本。 |

36| `CLAUDE_RUNNER_CLAUDE_BIN` | 运行器自己的 Claude Code 二进制文件的绝对路径。使用 `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` 结束您的包装脚本,以移交到固定的二进制文件,而无需硬编码安装路径。 |36| `CLAUDE_RUNNER_CLAUDE_BIN` | 运行器自己的 Claude Code 二进制文件的绝对路径。使用 `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` 结束您的包装脚本,以移交到固定的二进制文件,而无需硬编码安装路径。 |

37| `CLAUDE_CODE_REMOTE_SESSION_ID` | 会话 ID,采用标记的 `cse_...` 形式。这与[生命周期 hook](#lifecycle-hooks)以 `session_...` 形式在 `CLAUDE_RUNNER_SESSION_ID` 中看到的是同一个会话;UUID 变量在两者之间匹配,将 `cse_` 前缀替换为 `session_` 会产生会话 URL 中显示的 ID。 |37| `CLAUDE_CODE_REMOTE_SESSION_ID` | 会话 ID,采用标记的 `cse_...` 形式。这与[生命周期 hook](#lifecycle-hooks)以 `session_...` 形式在 `CLAUDE_RUNNER_SESSION_ID` 中看到的是同一个会话;UUID 变量在两者之间匹配,将 `cse_` 前缀替换为 `session_` 会产生会话 URL 中显示的 ID。 |

38| `CLAUDE_CODE_REMOTE_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式,供以 UUID 作为键的系统使用。 |38| `CLAUDE_CODE_REMOTE_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式,供以 UUID 作为键的系统使用。 |

39| `CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` | 对于属于某个 Slack 线程的 [Claude Tag](https://claude.com/docs/claude-tag/overview) 会话,为该线程的链接。其他会话未设置此变量,线程会话也可能未设置。 |

40| `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` | 对于属于某个 Slack 线程的 Claude Tag 会话,为该线程的 Slack 时间戳,例如 `1700000000.000100`。可能未设置,也可能在 `CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` 未设置时被设置,因此请分别检查每个变量。 |

39| `CLAUDE_SESSION_INGRESS_TOKEN_FILE` | 绝对路径,指向保存当前会话 JWT 的按会话文件,在令牌刷新时保持最新。Shell 子进程在下载用户添加到会话的附件时从中读取其 `Authorization` 标头。`exec` 自动保留该变量;重建子进程环境的包装脚本必须携带该变量,否则附件下载会无声地停止工作。 |41| `CLAUDE_SESSION_INGRESS_TOKEN_FILE` | 绝对路径,指向保存当前会话 JWT 的按会话文件,在令牌刷新时保持最新。Shell 子进程在下载用户添加到会话的附件时从中读取其 `Authorization` 标头。`exec` 自动保留该变量;重建子进程环境的包装脚本必须携带该变量,否则附件下载会无声地停止工作。 |

40| `CLAUDE_CONFIG_DIR` | 按会话 Claude 配置目录,在会话启动时从运行器在启动时捕获的运行器主机配置快照中写入;请参阅 [Permissions and tool approval](#permissions-and-tool-approval)。此处的写入仅限于此会话。除非您使用 [`--remove-session-state`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 启动运行器,否则会话结束后该目录仍会保留在 `<base-dir>/_sessions/` 下;请参阅 [Reuse a pre-warmed checkout](/docs/zh-CN/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout)。 |42| `CLAUDE_CONFIG_DIR` | 按会话 Claude 配置目录,在会话启动时从运行器在启动时捕获的运行器主机配置快照中写入;请参阅 [Permissions and tool approval](#permissions-and-tool-approval)。此处的写入仅限于此会话。除非您使用 [`--remove-session-state`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 启动运行器,否则会话结束后该目录仍会保留在 `<base-dir>/_sessions/` 下;请参阅 [Reuse a pre-warmed checkout](/docs/zh-CN/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout)。 |

41| `ANTHROPIC_BASE_URL` | 子进程将使用的 API 基础 URL,由控制平面按会话交付,通常为 `https://api.anthropic.com`。不要覆盖它:会话的推理凭据是 Anthropic 颁发的 OAuth 令牌,其他提供者不接受。 |43| `ANTHROPIC_BASE_URL` | 子进程将使用的 API 基础 URL,由控制平面按会话交付,通常为 `https://api.anthropic.com`。不要覆盖它:会话的推理凭据是 Anthropic 颁发的 OAuth 令牌,其他提供者不接受。 |


43 45 

44包装脚本还继承子进程的其余托管环境,包括任何服务器提供的环境变量。`exec` 自动传播所有内容;如果您的包装脚本以其他方式生成子进程,请转发完整环境。46包装脚本还继承子进程的其余托管环境,包括任何服务器提供的环境变量。`exec` 自动传播所有内容;如果您的包装脚本以其他方式生成子进程,请转发完整环境。

45 47 

48`CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` 和 `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` 会传递到您的包装脚本或 [`command` hook](#command)。它们也会传递到会话运行的内容,例如 shell 命令、git 钩子和 Claude Code hook。`checkout`、`post-session` 和 `spawn-runner` hook 不会接收它们。

49 

50<h3 id="give-a-default-to-variables-that-can-be-unset">

51 为可能未设置的变量提供默认值

52</h3>

53 

54`CCR_SESSION_ACCOUNT_EMAIL`、`CLAUDE_RUNNER_CLIENT_PLATFORM`、`CLAUDE_CODE_REMOTE_SLACK_THREAD_URL` 和 `CLAUDE_CODE_REMOTE_SLACK_THREAD_TS` 都可能未设置。如果您的脚本使用 `set -u`,Bash 在展开其中未设置的变量时会以 `unbound variable` 停止,因此请使用默认值展开它们,例如 `${CCR_SESSION_ACCOUNT_EMAIL:-}`。

55 

56在 shell 展开 Slack 线程链接的任何位置,请采取以下预防措施:

57 

58* **为其加引号**:该链接可能包含 shell 会处理的字符,例如 `?` 和 `&`,因此请为变量加引号,如 `"${CLAUDE_CODE_REMOTE_SLACK_THREAD_URL:-}"`。

59* **不要将其值放入 `eval` 和 `sh -c` 字符串**:不要将其值替换到 `eval` 或 `sh -c` 运行的字符串中,即使在引号内也不行。应让该字符串引用该变量。

60 

46<h3 id="keep-stdin-and-file-descriptor-3-attached">61<h3 id="keep-stdin-and-file-descriptor-3-attached">

47 保持 stdin 和文件描述符 3 的连接62 保持 stdin 和文件描述符 3 的连接

48</h3>63</h3>

49 64 

50子进程的 stdin 是运行器的控制通道。令牌轮换和会话结束信号在其上到达。运行器还在文件描述符 3 上打开一个管道,并从中读取子进程的活动信号以驱动空闲和启动超时。普通的 `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` 自动保留两者。65子进程的 stdin 是运行器的控制通道。令牌轮换和会话结束信号在其上到达。运行器还在文件描述符 3 上打开一个管道,并从中读取子进程的活动信号以驱动空闲和启动超时。普通的 `exec "$CLAUDE_RUNNER_CLAUDE_BIN" "$@"` 自动保留两者。

51 66 

52如果您的包装脚本使用裸 `&` 在后台运行子进程,它会切断子进程的 stdin:会话看起来健康,直到初始 OAuth 令牌的大约 30 分钟生命周期过期,然后每个 API 调用都失败,出现 `401 authentication_error`。如果您的包装脚本必须在后台运行子进程,例如保持拆卸陷阱活跃,请在文件描述符 4 或更高编号上保存 stdin 并显式重新连接它:67如果您的包装脚本使用裸 `&` 在后台运行子进程,它会切断子进程的 stdin。会话看起来健康,直到初始 OAuth 令牌的大约 30 分钟生命周期过期,然后每个使用该令牌的 API 调用都失败,出现 `401 authentication_error`。如果您的包装脚本必须在后台运行子进程,例如保持拆卸陷阱活跃,请在文件描述符 4 或更高编号上保存 stdin 并显式重新连接它:

53 68 

54```bash theme={null}69```bash theme={null}

55exec 4<&070exec 4<&0


59wait "$CHILD"74wait "$CHILD"

60```75```

61 76 

62不要在包装脚本中关闭或重用文件描述符 3。重定向子进程的 stdout 和 stderr 是可以的。77您可以重定向子进程的 stdout。请保持文件描述符 3 和 stderr 连接到运行器:

78 

79* **文件描述符 3**:将子进程的活动信号传送给运行器。不要在包装脚本中关闭或重用它。

80* **stderr**:当包装脚本或子进程以非零状态退出时,运行器会将 stderr 的最后几行发布到会话中,并在其自身日志中打印这些行。会话的用户会看到这些行,因此不要将密钥打印到 stderr,并在部署包装脚本之前移除 `set -x`。如果您重定向 stderr,会话仍会运行,但运行器仅以退出码报告失败。

63 81 

64<h3 id="pass-the-system-prompt-flags-through">82<h3 id="pass-the-system-prompt-flags-through">

65 透传系统提示词标志83 透传系统提示词标志


108 checkout126 checkout

109</h3>127</h3>

110 128 

111每个仓库运行一次,代替运行器的内置克隆和获取。使用此 hook 从读通镜像克隆、从存档为工作树设置种子或应用按会话的 git 身份验证。运行器设置以下变量,并且可能设置表中未列出的其他 `CLAUDE_RUNNER_` 变量:129每个仓库运行一次,代替运行器的内置克隆和获取。使用此 hook 从您通过 HTTPS 或 SSH 访问的读通镜像克隆、从存档为工作树设置种子,或应用按会话的 git 身份验证。运行器设置以下变量,并且可能设置表中未列出的其他 `CLAUDE_RUNNER_` 变量:

112 130 

113| 变量 | 描述 |131| 变量 | 描述 |

114| :- | :- |132| :- | :- |

115| `CLAUDE_RUNNER_REPO_URL` | 要克隆的存储库 URL,在应用任何 `--git-host-rewrite` 和 `--git-ssh-rewrite` 之后 |133| `CLAUDE_RUNNER_REPO_URL` | 要克隆的存储库 URL,在应用任何 `--git-host-rewrite` 和 `--git-ssh-rewrite` 之后 |

116| `CLAUDE_RUNNER_REPO_REF` | 要检出的修订版本:分支、标签或提交 SHA,如会话请求的那样。空表示存储库的默认分支。 |134| `CLAUDE_RUNNER_REPO_REF` | 要检出的修订版本,即会话所请求的形式:分支、标签、提交 SHA,或完整引用名称(例如 `refs/pull/<number>/head`)。为空表示仓库的默认分支。 |

117| `CLAUDE_RUNNER_CHECKOUT_PATH` | 必须留下工作树的绝对路径 |135| `CLAUDE_RUNNER_CHECKOUT_PATH` | 必须留下工作树的绝对路径 |

118| `CLAUDE_RUNNER_SESSION_ID` | 会话 ID,采用标记的 `session_...` 形式,用于日志记录和关联 |136| `CLAUDE_RUNNER_SESSION_ID` | 会话 ID,采用标记的 `session_...` 形式,用于日志记录和关联 |

119| `CLAUDE_RUNNER_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式 |137| `CLAUDE_RUNNER_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式 |

120| `CLAUDE_RUNNER_API_BASE_URL` | Anthropic API 基础 URL,用于会话范围的调用 |138| `CLAUDE_RUNNER_API_BASE_URL` | Anthropic API 基础 URL,用于会话范围的调用 |

121| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端表面,例如 `web_claude_ai`、`desktop_app` 或 `ios`。当会话没有记录或识别的表面时未设置。 |139| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app` 或 `ios`。当会话没有记录或可识别的使用入口时未设置,因此在 `set -u` 下请以 `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}` 的形式引用它。需要 Claude Code v2.1.229 或更高版本。 |

122| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话访问令牌,用于会话范围的 API 调用 |140| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话访问令牌,用于会话范围的 API 调用 |

123| `GIT_CONFIG_COUNT`、`GIT_CONFIG_KEY_n`、`GIT_CONFIG_VALUE_n` | 运行器为您的 hook 所运行的 git 固定的 Git 设置。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)对其进行了说明。需要 Claude Code v2.1.280 或更高版本。 |141| `GIT_CONFIG_COUNT`、`GIT_CONFIG_KEY_n`、`GIT_CONFIG_VALUE_n` | 运行器为您的 hook 所运行的 git 固定的 Git 设置。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)对其进行了说明。需要 Claude Code v2.1.280 或更高版本。 |

124 142 

125脚本必须在 `CLAUDE_RUNNER_CHECKOUT_PATH` 处留下一个工作树,检出到请求的修订版本。分离的 HEAD 是可以的;运行器在其上创建会话的工作分支。运行器之后验证路径包含 `.git`;如果您的钩子具体化非 git 源(例如 Perforce 或解包的 tarball),请在运行器的环境中设置 `CLAUDE_RUNNER_SKIP_GIT_VERIFY=1` 以跳过该检查。基于 Git 的流程(例如工作分支创建和推送结果)需要 git 检出,因此使用 [`post-session` 钩子](#post-session) 从非 git 树导出结果。143脚本必须在 `CLAUDE_RUNNER_CHECKOUT_PATH` 处留下一个检出到所请求修订版本的工作树。分离的 HEAD 也可以,因为运行器会在其上创建会话的工作分支。

126 144 

127运行器不会将 git 凭证传递给钩子。相反,从会话的身份生成按会话克隆凭证:使用标准 JWT 库针对 `CLAUDE_RUNNER_API_BASE_URL` 下的 JWKS 端点验证 `CLAUDE_CODE_SESSION_ACCESS_TOKEN`,如 [Verify the token from your service](/docs/zh-CN/self-hosted-environments-identity#verify-the-token-from-your-service) 中所述,然后让您的凭证服务为令牌的 `act` 声明中的身份发放短期克隆凭证。`CLAUDE_RUNNER_CLAUDE_BIN` 未在 checkout-hook 环境中设置,因此 `decode-token` 子命令在此处不可用。回退到主机已有的任何 git 身份验证(例如 SSH 代理、凭证助手或 `.netrc`)也是一个选项。145在您的 hook 返回后,运行器会验证 `CLAUDE_RUNNER_CHECKOUT_PATH` 包含 `.git`。如果您的 hook 具体化的是非 git 源(例如 Perforce 或解包的 tarball),请在运行器的环境中设置 `CLAUDE_RUNNER_SKIP_GIT_VERIFY=1` 以跳过该检查。基于 Git 的流程(例如工作分支创建和推送结果)需要 git 检出,因此请使用 [`post-session` hook](#post-session) 从非 git 树导出结果。

128 146 

129当钩子以非零状态退出,或以 0 退出但没有留下可用的检出时,运行器的行为取决于存储库:147<h4 id="get-git-credentials-in-the-hook">

148 在 hook 中获取 git 凭据

149</h4>

130 150 

131* **会话推送结果的存储库**:运行器失败会话,在非零退出时将脚本的 stderr 尾部呈现给用户。151运行器不会将 git 凭据传递给 hook。`decode-token` 子命令在此处同样不可用,因为 `CLAUDE_RUNNER_CLAUDE_BIN` 未在 checkout-hook 环境中设置。请改为从会话的身份生成按会话的克隆凭据,或回退到主机自身的 git 身份验证:

132* **会话仅从中读取的存储库**,例如添加到运行会话的存储库:运行器记录带有失败详情的 `[runner:warn]` 行,向会话发布 `Skipped` 步骤,删除钩子在检出路径处留下的任何内容,并继续处理其余存储库。当运行器无法立即删除路径时,它会在会话结束时重试删除。如果跳过使会话完全没有存储库,运行器仍然会失败会话。

133 152 

134在 v2.1.228 之前,运行器对任何存储库的钩子失败都会失败会话,因此钩子无法提供的只读存储库在会话恢复到的每个新运行器上再次失败会话。153* **按会话的克隆凭据**:使用标准 JWT 库,针对 `CLAUDE_RUNNER_API_BASE_URL` 下的 JWKS 端点验证 `CLAUDE_CODE_SESSION_ACCESS_TOKEN`,如[从您的服务验证令牌](/docs/zh-CN/self-hosted-environments-identity#verify-the-token-from-your-service)中所述。然后让您的凭据服务为令牌 `act` 声明中的身份发放短期克隆凭据。请以 `act.sub` 作为该凭据的键,不要依赖 `act.email`。

154* **主机 git 身份验证**:使用主机已有的任何 git 身份验证,例如 SSH agent、凭据助手或 `.netrc`。

135 155 

136运行器在会话结束后删除检出路径。156<h4 id="when-the-hook-fails">

157 hook 失败时

158</h4>

159 

160当 hook 以非零状态退出,或以 0 退出但没有留下可用的检出时,hook 即为失败:

161 

162* **会话推送结果的存储库**:运行器失败会话,在非零退出时将脚本的 stderr 尾部呈现给用户。

163* **会话仅从中读取的仓库**,例如添加到正在运行的会话中的仓库:运行器记录一行带有失败详情的 `[runner:warn]`,向会话发布一个 `Skipped` 步骤,删除 hook 在检出路径处留下的任何内容,并继续处理其余仓库。如果跳过后会话完全没有仓库,运行器仍然会使会话失败。

164 

165当 hook 成功时,运行器会在会话结束后删除检出路径。

137 166 

138<h3 id="post-session">167<h3 id="post-session">

139 post-session168 post-session


151| `CLAUDE_RUNNER_WORKSPACE_PATHS` | 会话工作树的冒号分隔绝对路径。对于零存储库会话为空。 |180| `CLAUDE_RUNNER_WORKSPACE_PATHS` | 会话工作树的冒号分隔绝对路径。对于零存储库会话为空。 |

152| `CLAUDE_RUNNER_DEBUG_LOG_PATH` | 会话的调试日志的路径,在钩子运行时仍在磁盘上 |181| `CLAUDE_RUNNER_DEBUG_LOG_PATH` | 会话的调试日志的路径,在钩子运行时仍在磁盘上 |

153| `CLAUDE_RUNNER_API_BASE_URL` | Anthropic API 基础 URL,用于会话范围的调用 |182| `CLAUDE_RUNNER_API_BASE_URL` | Anthropic API 基础 URL,用于会话范围的调用 |

154| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端表面,例如 `web_claude_ai`、`desktop_app` 或 `ios`。当会话没有记录或识别的表面时未设置。需要 Claude Code v2.1.229 或更高版本。 |183| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app` 或 `ios`。当会话没有记录或可识别的使用入口时未设置,因此在 `set -u` 下请以 `${CLAUDE_RUNNER_CLIENT_PLATFORM:-}` 的形式引用它。需要 Claude Code v2.1.229 或更高版本。 |

155| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话访问令牌,用于会话范围的 API 调用 |184| `CLAUDE_CODE_SESSION_ACCESS_TOKEN` | 会话访问令牌,用于会话范围的 API 调用 |

156| `GIT_CONFIG_COUNT`、`GIT_CONFIG_KEY_n`、`GIT_CONFIG_VALUE_n` | 运行器为您的 hook 所运行的 git 固定的 Git 设置。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)对其进行了说明。需要 Claude Code v2.1.280 或更高版本。 |185| `GIT_CONFIG_COUNT`、`GIT_CONFIG_KEY_n`、`GIT_CONFIG_VALUE_n` | 运行器为您的 hook 所运行的 git 固定的 Git 设置。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)对其进行了说明。需要 Claude Code v2.1.280 或更高版本。 |

157 186 

158`CLAUDE_RUNNER_EXIT_REASON` 采用四个值之一:187`CLAUDE_RUNNER_EXIT_REASON` 采用四个值之一:

159 188 

160* `completed`:会话干净地结束。Claude Code 进程正常退出,或会话在仍在运行时被存档或删除。189* `completed`:会话正常结束。Claude Code 进程正常退出,或在会话被存档或删除后自行退出。

161* `failed`:Claude Code 进程崩溃,或在启动后设置失败。190* `failed`:Claude Code 进程崩溃,或在启动后设置失败。

162* `interrupted`:运行器停止了会话。它释放了会话以释放插槽、会话在启动时超时、服务器将会话移出此运行器、运行器正在排空,或会话超过了其 [`--kill-session-after-min`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 限制。191* `interrupted`:运行器停止了会话,属于以下情况之一:

192 * 运行器释放了会话以腾出插槽。

193 * 会话在启动时超时。

194 * 服务器将会话移出了此运行器。

195 * 运行器的轮询在进程退出之前发现了存档或删除操作。

196 * 运行器正在排空。

197 * 会话超过了其 [`--kill-session-after-min`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 限制。

163* `abandoned`:为另一个运行器声称的会话保留。钩子目前在这种情况下不触发。198* `abandoned`:为另一个运行器声称的会话保留。钩子目前在这种情况下不触发。

164 199 

165[session lifecycle counters](/docs/zh-CN/self-hosted-environments-reference#session-lifecycle-counter-semantics) 将释放、启动超时和服务器移动计为 `completed` 而不是 `interrupted`,因为运行器干净地交还了插槽。如果您将钩子收据与计数器进行比较,请预期这种差异。200如果您将 hook 收据与[会话生命周期计数器](/docs/zh-CN/self-hosted-environments-reference#session-lifecycle-counter-semantics)进行比较,请预期某些 `interrupted` 收据在计数器中会计为 `completed`。计数器会将释放、启动超时、服务器移动,以及运行器轮询先发现的存档或删除计为 `completed`,因为运行器干净地交还了插槽。

166 201 

167钩子的退出状态永远不会影响会话结果;失败被记录并忽略。运行器在每个会话结束(包括运行器关闭)时等待最多 `--post-session-hook-timeout-sec`(默认 60 秒)。此示例将未提交的工作保存到救援分支:202钩子的退出状态永远不会影响会话结果;失败被记录并忽略。运行器在每个会话结束(包括运行器关闭)时等待最多 `--post-session-hook-timeout-sec`(默认 60 秒)。此示例将未提交的工作保存到救援分支:

168 203 

169```bash theme={null}204```bash theme={null}

170#!/usr/bin/env bash205#!/usr/bin/env bash

171set -u206set -u

207export GIT_ALLOW_PROTOCOL=${GIT_ALLOW_PROTOCOL:-https:http:ssh}

172IFS=':'208IFS=':'

173# -c overrides beat repo-local settings, blocking session-written fsmonitor,209# -c overrides beat repo-local settings, blocking session-written fsmonitor,

174# hook-path, and gpg-program config from executing code with the hook's210# hook-path, and gpg-program config from executing code with the hook's


188done224done

189```225```

190 226 

227脚本中的 `GIT_ALLOW_PROTOCOL` 行将 git 限制为 HTTPS、HTTP 和 SSH 远程。如果运行器的环境已经设置了自己的非空 `GIT_ALLOW_PROTOCOL` 列表,脚本会保留该列表。

228 

191hook 使用运行器主机上其自身环境中可用的任何 git 凭据进行推送。在[镜像中不含凭据的部署方式](/docs/zh-CN/self-hosted-environments-deploy#configure-git)下,包括内置克隆通过 Anthropic git 代理进行时,都没有可用凭据,因此请在推送前于 hook 内生成短期推送凭据:将 hook 在 `CLAUDE_CODE_SESSION_ACCESS_TOKEN` 中收到的会话令牌与您自己的令牌服务进行交换,并按照[验证会话身份](/docs/zh-CN/self-hosted-environments-identity)中的说明对其进行验证。当 hook 持有会话没有的凭据时,请将 `origin` 替换为操作员提供的 URL,并传递 `-c credential.helper=` 加上您自己的助手。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)说明了会话写入的配置仍可能影响哪些内容。229hook 使用运行器主机上其自身环境中可用的任何 git 凭据进行推送。在[镜像中不含凭据的部署方式](/docs/zh-CN/self-hosted-environments-deploy#configure-git)下,包括内置克隆通过 Anthropic git 代理进行时,都没有可用凭据,因此请在推送前于 hook 内生成短期推送凭据:将 hook 在 `CLAUDE_CODE_SESSION_ACCESS_TOKEN` 中收到的会话令牌与您自己的令牌服务进行交换,并按照[验证会话身份](/docs/zh-CN/self-hosted-environments-identity)中的说明对其进行验证。当 hook 持有会话没有的凭据时,请将 `origin` 替换为操作员提供的 URL,并传递 `-c credential.helper=` 加上您自己的助手。[生命周期 hook 中的 Git 配置](#git-configuration-inside-lifecycle-hooks)说明了会话写入的配置仍可能影响哪些内容。

192 230 

193<h4 id="hook-timing-when-the-runner-releases-a-session">231<h4 id="hook-timing-when-the-runner-releases-a-session">


264| `CLAUDE_RUNNER_ORDER_ID` | 不透明的幂等性密钥,每个生成请求唯一,对 Kubernetes 资源名称安全。仅将订单 ID 用作您的配置器的去重密钥。 |302| `CLAUDE_RUNNER_ORDER_ID` | 不透明的幂等性密钥,每个生成请求唯一,对 Kubernetes 资源名称安全。仅将订单 ID 用作您的配置器的去重密钥。 |

265| `CLAUDE_RUNNER_SESSION_ID` | 此请求所针对的会话。该会话的每次重新请求都会重复此值,因此请将其用于日志记录和路由,而不要用作去重密钥。对于预热请求为空,预热请求在设置 [`--min-idle`](/docs/zh-CN/self-hosted-environments-reference#orchestrator-cli-flags) 时于任何特定会话之前启动待命运行器,因此不要假设变量已设置。 |303| `CLAUDE_RUNNER_SESSION_ID` | 此请求所针对的会话。该会话的每次重新请求都会重复此值,因此请将其用于日志记录和路由,而不要用作去重密钥。对于预热请求为空,预热请求在设置 [`--min-idle`](/docs/zh-CN/self-hosted-environments-reference#orchestrator-cli-flags) 时于任何特定会话之前启动待命运行器,因此不要假设变量已设置。 |

266| `CLAUDE_RUNNER_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式。对于预热请求为空。 |304| `CLAUDE_RUNNER_SESSION_UUID` | 相同的会话 ID,采用规范 UUID 形式。对于预热请求为空。 |

267| `CLAUDE_RUNNER_ATTEMPT` | 此会话已有多少个生成请求。对于预热请求为 `0`。 |305| `CLAUDE_RUNNER_ATTEMPT` | 用于日志记录的按会话计数器。它不是重试次数,也不是请求次数。对于预热请求为 `0`,但针对某个会话的请求也可能携带 `0`。 |

268| `CLAUDE_RUNNER_ORDER_SERVER_TIME` | 来自轮询响应的 HTTP `Date` 标头的服务器时间。当 hook 验证工作单 JWT 的 `exp` 时,与此值进行比较而不是本地时钟,以容忍时钟偏差。当网关省略标头时为空。 |306| `CLAUDE_RUNNER_ORDER_SERVER_TIME` | 来自轮询响应的 HTTP `Date` 标头的服务器时间。当 hook 验证工作单 JWT 的 `exp` 时,与此值进行比较而不是本地时钟,以容忍时钟偏差。当网关省略标头时为空。 |

269| `CLAUDE_RUNNER_POOL_ID` | 新运行器应加入的环境的 ID,采用 `ccpool_...` 形式 |307| `CLAUDE_RUNNER_POOL_ID` | 新运行器应加入的环境的 ID,采用 `ccpool_...` 形式 |

270| `CLAUDE_RUNNER_ACCOUNT_ID` | 排队会话的帐户的标记 ID,用于按帐户路由、配额或退款。当不可用时为空,对于 Claude Tag 频道会话始终为空,这些会话没有帐户排队。 |308| `CLAUDE_RUNNER_ACCOUNT_ID` | 排队会话的帐户的标记 ID,用于按帐户路由、配额或退款。当不可用时为空,对于 Claude Tag 频道会话始终为空,这些会话没有帐户排队。 |

271| `CLAUDE_RUNNER_ACCOUNT_EMAIL` | 排队会话的帐户的电子邮件。当不可用时为空。将电子邮件视为个人可识别信息,不要记录它。 |309| `CLAUDE_RUNNER_ACCOUNT_EMAIL` | 排队会话的帐户的电子邮件。当不可用时为空。将电子邮件视为个人可识别信息,不要记录它。 |

272| `CLAUDE_RUNNER_PRIMARY_REPO_URL` | 会话的第一个 git 源的 URL,用于路由到已预热该仓库的运行器。当会话没有 git 源时为空。 |310| `CLAUDE_RUNNER_PRIMARY_REPO_URL` | 会话的第一个 git 源的 URL,用于路由到已预热该仓库的运行器。当会话没有 git 源时为空。 |

273| `CLAUDE_RUNNER_PRIMARY_REPO_REVISION` | 会话的第一个 git 源的修订版本:分支、SHA 或标签。当未指定时为空。 |311| `CLAUDE_RUNNER_PRIMARY_REPO_REVISION` | 会话的第一个 git 源的修订版本:分支、SHA、标签或完整引用名称。当未指定时为空。 |

274| `CLAUDE_RUNNER_REPO_SOURCES` | 所有会话的 git 源的 `{url, revision}` 的 JSON 数组,用于根据辅助仓库进行路由的 hook。当没有源时为空。 |312| `CLAUDE_RUNNER_REPO_SOURCES` | 所有会话的 git 源的 `{url, revision}` 的 JSON 数组,用于根据辅助仓库进行路由的 hook。当没有源时为空。 |

275| `CLAUDE_RUNNER_CORRELATION_ID` | 在会话创建时提供的关联 ID,回显以便 hook 可以将此工作单映射到创建会话的请求。当会话没有时为空。 |313| `CLAUDE_RUNNER_CORRELATION_ID` | 在会话创建时提供的关联 ID,回显以便 hook 可以将此工作单映射到创建会话的请求。当会话没有时为空。 |

276| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app`、`ios` 或 `scheduled_trigger`,用于采用分析。当会话没有记录或识别的使用入口时未设置,对于预热请求也未设置;使用 `[ -n "${CLAUDE_RUNNER_CLIENT_PLATFORM:-}" ]` 检查它,这在 `set -u` 下保持安全。 |314| `CLAUDE_RUNNER_CLIENT_PLATFORM` | 创建会话的客户端使用入口,例如 `web_claude_ai`、`desktop_app`、`ios` 或 `scheduled_trigger`,用于采用分析。当会话没有记录或识别的使用入口时未设置,对于预热请求也未设置;使用 `[ -n "${CLAUDE_RUNNER_CLIENT_PLATFORM:-}" ]` 检查它,这在 `set -u` 下保持安全。 |


282* **在生成的运行器上使用 `--capacity 1`**:会话绑定的工作单恰好注册一个绑定到该会话的运行器,因此更高的容量添加永远不会接收工作的插槽,运行器在启动时记录警告。320* **在生成的运行器上使用 `--capacity 1`**:会话绑定的工作单恰好注册一个绑定到该会话的运行器,因此更高的容量添加永远不会接收工作的插槽,运行器在启动时记录警告。

283* **预热工作单注册未绑定**:待命运行器未绑定到会话,并像固定队列运行器一样声称排队的工作。321* **预热工作单注册未绑定**:待命运行器未绑定到会话,并像固定队列运行器一样声称排队的工作。

284 322 

285约定有四个与配置器无关的规则:323无论您的 hook 在哪个平台上配置资源,约定都有四条规则:

286 324 

2871. **在 `CLAUDE_RUNNER_ORDER_ID` 上保持幂等。** 相同请求的重新交付必须最多生成一个运行器。从订单 ID 派生确定性资源名称,让您的平台拒绝重复。不要改为以 `CLAUDE_RUNNER_SESSION_ID` 作为键。会话的每次重新请求都携带相同的会话 ID 和新的订单 ID,因此按会话 ID 命名或去重的工作负载只会创建一次,之后该会话再也不会创建。3251. **在 `CLAUDE_RUNNER_ORDER_ID` 上保持幂等。** 相同请求的重新交付必须最多生成一个运行器。从订单 ID 派生确定性资源名称,让您的平台拒绝重复。不要改为以 `CLAUDE_RUNNER_SESSION_ID` 作为键。会话的每次重新请求都携带相同的会话 ID 和新的订单 ID,因此按会话 ID 命名或去重的工作负载只会创建一次,之后该会话再也不会创建。

2882. **不要重试工作负载。** 一个订单 ID 意味着最多创建一个工作负载。如果运行器从不注册,Anthropic 在 `--expected-spawn-seconds` 后使用新订单 ID 重新请求。3262. **不要重试工作负载。** 一个订单 ID 意味着最多创建一个工作负载。如果运行器从不注册,Anthropic 在 `--expected-spawn-seconds` 后使用新订单 ID 重新请求。

2893. **使用退出码约定。** 退出 0 表示已提交。退出 1 表示可重试失败;会话退避并被重新提供。退出 2 或更高表示不可重试;会话被阻止再次生成,直到 [Owner](/docs/zh-CN/cloud-environments#organization-shared-environments) 在环境的 **Activity** 标签中选择 **Retry**。在非零退出时,hook 的 stderr 尾部出现在那里作为失败原因,因此将可操作的错误写入 stderr,永远不要写密钥。对于预热请求,没有会话失败:编排器仅在本地记录非零退出,服务器在租约后重新请求生成。3273. **使用退出码约定。** 以与结果相匹配的状态退出:

2904. **将 `--expected-spawn-seconds` 设置为至少您的 p99 启动时间。** 这是服务器端租约。所有编排器副本必须使用相同的值。328 

329 * **退出 0**:已提交。

330 * **退出 1**:可重试失败。会话退避并被重新提供。

331 * **退出 2 或更高**:不可重试失败。会话被阻止再次生成,直到用户向其发送新消息,或 [Owner](/docs/zh-CN/cloud-environments#organization-shared-environments) 在环境的 **Activity** 标签中对其选择 **Retry**。

332 

333 在非零退出时,hook 的 stderr 尾部会作为失败原因出现在 **Activity** 标签中,因此请将可操作的错误写入 stderr,并且永远不要在其中写入密钥。在 shell hook 中,请[保持暂时性失败可重试](#keep-transient-failures-retryable-in-a-shell-hook)。

334 

335 预热请求没有可失败的会话:编排器仅在本地记录非零退出,服务器在 `--expected-spawn-seconds` 租约到期后重新请求生成。

3364. **将 `--expected-spawn-seconds` 设置为至少您从生成请求到运行器注册的 p99 时间。** 从编排器收到生成请求时开始计算,并包括在您的平台上等待容量的时间以及启动时间。此值是服务器端租约,工作单也随之过期,因此工作负载耗时更长的运行器无法注册。所有编排器副本必须使用相同的值。

291 337 

292hook 写入 stdout 或 stderr 的所有内容都出现在编排器的日志中,凭据会自动脱敏。如果会话保持排队,检查编排器的 `/healthz` 正文以获取队列计数,然后在 [**Cloud environments** 管理页面](https://claude.ai/admin-settings/cloud-environments) 上打开您的环境的 **Activity** 标签:在那里展开失败的会话以获取其生成错误,并选择 **Retry** 以重新请求它。338hook 写入 stdout 或 stderr 的所有内容都出现在编排器的日志中,凭据会自动脱敏。如果会话保持排队,检查编排器的 `/healthz` 正文以获取队列计数,然后在 [**Cloud environments** 管理页面](https://claude.ai/admin-settings/cloud-environments) 上打开您的环境的 **Activity** 标签:在那里展开失败的会话以获取其生成错误,并选择 **Retry** 以重新请求它。

293 339 

294如果会话保持排队,且 **Activity** 标签中没有生成错误,可能意味着 hook 以会话 ID 作为键。要确认这一点,请检查您的平台是否存在该会话第一次生成请求对应的工作负载,而重新请求却没有对应的工作负载。如果是这样,请改为以 `CLAUDE_RUNNER_ORDER_ID` 作为工作负载的键。340如果会话保持排队,且 **Activity** 标签中没有生成错误,可能意味着 hook 以会话 ID 作为键。要确认这一点,请检查您的平台是否存在该会话第一次生成请求对应的工作负载,而重新请求却没有对应的工作负载。如果是这样,请改为以 `CLAUDE_RUNNER_ORDER_ID` 作为工作负载的键。

295 341 

342<h4 id="keep-transient-failures-retryable-in-a-shell-hook">

343 在 shell hook 中保持暂时性失败可重试

344</h4>

345 

346在使用 `set -e` 的 shell hook 中,本可通过重试解决的失败可能会导致会话被阻止。hook 会在失败的命令处停止,并以该命令自身的状态退出,而编排器会对该状态应用退出码约定。许多失败返回 2 或更高的状态,例如命令未安装时返回的 `127`,以及 `curl --fail` 遇到 HTTP 错误时返回的 `22`,因此它们会在第一次失败时就阻止会话。

347 

348已被 hook 阻止的会话会保持阻止状态,直到用户向其发送新消息,或 [Owner](/docs/zh-CN/cloud-environments#organization-shared-environments) 在环境的 **Activity** 标签中对其选择 **Retry**。

349 

350要将此类失败改为退出 1,请将以下几行直接放在 hook 的 `#!` 行下方、任何可能失败的内容之上:

351 

352```bash theme={null}

353set -e

354PERMANENT=; permanent() { printf '%s\n' "$*" >&2; PERMANENT=1; exit 2; }

355trap 'rc=$?; [ "$rc" -eq 0 ] || [ -n "${PERMANENT:-}" ] || exit 1' EXIT

356```

357 

358这几行会改变 hook 其余部分的行为方式,因此添加后请检查 hook 中是否存在以下每种模式:

359 

360* **单独的 `exit 2` 或更高**:设置 trap 后,它会变为退出 1。对于任何重试都无法修复的错误,请改为调用 `permanent` 并附上原因,例如 `permanent "namespace claude-runners does not exist"`。请在主 shell 中调用它,而不要在 `$( )`、`( )` 或管道内调用。

361* **`exec`**:不要以 `exec` 开始 hook 的最后一条命令,因为 `exec` 会替换 shell,trap 将不会运行。

362* **第二个 `EXIT` trap**:第二个 `trap ... EXIT` 会替换第一个,因此请将两者合并为一个 trap。将您的清理命令直接放在 `rc=$?;` 之后,并在每条命令末尾加上 `|| true;`。这样清理在失败和成功时都会运行,而且失败的清理命令不会设置 hook 的退出状态。以下合并后的 trap 展示了其结构,其中 `your-cleanup-command` 代表您自己的命令:

363 

364 ```bash theme={null}

365 trap 'rc=$?; your-cleanup-command || true; [ "$rc" -eq 0 ] || [ -n "${PERMANENT:-}" ] || exit 1' EXIT

366 ```

367* **允许失败的命令**:如果 hook 之前未使用 `set -e`,它现在会在第一条返回非零值的命令处停止,例如未找到任何结果的查找,或被您的平台拒绝的重复提交。如果 hook 会根据结果执行操作,请将该命令作为 `if` 的条件。如果 hook 忽略结果,请在该命令后加上 `|| true`。

368 

369要确认 trap 是否生效,请在 `trap` 行正下方添加一行,调用一个不存在的命令,例如 `no-such-command`。从您的 shell 运行 hook 文件,检查 `echo $?` 是否输出 `1`,然后删除该行。

370 

296<h2 id="send-model-requests-to-bedrock-or-agent-platform">371<h2 id="send-model-requests-to-bedrock-or-agent-platform">

297 将模型请求发送到 Bedrock 或 Agent Platform372 将模型请求发送到 Bedrock 或 Agent Platform

298</h2>373</h2>


381将模型请求发送到 Amazon Bedrock 或 Google Cloud 的 Agent Platform 的会话与 Anthropic API 上的会话存在以下不同:456将模型请求发送到 Amazon Bedrock 或 Google Cloud 的 Agent Platform 的会话与 Anthropic API 上的会话存在以下不同:

382 457 

383* **来自 claude.ai 的策略**:[服务器托管设置](/docs/zh-CN/server-managed-settings)不会传递到这些会话。Owner 在 Claude Code 管理设置中设定的组织策略也不会传递到这些会话,因此 Claude Code 不会在会话中强制执行这些策略。请将您依赖的规则放入 runner 镜像的[托管设置文件](/docs/zh-CN/managed-settings#delivery-mechanisms)中。458* **来自 claude.ai 的策略**:[服务器托管设置](/docs/zh-CN/server-managed-settings)不会传递到这些会话。Owner 在 Claude Code 管理设置中设定的组织策略也不会传递到这些会话,因此 Claude Code 不会在会话中强制执行这些策略。请将您依赖的规则放入 runner 镜像的[托管设置文件](/docs/zh-CN/managed-settings#delivery-mechanisms)中。

459* **账户 skill**:这些会话不会下载用户的 claude.ai 账户中已启用的 skill。请参阅[每个会话的配置是如何组装的](#how-each-session’s-config-is-assembled)。

384* **文件**:用户在 claude.ai 或移动端、桌面端应用中附加到会话的文件不会传递到会话,Claude 也无法通过 [`SendUserFile` 工具](/docs/zh-CN/tools-reference)回传文件。请改为将输入文件放在仓库中或 runner 上。460* **文件**:用户在 claude.ai 或移动端、桌面端应用中附加到会话的文件不会传递到会话,Claude 也无法通过 [`SendUserFile` 工具](/docs/zh-CN/tools-reference)回传文件。请改为将输入文件放在仓库中或 runner 上。

385* **模型选择**:Anthropic 的控制平面会发送每个会话的模型;当会话启动时未指定模型,Claude Code 会使用该提供商的默认模型。runner 会从其传递给会话的环境中移除 `ANTHROPIC_MODEL` 和 `ANTHROPIC_DEFAULT_MODEL`。提供商页面的示例设置了 `ANTHROPIC_MODEL`,但在 runner 的环境中这两个变量都不起作用。[Amazon Bedrock](/docs/zh-CN/amazon-bedrock#4-pin-model-versions) 和 [Agent Platform](/docs/zh-CN/google-vertex-ai#5-pin-model-versions) 的"固定模型版本"中的各模型系列变量确实会传递到会话。它们决定的是 `opus` 等别名解析为哪个模型,而不是完整模型 ID 解析为哪个模型。461* **模型选择**:Anthropic 的控制平面会发送每个会话的模型;当会话启动时未指定模型,Claude Code 会使用该提供商的默认模型。您无法通过 runner 环境中的 `ANTHROPIC_MODEL` 或 `ANTHROPIC_DEFAULT_MODEL` 选择模型,但可以固定别名解析到的模型:

462 * **`ANTHROPIC_MODEL` 和 `ANTHROPIC_DEFAULT_MODEL`**:runner 会从其传递给会话的环境中移除这两个变量,尽管提供商页面的示例设置了 `ANTHROPIC_MODEL`。

463 * **各模型系列的固定变量**:[Amazon Bedrock](/docs/zh-CN/amazon-bedrock#4-pin-model-versions) 和 [Agent Platform](/docs/zh-CN/google-vertex-ai#5-pin-model-versions) 的"固定模型版本"中的变量确实会传递到会话。它们决定的是 `opus` 等别名解析为哪个模型,而不是完整模型 ID 解析为哪个模型。

386* **您的账户不提供的模型**:会话可能在某条消息上失败,并显示指明该模型的错误。请启用您的开发人员可以选择的模型、"固定模型版本"中所述的后台模型,以及[自动模式](/docs/zh-CN/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry)使用的分类器模型。在 Amazon Bedrock 上,请在策略中允许其中的每一个模型。464* **您的账户不提供的模型**:会话可能在某条消息上失败,并显示指明该模型的错误。请启用您的开发人员可以选择的模型、"固定模型版本"中所述的后台模型,以及[自动模式](/docs/zh-CN/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry)使用的分类器模型。在 Amazon Bedrock 上,请在策略中允许其中的每一个模型。

387* **Web 搜索和快速模式**:[Web 搜索](/docs/zh-CN/tools-reference#websearch-tool-behavior)在 Amazon Bedrock 上不可用,[快速模式](/docs/zh-CN/fast-mode)在这两个提供商上均不可用。有关因提供商而异的其他功能,请参阅[因提供商而异的 CLI 功能](/docs/zh-CN/feature-availability#cli-capabilities-that-vary-by-provider)。465* **Web 搜索和快速模式**:[Web 搜索](/docs/zh-CN/tools-reference#websearch-tool-behavior)在 Amazon Bedrock 上不可用,[快速模式](/docs/zh-CN/fast-mode)在这两个提供商上均不可用。有关因提供商而异的其他功能,请参阅[因提供商而异的 CLI 功能](/docs/zh-CN/feature-availability#cli-capabilities-that-vary-by-provider)。

388 466 


411 489 

412会话会继承运行器的环境,因此请在运行器环境中设置 [`ENABLE_TOOL_SEARCH`](/docs/zh-CN/mcp#scale-with-mcp-tool-search),以控制该运行器生成的每个会话的 MCP 工具搜索;MCP 页面介绍了可用的值。490会话会继承运行器的环境,因此请在运行器环境中设置 [`ENABLE_TOOL_SEARCH`](/docs/zh-CN/mcp#scale-with-mcp-tool-search),以控制该运行器生成的每个会话的 MCP 工具搜索;MCP 页面介绍了可用的值。

413 491 

492<a id="connection-timing" />

493 

494<h3 id="wait-for-mcp-servers-before-the-first-turn">

495 在第一轮之前等待 MCP 服务器

496</h3>

497 

498自托管会话会在两个不同的时间点短暂等待仍在连接中的 MCP 服务器。错过等待的服务器,其工具在第一轮开始时不可用,之后会自动变为可用,无需您进行任何操作。这两次等待分别是:

499 

500* **会话启动**:在首次获取工具列表之前,会话默认最多等待 5 秒,等待条目中设置了 [`alwaysLoad: true`](/docs/zh-CN/mcp#exempt-a-server-from-deferral) 的 HTTP 或 SSE 服务器;如果您在运行器的环境中设置了 [`MCP_CONNECTION_NONBLOCKING=0`](/docs/zh-CN/env-vars),则会等待所有服务器。否则,HTTP 和 SSE 服务器会在后台连接。会话在此处等待期间,初始化会变慢。[`MCP_CONNECT_TIMEOUT_MS`](/docs/zh-CN/env-vars) 可更改 5 秒的默认值。

501* **第一轮**:消息到达后,第一轮最多等待 2 秒,等待仍在连接中的 stdio 服务器。会话在此处等待期间,第一条回复会变慢。要更改此等待的时长,请在运行器的环境中设置 [`CLAUDE_CODE_MCP_STARTUP_WAIT_MS`](/docs/zh-CN/env-vars)。它不会改变此等待涵盖哪些服务器。需要 Claude Code v2.1.274 或更高版本。

502 

503`claude mcp add` 没有 `alwaysLoad` 标志。要设置该键,请改用 `claude mcp add-json` 添加服务器,该命令从服务器的 JSON 中接收该键并将其写入 `.claude.json`。在您的 Dockerfile 中:

504 

505```dockerfile theme={null}

506RUN claude mcp add-json core '{"type":"http","url":"https://mcp.example.com/mcp","alwaysLoad":true}' --scope user

507```

508 

509如果某个服务器的工具在后续轮次中也没有出现,请按照 [MCP 服务器](#mcp-servers)中的说明,检查该服务器是否到达了会话。

510 

414<h3 id="turn-off-built-in-session-tools">511<h3 id="turn-off-built-in-session-tools">

415 关闭内置会话工具512 关闭内置会话工具

416</h3>513</h3>


571 668 

572设置 `SELF_HOSTED_RUNNER_HOST_CONFIG_DIR` 可从其他路径获取初始内容,或将其指向空目录以禁用初始内容填充。669设置 `SELF_HOSTED_RUNNER_HOST_CONFIG_DIR` 可从其他路径获取初始内容,或将其指向空目录以禁用初始内容填充。

573 670 

574仓库中提交的 `.claude/settings.json` 会作为项目设置叠加在其上。在包含多个仓库的会话中,[最多只有一个仓库的文件生效](#repository-settings-in-sessions-with-several-repositories)。会话还会从运行器镜像中的标准系统路径读取 [`managed-settings.json`](/docs/zh-CN/settings#where-settings-live)。其中的键是否与[服务器托管设置](/docs/zh-CN/server-managed-settings)一起应用,取决于 [Claude Code 如何合并托管来源](/docs/zh-CN/managed-settings#how-claude-code-combines-managed-sources):默认情况下,当您的组织下发了任何服务器托管的键时,会话会忽略运行器镜像中的该文件,但 [Claude Code 从每个管理员来源读取的键](/docs/zh-CN/managed-settings#keys-read-from-every-admin-source)除外,例如 `env` 块、沙箱锁定、沙箱二进制路径和 `forceRemoteSettingsRefresh`。请参阅[设置优先级](/docs/zh-CN/settings#settings-precedence)。671会话还会读取以下设置文件:

672 

673* **项目设置**:仓库中提交的 `.claude/settings.json` 会叠加在用户级基线之上。在包含多个仓库的会话中,[最多只有一个仓库的文件生效](#repository-settings-in-sessions-with-several-repositories)。

674* **托管设置**:会话会从运行器镜像中的标准系统路径读取 [`managed-settings.json`](/docs/zh-CN/settings#where-settings-live)。关于其中的键是否与[服务器托管设置](/docs/zh-CN/server-managed-settings)一起应用,请参阅 [Claude Code 如何合并托管来源](/docs/zh-CN/managed-settings#how-claude-code-combines-managed-sources)。

675 

676有关这些来源的应用顺序,请参阅[设置优先级](/docs/zh-CN/settings#settings-precedence)。

575 677 

576当 Anthropic 的控制平面为会话提供 [Claude Code hook](/docs/zh-CN/hooks) 时,运行器会将它们与您自己的配置并行安装,而不是覆盖您的配置。需要 Claude Code v2.1.229 或更高版本。678当 Anthropic 的控制平面为会话提供 [Claude Code hook](/docs/zh-CN/hooks) 时,运行器会将它们与您自己的配置并行安装,而不是覆盖您的配置。需要 Claude Code v2.1.229 或更高版本。

577 679 


579* **编写者**:控制平面使用其自身部署中的固定常量填充这些脚本,绝不使用按会话或第三方的输入。681* **编写者**:控制平面使用其自身部署中的固定常量填充这些脚本,绝不使用按会话或第三方的输入。

580* **仍然适用的管控**:通过 `--settings` 下发的 hook 会进入普通的合并 hook 配置,而不是托管层,因此您的托管设置仍然适用。`disableAllHooks` 会禁用它们,并且它们不属于 [`allowManagedHooksOnly`](/docs/zh-CN/settings-reference#allowmanagedhooksonly) 保持加载的类别。682* **仍然适用的管控**:通过 `--settings` 下发的 hook 会进入普通的合并 hook 配置,而不是托管层,因此您的托管设置仍然适用。`disableAllHooks` 会禁用它们,并且它们不属于 [`allowManagedHooksOnly`](/docs/zh-CN/settings-reference#allowmanagedhooksonly) 保持加载的类别。

581 683 

684当某人启动自己的会话时,Claude Code 还会将[其 claude.ai 账户中启用的 skill](/docs/zh-CN/skills#skills-in-cowork-and-cloud-sessions) 下载到该会话的配置目录中。[Routine](/docs/zh-CN/routines) 运行不会获得其所有者的 skill,而[将模型请求发送到 Bedrock 或 Agent Platform](#send-model-requests-to-bedrock-or-agent-platform) 的会话不会下载任何 skill。对于这些会话需要的 skill,请将其提交到仓库的 `.claude/skills/` 中,或将其添加到您的运行器镜像中。

685 

582除 [Claude Tag](https://claude.com/docs/claude-tag/overview) 会话外,自托管环境中的会话默认关闭[自动记忆](/docs/zh-CN/memory#auto-memory)。对于需要跨会话保留的指令,请使用运行器镜像或仓库中的 `CLAUDE.md`。686除 [Claude Tag](https://claude.com/docs/claude-tag/overview) 会话外,自托管环境中的会话默认关闭[自动记忆](/docs/zh-CN/memory#auto-memory)。对于需要跨会话保留的指令,请使用运行器镜像或仓库中的 `CLAUDE.md`。

583 687 

584运行器对主机 `~/.claude/` 的快照不包含 `projects/` 目录。自动记忆的默认存储位置就在该目录下。如果您将记忆文件放在那里,运行器不会将它们填充到会话中,它们也不会启用自动记忆。688运行器对主机 `~/.claude/` 的快照不包含 `projects/` 目录。自动记忆的默认存储位置就在该目录下。如果您将记忆文件放在那里,运行器不会将它们填充到会话中,它们也不会启用自动记忆。

Details

20 20 

21* **临时的、按会话的容器**:在新容器或 VM 中运行每个运行器进程,该容器或 VM 在进程退出时被销毁,使用 `--capacity 1` 和默认的 `--drain-grace-sec 0`,以便每个容器恰好服务一个会话。在更高的容量或正的 drain grace 下,一个容器为来自同一[锁定所有者](/docs/zh-CN/self-hosted-environments#key-concepts)的多个会话服务;请参阅[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)。不要在运行器重启之间重用文件系统,除了在刻意的[预热检出](#reuse-a-pre-warmed-checkout)设置中,并且永远不要跨所有者。21* **临时的、按会话的容器**:在新容器或 VM 中运行每个运行器进程,该容器或 VM 在进程退出时被销毁,使用 `--capacity 1` 和默认的 `--drain-grace-sec 0`,以便每个容器恰好服务一个会话。在更高的容量或正的 drain grace 下,一个容器为来自同一[锁定所有者](/docs/zh-CN/self-hosted-environments#key-concepts)的多个会话服务;请参阅[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)。不要在运行器重启之间重用文件系统,除了在刻意的[预热检出](#reuse-a-pre-warmed-checkout)设置中,并且永远不要跨所有者。

22 * <span id="processes-a-stopped-session-leaves" />当运行器停止会话时,它不会向在其 shell 命令退出后仍在运行的进程(例如已转为守护进程的服务)发送任何信号。销毁容器或 VM 会结束该进程。22 * <span id="processes-a-stopped-session-leaves" />当运行器停止会话时,它不会向在其 shell 命令退出后仍在运行的进程(例如已转为守护进程的服务)发送任何信号。销毁容器或 VM 会结束该进程。

23* **镜像中没有广泛的凭证**:不要包含长期的 SSH 密钥、云提供商凭证或授予超过会话需要的个人访问令牌。从您的[包装脚本](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts)按会话铸造会话期间使用的凭证,例如推送或 API 令牌。对于在包装脚本运行之前发生的初始克隆,使用 [`checkout` 生命周期钩子](/docs/zh-CN/self-hosted-environments-configuration#checkout)或 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy);请参阅[配置 git](#configure-git)。23* **镜像中没有广泛的凭据**:不要包含长期的 SSH 密钥、云提供商凭据或授予超过会话需要的个人访问令牌。从您的[包装脚本](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts)按会话铸造会话期间使用的凭据,例如推送或 API 令牌。初始克隆发生在包装脚本运行之前,因此请使用 [`checkout` 生命周期 hook](/docs/zh-CN/self-hosted-environments-configuration#checkout) 处理它,或者在会话的所有仓库都位于 github.com 上时使用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy)。关于这两者,请参阅[配置 git](#configure-git)。

24* **使主机的 GitHub 凭据远离会话**:Claude 可以使用会话能够读取的任何 GitHub 凭据,并拥有该凭据授予的全部访问权限。请确保运行器主机自身的宽范围 GitHub 凭据不出现在会话可以读取的任何位置。此类凭据可以是个人访问令牌、`gh auth login` 为您的帐户保存的令牌,或运行器环境中的 `GH_TOKEN`。

25 * **使用 [Anthropic 托管的 git](#use-the-anthropic-git-proxy) 时**:有了此类凭据,Claude 会直接访问 GitHub,而不是通过 Anthropic 托管的 git。

26 * **不使用 Anthropic 托管的 git 时**:如果您按照[在镜像中附带 git 配置](#ship-git-config-in-your-image)所述严格限定克隆凭据的范围,则该凭据可以保留在镜像中。

24* **将环境密钥保持在运行会话的主机之外**:环境密钥可以注册运行器并获取在环境上排队的任何会话。在固定队列上,它存在于每个运行器主机上,任何会话的代码都可以读取密钥文件。优先使用[按需运行器](/docs/zh-CN/self-hosted-environments-configuration#on-demand-runners),其中密钥保留在编排器主机上,该主机从不运行用户代码,每个运行器接收单次使用的工作单,恰好注册一个运行器。在固定队列上,将环境密钥文件视为可由每个会话读取,并在任何可疑会话泄露后轮换密钥。27* **将环境密钥保持在运行会话的主机之外**:环境密钥可以注册运行器并获取在环境上排队的任何会话。在固定队列上,它存在于每个运行器主机上,任何会话的代码都可以读取密钥文件。优先使用[按需运行器](/docs/zh-CN/self-hosted-environments-configuration#on-demand-runners),其中密钥保留在编排器主机上,该主机从不运行用户代码,每个运行器接收单次使用的工作单,恰好注册一个运行器。在固定队列上,将环境密钥文件视为可由每个会话读取,并在任何可疑会话泄露后轮换密钥。

25* **默认拒绝网络出站流量**:在每个环境上限制运行器和会话容器的出站流量在您自己的网络边界;[默认拒绝出站流量](#default-deny-egress)涵盖允许什么以及原因。28* **默认拒绝网络出站流量**:在每个环境上限制运行器和会话容器的出站流量在您自己的网络边界;[默认拒绝出站流量](#default-deny-egress)涵盖允许什么以及原因。

26* **最小权限主机 IAM**:附加到运行器主机的计算身份(例如实例配置文件或节点服务帐户)应仅授予运行器本身需要的内容。会话应通过您的包装脚本而不是继承主机的身份获取自己的凭证。29* **最小权限主机 IAM**:附加到运行器主机的计算身份(例如实例配置文件或节点服务帐户)应仅授予运行器本身需要的内容。会话应通过您的包装脚本而不是继承主机的身份获取自己的凭证。


42 无论 [`--trust-workspace`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 如何,保护都会运行,并且不涵盖存储库钩子、`.mcp.json` 或 Bash 规则;请参阅[权限和工具批准](/docs/zh-CN/self-hosted-environments-configuration#permissions-and-tool-approval)了解这些授予的位置。45 无论 [`--trust-workspace`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 如何,保护都会运行,并且不涵盖存储库钩子、`.mcp.json` 或 Bash 规则;请参阅[权限和工具批准](/docs/zh-CN/self-hosted-environments-configuration#permissions-and-tool-approval)了解这些授予的位置。

43 46 

44<Note>47<Note>

45 您组织的 IP 允许列表默认不涵盖自托管运行器流量。不要将其作为运行器或会话流量的网络控制;而是在您自己的网络边界应用默认拒绝出站流量,如果您想为您的组织强制执行 IP 允许列表,请联系您的 Anthropic 帐户团队。48 如果您的组织启用了 [IP 允许列表](https://support.claude.com/en/articles/13200993-restrict-access-to-claude-with-ip-allowlisting),请在启动运行器和会话容器之前,将它们的公共出站地址添加到允许列表中。如果您运行[按需运行器](/docs/zh-CN/self-hosted-environments-configuration#on-demand-runners),还需添加编排器主机的地址。不要将允许列表作为运行器或会话流量的网络控制,而应在您自己的网络边界应用默认拒绝出站流量。

46</Note>49</Note>

47 50 

48<h2 id="network-requirements">51<h2 id="network-requirements">


55 58 

56| 主机 | 端口 | 用途 |59| 主机 | 端口 | 用途 |

57| :- | :- | :- |60| :- | :- | :- |

58| `api.anthropic.com` | 443,HTTPS;仅 SCM 连接器的 WSS | 运行器控制平面和会话流式传输、模型推理、功能标志、产品分析、[JWKS](/docs/zh-CN/self-hosted-environments-identity) 密钥获取、提交签名、设置 `--use-anthropic-git-proxy` 时的 git 代理,以及设置 `--scm-connector-host` 时编排器的 [SCM 连接器](/docs/zh-CN/self-hosted-environments-reference#scm-connector-flags)隧道 |61| `api.anthropic.com` | 443,HTTPS;[Anthropic 托管的 git](#use-the-anthropic-git-proxy) 使用 WSS | 运行器控制平面和会话流式传输、模型推理、功能标志、产品分析、[JWKS](/docs/zh-CN/self-hosted-environments-identity) 密钥获取、提交签名,以及设置 `--use-anthropic-git-proxy` 时的 Anthropic 托管 git |

59| 您的 git 主机,例如 `github.com` 或您的 GitHub Enterprise 主机 | 443 或 22 | 克隆和推送存储库。如果运行器使用 `--use-anthropic-git-proxy`(通过 `api.anthropic.com` 路由 git 流量)则不需要。 |62| 您的 git 主机,例如 `github.com` 或您的 GitHub Enterprise 主机 | 443 或 22 | 在运行器会话使用的每个 git 主机上克隆和推送仓库。对于使用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 的运行器,请参阅[何时仍需要 `github.com` 路径](#github-com-egress-with-the-anthropic-git-proxy)。 |

63 

64<span id="github-com-egress-with-the-anthropic-git-proxy" />使用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 的运行器通过 `api.anthropic.com` 路由其 `github.com` git 流量,因此不需要 `github.com` 的 git 主机路径。如果您设置了 `--push-outcome-on-release` 或从 `post-session` hook 推送,则仍需要该路径。

60 65 

61这些主机是否需要取决于您的配置:66这些主机是否需要取决于您的配置:

62 67 


71| `browser-intake-us5-datadoghq.com` | 443 | Anthropic 错误报告上传,仅在为会话帐户启用[错误报告](/docs/zh-CN/data-usage#telemetry-services)时发送。由 `DISABLE_ERROR_REPORTING=1` 或 `DISABLE_TELEMETRY=1` 抑制。 |76| `browser-intake-us5-datadoghq.com` | 443 | Anthropic 错误报告上传,仅在为会话帐户启用[错误报告](/docs/zh-CN/data-usage#telemetry-services)时发送。由 `DISABLE_ERROR_REPORTING=1` 或 `DISABLE_TELEMETRY=1` 抑制。 |

72| 您的云提供商用于模型请求、模型查询和续期凭据的端点,例如 `bedrock-runtime.us-east-1.amazonaws.com` 或 `aiplatform.googleapis.com` | 443 | 仅当运行器[将模型请求发送到 Amazon Bedrock 或 Google Cloud 的 Agent Platform](/docs/zh-CN/self-hosted-environments-configuration#send-model-requests-to-bedrock-or-agent-platform) 时 |77| 您的云提供商用于模型请求、模型查询和续期凭据的端点,例如 `bedrock-runtime.us-east-1.amazonaws.com` 或 `aiplatform.googleapis.com` | 443 | 仅当运行器[将模型请求发送到 Amazon Bedrock 或 Google Cloud 的 Agent Platform](/docs/zh-CN/self-hosted-environments-configuration#send-model-requests-to-bedrock-or-agent-platform) 时 |

73 78 

74运行器不会到达 `statsig.anthropic.com`、`*.sentry.io`、`claude.ai` 或 `platform.claude.com`。这些主机出现在一些较旧的企业网络检查清单中,但您不需要为运行器或会话流量允许列表它们:功能标志获取转到 `api.anthropic.com`,运行器使用环境密钥而不是交互式 OAuth 进行身份验证。两个主机端流程确实到达 `claude.ai`,因此从其出站允许它的主机运行它们,而不是扩大会话容器出站流量:单行安装程序在安装时从 `claude.ai` 获取 `install.sh`,交互式 `claude auth login`([引导设置](/docs/zh-CN/self-hosted-environments-quickstart#set-up-an-environment-and-runner)、`doctor` 的已登录模式和 [CI 分派](/docs/zh-CN/self-hosted-environments-testing#authenticate-from-ci)使用)通过 `claude.ai`、`claude.com` 和 `platform.claude.com` 登录。`mcp-proxy.anthropic.com` 也不是必需的:自托管会话不使用它,当为您的组织启用时,您组织的 claude.ai 连接器向会话的交付通过 `api.anthropic.com` 路由。请参阅 [MCP 服务器](/docs/zh-CN/self-hosted-environments-configuration#mcp-servers)。79您不需要为运行器或会话流量将以下主机加入允许列表:

80 

81* **`statsig.anthropic.com`、`*.sentry.io`、`claude.ai` 和 `platform.claude.com`**:这些主机出现在一些较旧的企业网络检查清单中,但运行器不会访问它们。功能标志获取转到 `api.anthropic.com`,运行器使用环境密钥而不是交互式 OAuth 进行身份验证。

82* **`mcp-proxy.anthropic.com`**:自托管会话不使用它。当为您的组织启用连接器交付时,您组织的 claude.ai 连接器通过 `api.anthropic.com` 到达会话。请参阅 [MCP 服务器](/docs/zh-CN/self-hosted-environments-configuration#mcp-servers)。

83 

84以下主机端流程确实会访问 `claude.ai`,因此请从出站流量允许访问它的主机运行这些流程,而不是扩大会话容器出站流量:

85 

86* **单行安装程序**:在安装时从 `claude.ai` 获取 `install.sh`。

87* **交互式 `claude auth login`**:通过 `claude.ai`、`claude.com` 和 `platform.claude.com` 登录。[引导设置](/docs/zh-CN/self-hosted-environments-quickstart#run-the-guided-setup)、`doctor` 的已登录模式和 [CI 分派](/docs/zh-CN/self-hosted-environments-testing#authenticate-from-ci)会使用它。您用于登录的浏览器还会从 `hcaptcha.com`、`*.hcaptcha.com` 和 `challenges.cloudflare.com` 加载 claude.ai 登录页面的浏览器检查。

75 88 

76<h3 id="default-deny-egress">89<h3 id="default-deny-egress">

77 默认拒绝出站流量90 默认拒绝出站流量


127* **让运行器配置 git**:使用 `--configure-git` 启动运行器,使其写入 Anthropic 托管会话使用的相同身份和提交签名配置140* **让运行器配置 git**:使用 `--configure-git` 启动运行器,使其写入 Anthropic 托管会话使用的相同身份和提交签名配置

128* **在镜像中提供 git 配置**:自己设置身份和推送凭证,例如在您自己的机器人身份下提交141* **在镜像中提供 git 配置**:自己设置身份和推送凭证,例如在您自己的机器人身份下提交

129 142 

143对于 github.com 上的仓库,您还可以使用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 启动运行器,或设置 `CLAUDE_RUNNER_USE_GIT_PROXY=1`,以请求 Anthropic 为运行器的会话提供 git 服务。

144 

130运行器主机上的 Git 版本下限:[`--configure-git`](#let-the-runner-configure-git) SSH 提交签名需要 Git 2.34 或更高版本,[`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 需要 2.32 或更高版本,从 [`--push-outcome-on-release`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 推送的分支恢复会话需要 2.29 或更高版本。如果您省略所有三个并自己管理 git 身份,Git 2.24 就足够了。145运行器主机上的 Git 版本下限:[`--configure-git`](#let-the-runner-configure-git) SSH 提交签名需要 Git 2.34 或更高版本,[`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 需要 2.32 或更高版本,从 [`--push-outcome-on-release`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 推送的分支恢复会话需要 2.29 或更高版本。如果您省略所有三个并自己管理 git 身份,Git 2.24 就足够了。

131 146 

132<h3 id="let-the-runner-configure-git">147<h3 id="let-the-runner-configure-git">


138* `user.name = Claude` 和 `user.email = noreply@anthropic.com`,与 Anthropic 托管会话匹配153* `user.name = Claude` 和 `user.email = noreply@anthropic.com`,与 Anthropic 托管会话匹配

139* SSH 格式提交和标签签名,通过运行器管理的垫片路由,使用会话自己的凭证通过 Anthropic 的签名服务签署每个提交。签名可在 GitHub 上针对 Anthropic 的已发布 SSH 签名密钥进行验证。154* SSH 格式提交和标签签名,通过运行器管理的垫片路由,使用会话自己的凭证通过 Anthropic 的签名服务签署每个提交。签名可在 GitHub 上针对 Anthropic 的已发布 SSH 签名密钥进行验证。

140* `push.negotiate = true`,所以 git 在打包推送之前询问您的 git 主机它已经拥有哪些提交。需要 Claude Code v2.1.257 或更高版本。155* `push.negotiate = true`,所以 git 在打包推送之前询问您的 git 主机它已经拥有哪些提交。需要 Claude Code v2.1.257 或更高版本。

141* `core.hooksPath` 指向运行器管理的钩子目录。其 `commit-msg` 和 `prepare-commit-msg` 钩子为每个提交添加 `Co-authored-by:` 预告片,用于会话的创建者,从 [`CCR_SESSION_ACCOUNT_EMAIL`](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts) 构建,当该变量未设置时省略。如果您的镜像已设置 `core.hooksPath`,运行器保留您的设置,跳过安装这些钩子,并打印 `[runner:git]` 警告。156* `core.hooksPath` 指向运行器管理的钩子目录。其 `commit-msg` 和 `prepare-commit-msg` 钩子为每个提交添加会话创建者的 `Co-authored-by:` 尾注。该尾注根据 [`CCR_SESSION_ACCOUNT_EMAIL`](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts) 中的电子邮件构建,当该变量未设置时省略。如果您的镜像已设置 `core.hooksPath`,且运行器未使用 [Anthropic 管理的 git](#use-the-anthropic-git-proxy),运行器会保留您的设置,跳过安装这些钩子,并打印 `[runner:git]` 警告。

142 157 

143提交签名需要 git 2.34 或更高版本;运行器在启动时检查并在您的 git 较旧时以错误退出。此标志不配置推送凭证,您仍然在镜像中提供。158提交签名需要 git 2.34 或更高版本;运行器在启动时检查并在您的 git 较旧时以错误退出。此标志不配置推送凭证,您仍然在镜像中提供。

144 159 

145在 v2.1.280 或更高版本的运行器上,您从 `checkout` 或 `post-session` 生命周期钩子中进行的提交也会以会话身份签名,但不带 `Co-authored-by:` 尾注。[生命周期钩子内的 Git 配置](/docs/zh-CN/self-hosted-environments-configuration#git-configuration-inside-lifecycle-hooks)介绍了运行器在这些钩子内固定的 git 设置。160在 v2.1.280 或更高版本的运行器上,您从 `checkout` 或 `post-session` 生命周期钩子中进行的提交也会以会话身份签名,但不带 `Co-authored-by:` 尾注。[生命周期钩子内的 Git 配置](/docs/zh-CN/self-hosted-environments-configuration#git-configuration-inside-lifecycle-hooks)介绍了运行器在这些钩子内固定的 git 设置。

146 161 

162无论是否使用 `--configure-git`,Claude Code 都会指示 Claude 在其提交信息末尾添加 `Claude-Session: <url>` 尾注,并在其 Pull Request 描述末尾添加会话的 URL。要省略两者,请在运行器主机的 [`~/.claude/settings.json`](/docs/zh-CN/self-hosted-environments-configuration#how-each-session’s-config-is-assembled) 中将 [`attribution.sessionUrl`](/docs/zh-CN/settings-reference#attribution-sessionurl) 设置为 `false`,然后重新启动运行器。

163 

147<h3 id="ship-git-config-in-your-image">164<h3 id="ship-git-config-in-your-image">

148 在镜像中提供 git 配置165 在镜像中提供 git 配置

149</h3>166</h3>


186 使用 Anthropic git 代理203 使用 Anthropic git 代理

187</h3>204</h3>

188 205 

189使用 `--use-anthropic-git-proxy` 启动运行器,或设置 `CLAUDE_RUNNER_USE_GIT_PROXY=1`,使其通过 Anthropic 的 git 代理克隆,使用会话自己的短期令牌进行身份验证。对于普通用户会话,代理使用为会话创建者存储的 GitHub 或 GitHub Enterprise OAuth 令牌;对于机器人和代理会话,它使用您组织的 GitHub App 安装令牌。无论哪种方式,运行器镜像根本不需要 git 凭证:没有 SSH 密钥、没有凭证助手、没有 `.netrc`。这是 Anthropic 托管环境使用的相同身份验证路径。206使用 Anthropic git 代理(也称为 Anthropic 管理的 git)时,运行器镜像无需为会话本身提供 SSH 密钥、凭据助手、`.netrc` 或其他 git 凭据。相反,运行器请求 Anthropic 为其会话提供 git 服务。对于 Anthropic 提供服务的用户会话,运行器的克隆以及会话自身的获取和推送都经过 Anthropic,Anthropic 使用为会话创建者存储的 GitHub OAuth 令牌。[Anthropic 如何为会话提供 git 服务](#how-anthropic-serves-git-for-a-session)介绍了机器人和 Agent 会话的情况。

207 

208除非您[启用它](#turn-the-anthropic-git-proxy-on),否则 git 代理处于关闭状态。使用自身凭据访问您的 git 主机的运行器不需要它,其 git 可与任何 git 主机配合使用。

209 

210作为交换,git 代理会限制运行器支持的内容,并改变运行器的需求:

211 

212* **仅限 github.com**:只有当会话的所有仓库都在 github.com 上时,Anthropic 才会为其提供服务,并且 git 代理尚不支持 GitHub Enterprise Server。在启用 git 代理的运行器上,包含其他 git 主机上仓库的会话[无法启动](#when-anthropic-doesnt-serve-a-session)。

213* **已连接的 GitHub 账户**:创建用户会话的人必须已在 claude.ai 上连接 GitHub,否则会话[无法启动](#creator-has-no-github-connection)。

214* **`--capacity 1`**:git 代理要求每个运行器进程只有一个会话,因此请运行更多副本以获得并行性。[启用 Anthropic git 代理](#turn-the-anthropic-git-proxy-on)列出了各项要求。

215* **替换全局 git 配置**:运行器会[删除并替换其运行用户的全局 git 配置](#git-proxy-replaces-global-git-config)。请以专用用户身份或在容器中运行它。

216* **主机推送使用主机凭据**:运行器的 [`--push-outcome-on-release`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 推送以及您的 [`post-session` 钩子](/docs/zh-CN/self-hosted-environments-configuration#post-session)进行的任何推送,仍使用运行器主机自身的 git 凭据及其[到 `github.com` 的网络路径](#github-com-egress-with-the-anthropic-git-proxy)。有关这些凭据,请参阅[在镜像中提供 git 配置](#ship-git-config-in-your-image)。

217* **按会话决定**:Anthropic 会针对运行器上的每个会话决定是否为其提供 git 服务,未获服务的会话将无法启动。[在启用 git 代理的运行器上会话无法启动时](#when-anthropic-doesnt-serve-a-session)介绍了原因。

218 

219<span id="git-proxy-replaces-global-git-config" />

220 

221<Warning>

222 设置 `--use-anthropic-git-proxy` 后,运行器会删除并替换其运行用户的全局 git 配置,且不保留备份。它会在启动时以及每个会话之前执行此操作。您保存在其中的登录或凭据助手将会丢失。[`--configure-git`](#let-the-runner-configure-git) 写入的设置会保留。请以专用用户身份或在容器中运行运行器,切勿以您自己的用户身份运行。

223</Warning>

224 

225将非机密的 git 设置(例如身份和 `safe.directory`)保存在系统 git 配置中。

226 

227<h4 id="turn-the-anthropic-git-proxy-on">

228 启用 Anthropic git 代理

229</h4>

230 

231在使用 `--use-anthropic-git-proxy` 启动运行器之前,请确认运行器主机满足以下每项要求。当容量或 git 要求未满足时,运行器会拒绝启动:

190 232 

191代理需要 `--capacity 1`,因为代理 URL 是按会话的,以及 git 2.32 或更高版本,因为较旧的 git 忽略代理用来隔离会话的配置机制。如果任一要求未满足,运行器拒绝启动。因为代理从 Anthropic 端获取,您的 git 主机必须可从 Anthropic 基础设施到达,与 Anthropic 托管会话相同的要求;对于仅在您的网络内可路由的 git 主机,改用 [`checkout` 生命周期钩子](/docs/zh-CN/self-hosted-environments-configuration#checkout)。每个运行器进程一次处理一个会话,因此运行更多副本以获得并行性。启用代理后,`--git-host-rewrite` 和 `--git-ssh-rewrite` 无效:代理 URL 指向 `api.anthropic.com`,而不是您的 git 主机。233* **Claude Code v2.1.267 或更高版本**:较早的版本接受该标志,但不会报告请求 Anthropic 提供 git 服务,也不会打印 `Registering as opted in` 行,因此 Anthropic 不会为其会话提供服务。

234* **`--capacity 1`(默认值)**:每个运行器进程一次处理一个会话,因此请运行更多副本以获得并行性。

235* **Git 2.32 或更高版本**:较旧的 git 会忽略运行器为 git 代理设置的按会话 git 配置。

192 236 

193<Warning>237<Warning>

194 本页上的 [Kubernetes](#kubernetes) 和 [Docker Compose](#docker-compose) 配方使用 `--capacity 4`。如果您在不将容量更改为 `1` 的情况下向其中一个添加 `--use-anthropic-git-proxy` 或 `CLAUDE_RUNNER_USE_GIT_PROXY=1`,每次您的编排器重新启动它时,运行器都会在启动时退出。设置 `--capacity 1` 并运行更多副本以获得并行性。[当运行器退出](#when-the-runner-exits)显示运行器打印的行。238 本页上的 [Kubernetes](#kubernetes) 和 [Docker Compose](#docker-compose) 配方使用 `--capacity 4`。如果您在不将容量更改为 `1` 的情况下向其中一个添加 `--use-anthropic-git-proxy` 或 `CLAUDE_RUNNER_USE_GIT_PROXY=1`,每次您的编排器重新启动它时,运行器都会在启动时退出。设置 `--capacity 1` 并运行更多副本以获得并行性。[当运行器退出](#when-the-runner-exits)显示运行器打印的行。

195</Warning>239</Warning>

196 240 

197运行器还在注册时向 Anthropic 报告选择加入,在启动时打印 `Registering as opted in to Anthropic-managed git (--use-anthropic-git-proxy)`。报告选择加入需要 Claude Code v2.1.267 或更高版本,较早的版本接受该标志而不报告它或打印该行。选择加入运行器上的每个会话然后使用 Anthropic 管理的 git 或按会话代理 URL。当会话使用按会话代理 URL 时,运行器记录一行 `[runner:warn]` 说明这一点。241要启用 git 代理,请将 `--use-anthropic-git-proxy` 添加到运行器的命令中,或在运行器的环境中设置 `CLAUDE_RUNNER_USE_GIT_PROXY=1`。在运行器主机的 shell 中运行以下命令,即可启动启用了 git 代理的[快速入门](/docs/zh-CN/self-hosted-environments-quickstart#set-up-manually)运行器:

242 

243```bash theme={null}

244claude self-hosted-runner --environment-secret-file '/etc/claude/environment-secret' --base-dir '<writable-dir>' --use-anthropic-git-proxy

245```

246 

247启动时,运行器会打印 `Registering as opted in to Anthropic-managed git (--use-anthropic-git-proxy)`。随后 Anthropic 会针对该运行器上的每个会话决定是否为其提供 git 服务。对于每个获得服务的会话,运行器会记录一行包含 `governed git ACTIVE` 的 `[runner:session]` 日志。如果会话反而无法启动,请参阅[在启用 git 代理的运行器上会话无法启动时](#when-anthropic-doesnt-serve-a-session)。

248 

249<h4 id="how-anthropic-serves-git-for-a-session">

250 Anthropic 如何为会话提供 git 服务

251</h4>

252 

253对于 Anthropic 提供服务的会话,运行器的克隆以及会话自身的获取和推送都经过 Anthropic,并使用会话自己的短期令牌进行身份验证:

254 

255* **用户会话**:Anthropic 使用为会话创建者存储的 GitHub OAuth 令牌。

256* **机器人和 Agent 会话**:Anthropic 使用您组织的 GitHub App 安装令牌。

257* **URL 重写**:`--git-host-rewrite` 和 `--git-ssh-rewrite` 对 git 代理提供服务的仓库无效。

258 

259<h4 id="when-anthropic-doesnt-serve-a-session">

260 在启用 git 代理的运行器上会话无法启动时

261</h4>

262 

263在使用 `--use-anthropic-git-proxy` 启动的运行器上,当 Anthropic 不为会话提供 git 服务时,会话将无法启动。请在运行器的日志中查找提及包含 `/git_proxy/` 的 `api.anthropic.com` 地址的 git 错误。

264 

265对于每个会话,Claude Code v2.1.267 或更高版本的运行器还会记录以下两者之一:当 Anthropic 为会话提供 git 服务时,记录一行包含 `governed git ACTIVE` 的 `[runner:session]` 日志;当不提供服务时,记录一行包含 `the server withheld Anthropic-managed git for this session` 的 `[runner:warn]` 日志。在以下情况中找到您看到的行:

266 

267* **既没有 `governed git ACTIVE` 也没有 `withheld` 行**:早于 Claude Code v2.1.267 的运行器不会记录这两行中的任何一行,Anthropic 也不会为其会话提供服务。请按照[固定版本](#pin-the-version)将运行器更新到 v2.1.267 或更高版本。

268* **`withheld` 行**:Anthropic 未为该会话提供服务。之前可以正常使用 git 代理的运行器,即使您这边没有任何更改,也可能以这种方式失败。

269 * **某个仓库不在 github.com 上**:只要会话中有一个仓库位于其他 git 主机(例如 GitHub Enterprise Server)上,该会话就不会获得服务,其 github.com 仓库也不例外。请为该环境的运行器[关闭 Anthropic git 代理](#turn-the-anthropic-git-proxy-off)。

270 * **所有仓库都在 github.com 上**:请将此失败连同 `withheld` 行中的会话 ID 一起报告给[您的 Anthropic 客户团队](#report-an-issue)。Anthropic 会在其一端记录原因。

271* **包含 `remote: access denied by the git proxy` 的行**:Anthropic 提供服务的会话仍可能被拒绝,例如当组织策略拒绝该会话的 git 访问,或该会话未获得该仓库的授权时。此时运行器的日志会显示一行包含 `remote: access denied by the git proxy` 的内容,该行的其余部分说明了原因。

272* <span id="creator-has-no-github-connection" />**`GitHub authentication required`**:当会话的创建者在 claude.ai 上没有可用的 GitHub 连接时会出现此情况。会话的克隆失败,git 错误显示为 `GitHub authentication required. Please reconnect your GitHub account.` 请让该用户在其 claude.ai 设置中连接或重新连接 GitHub。

273 

274修复原因后,请重新启动失败的会话。

275 

276<h4 id="turn-the-anthropic-git-proxy-off">

277 关闭 Anthropic git 代理

278</h4>

279 

280如果某个环境中的会话使用 github.com 以外的 git 主机(例如 GitHub Enterprise Server)上的仓库,请为该环境的运行器关闭 `--use-anthropic-git-proxy`。

281 

282<Steps>

283 <Step title="移除标志">

284 从运行器的命令中移除 `--use-anthropic-git-proxy`。如果您在运行器的环境(例如 pod spec 或 Compose 文件)中设置了 `CLAUDE_RUNNER_USE_GIT_PROXY`,请在那里将其移除。在 shell 中,取消设置它:

285 

286 ```bash theme={null}

287 unset CLAUDE_RUNNER_USE_GIT_PROXY

288 ```

289 </Step>

290 

291 <Step title="为运行器提供 git 凭据">

292 为运行器会话使用的每个 git 主机(包括 github.com)提供无需提示即可工作的凭据。运行器用户全局 git 配置中的任何凭据都已丢失,因为在设置 `--use-anthropic-git-proxy` 期间运行器删除了该配置。请[在镜像中提供凭据](#ship-git-config-in-your-image)或使用 [`checkout` 生命周期钩子](/docs/zh-CN/self-hosted-environments-configuration#checkout)。

293 </Step>

294 

295 <Step title="打开网络路径">

296 允许运行器通过 443 或 22 端口访问运行器会话使用的每个 git 主机。请参阅[网络要求](#network-requirements)中的 git 主机行。

297 </Step>

298 

299 <Step title="重新启动运行器">

300 重新启动运行器,使其在不使用 git 代理的情况下注册。然后重新启动每个失败的会话。

301 </Step>

302</Steps>

198 303 

199<h4 id="github-api-access-without-the-github-cli">304<h4 id="github-api-access-without-the-github-cli">

200 不使用 GitHub CLI 访问 GitHub API305 不使用 GitHub CLI 访问 GitHub API


266```dockerfile theme={null}371```dockerfile theme={null}

267FROM debian:bookworm-slim372FROM debian:bookworm-slim

268ARG CLAUDE_CODE_VERSION373ARG CLAUDE_CODE_VERSION

269RUN apt-get update && apt-get install -y --no-install-recommends git curl ca-certificates openssh-client \374RUN apt-get update && apt-get install -y --no-install-recommends git curl ca-certificates openssh-client jq \

270 && rm -rf /var/lib/apt/lists/*375 && rm -rf /var/lib/apt/lists/*

271RUN curl -fsSL "https://downloads.claude.ai/claude-code-releases/${CLAUDE_CODE_VERSION:?set with --build-arg CLAUDE_CODE_VERSION}/linux-x64/claude" \376RUN curl -fsSL "https://downloads.claude.ai/claude-code-releases/${CLAUDE_CODE_VERSION:?set with --build-arg CLAUDE_CODE_VERSION}/linux-x64/claude" \

272 -o /usr/local/bin/claude && chmod +x /usr/local/bin/claude377 -o /usr/local/bin/claude && chmod +x /usr/local/bin/claude


382kubectl create namespace claude-runners487kubectl create namespace claude-runners

383```488```

384 489 

385从保存您在管理 UI 的[**复制环境密钥**步骤](/docs/zh-CN/self-hosted-environments-quickstart#set-up-an-environment-and-runner)中复制的值的本地文件创建支持 Secret,以便密钥永远不会出现在您的 shell 历史记录中。运行 `(umask 077 && cat > ./environment-secret)`,粘贴密钥,按 Enter,然后按 Ctrl-D。然后创建 Secret 并删除文件:490从保存您在管理 UI 的 [**Copy environment key** 步骤](/docs/zh-CN/self-hosted-environments-quickstart#set-up-manually)中复制的值的本地文件创建支持 Secret,以便密钥永远不会出现在您的 shell 历史记录中。运行 `(umask 077 && cat > ./environment-secret)`,粘贴密钥,按 Enter,然后按 Ctrl-D。然后创建 Secret 并删除文件:

386 491 

387```bash theme={null}492```bash theme={null}

388kubectl create secret generic claude-runner-environment-secret -n claude-runners --from-file=environment-secret=./environment-secret493kubectl create secret generic claude-runner-environment-secret -n claude-runners --from-file=environment-secret=./environment-secret


500 重用预热的检出605 重用预热的检出

501</h2>606</h2>

502 607 

503对于大型仓库,克隆可能会主导会话启动。在 `--capacity 1` 且没有 [`checkout` hook](/docs/zh-CN/self-hosted-environments-configuration#checkout) 的情况下,运行器在 `<base-dir>/<repo-owner>/<repo>` 处为每个仓库保持一个规范克隆,并在会话间重用它:它获取请求的引用,分离 `HEAD`,并硬重置到该引用,当变化不大时这几乎是瞬间完成的。要跳过冷克隆,可以通过以下两种方式之一提供克隆:608对于大型仓库,克隆可能会主导会话启动。要跳过冷克隆,请在运行器保存其自身克隆的路径处自行提供一个克隆。在没有 [`checkout` hook](/docs/zh-CN/self-hosted-environments-configuration#checkout) 的情况下,运行器在 `<base-dir>/<repo-owner>/<repo>` 处为每个仓库保持一个规范克隆,并在会话间重用它:

609 

610* **在 `--capacity 1` 时**:运行器获取请求的引用,分离 `HEAD`,并硬重置到该引用,当变化不大时这几乎是瞬间完成的。

611* **在 `--capacity` 大于 1 时**:运行器获取到该克隆中,然后从中为每个会话检出单独的 worktree。预热的克隆可以节省下载,但不能节省检出。

612 

613在镜像中或持久卷上提供克隆:

504 614 

505* **在镜像中克隆**:在该路径处将克隆构建到运行器镜像中。每个新容器随后都会以预热克隆启动,而无需重用磁盘。615* **在镜像中克隆**:在该路径处将克隆构建到运行器镜像中。每个新容器随后都会以预热克隆启动,而无需重用磁盘。

506* **在持久卷上克隆**:在使用 [`--lock-to-account`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 预锁定到一个用户账户的运行器上,将 `--base-dir` 指向持久卷,这样磁盘只为该账户服务。预锁定的运行器永远不会接收 Claude Tag 频道会话,因此此选项不适用于为其服务的运行器。616* **在持久卷上克隆**:在使用 [`--lock-to-account`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags) 预锁定到一个用户账户的运行器上,将 `--base-dir` 指向持久卷,这样磁盘只为该账户服务。预锁定的运行器永远不会接收 Claude Tag 频道会话,因此此选项不适用于为其服务的运行器。


508重用路径的保证和不保证的内容:618重用路径的保证和不保证的内容:

509 619 

510* **任何克隆形状都可以工作**:路径处的完整、浅层或单分支克隆按原样使用。运行器在获取到现有克隆时永远不会传递 `--depth`,因此完整的预热保持其完整历史,浅层克隆保持浅层。`CLAUDE_RUNNER_FETCH_DEPTH`(`full`、`0` 或一个数字;默认 50)仅控制当尚不存在克隆时运行器进行的冷克隆。620* **任何克隆形状都可以工作**:路径处的完整、浅层或单分支克隆按原样使用。运行器在获取到现有克隆时永远不会传递 `--depth`,因此完整的预热保持其完整历史,浅层克隆保持浅层。`CLAUDE_RUNNER_FETCH_DEPTH`(`full`、`0` 或一个数字;默认 50)仅控制当尚不存在克隆时运行器进行的冷克隆。

511* **跟踪的更改重置,未跟踪的文件保留**:每个会话从硬重置开始,该重置会清除前一个会话的跟踪修改,但运行器永远不会运行 `git clean`,因此来自锁定所有者早期会话的未跟踪文件保留在树中。621* **跟踪的更改重置,未跟踪的文件保留**:在 `--capacity 1` 时,每个会话从硬重置开始,该重置会清除前一个会话的跟踪修改,但运行器永远不会运行 `git clean`,因此来自锁定所有者早期会话的未跟踪文件保留在树中。

512* **按会话目录也会保留**:在检出旁边,运行器在 `<base-dir>/_sessions/` 下为其运行的每个会话创建按会话条目。会话的 Claude 配置目录保存对话记录的本地副本。在其旁边是会话的上传文件,当会话有任何文件时。会话目录也在那里:它保存会话运行时的任何按会话工作树和 `checkout` hook 检出,以及 Claude 在其中写入的任何其他内容。622* **按会话目录也会保留**:在检出旁边,运行器在 `<base-dir>/_sessions/` 下为其运行的每个会话创建按会话条目。会话的 Claude 配置目录保存对话记录的本地副本。在其旁边是会话的上传文件,当会话有任何文件时。会话目录也在那里:它保存会话运行时的任何按会话工作树和 `checkout` hook 检出,以及 Claude 在其中写入的任何其他内容。

513 623 

514 默认情况下,运行器在会话结束时将这些保留在原地,因此在持久化的磁盘上它们会累积。每个会话都以运行器自己的用户身份运行,因此该磁盘服务的任何后续会话都可以读取它们。如果保持持久的 `--base-dir`,请为该增长调整卷的大小。同样适用于在同一文件系统上重启运行器的任何设置,包括 [Docker Compose 配方](#docker-compose)。624 默认情况下,运行器在会话结束时将这些保留在原地,因此在持久化的磁盘上它们会累积。每个会话都以运行器自己的用户身份运行,因此该磁盘服务的任何后续会话都可以读取它们。如果保持持久的 `--base-dir`,请为该增长调整卷的大小。同样适用于在同一文件系统上重启运行器的任何设置,包括 [Docker Compose 配方](#docker-compose)。


522 632 

523每个会话的子 Claude Code 进程运行运行器自己的二进制文件,运行器在它生成的会话内关闭自动更新,所以每个会话运行您在主机上安装或构建到镜像中的版本。主机级更新在运行器下次启动时生效。633每个会话的子 Claude Code 进程运行运行器自己的二进制文件,运行器在它生成的会话内关闭自动更新,所以每个会话运行您在主机上安装或构建到镜像中的版本。主机级更新在运行器下次启动时生效。

524 634 

525您的会话使用的模型可能需要比它们运行的 Claude Code 版本更新的版本。服务器随后会以 [Claude Code does not support this model](/docs/zh-CN/errors#claude-code-does-not-support-this-model) 拒绝对该模型的请求。在您固定版本之前,请检查[模型需要的 Claude Code 版本](/docs/zh-CN/model-config#available-models),以了解您的会话使用的每个模型。635选择您的会话运行哪个版本以及何时更改:

526 636 

637* **在固定版本之前**:针对您的会话使用的每个模型,检查[模型需要的 Claude Code 版本](/docs/zh-CN/model-config#available-models)。如果某个模型需要比您的会话所运行版本更新的版本,服务器会以 [Claude Code does not support this model](/docs/zh-CN/errors#claude-code-does-not-support-this-model) 拒绝对该模型的请求。

527* **将队列保持在一个版本上**:使用固定版本构建镜像,或在裸主机上安装特定版本并[禁用自动更新](/docs/zh-CN/setup#disable-auto-updates)638* **将队列保持在一个版本上**:使用固定版本构建镜像,或在裸主机上安装特定版本并[禁用自动更新](/docs/zh-CN/setup#disable-auto-updates)

528* **升级**:安装较新版本或重建镜像,然后重启运行器639* **升级固定队列**:阅读您当前版本与要安装版本之间的 [changelog](/docs/en/changelog) 条目,然后安装较新版本或重建镜像,并重启运行器

640* **升级按需运行器**:阅读您当前版本与要安装版本之间的 [changelog](/docs/en/changelog) 条目,然后更改您的 [`spawn-runner` hook](/docs/zh-CN/self-hosted-environments-configuration#the-spawn-runner-hook) 启动的镜像。每个新运行器都会获得新版本。已经在运行的运行器(包括由 [`--min-idle`](/docs/zh-CN/self-hosted-environments-reference#orchestrator-cli-flags) 启动的备用运行器)会保持其版本,直到退出。不要重启它,因为它的工作指令是一次性的。

529* **插件**:插件市场也不自动更新;在运行器的环境中设置 `FORCE_AUTOUPDATE_PLUGINS=1` 以让插件自动更新,同时二进制保持固定641* **插件**:插件市场也不自动更新;在运行器的环境中设置 `FORCE_AUTOUPDATE_PLUGINS=1` 以让插件自动更新,同时二进制保持固定

530 642 

531<h2 id="scale-the-fleet">643<h2 id="scale-the-fleet">


580</h3>692</h3>

581 693 

582* **恢复的会话丢失未推送的工作**:新的运行器会从其起始分支重新克隆仓库,因此会话未推送的工作会丢失。694* **恢复的会话丢失未推送的工作**:新的运行器会从其起始分支重新克隆仓库,因此会话未推送的工作会丢失。

583 * **要保留已提交的工作**:设置 [`--push-outcome-on-release`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags)。运行器随后会在释放之前尽力推送会话的结果分支,恢复的会话将从这些提交开始。未提交的更改仍会丢失。695 * **要保留已提交的工作**:在环境中的每个运行器上设置 [`--push-outcome-on-release`](/docs/zh-CN/self-hosted-environments-reference#runner-cli-flags),因为未设置该标志的运行器会从起始分支恢复会话。设置了该标志的运行器会在释放之前尽力推送会话的结果分支,恢复的会话将从这些提交开始。推送使用运行器主机自身的 git 凭据,在使用 [Anthropic 托管 git](#use-the-anthropic-git-proxy) 的运行器上也是如此。未提交的更改仍会丢失。

696 * **使用 `checkout` hook 时**:通过 [`checkout` 生命周期 hook](/docs/zh-CN/self-hosted-environments-configuration#checkout) 检出的仓库不会被推送。请改为从 [`post-session` hook](/docs/zh-CN/self-hosted-environments-configuration#post-session) 对其进行快照。

584 * **启用该标志之前**:限制谁可以推送到源远程上的 `claude/*` refs。在恢复时,运行器会获取之前推送的分支,而不验证是谁推送的。697 * **启用该标志之前**:限制谁可以推送到源远程上的 `claude/*` refs。在恢复时,运行器会获取之前推送的分支,而不验证是谁推送的。

585* **会话中途添加的仓库可能无法克隆**:Claude 通过 HTTPS 使用 `git clone` 克隆它。在未启用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 的运行器上,如果主机上没有任何内容能够读取该仓库,克隆会因 git 身份验证错误而失败。如有可能,请在创建会话时选择会话所需的每个仓库。698* **会话中途添加的仓库可能无法克隆**:Claude 通过 HTTPS 使用 `git clone` 克隆它。在未启用 [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy) 的运行器上,如果主机上没有任何内容能够读取该仓库,克隆会因 git 身份验证错误而失败。如有可能,请在创建会话时选择会话所需的每个仓库。

586* **某些连接器不出现在自托管会话中**:您在 claude.ai Settings 中尚未连接的连接器不在自托管会话中列出,会话不会提示您连接它。首先在 Settings 中连接它,然后启动新会话。向已运行的会话添加连接器也不会使其工具对 Claude 可用;启动新会话以获取新添加的连接器。699* **某些连接器不出现在自托管会话中**:您在 claude.ai Settings 中尚未连接的连接器不在自托管会话中列出,会话不会提示您连接它。首先在 Settings 中连接它,然后启动新会话。向已运行的会话添加连接器也不会使其工具对 Claude 可用;启动新会话以获取新添加的连接器。


606* **运行器未出现在环境中**:确认主机可以通过 HTTPS 到达 `api.anthropic.com`,环境密钥是最新的,并且主机时钟与实际时间相差在五分钟以内;更大的时间偏差会导致身份验证失败。运行器在身份验证失败时会记录 `[runner:fatal]` 和拒绝原因。719* **运行器未出现在环境中**:确认主机可以通过 HTTPS 到达 `api.anthropic.com`,环境密钥是最新的,并且主机时钟与实际时间相差在五分钟以内;更大的时间偏差会导致身份验证失败。运行器在身份验证失败时会记录 `[runner:fatal]` 和拒绝原因。

607* **运行器在启动时退出,显示 `cannot create or write to base directory`**:运行器无法创建或写入 `--base-dir`,其默认值为 `/workspace`。修复目录的所有权或将 `--base-dir` 指向可写路径,如 [保持基础目录和容量在运行器之间相同](#keep-the-base-directory-and-capacity-identical-across-runners) 中所述。如果运行器改为记录 `[runner:fatal]` 说基础目录检查超时,则该目录位于挂起的 NFS 或 CSI 挂载上。检查挂载健康状况而不是权限。运行器在打开 `--log-file` 之前将这两个启动失败打印到 stderr,因此请在终端或您的平台的容器日志中查找它们,而不是日志文件。在 v2.1.225 之前,运行器在启动时不检查基础目录,此错误配置在拾取后失败会话。720* **运行器在启动时退出,显示 `cannot create or write to base directory`**:运行器无法创建或写入 `--base-dir`,其默认值为 `/workspace`。修复目录的所有权或将 `--base-dir` 指向可写路径,如 [保持基础目录和容量在运行器之间相同](#keep-the-base-directory-and-capacity-identical-across-runners) 中所述。如果运行器改为记录 `[runner:fatal]` 说基础目录检查超时,则该目录位于挂起的 NFS 或 CSI 挂载上。检查挂载健康状况而不是权限。运行器在打开 `--log-file` 之前将这两个启动失败打印到 stderr,因此请在终端或您的平台的容器日志中查找它们,而不是日志文件。在 v2.1.225 之前,运行器在启动时不检查基础目录,此错误配置在拾取后失败会话。

608* **会话保持排队**:每个在线运行器可能被锁定到不同的所有者。检查每个运行器的 `claude_code_self_hosted_runner_locked_account` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 或其 `[runner:health]` 日志行的 `locked_account` 字段,以查看谁持有它。两者仅在运行器被颁发携带 `act.email` 声明的会话令牌后才显示所有者的电子邮件,Claude Tag 代理的会话永远不会这样做。没有该声明,运行器不发出 `locked_account` 系列,并记录 `locked_account=yes`,这告诉您运行器被锁定但不知道是哪个所有者。添加副本,或等待现有运行器耗尽并重新启动。如果环境使用按需运行器,请改为检查编排器;请参阅 [按需运行器](/docs/zh-CN/self-hosted-environments-configuration#on-demand-runners)。721* **会话保持排队**:每个在线运行器可能被锁定到不同的所有者。检查每个运行器的 `claude_code_self_hosted_runner_locked_account` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 或其 `[runner:health]` 日志行的 `locked_account` 字段,以查看谁持有它。两者仅在运行器被颁发携带 `act.email` 声明的会话令牌后才显示所有者的电子邮件,Claude Tag 代理的会话永远不会这样做。没有该声明,运行器不发出 `locked_account` 系列,并记录 `locked_account=yes`,这告诉您运行器被锁定但不知道是哪个所有者。添加副本,或等待现有运行器耗尽并重新启动。如果环境使用按需运行器,请改为检查编排器;请参阅 [按需运行器](/docs/zh-CN/self-hosted-environments-configuration#on-demand-runners)。

609* **会话在拾取后立即失败**:在 claude.ai/code 中打开会话以查看错误。最常见的原因是运行器镜像中缺少 [git 凭证](#configure-git) 和未安装的构建工具。不可写的基础目录会在启动时停止运行器,而不是失败会话。请参阅此列表中的 **运行器在启动时退出,显示 `cannot create or write to base directory`** 条目。722* **会话在拾取后立即失败**:在 claude.ai/code 中打开会话以查看错误。最常见的原因是运行器镜像中缺少 [git 凭据](#configure-git) 和未安装的构建工具。对于使用 `--use-anthropic-git-proxy` 启动的运行器,请参阅 [当会话在使用 git 代理的运行器上无法启动时](#when-anthropic-doesnt-serve-a-session)。不可写的基础目录会在启动时停止运行器,而不是失败会话。请参阅此列表中的 **运行器在启动时退出,显示 `cannot create or write to base directory`** 条目。

723* **在设置了 `--use-anthropic-git-proxy` 的运行器上会话无法启动**:在运行器的日志中查找 `access denied by the git proxy`,或查找指明包含 `/git_proxy/` 的 `api.anthropic.com` 地址的 git 错误。要判断 Anthropic 是否提供了该会话并修复原因,请参阅 [当会话在使用 git 代理的运行器上无法启动时](#when-anthropic-doesnt-serve-a-session)。

610* **会话无法通过身份验证出口代理到达网络**:当您使用 [`--proxy-authorization-command` 或 `--proxy-authorization-file`](#authenticate-to-an-egress-proxy) 设置的源失败、在 30 秒后超时或产生空值时,运行器以 `502 Bad Gateway` 应答该连接并记录原因。运行器在该日志中编辑命令的 stderr,并且永远不会记录标头值。使用 `--proxy-authorization-command` 时,在主机上自己运行该命令以确认它在 stdout 上打印整个标头值。如果运行器改为在启动时退出,显示 `could not start the proxy-authorization listener`,则它无法打开其环回监听器。724* **会话无法通过身份验证出口代理到达网络**:当您使用 [`--proxy-authorization-command` 或 `--proxy-authorization-file`](#authenticate-to-an-egress-proxy) 设置的源失败、在 30 秒后超时或产生空值时,运行器以 `502 Bad Gateway` 应答该连接并记录原因。运行器在该日志中编辑命令的 stderr,并且永远不会记录标头值。使用 `--proxy-authorization-command` 时,在主机上自己运行该命令以确认它在 stdout 上打印整个标头值。如果运行器改为在启动时退出,显示 `could not start the proxy-authorization listener`,则它无法打开其环回监听器。

611* **运行器记录包含 `rejecting the malformed poll response` 的 `Poll failed` 行**:运行器收到的工作轮询响应的正文不是队列的预期 JSON,最常见的原因是运行器和 `api.anthropic.com` 之间的某些内容(例如拦截代理或强制门户)用自己的页面进行了应答。运行器拒绝响应,在 `claude_code_self_hosted_runner_poll_errors_total` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 的 `transport` 类型下计数,并按 [会话生命周期](/docs/zh-CN/self-hosted-environments#session-lifecycle) 中描述的失败轮询计划重试。运行器继续为其实时会话提供服务。配置代理以将来自 `api.anthropic.com` 的响应原封不动地传递。在 v2.1.246 之前,运行器将这样的响应读取为空工作队列,这可能会结束其实时会话或使其退出。725* **运行器记录包含 `rejecting the malformed poll response` 的 `Poll failed` 行**:运行器收到的工作轮询响应的正文不是队列的预期 JSON,最常见的原因是运行器和 `api.anthropic.com` 之间的某些内容(例如拦截代理或强制门户)用自己的页面进行了应答。运行器拒绝响应,在 `claude_code_self_hosted_runner_poll_errors_total` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 的 `transport` 类型下计数,并按 [会话生命周期](/docs/zh-CN/self-hosted-environments#session-lifecycle) 中描述的失败轮询计划重试。运行器继续为其实时会话提供服务。配置代理以将来自 `api.anthropic.com` 的响应原封不动地传递。在 v2.1.246 之前,运行器将这样的响应读取为空工作队列,这可能会结束其实时会话或使其退出。

612* **会话的分支在远程上不再存在**:对于会话仅从中读取的 git 源,运行器跳过该源并继续处理其余源。对于会话推送结果的源,删除的分支(通常是因为它被合并并自动删除)会导致会话失败,并显示一个错误,命名存储库和分支,并要求您恢复分支并重试。当跳过会导致它完全没有存储库时,运行器会以相同的错误失败会话。在 v2.1.228 之前,这样的会话在空目录中启动。726* **会话的分支在远程上不再存在**:对于会话仅从中读取的 git 源,运行器跳过该源并继续处理其余源。对于会话推送结果的源,删除的分支(通常是因为它被合并并自动删除)会导致会话失败,并显示一个错误,命名存储库和分支,并要求您恢复分支并重试。当跳过会导致它完全没有存储库时,运行器会以相同的错误失败会话。在 v2.1.228 之前,这样的会话在空目录中启动。


616 730 

617 访问检查在每次会话在运行器上启动时再次运行,因此一旦运行器的 git 身份具有读取访问权限,下一次启动就会克隆存储库。在 v2.1.274 之前,这些拒绝中的每一个都导致会话启动失败。731 访问检查在每次会话在运行器上启动时再次运行,因此一旦运行器的 git 身份具有读取访问权限,下一次启动就会克隆存储库。在 v2.1.274 之前,这些拒绝中的每一个都导致会话启动失败。

618* **会话需要数分钟才能启动**:初始克隆通常占主导地位。观察 `claude_code_self_hosted_runner_session_init_duration_seconds` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 以确认,并使用 [预热检出](#reuse-a-pre-warmed-checkout) 或更小的 `CLAUDE_RUNNER_FETCH_DEPTH` 减少克隆。732* **会话需要数分钟才能启动**:初始克隆通常占主导地位。观察 `claude_code_self_hosted_runner_session_init_duration_seconds` [指标](/docs/zh-CN/self-hosted-environments-reference#prometheus-metrics) 以确认,并使用 [预热检出](#reuse-a-pre-warmed-checkout) 或更小的 `CLAUDE_RUNNER_FETCH_DEPTH` 减少克隆。

619* **轮次以 401 失败**:每个会话使用运行器从 Anthropic 获取并通过会话的 stdin 轮换的短期 [`CLAUDE_CODE_OAUTH_TOKEN`](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts) 对模型调用进行身份验证。当轮次以来自模型 API 的 401 或 403 结束时,运行器获取新令牌并将其传递给会话。失败的轮次不会重试。733* **轮次以 401 失败**:当轮次以来自 Anthropic API 的 401 或 403 结束时,运行器从 Anthropic 获取新的 [`CLAUDE_CODE_OAUTH_TOKEN`](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts) 并将其传递给会话。失败的轮次不会重试。此令牌是短期的,运行器通过会话的 stdin 轮换它。

620 734 

621 当获取失败时,运行器记录一条 `inference_token refresh failed` 行,说明何时重试,并在会话运行期间继续重试。735 当获取失败时,运行器记录一条 `inference_token refresh failed` 行,说明何时重试,并在会话运行期间继续重试。

622 736 


637 751 

638* **正常退出**:运行器完成了其会话并耗尽,达到了其退休时间,或被告知停止。重新启动它以便环境再次具有容量。[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle) 描述了这些退出。752* **正常退出**:运行器完成了其会话并耗尽,达到了其退休时间,或被告知停止。重新启动它以便环境再次具有容量。[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle) 描述了这些退出。

639* **启动失败**:运行器无法使用给定的配置或主机启动,因此它在启动后几秒钟退出,并且每次重新启动时都以相同的方式退出。更快地重新启动它没有帮助。有人需要阅读其输出并修复原因。753* **启动失败**:运行器无法使用给定的配置或主机启动,因此它在启动后几秒钟退出,并且每次重新启动时都以相同的方式退出。更快地重新启动它没有帮助。有人需要阅读其输出并修复原因。

754* **失去联系**:无法连接 Anthropic 的时间超过其 [租约](/docs/zh-CN/self-hosted-environments#session-lifecycle) 的运行器(例如在其主机休眠期间)可能会被从环境中移除。被移除的运行器重新连接时会退出。其日志可能显示一条包含 `runner record gone server-side` 的 `[runner:fatal]` 行,或者在较长时间的中断之后显示 [`poll auth failed`](/docs/zh-CN/self-hosted-environments-quickstart#set-up-an-environment-and-runner)。运行器不会自行重新注册,因此请重新启动它。

640 755 

641配置您的监督程序在运行器退出时重新启动它,当运行器在启动后立即保持退出时等待更长时间,并在这种情况持续发生时告知某人。756配置您的监督程序在运行器退出时重新启动它,当运行器在启动后立即保持退出时等待更长时间,并在这种情况持续发生时告知某人。

642 757 

Details

52 验证令牌52 验证令牌

53</h2>53</h2>

54 54 

55验证在两个地方之一运行。网络上的服务根据 Anthropic 发布的密钥对令牌进行加密验证,会话内的包装脚本可以改为使用运行程序二进制文件的内置解码器。55验证可以在两个位置之一进行。您网络中的服务可以使用 Anthropic 发布的密钥对令牌进行加密验证,而会话内的包装脚本则可以改用运行器二进制文件内置的解码器。

56 56 

57<h3 id="verify-the-token-from-your-service">57<h3 id="verify-the-token-from-your-service">

58 从您的服务验证令牌58 从您的服务验证令牌

59</h3>59</h3>

60 60 

61Anthropic 在公开的、未经身份验证的端点发布验证密钥:61Anthropic 在一个公开、无需身份验证的端点上发布验证密钥:

62 62 

63```text theme={null}63```text theme={null}

64https://api.anthropic.com/v1/code/.well-known/jwks.json64https://api.anthropic.com/v1/code/.well-known/jwks.json

65```65```

66 66 

67响应是标准的 [JSON Web Key Set](https://www.rfc-editor.org/rfc/rfc7517)。Anthropic 定期轮换签名密钥,轮换前的密钥在集合中保留足够长的时间,以便它们签名的令牌继续验证,因此不要固定单个密钥。端点设置 `Cache-Control: public, max-age=300`,因此缓存密钥集并每五分钟重新获取一次是安全的。67响应是标准的 [JSON Web Key Set](https://www.rfc-editor.org/rfc/rfc7517)。Anthropic 会定期轮换签名密钥,轮换前的密钥会在密钥集中保留足够长的时间,使其签发的令牌仍能通过验证,因此请勿固定使用单个密钥。该端点设置了 `Cache-Control: public, max-age=300`,因此缓存密钥集并每五分钟重新获取一次是安全的。

68 68 

69根据以下检查验证每个传入令牌:69请按以下检查项验证每个传入的令牌:

70 70 

71<Steps>71<Steps>

72 <Step title="检查前缀">72 <Step title="检查前缀">

73 如果值不以 `sk-ant-cc-` 开头,则拒绝该值,然后删除该前缀。其余部分是标准的紧凑 JWT。73 如果值不以 `sk-ant-cc-` 开头,则拒绝该值,否则移除该前缀。剩余部分是一个标准的紧凑格式 JWT。

74 </Step>74 </Step>

75 75 

76 <Step title="验证签名">76 <Step title="验证签名">

77 获取 JWKS,选择 `kid` 与令牌头部匹配的密钥,并验证 `ES256` 签名。拒绝 `alg` 头部不是 `ES256` 的令牌。如果令牌到达时带有缓存密钥集中没有的 `kid`,在拒绝之前重新获取 JWKS 一次:轮换后,新令牌使用缓存集还没有的密钥进行签名。77 获取 JWKS,选择 `kid` 与令牌头部匹配的密钥,并验证 `ES256` 签名。拒绝 `alg` 头部不是 `ES256` 的令牌。如果传入令牌的 `kid` 不在您缓存的密钥集中,请在拒绝之前重新获取一次 JWKS:密钥轮换后,新令牌会使用您缓存的密钥集中尚未包含的密钥进行签名。

78 </Step>78 </Step>

79 79 

80 <Step title="验证发行者">80 <Step title="验证签发者">

81 如果 `iss` 不完全是 `ccr`,则拒绝令牌。81 如果 `iss` 不完全等于 `ccr`,则拒绝该令牌。

82 </Step>82 </Step>

83 83 

84 <Step title="根据您的环境验证受众">84 <Step title="根据您的环境验证受众">

85 `aud` 声明是一个数组。除非它包含您的环境 ID(形式为 `ccpool_...`),否则拒绝令牌。环境 ID 显示在[**云环境**管理页面](https://claude.ai/admin-settings/cloud-environments)上您的环境的详细信息对话框中,并在任何环境的会话令牌中显示为 `ccr:pool_id` 声明。此检查是将令牌范围限制到您的环境并拒绝发布给其他组织的令牌的内容。85 `aud` 声明是一个数组。除非其中包含您的环境 ID(格式为 `ccpool_...`),否则拒绝该令牌。环境 ID 显示在 [**Cloud environments** 管理页面](https://claude.ai/admin-settings/cloud-environments)中您环境的详情对话框里,也会作为 `ccr:pool_id` 声明出现在该环境的任意会话令牌中。正是这项检查将令牌限定在您的环境内,并拒绝签发给其他组织的令牌。

86 </Step>86 </Step>

87 87 

88 <Step title="验证角色">88 <Step title="验证角色">

89 如果 `ccr:role` 不完全是 `session_worker`,则拒绝令牌。为自托管环境发布的其他令牌,例如环境机密、运行程序令牌和工作订单,由同一密钥集签名,但携带不同的角色。89 如果 `ccr:role` 不完全等于 `session_worker`,则拒绝该令牌。为自托管环境签发的其他令牌(例如环境密钥、运行器令牌和工单)由同一密钥集签名,但携带不同的角色。

90 </Step>90 </Step>

91 91 

92 <Step title="验证过期">92 <Step title="验证过期时间">

93 如果 `exp` 在过去,则拒绝令牌。Anthropic 默认发布生命周期为四小时、最长为八小时的会话令牌。运行程序在过期前刷新令牌,并将新值推送到会话,因此 Claude 在刷新后启动的子进程继承它。因此,一个会话在其生命周期内可以向您的服务呈现多个不同的有效令牌。93 如果 `exp` 已经过去,则拒绝该令牌。Anthropic 签发的会话令牌默认有效期为四小时,最长为八小时。运行器会在令牌过期前刷新令牌并将新值推送到会话中,因此 Claude 在刷新后启动的子进程会继承新令牌。因此,一个会话在其生命周期内可能会向您的服务出示多个不同的有效令牌。

94 </Step>94 </Step>

95 95 

96 <Step title="读取身份">96 <Step title="读取身份">

97 创建用户的身份在 `act` 声明中:`act.sub` 是他们的 Anthropic 用户 ID,采用前缀形式 `user:<id>`,`act.email`(当创建表面记录了一个时)是他们的电子邮件地址。您组织的服务身份创建的会话(包括 Claude Tag 频道会话)改为在 `act.sub` 中携带 `agent:` 主题,因此仅当 `act.sub` 携带 `user:` 前缀时才将会话视为用户创建的,而不是测试身份声明是否不存在。有关完整结构和平面重复声明,请参阅[声明参考](#claims-reference)。97 创建者的用户身份位于 `act` 声明中:`act.sub` 是其 Anthropic 用户 ID,采用带前缀的形式 `user:<id>`;`act.email`(当创建会话的使用入口记录了该信息时)是其电子邮件地址。由您组织的服务身份创建的会话(包括 Claude Tag 频道会话)则携带 `agent:` 主体,因此,仅当 `act.sub` 带有 `user:` 前缀时才将会话视为用户创建,而不是通过检测身份声明是否缺失来判断。有关完整结构和扁平的重复声明,请参阅[声明参考](#claims-reference)。

98 </Step>98 </Step>

99</Steps>99</Steps>

100 100 

101这些检查直接映射到标准 JWT 库。下面的示例使用 [`jose`](https://www.npmjs.com/package/jose) 在 Node.js 中实现完整序列,它处理 JWKS 获取、缓存和 `kid` 选择,以及使用 [`PyJWT`](https://pyjwt.readthedocs.io/) 及其内置 JWKS 客户端在 Python 中实现。101这些检查可以直接对应到标准 JWT 库。以下示例分别在 Node.js 中使用 [`jose`](https://www.npmjs.com/package/jose)(它负责 JWKS 的获取、缓存和 `kid` 选择),以及在 Python 中使用 [`PyJWT`](https://pyjwt.readthedocs.io/) 及其内置的 JWKS 客户端,实现了完整的检查流程。

102 102 

103<Tabs>103<Tabs>

104 <Tab title="Node.js (jose)">104 <Tab title="Node.js (jose)">


185 在会话内验证令牌185 在会话内验证令牌

186</h3>186</h3>

187 187 

188[包装脚本](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts)在会话内运行,在 Claude 启动之前。它们可以运行运行程序二进制文件的 `self-hosted-runner decode-token` 子命令,而不是调用 JWT 库。子命令从位置参数、`CLAUDE_CODE_SESSION_ACCESS_TOKEN` 或管道 stdin 读取令牌(按该顺序),然后删除前缀,根据 JWKS 端点验证签名,检查过期,并将声明打印为 JSON。子命令仅执行签名和过期检查;它不检查 `iss`、`aud` 或 `ccr:role`。当您的包装器的身份验证决定取决于这些声明时,从打印的 JSON 中读取它们并明确比较它们。188[包装脚本](/docs/zh-CN/self-hosted-environments-configuration#wrapper-scripts)在会话内、Claude 启动之前运行。它们无需调用 JWT 库,而是可以运行运行器二进制文件的 `self-hosted-runner decode-token` 子命令。该子命令依次从位置参数、`CLAUDE_CODE_SESSION_ACCESS_TOKEN` 或通过管道传入的 stdin 读取令牌,然后去除前缀,根据 JWKS 端点验证签名,检查过期时间,并以 JSON 格式打印声明。该子命令仅执行签名和过期检查;它不会检查 `iss`、`aud` 或 `ccr:role`。当您的包装脚本的授权决策依赖于这些声明时,请从打印的 JSON 中读取它们并进行显式比较。

189 189 

190此命令提取创建者身份,优先选择电子邮件地址,然后是创建者的 `act.sub` 主题 `user:<id>` 或 `agent:<id>`:190以下命令提取创建者身份,优先使用电子邮件地址,其次使用创建者的 `act.sub` 主体(`user:<id>` 或 `agent:<id>`):

191 191 

192```bash theme={null}192```bash theme={null}

193"$CLAUDE_RUNNER_CLAUDE_BIN" self-hosted-runner decode-token | jq -re '.act.email // .act.sub'193"$CLAUDE_RUNNER_CLAUDE_BIN" self-hosted-runner decode-token | jq -re '.act.email // .act.sub'

194```194```

195 195 

196包装脚本在 `CLAUDE_RUNNER_CLAUDE_BIN` 中接收运行程序自身二进制文件的绝对路径;使用该路径而不是 PATH 解析的 `claude`,以便解码在运行程序本身使用的同一二进制文件上运行。196包装脚本会通过 `CLAUDE_RUNNER_CLAUDE_BIN` 获得运行器自身二进制文件的绝对路径;请使用该路径,而不是通过 PATH 解析的 `claude`,以便解码操作在运行器本身所使用的同一个二进制文件上运行。

197 197 

198使用 `jq -re` 而不是 `jq -r`,以便缺少的声明导致非零退出。仅使用 `-r`,缺少的声明会打印文字字符串 `null` 并以零退出,这会以静默方式将坏值传递给下游。仅在 JWKS 端点无法访问的离线检查中将 `--no-verify` 传递给 `decode-token`。198请使用 `jq -re` 而不是 `jq -r`,这样缺失的声明会导致非零退出码。如果仅使用 `-r`,缺失的声明会打印字面字符串 `null` 并以零退出码退出,从而悄无声息地将错误值传递到下游。

199 

200如果 `decode-token` 无法从 JWKS 端点获取密钥或无法验证令牌,它会将原因打印到 stderr,不打印任何声明,并以退出码 1 退出。仅在 JWKS 端点无法访问、需要进行离线检查时,才向 `decode-token` 传递 `--no-verify`。

199 201 

200<h2 id="claims-reference">202<h2 id="claims-reference">

201 声明参考203 声明参考

Details

34运行器主机需要:34运行器主机需要:

35 35 

36* 一个 Linux 或 macOS 主机或容器,具有到 `api.anthropic.com` 的出站 HTTPS、到 `claude.ai` 和下面安装步骤重定向到的下载主机的出站 HTTPS,以及到您的 git 主机的出站 HTTPS 用于克隆;[网络要求表](/docs/zh-CN/self-hosted-environments-deploy#network-requirements)有完整列表。Windows 不支持作为运行器主机;改为在 Linux 容器中运行运行器。开发人员工作站不受影响,因为会话从浏览器中的 claude.ai 启动。36* 一个 Linux 或 macOS 主机或容器,具有到 `api.anthropic.com` 的出站 HTTPS、到 `claude.ai` 和下面安装步骤重定向到的下载主机的出站 HTTPS,以及到您的 git 主机的出站 HTTPS 用于克隆;[网络要求表](/docs/zh-CN/self-hosted-environments-deploy#network-requirements)有完整列表。Windows 不支持作为运行器主机;改为在 Linux 容器中运行运行器。开发人员工作站不受影响,因为会话从浏览器中的 claude.ai 启动。

37* 一个用于测试会话的仓库:可以是公共仓库,也可以是此主机已能通过其 HTTPS URL 克隆且无需提供凭据的仓库。

37* 与实时同步的时钟,例如使用 NTP。当时钟偏离超过五分钟时,身份验证失败;请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。38* 与实时同步的时钟,例如使用 NTP。当时钟偏离超过五分钟时,身份验证失败;请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。

38 39 

39<h3 id="software-on-the-runner-host">40<h3 id="software-on-the-runner-host">


57 设置环境和运行器58 设置环境和运行器

58</h2>59</h2>

59 60 

60Claude Code 包括一个引导式设置:一个交互式 Claude Code 会话,引导您在管理 UI 中创建环境、使用您保存的密钥文件启动本地运行器、确认运行器注册,并将速查表写入 `./runner-setup/CHEAT-SHEET.md`。在您已使用拥有所有者角色的帐户使用 `claude auth login` 登录的机器上运行它;它不适用于 API 密钥或第三方模型提供商。在无法进行交互式会话的主机上,改为使用下面的手动步骤。首先确认[版本检查](#software-on-the-runner-host)通过:在 2.1.224 之前的版本上,此命令启动一个普通的 Claude 会话,将这些词作为提示而不是引导式设置。要启动引导式设置,请运行设置子命令并按照提示进行:61使用[引导式设置](#run-the-guided-setup)或[手动步骤](#set-up-manually)。引导式设置只需一条命令,它会启动一个交互式 Claude Code 会话,并引导您完成其余步骤。在无法进行交互式会话的主机上,请改用手动步骤。如果拥有所有者角色的人员已创建环境并将其密钥交给您,也请使用手动步骤,因为引导式设置需要以所有者身份登录。

62 

63<h3 id="run-the-guided-setup">

64 运行引导式设置

65</h3>

66 

67引导式设置会引导您在管理 UI 中创建环境、使用您保存的密钥文件启动本地运行器、确认运行器已注册,并将速查表写入 `./runner-setup/CHEAT-SHEET.md`。运行之前,请确认您的登录状态和版本:

68 

69* **登录**:在您已使用拥有所有者角色的帐户通过 `claude auth login` 登录的机器上运行它。如果仅使用 API 密钥或第三方模型提供商,会话虽然会启动,但其组织检查会失败。

70* **版本**:确认[版本检查](#software-on-the-runner-host)已通过。在 2.1.224 之前的版本上,此设置命令会启动一个 Claude 会话,并将这些词作为提示词,而不是启动引导式设置。

71 

72要启动引导式设置,请在 shell 中运行设置子命令并按照提示进行操作:

61 73 

62```bash theme={null}74```bash theme={null}

63claude self-hosted-runner setup75claude self-hosted-runner setup

64```76```

65 77 

66要改为手动设置:78设置本身不会启动测试会话:它会提示您在 claude.ai/code 启动一个。设置的最后一步会停止它所启动的运行器。如果您在该步骤之前退出设置,运行器将继续运行。要在最后一步之后继续,请在 shell 中使用 `./runner-setup/CHEAT-SHEET.md` 中的命令再次启动运行器,然后[将会话路由到环境](#route-a-session)。

79 

80<h3 id="set-up-manually">

81 手动设置

82</h3>

83 

84在 claude.ai 上创建环境,从主机上的终端启动运行器,然后返回 claude.ai 确认运行器出现并将会话路由到它。如果拥有所有者角色的人员已创建环境并将其密钥交给您,请从第 2 步开始。

67 85 

68<Steps>86<Steps>

69 <Step title="创建环境">87 <Step title="创建环境">


73 </Step>91 </Step>

74 92 

75 <Step title="启动运行器">93 <Step title="启动运行器">

76 创建密钥目录。此步骤和下一步需要 root 用于 `/etc/claude` 路径;运行器进程可以读取的任何路径都有效,因此如果您使用不同的路径,请一起调整两个命令和 `--environment-secret-file` 值。94 创建密钥目录。此命令和下一条命令使用 `/etc/claude`,这需要 root 权限,并且它们创建的密钥文件仅可由运行这些命令的用户读取。如果运行器将以其他用户身份运行,它会退出并显示 `error: Failed to read environment secret file <path> (EACCES: permission denied, open '<path>')`。在这种情况下,请以运行器的用户身份运行这两条命令,并使用该用户可写入的目录代替 `/etc/claude`,同时将相同的路径传递给 `--environment-secret-file`。运行器进程可以读取的任何路径都有效。

77 95 

78 ```bash theme={null}96 ```bash theme={null}

79 mkdir -p /etc/claude97 mkdir -p /etc/claude


89 107 

90 如果运行器无法创建或写入路径,它在启动时以命名目录的错误退出,而不是注册。请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。108 如果运行器无法创建或写入路径,它在启动时以命名目录的错误退出,而不是注册。请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。

91 109 

92 然后使用 `--environment-secret-file` 和 `--base-dir` 启动运行器。运行器向您的环境注册并开始轮询工作。如果运行器退出,请手动重新启动它。生产部署在编排器下运行运行器,该编排器重新启动已退出的运行器,通常每次重新启动时使用新的文件系统;[重用预热的检查](/docs/zh-CN/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout)涵盖了支持的持久磁盘设置。110 然后使用 `--environment-secret-file` 和 `--base-dir` 启动运行器:

93 111 

94 ```bash theme={null}112 ```bash theme={null}

95 claude self-hosted-runner --environment-secret-file '/etc/claude/environment-secret' --base-dir '<writable-dir>'113 claude self-hosted-runner --environment-secret-file '/etc/claude/environment-secret' --base-dir '<writable-dir>'

96 ```114 ```

115 

116 运行器向您的环境注册后会记录 `Registered: runner_id=<runner-id>`,然后开始轮询工作。如果运行器之后退出,请手动重新启动它。有关何时会发生这种情况,请参阅[如果运行器退出](#if-the-runner-exits)。

97 </Step>117 </Step>

98 118 

99 <Step title="验证运行器出现">119 <Step title="验证运行器出现">

100 返回[**Cloud environments** 页面](https://claude.ai/admin-settings/cloud-environments)。您的环境状态在运行器启动后几秒内从 **No runners deployed** 更改为 **Healthy**;打开环境并选择 **Activity** 以查看运行器本身。120 返回[**Cloud environments** 页面](https://claude.ai/admin-settings/cloud-environments)。您的环境状态在运行器启动后几秒内从 **No runners deployed** 更改为 **Healthy**;打开环境并选择 **Activity** 以查看运行器本身。如果您无权访问管理页面,上一步运行器日志中的 `Registered: runner_id=<runner-id>` 行可提供相同的信号。

101 </Step>121 </Step>

102 122 

103 <Step title="将会话路由到环境">123 <Step title="将会话路由到环境">

104 在 claude.ai/code 启动会话,并从环境选择器中选择您的环境,其中自托管环境与 Anthropic 托管的环境一起出现。运行器使用主机已有的任何 git 凭证进行克隆,因此选择此主机已可以克隆的存储库或公共存储库;生产中私有存储库的凭证选项在[配置 git](/docs/zh-CN/self-hosted-environments-deploy#configure-git)上。下一个可用的运行器拾取排队的会话并记录 `Picked up session <session-id>` 以及其活跃计数和容量,因此您可以从运行器自己的输出中确认哪个主机接收了会话。在 [claude.ai/code](https://claude.ai/code) 观看会话工作并阅读 Claude 的回复。如果会话保持排队状态,请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。124 <span id="route-a-session" />在 claude.ai/code 启动会话,并从环境选择器中选择您的环境,其中自托管环境与 Anthropic 托管的环境一起出现。对于仓库,请选择[前提条件](#host-and-network)中的仓库:公共仓库,或此主机已可以克隆的仓库。运行器使用主机已有的任何 git 凭据进行克隆。

125 

126 下一个可用的运行器拾取排队的会话并记录 `Picked up session <session-id>` 以及其活跃计数和容量,因此您可以从运行器自己的输出中确认哪个主机接收了会话。在 [claude.ai/code](https://claude.ai/code) 观看会话工作并阅读 Claude 的回复。

127 

128 如果会话没有开始工作,请对照您看到的情况:

129 

130 * **会话保持排队状态**:请参阅[故障排除](/docs/zh-CN/self-hosted-environments-deploy#troubleshooting)。

131 * **会话因 git 错误而无法启动**:错误会显示在会话和运行器的日志中。如果错误包含 git 的 `could not read Username for`,后跟您的 git 主机的 URL,则说明运行器没有该主机的 HTTPS 凭据。请参阅[配置 git](/docs/zh-CN/self-hosted-environments-deploy#configure-git),其中还介绍了生产环境中私有仓库的凭据选项。

105 </Step>132 </Step>

106</Steps>133</Steps>

107 134 

108运行器在其活跃会话完成后按设计退出;请参阅[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)。对于生产,在编排器下部署它,该编排器在退出时重新启动它,并在运行器启动后立即继续退出时等待更长的时间再重新启动。请参阅[部署到生产环境](/docs/zh-CN/self-hosted-environments-deploy)和[当运行器退出时](/docs/zh-CN/self-hosted-environments-deploy#when-the-runner-exits)。135<h3 id="if-the-runner-exits">

136 如果运行器退出

137</h3>

138 

139如果运行器在本快速入门期间退出,请使用相同的命令再次启动它。运行器可能会自行退出:

140 

141* **会话已完成**:日志显示 `[runner:exit] account workload drained — exiting`。运行器在其活跃会话完成后按设计退出。请参阅[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)。

142* **失去联系**:日志显示一行包含 `runner record gone server-side` 或 `poll auth failed` 的 `[runner:fatal]`。如果运行器与 Anthropic 失去联系一段时间(例如因为主机休眠),它可能会在下次连接到 Anthropic 时退出。

143 

144一个轮次结束并不会结束您的测试会话。第一轮之后,会话仍处于连接状态,运行器也仍在运行,因此您可以[向会话发送后续消息](#send-a-follow-up-message-to-a-running-session),而无需先重新启动运行器。

145 

146对于生产,在编排器下部署运行器,该编排器在退出时重新启动它,并在运行器启动后立即继续退出时等待更长的时间再重新启动。请参阅[部署到生产环境](/docs/zh-CN/self-hosted-environments-deploy)和[当运行器退出时](/docs/zh-CN/self-hosted-environments-deploy#when-the-runner-exits)。

109 147 

110<h2 id="send-a-follow-up-message-to-a-running-session">148<h2 id="send-a-follow-up-message-to-a-running-session">

111 向运行中的会话发送后续消息149 向运行中的会话发送后续消息

Details

52| `--release-idle-session-min <n>` | `SELF_HOSTED_RUNNER_SESSION_IDLE_MS` | `0` | 在轮次完成或会话等待用户操作后,在 N 分钟的不活动后释放会话槽。仍在进行中的会话(包括持有永不完成的后台任务或从运行的工具调用内部请求的批准的会话)不计为空闲;与 `--kill-session-after-min` 配对作为硬后挡。在会话的后台任务完成后,运行器认为会话繁忙,直到读取结果的后续轮次开始,最多为 [`SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS`](#environment-variable-only-settings) 窗口。在运行器接收到关闭信号或达到其退休时间之前,留下运行器没有活跃会话的释放启动与正常排空相同的退出路径,由 `--drain-grace-sec` 管理。在您使用 [`--defer-shutdown-max-min`](/docs/zh-CN/self-hosted-environments-deploy#defer-the-drain-past-the-first-signal) 推迟的第一个信号之后,运行器在释放使其不持有任何会话时立即退出。`0` 禁用。 |52| `--release-idle-session-min <n>` | `SELF_HOSTED_RUNNER_SESSION_IDLE_MS` | `0` | 在轮次完成或会话等待用户操作后,在 N 分钟的不活动后释放会话槽。仍在进行中的会话(包括持有永不完成的后台任务或从运行的工具调用内部请求的批准的会话)不计为空闲;与 `--kill-session-after-min` 配对作为硬后挡。在会话的后台任务完成后,运行器认为会话繁忙,直到读取结果的后续轮次开始,最多为 [`SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS`](#environment-variable-only-settings) 窗口。在运行器接收到关闭信号或达到其退休时间之前,留下运行器没有活跃会话的释放启动与正常排空相同的退出路径,由 `--drain-grace-sec` 管理。在您使用 [`--defer-shutdown-max-min`](/docs/zh-CN/self-hosted-environments-deploy#defer-the-drain-past-the-first-signal) 推迟的第一个信号之后,运行器在释放使其不持有任何会话时立即退出。`0` 禁用。 |

53| `--remove-session-state [bool]` | `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE` | 关闭 | 当会话在此运行器上结束时,删除 `<base-dir>/_sessions/` 下的会话的每个会话目录,无论结果如何。[重用预热的检出](/docs/zh-CN/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout)描述它们保存的内容以及当它们保留时谁可以读取它们。删除是尽力而为:当运行器被杀死或在清理运行之前达到其排空截止时间时,每个会话目录保持到位。启用标志后,失败或中断的会话的调试日志不会保留在磁盘上。需要 Claude Code v2.1.268 或更高版本。 |53| `--remove-session-state [bool]` | `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE` | 关闭 | 当会话在此运行器上结束时,删除 `<base-dir>/_sessions/` 下的会话的每个会话目录,无论结果如何。[重用预热的检出](/docs/zh-CN/self-hosted-environments-deploy#reuse-a-pre-warmed-checkout)描述它们保存的内容以及当它们保留时谁可以读取它们。删除是尽力而为:当运行器被杀死或在清理运行之前达到其排空截止时间时,每个会话目录保持到位。启用标志后,失败或中断的会话的调试日志不会保留在磁盘上。需要 Claude Code v2.1.268 或更高版本。 |

54| `--retire-at <epoch-seconds>` | `SELF_HOSTED_RUNNER_RETIRE_AT` | 未设置 | 在绝对 Unix 时间戳(以秒为单位)处退休运行器,用于在已知时间杀死运行器的基础设施;[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)描述释放序列以及如何调整边距。2001 年之前或 5138 年之后的值被标志拒绝,被环境变量忽略。 |54| `--retire-at <epoch-seconds>` | `SELF_HOSTED_RUNNER_RETIRE_AT` | 未设置 | 在绝对 Unix 时间戳(以秒为单位)处退休运行器,用于在已知时间杀死运行器的基础设施;[运行器生命周期](/docs/zh-CN/self-hosted-environments#runner-lifecycle)描述释放序列以及如何调整边距。2001 年之前或 5138 年之后的值被标志拒绝,被环境变量忽略。 |

55| `--server-auto-mode-lists <mode>` | `SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS` | `no-allow` | 控制平面随会话发送的[自动模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode)分类器规则列表中,哪些可以到达该会话:`all`、`no-allow` 或 `none`。请参阅[自动模式规则列表](#auto-mode-rule-lists)了解每个值应用的内容。无效值会使运行器在启动时停止。需要 Claude Code v2.1.295 或更高版本。 |

55| `--session-stop-grace-sec <n>` | `SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS` | `5` | 会话结束后等待 Claude 进程干净退出的时间,然后强制杀死它。如果子进程自己的 `SessionEnd` 钩子需要更多时间,请提高该值。 |56| `--session-stop-grace-sec <n>` | `SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS` | `5` | 会话结束后等待 Claude 进程干净退出的时间,然后强制杀死它。如果子进程自己的 `SessionEnd` 钩子需要更多时间,请提高该值。 |

56| `--startup-timeout-min <n>` | `SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS` | `15` | 如果子进程在生成后 N 分钟内未在[活动频道](/docs/zh-CN/self-hosted-environments-configuration#keep-stdin-and-file-descriptor-3-attached)上发出初始化信号,则释放会话槽。由子进程的初始化信号清除,而不是普通输出,之后 `--release-idle-session-min` 接管。`0` 禁用。 |57| `--startup-timeout-min <n>` | `SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS` | `15` | 如果子进程在生成后 N 分钟内未发出已完成初始化的信号,则释放会话槽。克隆发生在生成之前,因此克隆时间不计入。由子进程在[活动频道](/docs/zh-CN/self-hosted-environments-configuration#keep-stdin-and-file-descriptor-3-attached)上的初始化信号清除,而不是由普通输出清除,之后 `--release-idle-session-min` 接管。`0` 禁用。 |

57| `--trust-workspace [bool]` | `SELF_HOSTED_RUNNER_TRUST_WORKSPACE` | 开启 | 为每个会话的存储库路径播种持久化信任,以便遵守存储库提交的 `permissions.allow` 和 `additionalDirectories`。设置 `false` 以删除存储库提交的权限授予,并在主机配置的 `settings.json` 中配置允许规则;无论如何,存储库提交的 `sandbox.*` 设置仍然适用,这就是为什么[存储库设置保护](/docs/zh-CN/self-hosted-environments-deploy#harden-your-deployment)无论此标志如何都扫描它们。 |58| `--trust-workspace [bool]` | `SELF_HOSTED_RUNNER_TRUST_WORKSPACE` | 开启 | 为每个会话的存储库路径播种持久化信任,以便遵守存储库提交的 `permissions.allow` 和 `additionalDirectories`。设置 `false` 以删除存储库提交的权限授予,并在主机配置的 `settings.json` 中配置允许规则;无论如何,存储库提交的 `sandbox.*` 设置仍然适用,这就是为什么[存储库设置保护](/docs/zh-CN/self-hosted-environments-deploy#harden-your-deployment)无论此标志如何都扫描它们。 |

58| `--use-anthropic-git-proxy` | `CLAUDE_RUNNER_USE_GIT_PROXY=1` | 关闭 | 通过 [Anthropic git 代理](/docs/zh-CN/self-hosted-environments-deploy#use-the-anthropic-git-proxy)而不是客户管理的 git 身份验证进行克隆。需要 `--capacity 1` 和 git 2.32 或更高版本;运行器否则拒绝启动。取代重写标志。 |59| `--use-anthropic-git-proxy` | `CLAUDE_RUNNER_USE_GIT_PROXY=1` | 关闭 | 通过 [Anthropic git 代理](/docs/zh-CN/self-hosted-environments-deploy#use-the-anthropic-git-proxy)而不是客户管理的 git 身份验证克隆 github.com 上的仓库。需要 `--capacity 1` 和 git 2.32 或更高版本;运行器否则拒绝启动。取代重写标志。 |

59 60 

60大多数持续时间标志都有最大值,选择以将每个超时保持在运行时的 32 位计时器上限内,大约 24.85 天。`--*-min` 标志上限为 10080 分钟,7 天;`--drain-grace-sec` 为 604800 秒,也是 7 天;`--drain-wait-sec` 为 86400 秒,24 小时。`--session-stop-grace-sec` 和 `--post-session-hook-timeout-sec` 无上限。超过上限的行为因表面而异:61大多数持续时间标志都有最大值,选择以将每个超时保持在运行时的 32 位计时器上限内,大约 24.85 天。`--*-min` 标志上限为 10080 分钟,7 天;`--drain-grace-sec` 为 604800 秒,也是 7 天;`--drain-wait-sec` 为 86400 秒,24 小时。`--session-stop-grace-sec` 和 `--post-session-hook-timeout-sec` 无上限。超过上限的行为因表面而异:

61 62 

62* **标志**:启动失败并出现错误。63* **标志**:启动失败并出现错误。

63* **环境变量**:运行器将值夹紧到计时器上限,而不是拒绝它。64* **环境变量**:运行器将值夹紧到计时器上限,而不是拒绝它。

64 65 

66<h3 id="auto-mode-rule-lists">

67 自动模式规则列表

68</h3>

69 

70`--server-auto-mode-lists` 让您决定来自运行器外部的哪些[自动模式](/docs/zh-CN/permission-modes#eliminate-prompts-with-auto-mode)分类器规则可以到达您的运行器上的会话。Anthropic 的控制平面可以随会话发送规则列表,并要求运行器应用它们。其中某些条目可能是您组织的管理员编写的规则。这些列表是 `environment`、`soft_deny` 和 `allow`:

71 

72* **`environment`**:条目既可以让分类器允许更多操作,也可以让其允许更少操作。

73* **`soft_deny`**:条目会阻止某个操作,除非用户明确要求执行该操作,或者适用某个 `allow` 例外。

74* **`allow`**:`soft_deny` 条目的例外。

75 

76标志的值决定运行器应用哪些列表:

77 

78* **`no-allow`**:默认值。应用 `environment` 和 `soft_deny`,不应用 `allow`。`environment` 条目仍然可以让分类器允许更多操作,因此默认值并不能排除所有放宽。

79* **`all`**:应用全部三个列表。

80* **`none`**:不应用其中任何列表。选择 `none` 可排除来自这些列表的所有放宽。它也会丢弃 `soft_deny` 限制。

81 

82没有任何运行器设置能让控制平面要求运行器应用这些列表。当控制平面没有提出要求时,无论您如何设置,会话都不会收到任何列表。要查看发生了哪种情况,请使用 `--log-level debug` 启动运行器。随后,运行器会为每个会话记录一行包含 `the server asked this runner to apply` 的日志,或一行包含 `the server did not ask this runner to apply the auto mode lists it sends` 的日志。

83 

65<h2 id="orchestrator-cli-flags">84<h2 id="orchestrator-cli-flags">

66 Orchestrator CLI 标志85 Orchestrator CLI 标志

67</h2>86</h2>


72| :- | :- | :- |91| :- | :- | :- |

73| `--hook-concurrency <n>` | `4` | 最大 `spawn-runner` 钩子并行运行。还限制每次轮询声称的生成请求数。 |92| `--hook-concurrency <n>` | `4` | 最大 `spawn-runner` 钩子并行运行。还限制每次轮询声称的生成请求数。 |

74| `--hook-timeout <sec>` | `60` | 在这么多秒后终止钩子的进程树。超时加其 5 秒杀死宽限期必须保持在 `--expected-spawn-seconds` 以下;编排器在启动时强制执行此操作。 |93| `--hook-timeout <sec>` | `60` | 在这么多秒后终止钩子的进程树。超时加其 5 秒杀死宽限期必须保持在 `--expected-spawn-seconds` 以下;编排器在启动时强制执行此操作。 |

75| `--expected-spawn-seconds <sec>` | `120` | 生成的运行器的预期 p99 启动时间,在服务器强制的范围 10 到 3600 内。在每次轮询时发送作为服务器端租约;如果没有运行器在其过期前注册,会话将使用新的订单 ID 重新提供。所有副本必须共享此值。 |94| `--expected-spawn-seconds <sec>` | `120` | 从编排器收到生成请求到运行器注册的预期 p99 时间,包括在您的平台上等待容量的任何时间。服务器强制的范围为 10 到 3600。在每次轮询时作为服务器端租约发送;如果没有运行器在其过期前注册,会话将使用新的订单 ID 重新提供。所有副本必须共享此值。 |

76| `--min-idle <n>` | `0` | 通过主动生成待命运行器来保持至少 N 个空闲会话槽。`0` 禁用预热。与运行器的 `--exit-if-unused-min` 配对,以便多余的待命运行器回收自己。 |95| `--min-idle <n>` | `0` | 通过主动生成待命运行器来保持至少 N 个空闲会话槽。`0` 禁用预热。与运行器的 `--exit-if-unused-min` 配对,以便多余的待命运行器回收自己。 |

77| `--debug-dir <path>` | 未设置 | 将每个生成请求的工作订单和钩子 stderr 写入磁盘。仅用于调试;永远不要在生产中设置。 |96| `--debug-dir <path>` | 未设置 | 将每个生成请求的工作订单和钩子 stderr 写入磁盘。仅用于调试;永远不要在生产中设置。 |

78 97 


108| `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS` | `7000` | 运行器在轮次完成后计算会话繁忙的时间上限,用于 `--drain-wait-sec` 排空,而会话的进程向 Anthropic 报告轮次的结束。`0` 或不可用的值回退到默认值,因此无法关闭保持。需要 Claude Code v2.1.275 或更高版本。 |127| `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS` | `7000` | 运行器在轮次完成后计算会话繁忙的时间上限,用于 `--drain-wait-sec` 排空,而会话的进程向 Anthropic 报告轮次的结束。`0` 或不可用的值回退到默认值,因此无法关闭保持。需要 Claude Code v2.1.275 或更高版本。 |

109| `SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS` | `30000` | 运行器等待操作系统向陷入不可中断 I/O 的子进程传递 `SIGKILL` 的时间,然后自己退出。下限为 `--post-session-hook-timeout-sec` 加 15 秒,设置 `--push-outcome-on-release` 时再加 30 秒,因此有效最小值在默认值处为 75 秒。 |128| `SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS` | `30000` | 运行器等待操作系统向陷入不可中断 I/O 的子进程传递 `SIGKILL` 的时间,然后自己退出。下限为 `--post-session-hook-timeout-sec` 加 15 秒,设置 `--push-outcome-on-release` 时再加 30 秒,因此有效最小值在默认值处为 75 秒。 |

110| `CLAUDE_RUNNER_FETCH_DEPTH` | `50` | 新克隆的 git 获取深度。设置正整数,或 `full` 或 `0` 以进行完整获取。工作区中已存在的存储库保持其现有深度。 |129| `CLAUDE_RUNNER_FETCH_DEPTH` | `50` | 新克隆的 git 获取深度。设置正整数,或 `full` 或 `0` 以进行完整获取。工作区中已存在的存储库保持其现有深度。 |

130| `CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS` | `600000` | 在 git 服务器自身的进度数字持续上升期间(例如服务器为大型仓库准备 pack 时),每次尝试中 git 获取等待首批数据的最长时间(以毫秒为单位)。`0` 或 `off` 会关闭此等待:此类获取在两分钟内没有收到数据时将被中断。任何其他整数都会被限制在 `120000` 到 `1800000` 之间,即 2 到 30 分钟。需要 Claude Code v2.1.295 或更高版本。 |

111| `CLAUDE_RUNNER_SKIP_GIT_VERIFY` | 未设置 | 当为 `1` 时,跳过 `checkout` 钩子运行后的 `.git` 存在检查。当您的钩子物化非 git 源时设置此项。 |131| `CLAUDE_RUNNER_SKIP_GIT_VERIFY` | 未设置 | 当为 `1` 时,跳过 `checkout` 钩子运行后的 `.git` 存在检查。当您的钩子物化非 git 源时设置此项。 |

112| `FORCE_AUTOUPDATE_PLUGINS` | 未设置 | 当为 `1` 时,让插件市场自动更新,即使二进制文件被固定 |132| `FORCE_AUTOUPDATE_PLUGINS` | 未设置 | 当为 `1` 时,让插件市场自动更新,即使二进制文件被固定 |

113| `CLAUDE_CODE_DISABLE_ARTIFACT` | 未设置 | 当为 `1` 时,无论组织的管理员设置如何,都在会话中禁用 Artifact 工具,并删除 `*.frame.claudeusercontent.com` 出口要求 |133| `CLAUDE_CODE_DISABLE_ARTIFACT` | 未设置 | 当为 `1` 时,无论组织的管理员设置如何,都在会话中禁用 Artifact 工具,并删除 `*.frame.claudeusercontent.com` 出口要求 |


178| `claude_code_self_hosted_orchestrator_poll_errors_total{error_kind}` | 按类型累积 PollSpawnHints 失败:`transport`、`timeout`、`5xx`、`429` 或 `4xx`。所有五个系列从进程启动时存在;在 `rate(...[5m]) > 0` 时发出警报。 |198| `claude_code_self_hosted_orchestrator_poll_errors_total{error_kind}` | 按类型累积 PollSpawnHints 失败:`transport`、`timeout`、`5xx`、`429` 或 `4xx`。所有五个系列从进程启动时存在;在 `rate(...[5m]) > 0` 时发出警报。 |

179| `claude_code_self_hosted_orchestrator_queue_pending_sessions` | 现在可声称的生成请求 |199| `claude_code_self_hosted_orchestrator_queue_pending_sessions` | 现在可声称的生成请求 |

180| `claude_code_self_hosted_orchestrator_queue_backing_off_sessions` | 在可重试钩子失败后处于重试退避中的生成请求 |200| `claude_code_self_hosted_orchestrator_queue_backing_off_sessions` | 在可重试钩子失败后处于重试退避中的生成请求 |

181| `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions` | 被阻止的生成请求,直到所有者从环境的**活动**选项卡重试它们;如果高于零则发出警报 |201| `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions` | 被阻止生成的会话。每个会话都保持阻止状态,直到用户向其发送新消息,或所有者从环境的**活动**选项卡重试它。修复原因后,该计数可能仍保持在零以上。如果高于零则发出警报。 |

182| `claude_code_self_hosted_orchestrator_pool_pending_sessions` | 等待此环境中的运行器的总会话。环境范围的聚合,在每个编排器实例上相同:在实例间使用 `MAX` 而不是 `SUM`。 |202| `claude_code_self_hosted_orchestrator_pool_pending_sessions` | 等待此环境中的运行器的总会话。环境范围的聚合,在每个编排器实例上相同:在实例间使用 `MAX` 而不是 `SUM`。 |

183| `claude_code_self_hosted_orchestrator_pool_active_sessions` | 当前分配给此环境中活跃运行器的会话。环境范围的聚合,在每个编排器实例上相同:在实例间使用 `MAX` 而不是 `SUM`。 |203| `claude_code_self_hosted_orchestrator_pool_active_sessions` | 当前分配给此环境中活跃运行器的会话。环境范围的聚合,在每个编排器实例上相同:在实例间使用 `MAX` 而不是 `SUM`。 |

184| `claude_code_self_hosted_orchestrator_spawn_hooks_total{result}` | 累积 `spawn-runner` 钩子结果:`ok`、`retryable`、`non_retryable`。计数编排器钩子调用,而不是运行器生成的会话子进程:与 `sessions_started_total` 不可比,因为容量高于 1、热池和为同一会话再次生成的运行器都使两者分散。 |204| `claude_code_self_hosted_orchestrator_spawn_hooks_total{result}` | 累积 `spawn-runner` 钩子结果:`ok`、`retryable`、`non_retryable`。计数编排器钩子调用,而不是运行器生成的会话子进程:与 `sessions_started_total` 不可比,因为容量高于 1、热池和为同一会话再次生成的运行器都使两者分散。 |


283 for: 1m303 for: 1m

284 labels: {severity: critical}304 labels: {severity: critical}

285 annotations:305 annotations:

286 summary: "{{ $value }} 个会话断路 — spawn-runner 钩子反复不可重试;修复基础设施然后从活动选项卡重试"306 summary: "被阻止生成的会话:{{ $value }}。在 Activity 选项卡中查看每个会话的错误,修复原因,然后选择 Retry"

287 - alert: ClaudeOrchestratorPollErrors307 - alert: ClaudeOrchestratorPollErrors

288 expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0308 expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0

289 for: 2m309 for: 2m


318 338 

319在 v2.1.260 之前,运行器终止达到其 `--kill-session-after-min` 限制的每个会话,并在 `sessions_interrupted_total` 中计数。339在 v2.1.260 之前,运行器终止达到其 `--kill-session-after-min` 限制的每个会话,并在 `sessions_interrupted_total` 中计数。

320 340 

321[`post-session` 钩子](/docs/zh-CN/self-hosted-environments-configuration#post-session)的 `CLAUDE_RUNNER_EXIT_REASON` 以不同方式分类干净交接。钩子将释放、启动超时和服务器取消分配报告为 `interrupted`,因为运行器停止了子进程。这些计数器记录与 `completed` 相同的事件,因为槽被干净地交还。341[`post-session` 钩子](/docs/zh-CN/self-hosted-environments-configuration#post-session)的 `CLAUDE_RUNNER_EXIT_REASON` 以不同方式分类干净交接。钩子将以下情况报告为 `interrupted`,因为运行器停止了子进程:释放、启动超时、服务器取消分配,以及轮询先注意到的存档或删除。这些计数器记录与 `completed` 相同的事件,因为槽被干净地交还。

322 342 

323如果您直接根据 `sessions_completed_total` 协调钩子收据,您会低估完成。对每个会话保证使用钩子,对聚合速率使用计数器。343如果您直接根据 `sessions_completed_total` 协调钩子收据,您会低估完成。对每个会话保证使用钩子,对聚合速率使用计数器。

324 344 

Details

87 87 

88`--environment` 和 `--ref` 分派标志需要在运行脚本的机器上使用 Claude Code v2.1.224 或更高版本,这与运行器本身的下限相同。安装 hook 并在此主机上启动运行器后,测试脚本:88`--environment` 和 `--ref` 分派标志需要在运行脚本的机器上使用 Claude Code v2.1.224 或更高版本,这与运行器本身的下限相同。安装 hook 并在此主机上启动运行器后,测试脚本:

89 89 

901. 使用 `claude -p "<prompt>" --environment <environment-id> --output-format json` 在测试环境上创建会话,从 git 检出运行,以便 CLI 可以从 `origin` 远程自动检测存储库。可选的 `--ref <branch>` 将会话的检出基于命名的 ref 而不是本地 HEAD。该命令创建会话,打印包含 `session_id` 的一行 JSON,并退出而不等待 Claude 的回复。901. 使用 `claude -p "<prompt>" --environment <environment-id> --output-format json` 在测试环境上创建会话。请从 git 检出中运行该命令,以便 CLI 可以从 `origin` 远程自动检测仓库。可选的 `--ref <branch>` 将会话的检出基于命名的 ref 而不是本地 HEAD。该命令退出时不会等待 Claude 的回复。其输出会告知脚本结果:

91 * **会话已创建**:一行 JSON,例如 `{"ok":true,"session_id":"session_...","title":"...","url":"...","pool_id":"..."}`

92 * **会话创建失败**:输出 `{"ok":false,"error":"..."}` 这一行,并且命令以状态 1 退出

93 * **某些较早发生的错误**,例如您的组织无法使用云端会话或缺少提示词:错误输出到 stderr,不输出 JSON 行,并且命令以状态 1 退出

912. 等待回复出现在 `$E2E_REPLY_DIR/<session_id>.txt` 中,由运行器上的 Stop hook 在回合完成后写入。942. 等待回复出现在 `$E2E_REPLY_DIR/<session_id>.txt` 中,由运行器上的 Stop hook 在回合完成后写入。

923. 使用 `claude -p "<message>" --cloud <session_id> --output-format json` 发送后续消息(请参阅[向运行中的会话发送后续消息](/docs/zh-CN/claude-code-on-the-web#send-follow-ups-from-the-cli)),它将用户事件发布到现有会话并退出。953. 使用 `claude -p "<message>" --cloud <session_id> --output-format json` 发送后续消息(请参阅[向运行中的会话发送后续消息](/docs/zh-CN/claude-code-on-the-web#send-follow-ups-from-the-cli)),它将用户事件发布到现有会话并退出。

934. 以与步骤 2 相同的方式等待后续回复。964. 以与步骤 2 相同的方式等待后续回复。


104 示例脚本107 示例脚本

105</h2>108</h2>

106 109 

107下面的脚本针对 `$CLAUDE_TEST_ENVIRONMENT_ID`(您的测试环境的 `ccpool_...` ID,显示在管理页面上的环境详细信息对话框中或由[创建环境调用](#create-a-dedicated-test-environment)返回)运行完整循环,并对每个回复中的哨兵短语进行断言。从您希望会话在其中工作的仓库的 git 检出运行它,在此主机上启动运行器后,安装捕获 hook 并导出 `E2E_REPLY_DIR`。首先,按照[从 CI 进行身份验证](#authenticate-from-ci)中的说明,在运行该脚本的机器上使用 claude.ai 账户登录。如果未登录,第一次分派将失败,并出现诸如 `Unable to get organization UUID for cloud session creation` 之类的错误。110示例脚本与测试运行器在同一台机器上运行。运行之前,请先准备好该机器:

111 

112* **仓库检出**:从您希望会话在其中工作的仓库的 git 检出运行该脚本。

113* **运行器**:在此主机上启动运行器,安装捕获 hook 并导出 `E2E_REPLY_DIR`。

114* **登录**:按照[从 CI 进行身份验证](#authenticate-from-ci)中的说明,在运行该脚本的机器上使用 claude.ai 账户登录。

115* **环境 ID**:将 `CLAUDE_TEST_ENVIRONMENT_ID` 设置为您的测试环境的 `ccpool_...` ID,该 ID 显示在管理页面上的环境详细信息对话框中,或由[创建环境调用](#create-a-dedicated-test-environment)返回。

116 

117下面的脚本针对 `$CLAUDE_TEST_ENVIRONMENT_ID` 运行完整循环,并对每个回复中的哨兵短语进行断言。

108 118 

109```bash theme={null}119```bash theme={null}

110#!/usr/bin/env bash120#!/usr/bin/env bash


152TURN1="e2e-probe-$(date +%s)-$$: say exactly 'ok: custom tools are reachable' and nothing else"162TURN1="e2e-probe-$(date +%s)-$$: say exactly 'ok: custom tools are reachable' and nothing else"

153EXPECT1="ok: custom tools are reachable"163EXPECT1="ok: custom tools are reachable"

154create_json=$(claude -p "$TURN1" --environment "$CLAUDE_TEST_ENVIRONMENT_ID" \164create_json=$(claude -p "$TURN1" --environment "$CLAUDE_TEST_ENVIRONMENT_ID" \

155 --ref "$TEST_REPO_REF" --output-format json)165 --ref "$TEST_REPO_REF" --output-format json < /dev/null)

156echo "create: $create_json"166echo "create: $create_json"

157SESSION_ID=$(jq -er '.session_id' <<<"$create_json")167SESSION_ID=$(jq -er '.session_id' <<<"$create_json")

158 168 


163# 3. Post a follow-up via the CLI.173# 3. Post a follow-up via the CLI.

164TURN2="e2e-probe-followup-$(date +%s): say exactly 'ok: follow-up delivered' and nothing else"174TURN2="e2e-probe-followup-$(date +%s): say exactly 'ok: follow-up delivered' and nothing else"

165EXPECT2="ok: follow-up delivered"175EXPECT2="ok: follow-up delivered"

166followup_json=$(claude -p "$TURN2" --cloud "$SESSION_ID" --output-format json)176followup_json=$(claude -p "$TURN2" --cloud "$SESSION_ID" --output-format json < /dev/null)

167echo "followup: $followup_json"177echo "followup: $followup_json"

168jq -e '.ok == true' <<<"$followup_json" >/dev/null178jq -e '.ok == true' <<<"$followup_json" >/dev/null

169 179 

skills.md +1 −1

Details

235 235 

236如果 skill 仅存在于您机器上的 `~/.claude/skills/` 中,当 [routine](/docs/zh-CN/routines) 调用它时,Claude Code 会报告找不到该 skill,因为每个 routine 运行都作为新的云会话启动。要在这些会话中使用个人 skill:236如果 skill 仅存在于您机器上的 `~/.claude/skills/` 中,当 [routine](/docs/zh-CN/routines) 调用它时,Claude Code 会报告找不到该 skill,因为每个 routine 运行都作为新的云会话启动。要在这些会话中使用个人 skill:

237 237 

238* 对于 Cowork 和云会话,为您的 claude.ai 账户启用该 skill。238* 对于 Cowork 和云端会话,为您的 claude.ai 账户启用该 skill。[自托管环境中的某些会话](/docs/zh-CN/self-hosted-environments-configuration#how-each-session’s-config-is-assembled) 不会加载您账户的 skill。

239* 对于云会话,您可以改为将 skill 提交到存储库的 `.claude/skills/`。在存储库的 `.claude/settings.json` 中声明的插件和仅在您的用户设置中启用的插件 [不会在云会话中加载](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)。239* 对于云会话,您可以改为将 skill 提交到存储库的 `.claude/skills/`。在存储库的 `.claude/settings.json` 中声明的插件和仅在您的用户设置中启用的插件 [不会在云会话中加载](/docs/zh-CN/cloud-environments#what-carries-over-from-your-setup)。

240 240 

241[Desktop 计划任务](/docs/zh-CN/desktop-scheduled-tasks) 在您的机器上本地运行,因此它们确实加载 `~/.claude/skills/`。241[Desktop 计划任务](/docs/zh-CN/desktop-scheduled-tasks) 在您的机器上本地运行,因此它们确实加载 `~/.claude/skills/`。

vs-code.md +1 −1

Details

479 479 

480Claude 为浏览器任务打开新标签页并共享您浏览器的登录状态,因此它可以访问您已登录的任何网站。480Claude 为浏览器任务打开新标签页并共享您浏览器的登录状态,因此它可以访问您已登录的任何网站。

481 481 

482如需让每个会话在启动时自动连接到您的浏览器,而无需输入 `@browser`,请参阅[默认启用 Chrome](/docs/zh-CN/chrome#enable-chrome-by-default)。关于在以这种方式连接的会话中,Claude Code 在执行浏览器操作前询问您的情况,请参阅 [VS Code 会话中的权限提示](/docs/zh-CN/chrome#permission-prompts-in-vs-code-sessions)。482如需让每个会话在启动时自动连接到您的浏览器,而无需输入 `@browser`,请参阅[默认启用 Chrome](/docs/zh-CN/chrome#enable-chrome-by-default)。关于 Claude Code 在执行浏览器操作前询问您的情况,请参阅 [VS Code 会话中的权限提示](/docs/zh-CN/chrome#permission-prompts-in-vs-code-sessions)。

483 483 

484有关设置说明、完整的功能列表和故障排除,请参阅 [在 Chrome 中使用 Claude Code](/docs/zh-CN/chrome)。484有关设置说明、完整的功能列表和故障排除,请参阅 [在 Chrome 中使用 Claude Code](/docs/zh-CN/chrome)。

485 485