把 Claude Agent 部署成服务:hosting 与 secure deployment 写明的前置条件

2026-08-18

一、先说清楚要解决的是哪种处境

在自己机器上跑通一段调用 Claude Agent SDK 的脚本,和把它变成一个别人能持续访问的服务,是两件事。常见的翻车不是代码写错,而是把它当成无状态的 API 包装层去部署:起容器、挂负载均衡、按请求扩缩容——然后发现会话对不上、重启后历史没了、两个租户的上下文串了。

官方文档《Hosting the Agent SDK》开头就把这个预期掐掉了:SDK 会派生并监管一个 claude CLI 子进程,这个子进程拥有一个 shell、一个工作目录,以及磁盘上的会话文件;托管它「不像托管一个无状态的 API 包装层」。一个 agent 会话对应一个子进程,跑 N 个并发会话就是 N 个子进程,各自有自己的进程树和 transcript 文件。这一句是后面所有部署决策的地基。

文档同页也给了退路:不需要基础设施控制、自定义隔离或自己的数据平面时,可以考虑 Managed Agents——由 Anthropic 托管 agent 与 sandbox 的 REST API 形态。本文讲的是自托管那一支。

二、前置条件(这一段最容易被跳过)

运行时版本。 文档在 Runtime dependencies 一节写明:容器里需要所用 SDK 的语言运行时——Python SDK 需要 Python 3.10+,TypeScript SDK 需要 Node.js 18+。两种 SDK 在多数安装方式下都自带一个原生 Claude Code 二进制,被派生的 CLI 不需要另外装 Node.js;哪些安装方式需要单独装原生 Claude Code,文档指向 quickstart 的安装说明。

版本耦合。 这个自带的二进制钉死在 SDK 包版本上,升级 CLI 的方式就是升级 SDK。文档说 SDK 遵循 semver,建议持续吃 patch 版本,升 minor 前先看 changelog。也就是说 CLI 版本跟着依赖锁文件走,不是容器里单独管的一件事。

网络出入口。 出站上,文档写明 SDK 需要到 api.anthropic.com 的出站 HTTPS;跑在 Amazon Bedrock 或 Google Cloud 的 Agent Platform 上时则是对应供应商的区域端点,agent 用到的 MCP 服务或外部工具端点也要放行。入站上文档写的是:容器暴露一个 HTTP 或 WebSocket 端口,由你的应用接请求、在内部调 SDK——子进程自己不监听网络。这句话决定了网关挡在哪一层。

鉴权。 子进程从环境里读 ANTHROPIC_API_KEY,文档给了两条路:从密钥管理器注入,或设置 ANTHROPIC_BASE_URL 把模型调用路由到容器外注入密钥的代理上。入站鉴权则明确要求放在 agent 容器前面的网关上——agent 应该收到已鉴权的请求,不该是校验用户 token 的那个组件。

资源。 文档给了每个 agent 的起步资源建议值,但紧跟着写明内存占用会随会话长度与工具活动增长,要按实际需要的会话长度和并发去估而非空闲基线,Scaling 一节还点名那个起步值是下限而不是上限。具体数值见官方原页,本文不复述会随版本变动的数字。

三、按文档写明的步骤走一遍

第 1 步:先选会话形态,再选跑在哪

文档把这一层叫 session pattern,明确列了四种,关注的是「容器的寿命相对于它服务的会话有多长」:

形态文档写明的适用场景关键约束
Ephemeral sessions一次性任务,任务完成即销毁容器容器跑一次性 entrypoint 后退出
Long-running sessions自主行动、持续服务、高频消息流容器要能把最大并发会话数装进内存
Hybrid sessions跨多次交互但中间长时间空闲必须SessionStore,否则关容器就丢 transcript
Multi-agent container多个 agent 在共享环境里协作每个 agent 各自的工作目录 + 隔离设置加载

Hybrid 那一行值得划重点:文档原话是没配 SessionStore 就关容器会连 transcript 一起丢,所以对这个形态而言 store 是必需项,不是可选项。另外文档提到 TypeScript 侧写一次性 entrypoint 时,文件要存成 entrypoint.mts 或在 package.json 里设 "type": "module",好让顶层 await 可用——按文档这句话的口径,漏了这一条顶层 await 就用不上,而一次性 entrypoint 的写法通常正靠它。

「跑在哪」文档交给了 hosting cookbook,只把选容器沙箱供应商拆成五个要问的问题:谁来运维 sandbox、冷启动延迟、有没有持久化存储、计费模型、网络(自定义出站规则、出站代理、私有 VPC 对等)。

