Skip to content

用 HTTP 接口扩展 AI 能力 ​

给合从一个接口地址,AI 机器人就能在对话里调用它——查订单状态、查库存、查会员等级,拿到结果后用自己的话回答客户。

做出来是什么样 ​

客户问「我的订单到哪了」,机器人识别出这需要查订单,从对话里提取出订单号,调用你的接口,拿到物流状态后组织成一句话回答客户。

整个过程你要提供的就是一个接口。什么时候调、参数从哪来、结果怎么说给客户听,都由机器人自己判断,你不用写任何触发规则。

调用过程完整记录在每条机器人消息的 AI 推理过程 里,你配的工具会和内置工具一样出现在这个列表中,展开可以看到传入的参数和接口返回的原始内容:

工作台对话中展开的 AI 推理过程,按顺序列出思考与工具调用步骤及各自耗时

这是联调和排障的主要入口——接口没被调用、参数提取错了、返回被截断,都能在这里看出来。

开始之前 ​

下面三条不满足就跑不通,先确认:

  • 接口必须公网可访问。合从的服务器直接发起请求,内网地址、localhost、私有网段(10./172.16-31./192.168./127./169.254.)一律被拒绝,配置时就会报错。
  • 接口必须在 13 秒内返回,超时视为调用失败。
  • 响应内容要精简。序列化后超过 1000 字符会被截断,机器人看不到被截掉的内容。详见响应契约。

你还需要工作台的 AI 管理权限。

关于请求来源校验 ​

合从不会对请求签名,也不会在请求里携带任何可识别为合从的标识——没有专属 User-Agent(发出的是 axios/<版本号> 这样的默认值),没有 request id,没有时间戳或 nonce。

这意味着:你无法在接口侧验证「这个请求确实来自合从」。你能做的只有一件事——把配置里的认证凭据当作共享密钥来校验。

据此设计接口:

  • 接口只暴露必要的最小数据。这个凭据保存在工作台里,团队中任何拥有 AI 管理权限的人都能看到,泄露面比你自己系统里的密钥大得多。
  • 涉及个人信息、金额、可写操作的接口,不要直接开放给这里,先包一层只读且脱敏的专用接口。
  • 凭据没有自动轮换机制,需要更换时手动改工具配置。

没有出口 IP 白名单可用

合从服务端的出口 IP 不对外公布,也不保证固定,没法用 IP 白名单加固。安全评审有硬性来源校验要求时,按上面的最小暴露原则设计接口。

配置 ​

在左侧栏选择 AI Agent > 工具,选择 添加自定义工具 > HTTP API 工具。

创建 HTTP API 工具页面,左侧配置右侧测试面板

基本信息 ​

字段必填上限说明
显示名称✅200 字符工作台里的名字,团队内唯一
工具描述(给 AI 看)✅500 字符决定机器人什么时候调用它

工具描述是这一整页最关键的字段。 机器人靠它判断当前该不该用这个工具。写清楚「什么情况下用」,不要只写接口做什么。

  • ✅ 客户询问订单物流状态、发货进度、什么时候到货时调用。需要订单号。
  • ❌ 查询订单物流接口

工具的调用名由系统生成

你填的是显示名称,机器人实际看到的函数名是系统分配的 tool_ + 四位数字。这是刻意的——过长的标识符会让模型在复述时出错。

API 配置 ​

字段必填说明
请求方法✅GET / POST / PUT / PATCH / DELETE
请求地址✅2000 字符以内,支持 模板
认证方式✅见下表
自定义请求头❌最多 10 条,支持 模板

认证方式:

方式实际发出的请求头
无认证—
API KeyX-API-Key: <你填的凭据>
BearerAuthorization: Bearer <你填的凭据>

自定义请求头在认证之后应用,同名会覆盖认证生成的头。host、cookie、content-length、transfer-encoding 禁止自定义。

请求参数 ​

参数分两类,区别在于值从哪来:

类型值从哪来机器人看得见吗
AI 参数机器人从客户的聊天内容里提取看得见,会主动追问必填项
系统参数系统从当前对话自动填入客户信息看不见,不占用它的判断

每个参数的字段:

