Claude智能体系列第 19 / 22 篇

托管智能体入门:循环、沙箱和会话都交给 Anthropic,你只管发事件、收事件

Claude Managed Agents 把智能体的循环、工具执行和会话状态放到 Anthropic 那边运行。本文按官方文档整理它的四个概念、最小流程、工具和权限策略、事件怎么收发,以及从自己写的循环迁过来要改什么。中转站没有这组接口,全文未实测。

发布 · 约 12 分钟读完 · 经人工审核()· 本站的内容怎么来的

本文根据公开分享整理,本站尚未实测。操作前请对照文末的原始来源。

本页目录(11 节)
  1. 一、它和消息接口、Agent SDK 的区别
  2. 二、四个概念和一个最小的流程
  3. 三、定义智能体
  4. 四、工具
  5. 五、权限策略:哪些工具调用要先问你
  6. 六、事件:发什么,收什么
  7. 七、会话的状态和寿命
  8. 八、限流、数据和命名
  9. 九、从自己写的循环或 Agent SDK 迁过来
  10. 这组文章接下来讲什么
  11. 没有实测的部分

这篇教程解决一个问题:想让 Claude 自己跑几十分钟到几小时的任务,读文件、跑命令、上网查资料,但不想自己写循环、搭沙箱、存对话历史,有没有现成的?

有,叫 Claude Managed Agents(托管智能体)。它是 beta 功能,本文连同后面两篇把它的 37 页文档整理成三篇。

先说清楚:全文按官方文档整理,没有实测。 这组接口只在官方平台上有。本站在酷站AI 中转站上探测了智能体、环境、会话、保险库、记忆库、部署这六个接口,全部返回 404。文中的示例代码来自官方文档,本站没有运行过。

一、它和消息接口、Agent SDK 的区别

这个系列前面十几篇讲的都是消息接口:你发一个请求,模型回一个响应,循环、工具执行、历史都归你管。托管智能体是另一条路:

消息接口 Agent SDK 托管智能体
循环谁来跑 你写 SDK 替你跑,在你的进程里 Anthropic 那边跑
工具在哪执行 你的环境 你的机器,对着你的文件系统 Anthropic 托管的沙箱(也可以换成你自己的)
对话历史存在哪 你自己存,每次重发 SDK 管,在你这边 服务端存着
适合 要自己控制每一步 要一个现成的智能体,跑在自己的机器上 跑得久、异步、不想管基础设施

官方的概括:消息接口适合“自己写循环、要细粒度控制”,托管智能体适合“长时间运行的任务和异步的工作”。缓存、上下文压缩这些优化,托管智能体内置了。

Agent SDK 见《第一个智能体》。

二、四个概念和一个最小的流程

概念 是什么
智能体(agent) 一份配置:模型、系统提示词、工具、MCP 服务器、skill。建一次,反复用
环境(environment) 会话在哪里运行的配置:Anthropic 托管的云端沙箱,或你自己机器上的沙箱
会话(session) 智能体在某个环境里的一次运行,做一件具体的事
事件(event) 你的程序和智能体之间来回传的消息:用户的话、工具结果、状态变化

官方快速上手里的完整流程是四步:

from anthropic import Anthropic

client = Anthropic()

# 1. 建智能体(只建一次,记下 ID)
agent = client.beta.agents.create(
    name="Coding Assistant",
    model="claude-opus-5-5",
    system="You are a helpful coding assistant. Write clean, well-documented code.",
    tools=[{"type": "agent_toolset_20260401"}],        # 整套内置工具
)

# 2. 建环境(也只建一次)
environment = client.beta.environments.create(
    name="quickstart-env",
    config={"type": "cloud",
            "networking": {"type": "limited", "allow_package_managers": True}},
)

# 3. 建会话
session = client.beta.sessions.create(agent=agent.id, environment_id=environment.id)

# 4. 先打开事件流,再发消息,然后处理收到的事件
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": "写一个脚本,生成前 20 个斐波那契数,存到 fibonacci.txt"}]},
    ])
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "agent.tool_use":
                print(f"\n[调用工具:{event.name}]")
            case "session.status_idle":
                print("\n智能体做完了。")
                break

发出消息之后,服务端做的事是:按环境配置准备一个沙箱;跑智能体的循环,由 Claude 决定用哪些工具;工具在沙箱里执行;过程通过事件流实时发给你;没事可做时发一个 session.status_idle。

