跳到主要内容

智能体 Webhook

外部系统可以向 DesireCore 发送一个已配置的事件,让目标智能体在后台处理事件内容。适合将业务通知、监控事件或其他应用的消息交给智能体处理。

实例所有者可以通过管理接口创建事件、选择工具并取得专用密钥。仅负责发送事件的外部服务,则向管理员取得已配置的事件参数和密钥。

先调用认证握手,检查 capabilities.webhookManagement。只有值为 true 的实例支持下方管理步骤;字段缺失或为 false 时,当前实例暂不可通过这些接口创建或修改事件。已有有效配置仍可按触发请求调用。

调用前准备​

信息获取方式与要求
BASE_URL管理员提供的 Agent Service 地址;参见连接与认证。公开文档站点的地址不能用于调用。
AGENT_ID管理员提供的目标智能体 ID,不能用显示名称替代。该智能体必须已启用 Webhook。
event管理员提供的已配置事件名称,必须完全匹配,例如 demo.ping。
WEBHOOK_SECRET目标智能体的专用 Webhook 密钥。发送方通过自己的密钥管理方式保存和注入;需要轮换时联系管理员,并同步更新发送方。
事件处理约定确认事件使用的字段、可执行操作及结果观察方式。触发请求本身不提供工具或文件权限设置;实际操作取决于已选工具和文件范围。

外部调用必须配置 Webhook 密钥。远程实例未配置密钥时会拒绝触发;本机实例没有密钥时,也不能通过本页的外部调用方式触发。这份密钥与实例访问令牌、模型供应商 API Key 的用途不同;发送方应使用管理员提供的专用 Webhook 密钥。

发送方需要能访问实例地址。桌面实例的本机回环地址只适用于同一台电脑上的调用;外部服务器需要管理员提供可访问的服务地址。DesireCore 服务必须保持运行。

创建事件并选择运行权限​

本节由 standalone 实例所有者操作,使用连接与认证中的 X-Agent-Service-Token。Webhook 密钥只用于触发,不授予事件管理或回执读取权限。命令示例需要 curl 和 jq。

1. 查看事件与可选工具​

使用已有实例地址、所有者令牌和目标智能体 ID。智能体 ID 可从智能体列表取得。下面保存的管理响应只包含密钥是否存在,不包含密钥正文。

BASE_URL='https://your-instance.example'
AGENT_ID='your-agent-id'
AGENT_SERVICE_TOKEN='replace-with-your-existing-instance-token'
umask 077

curl --fail-with-body --silent --show-error \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
"${BASE_URL}/api/agents/${AGENT_ID}/webhooks" \
--output webhook-config.json

jq '{enabled,hasSecret,events,availableTools}' webhook-config.json
响应字段说明
enabled该智能体的 Webhook 入口是否启用。
hasSecret是否已配置密钥;读取不会再次返回密钥。
events已有事件的 event、promptTemplate、maxTurns 和 toolIds。
availableTools当前可选择工具的 id、name、riskLevel 与 requiresConfirmation。

选择事件实际需要的工具 ID。toolIds: [] 表示不允许使用工具。本例选择 SendUserMessage,用于把测试结果主动发送到用户对话;如果它不在 availableTools 中,请先调整目标智能体的工具配置,再重新读取。

只为事件完成工作所需的操作选择工具。本例只需 SendUserMessage;确实需要写文件或执行命令时,再添加 Write、Bash 等工具。这些工具可以修改有效文件范围内的配置文件,包括该范围中的智能体与事件配置。工具选择和文件范围沿用实例现有的权限机制,授予写入能力时需要同时考虑它能修改哪些配置。

2. 保存 demo.ping​

管理接口接受事件模板、所选工具 ID 和最多执行轮数;保存时由服务确定对应工具和当前文件范围。你不需要填写工具定义或权限对象。运行时仍受目标智能体的当前权限限制。

字段要求
事件名称(路径中的 :event)长度 1–128;首字符为英文字母或数字,其余可用英文字母、数字、.、_、-;不能为 constructor、prototype 或 __proto__。
promptTemplate必填非空字符串,最多 32,768 个字符;支持下文的 {{key}} 模板字段。
toolIds必填,来自 availableTools 的 ID 数组,不能重复;最多 512 项,空数组表示不授予工具权限。
maxTurns可选整数,范围 1–100,省略时为 5。

PUT 新建或替换同名事件,并启用该智能体的 Webhook 入口。替换会同时更新模板和工具选择;再次保存时会重新采集当前文件访问范围。请求体上限为 128 KiB。

如果保存返回 409 和 error: "webhook_configuration_changed",说明智能体配置在保存期间发生变化,本次事件修改未提交。重新 GET 读取事件和可选工具,确认模板、工具选择及当前文件权限后,再发起保存。

SEND_USER_MESSAGE_TOOL_ID="$(jq -er \
'[.availableTools[] | select(.name == "SendUserMessage")] | if length == 1 then .[0].id else error("SendUserMessage is not available") end' \
webhook-config.json)"

