Managed Agent(MA)支持内置工具、Custom Tool 和 MCP 工具。工具类型和基础配置请参见 Tools。 内置工具适合在托管 sandbox 中执行文件读写、命令执行、网页检索等操作;Custom Tool 适合将少量业务函数交给 Agent 调用;MCP 工具适合接入已经按 MCP 协议封装的外部能力。
在企业应用中,开发者通常还需要让 Agent 调用业务系统中的专用操作,例如查询订单、创建工单、调用库存系统、访问内网风控接口,或触发企业已有的图像、视频、数据处理服务。如果这些能力都通过 MCP server 接入,需要额外部署服务、维护 HTTP endpoint 和鉴权链路;如果让 Agent 直接通过命令行调用内部接口,则缺少稳定的参数 schema、权限边界和结果格式约束。
Custom Tool 用于解决这类“将少量业务函数交给 Agent 调用”的场景。开发者只需要在 Agent 中声明工具名称、用途和输入 schema,运行时由业务侧接收工具调用事件、执行真实业务逻辑,并将工具结果回传给 Session。Agent 可以基于工具结果继续推理和回复用户。
本文先通过订单查询演示可直接执行的最小事件闭环,再通过 4 个多媒体示例说明如何声明工具、触发调用和回传结果:
前提条件
你需要准备:
- 已开通 Managed Agent,并已获取可用的 API Key。
- 已创建云环境,并将其 ID 配置到 ENVIRONMENT_ID。
- 本地已安装 curl 7.76.0 或更高版本,以及 jq。
- 已明确需要暴露给 Agent 的业务操作,包括操作名称、用途、输入参数、返回结果和错误处理方式。
- 已准备业务侧执行逻辑。该逻辑可以运行在你的服务端、内部系统或任务队列中,用于接收工具调用事件、执行实际操作,并向 Session 回传工具结果。
- 如果工具需要访问内部系统,请提前配置鉴权、权限控制、审计日志和超时策略。
使用流程
使用 Custom Tool 的一般流程如下:
- 声明工具:创建 Agent 时,在 tools 中添加 type: custom 的工具,填写 name、description 和 input_schema。
- 创建 Session:基于该 Agent 创建 Session。
- 建立事件流:订阅 Session SSE,并等待服务端返回 : ready。
- 发送用户消息:向 Session 发送 user.message。
- 接收工具调用事件:当 Agent 判断需要调用自定义工具时,Session 事件流中会出现 agent.custom_tool_use 事件。该事件包含工具名称、工具输入参数和事件 ID。
- 等待 Session 暂停:Session 随后进入 idle,并发出 session.status_idle 事件。该事件的 stop_reason.type 为 requires_action,stop_reason.event_ids 中包含需要业务侧处理的事件 ID。
- 执行业务逻辑:业务侧根据 agent.custom_tool_use 的 name 和 input 执行对应操作。
- 回传工具结果:业务侧发送 user.custom_tool_result 事件,使用 custom_tool_use_id 关联第 5 步中的工具调用事件 ID。
- 继续运行:所有阻塞事件处理完成后,Session 从 idle 切回 running。业务侧继续监听,直到收到 session.status_idle 且 stop_reason.type=end_turn。
- 清理测试资源:完成验证后,按 Session、Agent 的顺序删除本教程创建的资源。
如果 stop_reason.event_ids 中包含多个事件 ID,需要为每个阻塞事件回传结果。建议将同一轮阻塞事件对应的多个 user.custom_tool_result 放在同一个 events 数组中发送。
声明自定义工具
自定义工具通过 Agent 的 tools 字段声明。每个工具至少包含以下字段:
声明工具时,建议遵循以下原则:
- description 明确说明工具应该在什么场景下使用,以及不应该在什么场景下使用。
- input_schema 只暴露业务必要参数,不暴露 API Key、内部服务地址等敏感配置。
- 对枚举值、数字范围、必填字段和 additionalProperties 做明确约束。
- 工具返回值保持结构化,便于 Agent 判断是否成功、是否需要重试,以及如何向用户解释结果。
以下示例显式关闭内置工具集,避免主 Agent 在只配置自定义工具时回退启用全部内置工具。响应示例仅展示与流程相关的关键字段,实际响应字段以 API 返回为准。
响应示例:
创建 Session
响应示例:
以下函数从空 Session 开始完成一次 query_order 调用。函数先建立 SSE 并等待 : ready,再发送消息;收到 requires_action 后,它使用真实 stop_reason.event_ids 找到对应的 agent.custom_tool_use,生成确定性的订单查询结果,批量回传 user.custom_tool_result,最后等待 end_turn:
运行函数:
正常完成时,函数输出 Agent 的最终回复并返回状态码 0。返回 3 表示本轮重试耗尽,返回 4 表示 Session 已终止。SSE 在终态前断开时,函数返回非零状态,不会把断流当作成功。
注意
本节用固定订单结果演示业务侧执行器。接入真实系统时,只替换函数中 query_order 的业务查询逻辑,保留 : ready、requires_action.event_ids、custom_tool_use_id 和 end_turn 的处理顺序。
场景一:Custom Tool 生图
本场景演示如何通过 Custom Tool 接入企业已有的生图服务。完整链路包括:声明 generate_image 工具、创建 Agent 和 Session、发送用户消息、接收工具调用事件、执行生图逻辑并回传图片结果。
以下多媒体场景聚焦工具 Schema 和结果格式,只展示事件 payload。实际执行时,沿用 运行最小可执行闭环 中的 SSE 循环,并替换业务处理逻辑。不要在尚未收到 : ready 时单独执行发送消息的 cURL。 创建 Agent 时,在 tools 中声明生图工具:
创建包含该工具的 Agent 并创建 Session 后,发送生图请求:
模型产生 agent.custom_tool_use:
随后 Session 进入 idle,stop_reason.type 为 requires_action:
业务侧执行器调用生图服务,并回传工具结果:
模型拿到结果后即可回复用户,例如:
场景二:多图 Base64 回传
本场景演示一个工具调用返回多个多模态内容块。可以复用场景一中的 generate_image 工具声明,但需要在 input_schema 中为 n 设置合理范围,例如 minimum: 1、maximum: 4。
创建包含该工具的 Agent 和 Session 后,用户可以要求一次生成多张图片:
Agent 生成的工具调用事件示例如下:
回传结果时,文本块只放机器可读摘要,不重复塞入 Base64;每张图独立使用一个 image/base64 内容块:
这种结构有两个好处:
- 文本 JSON 便于 Agent 判断工具是否成功、生成了几张图、是否需要重试。
- 原生 image 内容块便于模型直接消费图像模态,不需要从文本中解析大段 Base64。
场景三:File ID 参考生视频
本场景演示如何让 Custom Tool 接收 File ID,并由业务侧把文件解析为视频生成服务可读取的参考素材。适用于参考图、参考视频、参考音频等素材已经通过 Files API 上传的场景。
创建 Agent 时,声明 generate_video 工具:
创建包含该工具的 Agent 和 Session 后,用户可以在消息中引用 File ID:
用户请求:
模型调用 generate_video:
业务侧执行器可以把 File ID 解析为视频生成服务可访问的素材,再提交异步任务。首次回传通常只表示任务已受理:
用户稍后查询任务:
任务完成时的回传示例:
视频结果建议以文本 JSON 返回 video_url。当前不要把 MP4 二进制作为 document/base64 塞回 Tool Result;这会显著放大事件体积,也可能无法被模型消费层按视频模态解析。
场景四:查询并理解视频
本场景演示如何把异步任务查询和后续视频理解串联起来。查询任务和理解视频内容是两个动作:
- get_video_task 负责确认任务状态,并拿到 video_url。
- 内置多模态或视频理解工具负责读取 video_url 并总结画面内容。
创建 Agent 时,声明任务查询工具:
创建包含该工具的 Agent 和 Session 后,用户请求查询并理解视频:
模型先调用 get_video_task:
业务侧执行器回传视频 URL:
接下来,Agent 应使用环境中可用的内置视频理解能力读取该 video_url。如果您的环境把该能力暴露为内置工具,可以在 Agent 的 system prompt 中明确要求:
最终回复示例:
如果当前环境没有视频理解内置工具,Agent 应说明只能确认 video_url 已生成,不能声称已经理解视频画面。
业务侧执行器参考逻辑
业务侧执行器需要维护一个待处理工具调用表。收到 agent.custom_tool_use 时先记录事件;收到 session.status_idle 且 stop_reason.type 为 requires_action 时,按 event_ids 找到对应工具调用,执行并批量回传。
完成教程并确认不再使用本次创建的 Agent 后,使用创建响应中保存的 SESSION_ID 和 AGENT_ID 清理测试资源。脚本先删除 Session,再删除 Agent:
本节不删除前提条件中已有的云环境。该环境不是本教程创建的资源,可能仍被其他 Session 使用。
警告
删除操作不可恢复。只使用本教程创建响应中保存的精确 SESSION_ID 和 AGENT_ID,不要按名称查找并批量删除资源。
常见问题
input_schema 是否可以传字符串?
不可以。input_schema 必须以 JSON 对象传入,且顶层 type 仅支持 object。
Custom Tool 名称有什么限制?
API 允许名称包含 1~128 个字符,只能使用英文字母、数字、下划线或连字符。为保证模型稳定引用,建议将名称控制在 1~64 个字符,例如 generate_image、get_video_task。同一个 Agent 最多配置 8 个 Custom Tool。
为什么视频结果只返回 video_url?
视频生成通常是异步任务,MP4 体积较大,直接作为 Tool Result 回传不适合。推荐返回文本 JSON,让 Agent、前端或后续内置视频理解工具通过 video_url 继续处理。
多个 Custom Tool 同时触发时怎么回传?
以 stop_reason.event_ids 为准。该数组里的所有工具调用都完成后,放在同一个 events 数组中批量发送:
调试建议
- 业务侧执行器先建立 SSE 并等待 : ready,再发送用户消息,避免错过 requires_action。
- 工具执行失败时也要回传 user.custom_tool_result,并设置 is_error: true。
- 不要在日志或文档中打印真实 API Key、完整签名 URL、完整 Base64 或未脱敏资源 ID。
- 生图和生视频后端建议使用独立的最小权限 API Key,便于审计和轮换。