字段必填取值
name✅参数名,100 字符以内
type✅string / number / boolean / array
in✅body / query / path / header
required✅必填的 AI 参数,客户没提供时机器人会主动追问
description✅200 字符以内。AI 参数靠它决定填什么值

参数类型只有四种,不支持对象和嵌套

type 只能是 string、number、boolean、array,不支持 object、不支持嵌套结构、不支持枚举约束。

需要传结构化数据时,把它拆成多个平铺的参数,或者让接口接收 JSON 字符串再自行解析。

单个工具最多 10 个参数。

AI 参数的描述怎么写,直接决定提取准确率:

  • ✅ 11 位手机号码,不含区号和分隔符
  • ❌ 手机号

系统参数可用的值:

变量含义
customer_id客户在合从的 ID
customer_unique_id你通过接入代码传入的用户标识
customer_name客户名称
customer_tel客户电话
customer_email客户邮箱
customer_card.<字段名>客户名片的自定义字段

系统参数取不到值时整次调用失败

配了 customer_tel 但这位客户从未留过电话,这次工具调用会直接失败、请求根本不会发出,机器人拿不到任何结果。空字符串同样算作取不到。

只把真正必需的客户信息配成系统参数。 可有可无的信息,改成让接口自己处理缺失,或者配成 AI 参数由机器人按需提取。最稳的是 customer_id——它对任何客户都一定有值。

⚠️ 测试面板发现不了这个问题:测试时系统变量会被替换成 [test:变量名] 这样的占位值,永远不会为空。配了 customer_tel 的工具在测试面板里一切正常,上线后遇到没留电话的客户就全部失败。

参数怎么变成 HTTP 请求 ​

按每个参数的 in 分派:

in去向值的处理
path替换请求地址里的 :name 或 {name}转成字符串直接替换,不做 URL 编码
query拼到 URL 查询串转成字符串,自动 URL 编码
header作为请求头发送转成字符串
body进 JSON 请求体保留原始类型(数组仍是数组)

请求体是扁平的 JSON,没有包装层,固定带 Content-Type: application/json:

json
{ "order_no": "SO20260801001", "customer_id": "12345" }

没有 body 参数时不发送请求体。

几个容易踩的细节:

  • array 类型放在 query 或 header 时会被拼成逗号分隔的字符串(["a","b"] → a,b),只有放在 body 才保持数组结构。
  • path 参数不做 URL 编码。值里如果可能出现 /、?、#,改用 query 传,否则会破坏地址结构。
  • GET 请求配了 body 参数,请求体照样会发出去。多数服务端框架会忽略 GET 的请求体,需要读取时改用 query。
  • path 参数的 {name} 和下面的 模板是两套语法,先替换 path 参数、再替换变量模板,两者不会互相干扰。

模板 ​

请求地址和自定义请求头里可以直接写 ,运行时替换为上表中的系统变量值:

https://api.example.com/members/{{customer_unique_id}}/orders

URL 中的值会自动做 URL 编码。

图片自动发送(可选) ​

接口返回里带图片链接时,填写链接所在的字段路径,系统会自动下载并作为独立消息发给客户:

data.image.url        单个字段
items[].image_url     数组中每一项
items[0].url          数组指定下标

单次响应最多发 3 张图,单张下载上限 5 MB。

响应契约 ​

没有强制的返回结构,返回什么都行,机器人会自己理解。但有几条硬规则:

情况结果
HTTP 2xx视为成功
HTTP 401 / 403失败,机器人收到「认证被拒绝」
HTTP 5xx失败,机器人收到「目标服务出错」
其他非 2xx失败,机器人收到 HTTP <状态码>
响应体超过 1 MB整次调用失败(不是截断)
序列化后超过 1000 字符截断

响应体是 JSON 对象则直接使用;是字符串会尝试解析 JSON,解析不了就包成 { "result": "<原文>" }。

非 2xx 时响应体仍会一并交给机器人,所以业务错误可以在 body 里说明原因。但机器人同时会收到「失败」的信号,措辞上会偏向告知客户出了问题。