jq -n --arg tool "${SEND_USER_MESSAGE_TOOL_ID}" \
--arg prompt '收到消息:{{message}}。请使用 SendUserMessage 向用户发送这条收到的消息。' \
'{promptTemplate:$prompt,toolIds:[$tool],maxTurns:5}' \
> webhook-event.json

curl --fail-with-body --silent --show-error --request PUT \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
--header 'Content-Type: application/json' \
--data-binary @webhook-event.json \
"${BASE_URL}/api/agents/${AGENT_ID}/webhooks/events/demo.ping" \
--output webhook-write.json

保存成功返回 200:

{
"success": true,
"enabled": true,
"event": "demo.ping",
"secret": "<generated-webhook-secret>"
}

secret 仅在这次保存首次生成密钥时出现。立即通过发送方的密钥管理方式保存这个值;不要把包含密钥的响应文件放入公开仓库或日志。已有密钥时,响应只有 success、enabled 和 event。

如果已保存的密钥丢失,或首次生成密钥的响应丢失,请按轮换密钥取得新值。重新 GET 或再次保存事件不会取回旧密钥。

3. 触发并查看主动交付​

将生成或轮换得到的密钥设置为 WEBHOOK_SECRET,按下方发送一次请求触发 demo.ping,然后按查看处理结果确认主动消息已交付。智能体需要可用的模型配置,并且实际调用了获准的发送消息工具;保存和接收成功都不能代替这一步确认。

暂停、删除与密钥轮换​

以下管理操作均使用实例访问令牌。它们改变之后的触发配置,不会停止已经接收的后台执行。

操作请求成功响应
暂停全部事件PATCH /api/agents/:id/webhooks,JSON {"enabled":false}{"success":true,"enabled":false}
恢复已有事件同一路径,JSON {"enabled":true}{"success":true,"enabled":true};需要已有事件和密钥。
删除一个事件DELETE /api/agents/:id/webhooks/events/:event,无请求体{"success":true,"enabled":...};删除最后一个事件后自动暂停入口。

轮换密钥​

一个智能体的事件共用同一份 Webhook 密钥。轮换后旧密钥立即不能用于之后的触发,所有发送方都要更新;已有运行继续处理。

curl --fail-with-body --silent --show-error --request POST \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
"${BASE_URL}/api/agents/${AGENT_ID}/webhooks/secret/rotate" \
--output webhook-secret.json

此请求不发送正文,成功返回 200 {"secret":"<new-webhook-secret>"}。将新值保存到发送方的密钥管理配置。轮换响应丢失时,读取配置也不能取回密钥,需要再次轮换并同步全部发送方。

请求​

POST /api/webhook/:agent_id
Authorization: Bearer <Webhook secret>
Content-Type: application/json

Authorization 使用上面的 Bearer 前缀,后面紧接密钥。请求体上限为 1 MiB(1,048,576 字节);这是整个 JSON 请求的大小上限。

字段类型必填说明
eventstring是目标智能体中已配置的事件名称。
payloadobject否提供事件模板需要的字段;省略时按空对象处理。

顶层只接受 event 和 payload。payload 内可以包含事件约定的 JSON 字段,但它必须是对象,不能直接传数组或字符串。

{
"event": "demo.ping",
"payload": {
"message": "测试事件:请确认已收到。"
}
}

第三方系统的原始通知需要先转换成这个结构。例如,使用 GitHub 推送事件时,发送方需要映射事件名和负载,并添加这里要求的 Bearer 密钥;本接口不直接校验 GitHub 的签名头。

模板字段​

管理员配置的提示模板通过 {{key}} 读取 payload 中同名的顶层字段。例如,模板 收到消息:{{message}} 会从上面的请求得到 收到消息:测试事件:请确认已收到。。

  • 字符串、数字和布尔值转换为文本;对象和数组转换为 JSON 文本。
  • 字段缺失或值为 null 时,原占位符保留,例如 {{message}}。
  • {{user.name}} 这样的嵌套字段路径不支持。需要使用的值应由发送方放入约定的顶层字段。

发送方应按事件约定填写所需字段,避免将未替换的占位符交给智能体处理。

发送一次请求​

下面的示例使用上方创建的 demo.ping,或管理员已经配置的同名事件,并约定使用 payload.message。替换实例地址和智能体 ID,通过发送方的密钥管理方式设置 WEBHOOK_SECRET。如果实际事件名称或字段不同,同步修改 JSON 请求体。

BASE_URL='https://your-instance.example'
AGENT_ID='your-agent-id'

curl --include --request POST \
"${BASE_URL%/}/api/webhook/${AGENT_ID}" \
--header "Authorization: Bearer ${WEBHOOK_SECRET}" \
--header 'Content-Type: application/json' \
--data '{"event":"demo.ping","payload":{"message":"测试事件:请确认已收到。"}}'

正常接收时返回 200 OK:

{
"accepted": true,
"agentId": "your-agent-id",
"event": "demo.ping"
}

accepted: true 表示事件已接收,后台处理随后进行。它不代表模型已启动、工具调用成功或任务已经完成。响应没有 Run ID、请求 ID 或最终回答;后台失败也不会将这次已经返回的 200 改成错误响应。

