在自托管服务器上调用 API
将官方 SDK、cURL 或 ant CLI 指向您的自托管 Claude Managed Agents 服务器,启动会话并读取智能体的回复。然后,如果需要,连接您自己的 worker。
自托管 Claude Managed Agents 服务器提供的 API 与 Anthropic 托管的 Managed Agents 服务相同。您的代码使用官方 SDK、cURL 或 ant CLI 调用它。有两处变化:基础 URL 是您服务器的地址,API 密钥是您的服务器 API 密钥,而不是 Claude API 密钥。
要在浏览器中创建智能体并运行会话,请参阅使用您服务器上的控制台。
先决条件
- 正在运行的服务器: 使用开始使用自托管 Claude Managed Agents或在 Kubernetes 上部署启动一个服务器。
- 服务器的访问权限: 如果服务器由其他人运行,请向他们询问服务器的地址以及如何进行身份验证。如果他们使用单点登录,请参阅让开发者从终端登录。
antCLI: 请按照 CLI 快速入门中的说明,安装最新版本。
将您的客户端指向您的服务器
SDK 和 ant CLI 会从 ANTHROPIC_BASE_URL 读取服务器地址,从 ANTHROPIC_API_KEY 读取 API 密钥。请在您为此服务器保留的终端中设置这两个变量。
对于快速入门栈,请在包含您的 .env 文件的目录中运行以下命令:
export ANTHROPIC_BASE_URL=http://127.0.0.1:8400
export ANTHROPIC_API_KEY=$(grep '^CMA_SERVER__API_KEY=' .env | cut -d= -f2)在 Kubernetes 上,请按照运行会话中的说明设置这两个变量,并保持其端口转发处于运行状态。
在该终端中,每个 ant 命令(例如 ant beta:agents list)都会发送到您的服务器。请不要在该终端中运行 Claude Code 或 docker compose,因为它们会读取相同的变量。
启动会话
会话需要一个智能体的 ID 和一个环境的 ID:
- 智能体: 按照创建智能体中的说明创建一个,并将您的客户端指向您的服务器。如果您发送原始 HTTP 请求,请将 URL 中的
https://api.anthropic.com替换为$ANTHROPIC_BASE_URL。 - 环境: 快速入门栈会创建一个名为
compose-sandbox的环境,Helm chart 会创建一个名为default的环境。ant beta:environments list会打印每个环境的名称和 ID。对于您自己的 worker,该 ID 是管理 CLI 在运行您自己的 worker中打印的 ID。
将您的两个 ID 放入您的 shell,替换这些示例 ID:
export AGENT_ID=agent_011CYm1BLqPXpQRk5khsSXrs
export ENVIRONMENT_ID=env_01595EKxaaTTGwwY3kyXdtbs以下示例创建一个会话,并在同一请求中发送其第一条消息:
import os
from anthropic import Anthropic
client = Anthropic()
session = client.beta.sessions.create(
agent=os.environ["AGENT_ID"],
environment_id=os.environ["ENVIRONMENT_ID"],
initial_events=[
{
"type": "user.message",
"content": [
{"type": "text", "text": "List the files in the working directory."}
],
},
],
)
print(session.id)响应中包含会话的 ID,该 ID 以 sesn_ 开头。智能体会立即开始工作。它的内置工具(例如 bash)在为该环境提供服务的 worker 上运行。
要观察会话,请在浏览器中打开您服务器上的控制台,选择 Sessions,然后选择该会话。像本页面这样使用服务器 API 密钥启动的会话仅对管理员可见。
如果要改为在终端中跟踪会话,请将其 ID 传给 ant beta:sessions connect:
ant beta:sessions connect sesn_011CZkZAtmR3yMPDzynEDxu7有关会话还能做的其他事情(例如固定智能体版本),请参阅启动会话。
发送消息并读取回复
将您的会话 ID 放入您的 shell,替换此示例 ID:
export SESSION_ID=sesn_011CZkZAtmR3yMPDzynEDxu7请等到会话处于空闲状态后再运行下一个示例。该示例会在一个轮次结束时停止读取。如果之前的轮次仍在运行,它的结束可能会在您消息的回复到达之前使示例停止。控制台和 ant beta:sessions connect 都会显示会话的状态。
以下示例发送一条消息,并打印智能体的回复。它会先打开会话的事件流,因为事件流只会传递其打开之后发生的事件:
import os
from anthropic import Anthropic
client = Anthropic()
session_id = os.environ["SESSION_ID"]
with client.beta.sessions.events.stream(session_id) as stream:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.message",
"content": [
{"type": "text", "text": "Summarize what you did in one sentence."}
],
},
],
)
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
case "session.error":
error_message = event.error.message if event.error else "unknown"
print(f"\n[Error: {error_message}]")
case "session.status_idle":
if event.stop_reason.type != "requires_action":
break
case "session.status_terminated":
break除了打印 agent.message 文本外,循环还会处理三种事件:
session.status_idle: 循环结束,除非该事件的stop_reason.type是requires_action。session.status_terminated: 循环结束。session.error: 循环会打印错误的消息并继续读取,因为服务器可以重试失败的模型调用并完成该轮次。
requires_action 表示会话已为工具调用而暂停。结束暂停的方式取决于该调用:
- 自定义工具调用,或确认工具调用的请求: 只有您的代码可以回答它。如果您的智能体使用了其中任何一种,请参阅回答使会话暂停的工具调用。
- 对由 worker 运行的工具(例如
bash)的调用: 该调用通常不会暂停会话。如果大约 3 分钟内没有 worker 接手该调用,会话会暂停,直到某个 worker 返回结果。此时您的代码无需回答任何内容。请保持事件流处于打开状态,当 worker 运行该调用时,该轮次会继续。
有关会话发送的其他事件,以及如何在不遗漏任何事件的情况下重新连接,请参阅会话事件流。
在会话中传入和传出数据
数据通过 worker 的工作目录进入和离开会话。
在快速入门栈上,每个会话的容器启动时,其 /workspace 目录中除了会话仓库的克隆之外不包含任何内容。默认情况下,在一轮结束大约一分钟后,容器会退出,Docker 会将其连同该目录一起删除。会话必须保留的任何内容都必须在此之前通过工具调用(例如上传或 git push)传出。
容器在启动大约一小时后也会退出,即使正处于某一轮的中途。没有任何设置可以改变这一点。该轮次会在新容器中继续,通常在一两分钟之后,并且您的客户端不会收到关于此切换的任何事件。此切换有两项代价:
- 命令: 在旧容器中运行的所有内容都会停止。新容器会从头重新运行被中断的工具调用,但不会重新启动智能体留在后台运行的命令。
- 文件: 新容器的
/workspace再次为空,只包含会话仓库的全新克隆。
在较长的轮次中,请让智能体边工作边上传或推送其成果,并避免使用运行两次会造成危害的命令。
在 Kubernetes 上,一个会话最多保留一个 pod 约一小时,并且该轮次会以相同的方式继续。有两点不同:新 pod 会在 /workspace 中找到会话的文件,并且它会在旧 pod 停止大约 6 分钟后启动。
对于您自己启动的 worker,请在发送需要输入文件的消息之前,将这些文件放入工作目录。之后再从中读取输出文件。
当您自己为每个会话启动容器时,请将包含会话输入文件的目录挂载为容器的工作目录。容器退出后,从中收集输出文件。请参阅为会话准备文件。
在托管服务指南中查找更多示例
托管服务的指南介绍了 API 的核心概念,并为每项功能提供了示例。在设置了 ANTHROPIC_BASE_URL 和 ANTHROPIC_API_KEY 的终端中运行时,这些指南中的 SDK 和 CLI 示例会调用您的服务器。这些指南中的 cURL 示例使用的是 https://api.anthropic.com,因此在运行之前,请将该地址替换为 $ANTHROPIC_BASE_URL。
对于某些功能,您的服务器需要先进行设置,或者示例需要进行修改:
| 任务 | 托管服务指南 | 在您的服务器上 |
|---|---|---|
| 设置智能体的模型、系统提示和版本 | 定义您的智能体 | 某些字段取决于您的推理提供商。 |
| 选择内置工具,或添加自定义工具 | 工具 | 要使用 Web 工具,请先按照 Web 工具需要服务器设置中的说明启用它们。具体有哪些工具取决于您的推理提供商。 |
| 连接 MCP 服务器并存储其令牌 | MCP 连接器和使用保管库进行身份验证 | 将 MCP 服务器的主机添加到 MCP 服务器允许列表中。将令牌存储为 static_bearer 凭据。 |
| 为智能体提供技能 | 技能 | 将每个技能作为单独的文件上传,因为您的服务器会拒绝 zip 归档。该指南示例中的预构建技能不可用。 |
| 跨会话保留记忆 | 使用智能体记忆 | 如果您运行自己的 worker,请为它们提供一个可写的 /mnt/memory 目录,详见自托管沙箱中的记忆存储。 |
| 将工作交给其他智能体 | 多智能体编排 | 将该指南示例中的 multiagent_20261001 块替换为 coordinator 块。 |
| 在 Git 仓库中工作 | 访问 GitHub | 按照 Git 仓库需要允许列表条目中的说明,在您服务器的设置中列出 Git 主机。该指南中的示例智能体还需要将 api.githubcopilot.com 加入 MCP 服务器允许列表。 |
| 让评分器根据评分标准检查工作 | 定义结果 | 以文本形式发送评分标准。Files API 不可用,因此请从工作目录中收集输出文件。 |
| 跟踪会话并回答其工具调用 | 会话事件流 | 该指南的第一个示例会在任何暂停时关闭事件流,因此请改为从发送消息并读取回复中的循环开始。 |
与托管服务之间的差异列出了完整清单。在迁移现有应用程序之前,请先查看该页面。
运行您自己的 worker
快速入门栈会创建一个环境并运行其 worker。在 Kubernetes 上部署中的 Helm chart 也是如此。如果您只需要这些 worker,请跳过本节。
运行 worker 的方式与自托管沙箱相同:使用相同的 ant beta:worker 命令和 SDK worker,并采用部署自托管 worker 中所示的方式。例外的是由 webhook 触发的 worker,因为您的服务器不会发送任何 webhook。
创建环境及其密钥
请使用管理 CLI(而不是在 Claude Console 中)创建一个环境和一个环境密钥。该 CLI cma-server-admin 位于发布归档的顶层,因此请在该位置运行此命令。对于 -base-url,请传递您的 worker 访问服务器所用的地址:
- 在运行快速入门栈的机器上的 worker:
http://127.0.0.1:8400 - 另一台机器上的 worker: 您放在服务器前面的 TLS 代理的
https地址
该管理 CLI 会在同一地址调用服务器,因此请在能够访问该地址的机器上运行它。
echo "$ANTHROPIC_API_KEY" | ./cma-server-admin bootstrap \
-base-url http://127.0.0.1:8400 -name my-env -key-file -该命令会打印 worker 的设置、启动 worker 的命令,以及密钥的 ID 和过期时间:
export ANTHROPIC_BASE_URL='http://127.0.0.1:8400'
export ANTHROPIC_ENVIRONMENT_ID='env_...'
export ANTHROPIC_ENVIRONMENT_KEY='sk-ant-oat01-...'
# then: histchars= HISTFILE=/dev/null ant beta:worker poll --workdir /workspace
# key id: 'etok_...' expires: '...'该命令只显示一次密钥,因此请将密钥、其 ID 和过期时间存储在您的密钥管理器中。该密钥在 365 天后失效。在此之前,请按照为您自己的 worker 替换环境密钥中的说明操作。
不要将服务器 API 密钥放在运行 worker 的机器上。请在不包含任何需要保护内容的容器或虚拟机中运行 worker。有关您的其他安全职责,请参阅您的安全职责。
运行本地实验
在您启动 worker 的 shell 中运行这三行 export。然后使用以下命令(而不是打印出的命令)启动 worker。第一条命令会创建 worker 的工作目录,因为 worker 不会创建它:
mkdir -p "$HOME/cma-workspace" "$HOME/.config/cma"
cat > "$HOME/.config/cma/worker.inputrc" <<'EOF'
$include /etc/inputrc
set disable-completion on
EOF
histchars= HISTFILE=/dev/null INPUTRC="$HOME/.config/cma/worker.inputrc" \
ant beta:worker poll --workdir "$HOME/cma-workspace"histchars、INPUTRC 和 HISTFILE 用于设置 worker 的 bash 工具背后的 shell,使其按照智能体编写的原样运行每条命令:
histchars=: shell 不会将!视为对其命令历史的引用。INPUTRC: 该文件会关闭补全功能,否则补全会吞掉命令中的每个制表符。请将该文件放在工作目录之外,以免智能体的文件工具改写它。HISTFILE=/dev/null: shell 既不读取也不写入历史文件。
不要将此 worker 用于其他任何用途。它持有环境密钥,并在一个进程中运行每个会话的工具。它也不会克隆会话的仓库。会话会在没有这些仓库的情况下运行,并且您的客户端不会收到任何错误。
在生产环境中运行 worker
对于本地实验以外的任何情况,请按照为每个会话运行一个沙箱中的说明,为每个会话启动一个容器,并在其中运行 ant beta:worker run。请为其镜像提供构建您自己的沙箱镜像中列出的内容,并在该设置中更改三处:
- 环境密钥: 不要将
ANTHROPIC_ENVIRONMENT_KEY传入会话的容器。服务器会对该环境中的每个会话接受该密钥,而容器只需要访问一个会话。 - 工作项的机密: 请传递此机密来代替该密钥,因为服务器仅针对这一个会话接受它。转发工作项的机密展示了您的代码接收它的位置。在该节设置
ANTHROPIC_WORK_SECRET的地方,请将该机密放在一个只有容器用户可以读取的文件中。例如,将该机密通过管道传入容器的标准输入,并让容器在启动 worker 之前写入该文件。然后将ANTHROPIC_WORK_SECRET_FILE设置为该文件的路径。 - 服务器地址: 将
ANTHROPIC_BASE_URL设置为容器可以访问的地址。http://127.0.0.1:8400不是这样的地址。
对于 SDK worker,还有两点适用:
- 版本: 请按照 SDK、CLI 和库中的说明,基于最新版本的 SDK 构建 worker。该版本的 worker 会在运行需要批准的工具调用之前等待批准,并且绝不会运行被策略拒绝的调用。基于更早版本构建的 worker 会在每个工具调用到达后立即运行它。
- 示例: 在沙箱内运行 SDK worker 中的示例会读取环境密钥,因此无法直接在此使用。
构建您自己的沙箱镜像
您自己的镜像需要以下软件包和设置:
-
软件包: Git 2.38 或更高版本、
curl、jq和 ripgrep(worker 的grep工具使用它进行搜索)。 -
Shell 设置: 与本地实验中相同的
histchars、HISTFILE和INPUTRC,以及TERMINFO。请在 Dockerfile 中任何USER行之前加入以下几行:ENV histchars= RUN printf '\nset disable-completion on\n' >> /etc/inputrc ENV INPUTRC=/etc/inputrc TERMINFO=/etc/terminfo HISTFILE=/dev/null RUN test -r /etc/terminfo/d/dumbTERMINFO必须指定包含d/dumb(worker 的bash读取的终端描述)的目录。在已安装bash的 Alpine 上,该目录是/etc/terminfo,如上所示。在其他基础镜像(例如 Debian 或 Ubuntu)上,该目录是/lib/terminfo或/usr/share/terminfo,以包含d/dumb的那个为准。请在TERMINFO设置和RUN test行中写入该目录;如果该文件缺失,RUN test行会使构建停止。
该镜像还需要归档中的两个脚本,它们会在 worker 启动之前运行:
- 将
image-build/with-repositories.sh复制到/usr/local/bin/cma-with-repositories。它会克隆一个会话的仓库。 - 将
image-build/with-egress.sh复制到/usr/local/bin/cma-with-egress。如果您的服务器运行了"egress gateway"(出口网关),它会将会话的工具指向该网关。 - 使这两个文件都可执行。
- 将两者都放在 worker 命令的前面,例如
cma-with-egress cma-with-repositories ant beta:worker run ...。如果您的镜像运行归档中的kubernetes/sandbox/worker.sh,请跳过此步骤,因为该脚本就是以这种方式启动 worker 的。
不使用 cma-with-repositories 启动的 worker 会在没有仓库的情况下运行会话。您的客户端不会收到任何错误。
从托管服务迁移 worker
如果您已在为 Anthropic 的托管服务运行 worker,这些 worker 可以改为为您的服务器提供服务。请完成以下三件事:
- 将管理 CLI 打印的三个
export值提供给轮询工作的进程。 - 按照本地实验中的方式设置
histchars、HISTFILE和INPUTRC后启动该进程。 - 进行在生产环境中运行 worker中所述的更改,并对照构建您自己的沙箱镜像检查每个会话的镜像。
后续步骤
此页面对您有帮助吗?