几件上手时要知道的事:

  • 所有接口都要带 beta 头 managed-agents-2026-04-01,SDK 会自动加。
  • 所有 API 账号默认都有权限。
  • 不想先写代码,可以在控制台里用图形界面配智能体、直接开一个测试会话看事件流,满意了再把智能体和环境的 ID 抄进代码。界面会显示等价的接口请求。
  • 在 Claude Code 里运行 /claude-api managed-agents-onboard,有一个问答式的引导。

三、定义智能体

智能体的字段:

字段 说明
name 必填
model 必填。Claude 4.5 及之后的模型。可以写模型名,也可以写成对象,对象里还能设 speed(快速模式)、effort、inference_geo(推理所在的地区)
system 系统提示词,定义行为和人设。具体要做的事放在用户消息里,不放这里
tools 内置工具集、MCP 工具、自定义工具
mcp_servers 要连的 MCP 服务器
skills 挂上的 skill
multiagent 让它把活交给别的智能体,见本组第三篇
description、metadata 说明和你自己用的标签

智能体是有版本的。 每次更新只要改动了配置,版本号就加一。围绕版本有几条规则:

  • 更新时可以带上当前的 version。和服务端的不一致就返回 409,这样两个人同时改不会互相覆盖。不带就是无条件覆盖,后写的赢。
  • 没写的字段保持原样。数组类的字段(tools、mcp_servers、skills)是整体替换。metadata 按键合并,把某个键设成 null 是删除它。
  • 更新后和当前版本没有差别,就不产生新版本。
  • 归档不可逆。 归档后智能体只读,不能再被新的会话引用,已有的会话照常运行。

建会话时,传智能体的 ID 用的是最新版本;想控制上线节奏,就传一个带版本号的对象,把会话钉在某个版本上。

单个会话可以临时改配置,不动智能体本身,也不产生新版本。可以覆盖的有 model、system、tools、mcp_servers、skills,每个字段三种写法:不写就继承;写成 null 或空数组就清空;写了值就整体替换(不会和智能体的配置合并,所以覆盖 tools 时要把这个会话需要的工具列全)。model 不能清空。

四、工具

内置的工具集

在 tools 里写 {"type": "agent_toolset_20260401"},就打开了整套内置工具,默认全部启用:

工具 名字 做什么
Bash bash 在一个 shell 会话里执行命令
读 read 读沙箱里的文件
写 write 写文件
编辑 edit 按字符串替换改文件
Glob glob 按通配符找文件
Grep grep 用正则搜文本
抓取网页 web_fetch 取一个网址的内容
联网搜索 web_search 搜索

用 configs 关掉个别工具,或者反过来先全关、只开需要的:

tools = [{
    "type": "agent_toolset_20260401",
    "default_config": {"enabled": False},                 # 先全关
    "configs": [{"name": "read", "enabled": True},        # 只开这两个
                {"name": "grep", "enabled": True}],
}]

工具的输出超过 10 万个字符(约 2.5 万 token)时,会被自动写进沙箱里的一个文件,模型拿到的是截断的预览和文件路径。

限制它能上哪些网站

web_search 和 web_fetch 的配置里各自可以放一个域名清单:allowed_domains(只许这些)或 blocked_domains(不许这些),二选一,每个清单 1 到 64 个域名。web_fetch 还可以设 max_content_tokens,web_search 可以设 user_location。

要留意:这两个工具跑在 Anthropic 的服务器上,不在沙箱里。 所以沙箱的网络限制本来管不到它们;但如果环境用的是 limited 网络,环境的 allowed_hosts 也会作用到这两个工具上。被清单拦下的搜索结果直接不出现,被拦下的抓取返回一个出错的工具结果。

自定义工具

和消息接口里自己定义的工具是一回事:你给出名字、说明和参数的 schema,Claude 决定什么时候调,由你的程序执行,再把结果送回会话。

{"type": "custom",
 "name": "get_weather",
 "description": "Get current weather for a location",
 "input_schema": {"type": "object",
                  "properties": {"location": {"type": "string", "description": "City name"}},
                  "required": ["location"]}}

名字不能以 mcp__ 或 ant__ 开头,也不能和内置工具重名。说明怎么写好,和《工具调用入门》第三节讲的完全一样。

五、权限策略:哪些工具调用要先问你