查看处理结果​

调用前,让管理员明确这个事件预期如何交付结果。如果事件获准使用 SendUserMessage(向用户发送消息),并在运行中调用了它,已成功写入的消息或附件会出现在与该实例连接的 DesireCore 中,目标智能体的对话里。重新进入目标智能体的对话可以读取已有交付。

普通的模型最终回答不会自动变成这里的用户交付。没有看到消息可能是事件尚在处理、事件没有发送消息、权限或交付失败,不能单凭界面没有消息判断任务成败。已有交付也不代表该次运行的后续操作全部完成。

实例所有者也可以读取持久交付记录:

curl --fail-with-body --silent --show-error \
--header "X-Agent-Service-Token: ${AGENT_SERVICE_TOKEN}" \
"${BASE_URL}/api/agents/${AGENT_ID}/schedule-messages?limit=20&offset=0"

响应为 {"items":[...],"total":...,"limit":20,"offset":0}。Webhook 交付条目的 origin 为 webhook、displayName 为事件名,正文通常在 delivery.message;附件引用在 delivery.attachments。降级为纯文本的交付记录使用 text。只返回当前身份有权读取的条目。默认 limit 为 50,最大 200,offset 从 0 开始。

记录是该智能体的交付列表,并非按本次触发查询的终态。相同事件多次触发的记录可能混在一起,列表为空也不代表执行失败。需要区分业务事件时,可在约定负载和交付正文中携带发送方的业务编号;它不会使触发接口具备去重或唯一运行查询能力。

如果该事件未提供用户交付,本页调用方只能取得 accepted 接收反馈,执行情况需要管理员查看日志。本接口没有提供按本次请求查询完成状态或最终结果的方式。需要核实失败或超时时,请把目标智能体 ID、事件名称、发送时间和 HTTP 响应交给实例管理员,由管理员检查服务运行日志。不要在排查记录中包含密钥。

如果业务要求每次调用都取得唯一执行编号、可轮询的终态或结果回调,请先与管理员确认是否有适合该需求的接入方式。

重复调用与超时​

本接口没有幂等键或请求去重功能。相同请求发送两次,可能触发两次执行;在 payload 中放入业务事件 ID 也不会自动启用去重。

发送方超时或连接中断时,接收结果可能未知:服务有可能已经接收事件并开始执行。先保存发送时间、事件名称和可用的响应信息,再核实处理情况。对于会产生外部操作的事件,不应仅因没有收到响应就无条件重发。

后台处理有自己的执行超时控制,失败或超时可能发生在接收成功之后。延长发送方的 HTTP 等待时间不能让这个异步接口返回最终结果。

管理接口错误​

管理接口使用 error 中的稳定标识;字段校验失败可能还返回 details。

HTTP 状态error处理方法
400invalid_webhook_management_request核对必填字段、类型和限制;轮换请求不要发送正文。
400invalid_webhook_event使用符合事件命名规则的名称。
400webhook_tool_unavailable重新读取 availableTools,只选择仍可用的准确 ID。
400webhook_events_required恢复前先保存事件并确认已有密钥。
400invalid_agent_id核对目标智能体 ID。
401 / 403认证或治理拒绝,或 webhook_owner_required使用目标实例所有者的访问令牌;Webhook 密钥不能用于管理。
404agent_not_found / webhook_event_not_found核对目标智能体与待删除事件。
409webhook_configuration_changed本次保存未提交;重新读取配置和可选工具,确认权限后重试保存。
409webhook_configuration_invalid请实例管理员修复已有配置后再保存。
413保存请求体过大缩小整个事件保存请求到 128 KiB 以内。
500webhook_management_failed请管理员查看服务日志,核实修改是否生效后再处理。

触发接口错误​

优先检查 HTTP 状态和实际返回的 error。部分错误还带有 message 或 details;不要按固定的 success/data/error 包装解析所有响应。

HTTP 状态错误或现象调用方操作
400Invalid request body,可能带校验 details确认 JSON 顶层为对象、event 为字符串、payload 为对象,移除其他顶层字段。
400Unknown event type: ...核对管理员提供的事件名称、大小写和目标智能体。
400JSON 无法解析修正 JSON 语法后重新发送。
401Invalid webhook secret检查 Authorization: Bearer ... 和当前密钥,确认发送方已同步管理员的密钥轮换。
401Invalid embedded instance token该本机事件没有外部调用所需的密钥;请管理员提供已配置密钥的事件。
403webhook_secret_required远程实例上的目标智能体没有有效 Webhook 密钥;请管理员完成配置。
404Agent not found核对实例地址与目标智能体 ID。
404Webhook not enabled for this agent请管理员确认目标智能体的事件已启用。
413请求体过大缩小整个 JSON 请求到 1 MiB 以内,按事件约定减少负载。
415请求媒体类型不支持使用 Content-Type: application/json。
500Failed to parse agent.json请管理员检查目标智能体配置;反复重发不能修复配置。

反向代理和服务连接故障还可能返回其他错误,参见错误与排查。修复明确拒绝接收的请求后再发送;响应丢失的情况按上面的未知结果规则处理。