实测 Composio 升级后的写请求重试差异
作者用本地返回 503 的服务对比 Composio 两个版本:高层工具执行接口均只发送一次,而触发器创建和底层工具调用从三次降为一次。显式设置 maxRetries 仍可恢复重试,GET 查询也继续重试。
AI 深度解读
Composio 0.28.0 把 POST、PATCH 改成默认只发送一次,但如果你一直用 composio.tools.execute(),这次升级并没有改变工具调用的重试次数。作者用本地服务统计请求,发现真正受影响的是触发器创建和底层客户端。
这篇实测值得读的地方,是把更新日志里的笼统描述拆成了具体入口。对写 AI Agent 的程序员来说,关键既是确认升级会影响哪里,也是分清:请求报错后,到底能不能再发一次。
工具执行早就不重试了,这次改的是哪些入口
停止自动重试写请求,是为了避免重复副作用。服务端可能已经发完邮件、创建完 issue,只是响应在途中丢了。客户端看见失败后重发,就可能再执行一次。
但高层工具执行接口早已处理过这个问题:
0.14.0的更新日志就说明,tools.execute()和tools.proxyExecute使用配置了maxRetries: 0的客户端。0.23.0把相同策略用于session.execute()和 session proxy 调用。- 作者在
0.27.0构建产物中仍能找到相关辅助函数,注释指向重复副作用问题#3654。
因此,按作者的梳理,如果 Agent 通过这些高层接口、session 或 provider wrapper 执行工具,升级不会改变失败工具调用到达 API 的次数。
真正变化的入口有两个。triggers.create() 在 0.27.0 遇到 upsert 返回 503 时,会发送三次 POST;0.28.0 只发一次。通过 getClient() 获取的底层客户端,其 POST、PATCH 此前默认重试两次,现在也改成只发送一次,除非单次调用显式指定 maxRetries。
默认重试两次,加上首次请求,一共是三次尝试。
实测证明了请求次数,但没有覆盖所有失败
作者搭了一个 Node HTTP 服务:工具定义和触发器类型查询的 GET 返回模拟数据,每个 POST 都返回 503,然后统计收到的请求。
测试使用 baseURL: 'http://127.0.0.1:4010',并设置 COMPOSIO_ALLOW_INSECURE_HTTP=1。运行环境是 Node 22.23.4,对比的依赖组合为:
@composio/core 0.27.0,引入@composio/client 2.0.0-rc.19。@composio/core 0.28.0,引入@composio/client 2.0.1。
作者还让工具查询 GET 返回 503,两个版本都会请求三次才放弃。也就是说,写请求前的查询仍可能重试,不能把整段日志里的请求数量都算成工具执行次数。
下面这段代码展示底层客户端的默认行为,以及如何为单次调用恢复重试:
import { Composio } from '@composio/core';
const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const client = composio.getClient();
// 0.28:只发送一次。遇到 503 或响应丢失时,会返回错误。
await client.tools.execute('GITHUB_CREATE_AN_ISSUE', {
user_id: 'user_1',
arguments: { owner: 'acme', repo: 'app', title: 'Bug' },
});
// 仅为本次调用重新启用重试。只应对可安全重复的写操作这样做。
await client.tools.execute(
'GITHUB_CREATE_AN_ISSUE',
{ user_id: 'user_1', arguments: { owner: 'acme', repo: 'app', title: 'Bug' } },
{ maxRetries: 2 },
);
要盯住最后的 { maxRetries: 2 }:作者确认它会让模拟服务收到三次请求,但这不代表创建 issue 可以安全重复。
测试边界也很明确:作者没有调用真实 Composio API,没有模拟连接中断或超时。实测直接支持的是本地 503 场景下的请求次数,响应丢失场景不能算作已经验证。
用了 getClient(),升级还要检查什么
底层客户端的变化不止重试策略。request() 已被移除,需要改用 get、post、patch、put 或 delete。资源现在是普通对象,原来的资源类和 Composio.Tools 风格静态成员也已移除。
此外,@composio/client 带 .js、.mjs 的子路径导入不再解析。直接引用这些路径的代码,需要一起调整。
运行环境同样有门槛:@composio/core 0.28.0 的 engines 声明要求 "node": ">=22.22.3"。不能只确认开发机能安装,还要检查 CI 和实际运行 Agent 的 Node 版本。
我的判断
我赞成这次调整的方向:SDK 无法仅凭一次网络错误,就判断写操作没有发生。让调用方处理结果不确定的情况,比静默重复创建更容易控制。
但只发送一次,不等于服务端恰好执行一次。 出错后仍可能需要查询触发器或 issue,确认操作是否完成。作者建议使用自己的代码能检查的幂等键,也不能理解成所有工具都原生支持它;原文没有交代这部分实现。
和统一套一层重试循环相比,按操作判断是否可重复更稳妥。但作者没有给出生产环境中的重复写入率、成功率或延迟对照。这篇提供了明确的版本差异证据,尚不足以量化升级后的业务收益。
能拿来做什么
- 在 Node Agent 项目里先搜索
getClient()和triggers.create(),确认是否依赖旧版自动重试,再检查request()、静态资源成员和子路径导入。 - 给创建 issue、发送消息等写操作设计失败后的查询路径,确认上一次是否成功,再决定是否重发。
- 只有确认操作可安全重复时,才为单次调用设置
maxRetries;自行设计幂等键时,也要实现对应的查重机制。 - 升级前核对开发、CI、部署环境是否满足 Node
>=22.22.3,并用本地模拟服务检查自己实际使用的调用入口。