在服务端执行的工具(内置工具集和 MCP 工具)受权限策略管:

策略 行为
always_allow 直接执行,不问
always_ask 会话暂停,等你批准
auto 服务端逐个评估每次调用:放行、拒绝,或者拿不准时暂停问你

默认值要记住:内置工具集是 always_allow,MCP 工具集是 always_ask。 也就是说,不做任何配置时,bash 命令是不经确认直接跑的。

可以给整个工具集设一个默认策略,再对个别工具单独设。下面是“别的都放行,bash 每次都问”:

tools = [{
    "type": "agent_toolset_20260401",
    "default_config": {"permission_policy": {"type": "always_allow"}},
    "configs": [{"name": "bash", "permission_policy": {"type": "always_ask"}}],
}]

关于 auto,文档有几句话说得很直接:

  • 服务端判断时看的是工具、这次调用的参数和会话到此为止的内容,所以同一个工具的两次调用可能结果不同。
  • 被它判成高风险而拒绝的调用,你的程序不能推翻。
  • 你在用户消息里说的话算作你的意图,可以让它放行原本会拒绝的调用。工具结果、抓来的网页、MCP 服务器的返回里的话不算。
  • auto 不是人工把关。 它判断为安全的调用会在任何人看到之前就执行,后果可能无法撤销。必须有人先看的,用 always_ask。

权限策略管不到自定义工具。自定义工具本来就是你的程序在执行,要不要执行由你的代码决定。

六、事件:发什么,收什么

和智能体的全部交流都是事件。事件的类型名是“领域.动作”的形式。

你发的:

事件 用途
user.message 给它派活,或者接着聊
user.interrupt 打断正在做的事
user.custom_tool_result 回自定义工具的结果
user.tool_confirmation 批准或拒绝一次需要确认的工具调用
user.define_outcome 定义一个要达成的成果,见下一篇
system.message 追加系统级的上下文(要模型支持)

你收的,常用的几种:

事件 含义
agent.message 智能体说的话
agent.thinking 它在思考。只是进度信号,不带思考内容
agent.tool_use、agent.tool_result 调了内置工具,以及结果
agent.mcp_tool_use、agent.mcp_tool_result 调了 MCP 工具,以及结果
agent.custom_tool_use 调了你的自定义工具,等你回结果
session.status_running、session.status_idle 开始干活、停下来等输入
session.error 出错了,带一个是否在重试的状态
span.model_request_end 一次模型请求结束,带 token 用量

三条容易错的规则

先开流,再发消息。 事件流只送它打开之后产生的事件,先发后开会漏。

停下来不一定是做完了。 session.status_idle 里有一个 stop_reason,要看它的类型:

stop_reason.type 为什么停 你要做什么
end_turn 这一轮做完了,或者被你打断了 有新的活就再发 user.message
requires_action 有工具调用在等你:自定义工具的结果,或者一次确认 逐个回应
budget_reached 花费到了这个会话的预算 调高或去掉预算

断线重连要对历史。 重连的做法是:开一个新流,把完整的事件历史列出来、记下见过的事件 ID,再跟着新流走,跳过已经见过的。

回应等着你的工具调用

自定义工具被调用时,收到 agent.custom_tool_use,执行完用 user.custom_tool_result 回:

with client.beta.sessions.events.stream(session.id) as stream:
    for event in stream:
        match event.type:
            case "agent.custom_tool_use":
                result = call_tool(event.name, event.input)          # 你自己的执行逻辑
                client.beta.sessions.events.send(session.id, events=[
                    {"type": "user.custom_tool_result",
                     "custom_tool_use_id": event.id,
                     "content": [{"type": "text", "text": result}]},
                ])
            case "session.status_idle":
                if event.stop_reason and event.stop_reason.type == "end_turn":
                    break

需要确认的调用,等会话停在 requires_action 时,stop_reason.event_ids 里就是要回应的那几个事件。对每一个发 user.tool_confirmation,result 写 allow 或 deny,拒绝时可以用 deny_message 说明原因,这句话会交给智能体。会话会一直等下去,不会超时。

打断和改方向

发一个 user.interrupt,紧跟着再发一个 user.message 说新的要求。正在生成的模型回复会立刻停,正在跑的工具调用可能要多等一会儿。被打断的那一轮同样以 end_turn 结束。

边生成边显示