第 2 步:认清哪些状态在本地磁盘上

文档列了三类默认落在容器文件系统上的状态,并明说它们都不会在容器重启、缩容或换节点后存活:

状态默认位置
会话 transcript~/.claude/projects/,或设了 CLAUDE_CONFIG_DIR 时其下的 projects/ 目录
CLAUDE.md 记忆文件user 层在 ~/.claude/CLAUDE.md,project 层在该会话的工作目录
工作目录产物该会话的工作目录

处置有三条必须记住:SessionStore 只镜像 transcript,不管 CLAUDE.md 和其它工作目录产物,那些要自己挂卷或同步;它是镜像而不是替代,子进程先写本地磁盘,SDK 再把每批的副本转发给 store;投递失败时它会丢弃这一批,发出一条 { type: "system", subtype: "mirror_error" } 消息然后继续跑查询——文档的说法是,如果 store 的持久性对你重要就对这些消息告警。

第 3 步:多租户隔离要显式关掉的几处默认行为

这是整页里最容易漏、后果又最脏的一段。文档写明:SDK 的默认行为会从文件系统读取设置和 CLAUDE.md 记忆文件;在服务多个租户的共享容器里,这些文件会把一个租户的上下文泄漏进另一个租户的会话。文档给出的容器内隔离动作是五条:

  • TypeScript 传 settingSources: []、Python 传 setting_sources=[],让文件系统设置一概不加载;
  • env 里设 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1——文档特意点明,auto memory 位于 ~/.claude/projects/<project>/memory/,它不受 settingSources,照样会进系统提示词;
  • CLAUDE_CONFIG_DIR 指向每租户独立目录,避免共用全局的 ~/.claude.json
  • 每租户独立工作目录,每次 query() 调用都显式传 cwd
  • 在代理层做每租户的出站规则(不同出站 IP、凭据或域名允许列表)。

前两条是两个开关,关掉一个不等于关掉另一个。文档还提醒了一处语言差异——TypeScript 里 env替换子进程环境,要展开 ...process.env 才能保住 PATHANTHROPIC_API_KEY 这类继承变量;Python 里 env合并在继承环境之上。文档点名要保住的正是 PATHANTHROPIC_API_KEY 这一类继承变量,两种语言的语义差异写在同一段里,照抄另一种语言的写法就会把它们漏掉。

第 4 步:安全侧文档标出的前置项

《Securely deploying AI agents》里有一句常被读反,必须原样转述。关于 bash 命令的权限校验,文档写的是:执行前把命令解析成 AST 再与权限规则匹配,解析不干净或没命中允许规则的命令需要显式批准,eval 这类少数构造无论允许规则怎么写都要批准;紧接着的原话是——这是一道权限闸门,不是 sandbox,它不会从命令的目标路径或副作用去推断命令危不危险。

隔离技术那张表列了四档:sandbox runtime、容器(Docker)、gVisor、虚拟机(Firecracker、QEMU),按隔离强度、性能开销、复杂度三列排开,每一档的代价文档也写了。以 sandbox-runtime 为例,它的两条安全注意事项是:与宿主共享同一内核,内核漏洞理论上可导致逃逸;以及不做 TLS 检查——代理按客户端提供的主机名做域名允许列表,不终止也不检查加密流量,因此 sandbox 内的代码有可能用 domain fronting 之类的手法访问允许列表之外的主机。

凭据这块文档推荐代理模式:代理跑在 agent 安全边界之外,由它在往外发的请求里注入凭据。给 Claude Code 配代理的方式文档写了两种:

# 方式一:只作用于 sampling 请求
export ANTHROPIC_BASE_URL="http://localhost:8080"

# 方式二:系统级
export HTTP_PROXY="http://localhost:8080"
export HTTPS_PROXY="http://localhost:8080"

差别文档说得直白:方式一让代理收到明文 HTTP 请求,可以检查和改写(包括注入凭据);方式二走标准环境变量,但对 HTTPS 而言代理建立的是加密 CONNECT 隧道,不做 TLS 拦截就看不到也改不了请求内容。要对任意 HTTPS 服务注入凭据,文档说需要 TLS 终止代理,并列了三项要求:代理跑在 agent 容器之外、把代理的 CA 证书装进 agent 的信任库、配置 HTTP_PROXY/HTTPS_PROXY。还有一条容易踩:并非所有程序都尊重这两个变量,文档举的例子是 Node.js 的 fetch() 默认忽略它们,Node 24+ 可设 NODE_USE_ENV_PROXY=1 打开支持。