1000 字符的精确口径 ​

  • 算的是 JSON.stringify(响应体) 之后的字符串长度,不是字节数。一个中文字算 1,{、"、, 这些结构符号也各算 1。
  • 截断方式是从第 1000 个字符处直接切断,不做结构化裁剪——切完的内容大概率不是合法 JSON。
  • 被截断时,机器人收到的是 { "result": "<前 1000 个字符>", "truncated": true }。它知道数据不完整,但看不到被切掉的部分。

1000 字符很容易撞到

一个带十几个字段的订单对象,或者三条以上的物流轨迹,序列化后很容易过千。

对接时务必让接口只返回机器人需要的字段:去掉内部 ID、时间戳、冗余嵌套。列表类结果限制条数,一次返回 3–5 条足够。

建议的返回形状 ​

json
{
  "status": "已发货",
  "carrier": "示例物流",
  "tracking_no": "SF1234567890",
  "estimated_arrival": "2026-08-03"
}

字段名用英文、语义自解释,机器人组织回复时会更准。

「业务上没查到」建议返回 200 加业务字段,而不是 404:

json
{ "found": false, "reason": "订单号不存在,请客户核对后重新提供" }

返回 404 时机器人首先收到的是「失败」,容易直接告诉客户系统出了问题;返回 200 则它能读懂原因,转而引导客户核对订单号。

失败时会发生什么 ​

情况行为
超时(13 秒)机器人收到超时信息
连不上目标服务机器人收到「无法连接目标服务」
参数无法解析 / 超过 10 KB不发起请求,直接返回错误
系统参数取不到值不发起请求,整次调用失败

合从不做重试,也不做熔断。 失败信息原样交给机器人,由它决定是换个方式回答还是转人工。

你的服务故障时会被持续调用

同一个工具连续失败 3 次后,机器人只是被告知了这个情况,工具不会被停用、不会退避、也不会限流。你的接口挂掉期间,机器人仍会按客户提问的频率继续调用,且每次都可能占用 13 秒。

在你自己的网关侧做熔断和限流。 注意限流返回 429 会被当成普通失败(见上表「其他非 2xx」),机器人不会退避重试。

另外,自定义工具调用失败时,对话里会给客服发一条只有内部可见的系统提示,方便及时发现问题。

并发 ​

合从侧没有针对自定义工具的并发或 QPS 限制。同一时间有多少客户在咨询,就可能有多少个请求打到你的接口。按机器人的实际接待量做容量评估。

同一次推理内机器人可能多次调用同一个工具(例如客户先后给了两个订单号)。接口应当是幂等的,至少不能因为重复查询产生副作用。

联调 ​

配置页右侧有 测试工具 面板:填入参数的测试值,选择 发送,可以直接看到真实的请求结果,不需要先绑定到机器人。

本地接口没法直接联调

合从的服务器要能访问到你的接口,本地 localhost 地址一定被拒。开发阶段用内网穿透工具(如 ngrok、frp)暴露一个临时公网地址,或者先部署到测试环境。

测试面板通过,不代表线上跑得通。 它和真实调用有两处关键差异,上线前要单独验证:

测试面板真实对话
系统参数的值替换成 [test:变量名] 占位值,永不为空从当前客户取,取不到就整次失败
AI 参数的值你手填机器人从对话里提取,可能提取错或提取不到

尤其是第二点:机器人可能把客户随口说的「上周那单」拼成一个不存在的订单号。接口要自己校验参数格式,并在返回里说清楚问题,而不是直接 500。

测试通过后,到机器人详情页的 工具 卡片上选择 管理,绑定这个工具。绑定后用测试对话完整走一遍——那是最接近线上的验证方式。

参考 ​

限制 ​

项值
每个团队的自定义工具总数20
单个机器人可绑定的自定义工具10
单个工具的参数数量10
单个工具的自定义请求头10
请求超时13 秒
参数总大小10 KB
响应体上限1 MB
传给机器人的结果上限1000 字符
图片自动发送每次响应最多 3 张,单张 5 MB

地址限制 ​

只接受 http / https。域名解析后落在以下网段的一律拒绝:

10.0.0.0/8        172.16.0.0/12     192.168.0.0/16
127.0.0.0/8       169.254.0.0/16    0.0.0.0/8
100.64.0.0/10     198.18.0.0/15     240.0.0.0/4

不支持直接填写 IPv6 地址。变量替换之后会再校验一次,所以用 拼出来的地址同样受此限制。

下一步 ​