默认情况下,agent.message 是整条攒好了才发的。要做“打字机”效果,打开事件流时加上 event_deltas[] 参数,就能在整条消息到达之前收到增量的预览。文档强调:预览只是显示上的辅助,最后那条完整的 agent.message 才是准的;忽略预览的客户端拿到的仍然是完整正确的事件流。预览事件不进历史。

七、会话的状态和寿命

状态 含义
idle 在等输入。刚建好、还没发消息的会话就是这个状态
running 正在干活
rescheduling 遇到临时错误,在自动重试
terminated 结束了:出了无法恢复的错误,或者被归档

正常做完的会话是回到 idle,不是 terminated。

  • 会话可以隔很久再接着用。 对话历史一直留着,除非你删除。会话空闲时,沙箱会被存一个检查点,文件、装过的包都在。
  • 沙箱的状态只保留 30 天,从沙箱创建算起,期间有没有活动都不延长。 过了 30 天再继续,拿到的是一个全新的沙箱。重要的产出让智能体写到输出目录里,及时取走。
  • 会话建好以后,只能改它的 tools 和 mcp_servers,而且会话必须是空闲的。模型、系统提示词、skill 要在建会话时用覆盖的办法定下来。
  • 归档:不再接收新事件,历史保留。删除:会话记录、事件和沙箱一起永久删除,会话自己产生的文件也一起删,你通过 Files API 上传的文件不受影响。正在运行的会话要先打断,等它空闲了才能归档或删除。

建会话时可以用 initial_events 把第一条消息一起带上,省一次调用。

八、限流、数据和命名

  • 创建类的接口每个组织每分钟 300 次,读取类的每分钟 1,200 次。组织原有的消费上限和按档位的限流照样生效。
  • 不在零数据保留和 HIPAA 的范围内。 它天生有状态:对话历史、沙箱状态、产出都存在服务端。你可以随时删除会话和上传的文件。
  • 在自己的产品里提到它时,可以叫“Claude Agent”或“由 Claude 驱动的某某”,不能叫“Claude Code”或“Claude Cowork”,界面也不能做得像这两个产品。

会话的费用由三部分组成:模型的 token、联网搜索的次数、会话的运行时长。怎么给一个会话设花费上限,见下一篇。

九、从自己写的循环或 Agent SDK 迁过来

原来用消息接口自己写循环的,大部分代码可以删掉:

以前 以后
自己维护对话历史,每轮重发 历史在服务端,你只发事件、收事件
遍历工具调用、逐个执行、把结果拼回去 内置工具在沙箱里自动执行,你只处理自定义工具
自己准备跑代码的沙箱 用会话的沙箱
自己判断循环什么时候结束 等 session.status_idle

原来用 Agent SDK 的,概念是对得上的,区别在于在哪里运行:

Agent SDK 托管智能体
每次运行构造一份选项 建一次智能体,服务端保存并带版本
query() 或客户端对象 建会话,然后收发事件
用装饰器定义的工具,SDK 自动分发 声明成自定义工具,你的程序处理事件并回结果
内置工具对着你的文件系统 同样的工具,对着沙箱里的 /workspace
指向本地目录 把文件上传或把仓库挂载成会话的资源
系统提示词加 CLAUDE.md 的层级 智能体上的一个 system 字符串
权限模式和回调 每个工具的权限策略,加确认事件

有几样 SDK 自动做的事,迁过来以后归你的程序:

SDK 里的功能 在托管智能体里怎么办
计划模式 先跑一个只做计划的会话,再开第二个会话执行
输出风格、斜杠命令 在发消息之前、收到回复之后,由你的程序处理
工具调用前后的钩子 自定义工具本来就经过你的程序;内置工具用 always_ask 逐个审
最大轮数 自己数

这组文章接下来讲什么

  • 第二篇:环境和沙箱、文件和代码仓库、凭据、MCP、skill、记忆、成果、预算、观测、webhook、定时运行。
  • 第三篇:多个智能体协作,以及把沙箱放在自己的机器上。

没有实测的部分

  • 全文没有实测。 托管智能体只在官方平台上有,本站用的中转站对这组接口返回 404。
  • 示例代码来自官方文档,本站没有运行过,只把其中的提示词换成了中文、删掉了部分输出语句。
  • 价格、限流的数字和支持的模型以官方文档为准,这是 beta 功能,行为可能在版本之间调整。
  • 控制台的图形界面没有看过,是按文档的描述写的。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章