以上为按官方文档中的参数语义组合的示例,未经实测,以官方文档与 --help 的实际输出为准。

第 5 步:Windows 侧要单独说的部分

得实话实说:上面这些命令与路径,官方文档给的形态都是 POSIX 侧的。

  • 状态位置写的是 ~/.claude/projects/ 这类 POSIX 风格路径,Windows 上的对应位置官方文档没有说明这一点
  • sandbox-runtime 用 OS 原语做文件系统与网络限制,文档写明 Linux 用 bubblewrap、macOS 用 sandbox-exec,网络侧 Linux 是移除网络命名空间、macOS 是 Seatbelt profile——Windows 上的对应原语官方文档没有说明
  • 容器加固示例是 docker run 的 Linux 容器参数(--cap-drop ALL--security-opt no-new-privileges--read-only--tmpfs--pids-limit--network none 等),gVisor 那段要在 /etc/docker/daemon.json 里注册 runsc 运行时;
  • 环境变量示例用的是 export,即 POSIX shell 写法。Windows 上怎么注入这些变量取决于你的编排方式(这属于通用做法,非该产品官方文档内容)。

也就是说,Windows 侧真正能照抄的部分都在 Linux 容器那一侧。

四、边界:文档自己标出来的不保证

  • 没有顶层会话超时。 Known limitations 表第一行写明:会话不会自己超时,要用 Options 里的 maxTurns 去约束 agent 停下来之前走多少轮工具调用。
  • 长会话内存增长。 文档给的处置是限制会话长度或周期性回收子进程。
  • 大规模并行 subagent 扇出可能撞上速率限制。 文档的处置是拆成小批次,而不是一次宽派发。
  • 没有 per-subagent 的挂钟截止时间。 处置是在各自的 AgentDefinition 里用 maxTurns 封顶;文档同时写明 CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS 只对后台 subagent 有效,它是 run_in_background 的 subagent 停止产出时触发的停滞看门狗,不是总运行时长的截止时间,两者当成一回事就会误判。
  • mirror_error 是尽力而为语义,不是重试保证——投递不上就丢这一批并继续。
  • 遥测里有一个 beta 变量。 可观测性一节的示例里,CLAUDE_CODE_ENHANCED_TELEMETRY_BETA 名字本身带 BETA,文档写明它只有导出 traces 时才需要,只导 metrics 和 logs 可以省掉。beta 意味着随时可能变。
  • 提示词文本与工具输入默认不进遥测导出,要开另有 opt-in 开关。

五、怎么确认配对了

文档没有给验收清单,下面几条是把文档里白纸黑字的语义翻成可核对项,每条都能回到上面某处原文:

  1. 隔离对没对:起两个不同租户的会话,各自的 cwdCLAUDE_CONFIG_DIR 应当互不可读;settingSources(Python 为 setting_sources)为空数组,且 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 确实进了子进程环境——按文档这两条缺一不可。
  2. TS 的 env 有没有写坏:既然 TypeScript 里是替换语义,就该确认 PATHANTHROPIC_API_KEY 仍在子进程环境里。
  3. 持久化对没对:按文档,从 store 恢复的运行结束时会删掉本地副本,store 持有唯一持久副本;所以有意义的验证动作是「重启容器后能不能按会话 ID 恢复」,而不是看本地磁盘还有没有文件。
  4. 告警接没接{ type: "system", subtype: "mirror_error" } 有没有落到告警链路上。
  5. 出站收没收窄:放行 api.anthropic.com(或所用供应商的区域端点)与 MCP / 外部工具端点,其余走代理策略。
  6. 入站在不在网关:请求到 agent 容器时是否已鉴权过。

最后提醒一句口径:《Hosting》讲怎么跑起来,《Secure Deployment》讲怎么把边界画紧,同一个东西(比如代理)在两页里的侧重点不同,别把某一页的片段当成全貌。


本文依据 Claude Code 官方文档(code.claude.com/docs)于 2026-08-17 的公开内容整理。 该产品闭源,本文只复述官方文档写明的机制,不推断其内部实现我们没有对文中涉及的功能做过实测,因此不涉及界面外观、操作手感与运行速度的任何描述。 该产品迭代频繁,文中涉及的命令、配置项与默认值随版本变动,请以官方文档最新内容为准。 本文不涉及价格、额度与限流的具体数值,相关信息请以官方定价与用量说明页为准。 安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。