首页
/ Composio 平台分页指南:端点级限制与 cursor 分页的完整实践

Composio 平台分页指南:端点级限制与 cursor 分页的完整实践

2026-09-10 17:54:23作者:宣聪麟

本指南以 Composio 平台的官方分页文档为核心,讲解其“分页上限随端点而定”的设计原则,并以 auth configs 列表接口(GET /api/v3/auth_configsGET /api/v3.1/auth_configs)为实例,深入说明如何通过 next_cursor 驱动的 cursor 分页完整遍历数据。读完本文,你将掌握 Composio 各资源列表的正确分页姿势、SDK 内置的分页工具用法,以及如何规避文档描述与实际部署行为不一致的坑。

核心原则:分页限制是端点特定的

Composio 平台不存在一个全局统一的 page-size 上限。资源列表、目录、Tool Router、日志、计费(billing)等不同类别的端点,可以各自定义不同的单页大小;而 toolkit 的 actions 还会额外继承 provider(第三方服务商)特定的分页规则。

因此,在接入任何列表接口之前,正确做法是:

  1. 先检查该端点的精确 schema(字段定义、是否携带 cursor / limit 参数);
  2. 再通过真实请求验证线上行为(实际返回多少条、next_cursor 何时为空);
  3. 最后才在代码里固化分页假设——不要凭经验假设“所有接口都是每页 100 条”或“所有接口都支持同样的 limit”。

这条原则在 SDK 源码中同样有体现:Composio 的 TypeScript SDK 在 ts/packages/core/src/utils/pagination.ts 中封装了统一的 getAllPages 工具,它内部固定以 limit: 100 发起请求(MAX_LIMIT_ALLOWED_BY_API = 100),并通过 next_cursor 不断翻页直到取完。也就是说:客户端默认请求 100 条,但服务端端点仍可能按自己的上限钳制返回数量——这正是“端点特定限制”在客户端与服务端两侧的完整表现。

auth configs 列表:每页最多 50 条

文档明确给出了当前(2026-07-16 时间戳标注的公开指南)实测限制:

  • GET /api/v3/auth_configs:每页最多返回 50 个 auth configs;
  • GET /api/v3.1/auth_configs:同样最多返回 50 个

(对应中文文档:docs/kb/source/platform/pagination/public.md,平台分页总览见 docs/api-overviews/auth-configs.mdx。)

必须完成的翻页循环

拿到每一页响应后,需要:

  1. 从响应中读取 next_cursor 字段;
  2. 将其作为下一次请求的 cursor 查询参数传入;
  3. 重复以上两步,直到 next_cursor 为空(null / undefined / 空字符串)为止。

伪代码形态如下:

cursor = null
loop:
    response = GET /api/v3/auth_configs?cursor=<cursor>
    process(response.items)
    if response.next_cursor is empty: break
    cursor = response.next_cursor

文档/运行时不一致:不要跳过 cursor 分页

部分由 schema 自动生成的接口描述文档,可能宣称 auth_configs 接口支持更大的单页限制(例如 100 甚至更多)。但已部署的端点仍会把每一页钳制到 50 条

文档给出的处理建议是:把这种“文档宣传值 > 运行时实际值”的偏差视为产品问题(product issue),在集成侧则把它当作一个明确信号——绝不能因为文档写着更大的 limit 就跳过 cursor 分页。正确姿势永远是:信任 next_cursor,逐页拉取,直到游标耗尽。

从源码理解 cursor 分页的完整链路

TypeScript SDK:getAllPages 的类型安全翻页工具

Composio 的 TypeScript SDK 在 ts/packages/core/src/utils/pagination.ts 提供了开箱即用的全量拉取工具 getAllPages

export async function getAllPages<TFn extends (
  params: PaginationParams
) => Promise<{ items: Array<unknown>; next_cursor?: string | null }>,
>(fetchFn: TFn): Promise<Array<ExtractItemType<Awaited<ReturnType<TFn>>>>> {
  const allItems = [];
  let cursor: string | null | undefined = undefined;
  const MAX_LIMIT_ALLOWED_BY_API = 100;

  while (true) {
    const params = {
      ...(cursor !== undefined && { cursor }),
      limit: MAX_LIMIT_ALLOWED_BY_API,
    };
    const response = await fetchFn(params);
    allItems.push(...response.items);
    if (!response.next_cursor) break;   // 游标为空即停止
    cursor = response.next_cursor;
  }
  return allItems;
}

它的关键行为(与单元测试一一对应):

  • 首次请求不携带 cursor,只带 limit: 100(测试 should not include cursor in first request);
  • 后续请求携带 cursor,值为上一页的 next_cursor(测试 should include cursor in subsequent requests);
  • next_cursornullundefined 均视为翻页结束should stop pagination when next_cursor is null 等用例);
  • 支持空 items 但仍有游标、游标含特殊字符、超长游标、多页合并后保持元素顺序等边界场景;
  • 请求抛错时异常会向上传播,由调用方处理重试与错误(should handle async fetch function errors)。

典型用法(来自该文件注释中的示例):

import { getAllPages } from './utils/pagination';

// 拉取全部工具列表,类型自动推断
const allTools = await getAllPages((params) =>
  client.tools.list({
    ...params,
    tool_slugs: 'tool1,tool2',
  })
);

值得注意:getAllPages 请求 limit: 100,但 auth_configs 端点实际返回 50 条——这一组合正好印证了文档反复强调的“端点限制优先于客户端请求值”,SDK 靠游标机制保证了无论服务端返回多少条都不会丢数据。

响应字段的蛇形/驼峰转换

auth configs 列表响应的原始字段是蛇形命名(snake_case),SDK 在 ts/packages/core/src/utils/transformers/authConfigs.ts 中将其转换为 SDK 风格:

export function transformAuthConfigListResponse(response) {
  return {
    items: response.items.map(transformAuthConfigRetrieveResponse),
    nextCursor: response.next_cursor ?? null,   // next_cursor -> nextCursor
    totalPages: response.total_pages,
  };
}

也就是说,直接调用 HTTP API 时你看到的是 next_cursor / total_pages;而通过 TypeScript SDK 的高层接口使用时,字段名会变成 nextCursor / totalPages。理解这一层转换,能避免在“读 SDK 文档”与“读 OpenAPI 文档”之间切换时产生困惑。

Python SDK:透传 cursor 查询参数

Python SDK 侧,auth configs 的列表操作定义在 python/composio/core/models/auth_configs.py

class AuthConfigs(Resource):
    def list(self, **query: te.Unpack[auth_config_list_params.AuthConfigListParams]):
        """Lists authentication configurations based on provided filter criteria."""
        return self._client.auth_configs.list(**query)

list()cursorlimit 等查询参数原样透传给底层 HTTP 客户端,因此分页循环在 Python 中同样遵循“把上一页 next_cursor 作为下一页 cursor”的通用模式:

from composio import Composio

client = Composio()
cursor = None
all_configs = []

while True:
    response = client.auth_configs.list(cursor=cursor, limit=50)
    all_configs.extend(response.items)
    if not response.next_cursor:
        break
    cursor = response.next_cursor

同样的 cursor 模式也贯穿其他资源:例如 Tool Router 的会话文件列表在 python/composio/core/models/tool_router_session_files.py 中接收 cursor 参数并返回 FileListResponse(含 itemsnext_cursor);Tool Router 会话列表在 python/composio/core/models/tool_router_session.py 中同样基于 next_cursor 做多页拼装。

实战检查清单

无论使用 REST 直连还是 SDK,接入任意 Composio 列表接口时建议按以下清单核对:

  1. 确认端点上限:查阅该端点的 schema 或实际发一次请求,记录真实单页条数(如 auth_configs 为 50);
  2. 携带游标翻页:每一页都读取 next_cursor(SDK 侧为 nextCursor),非空则作为 cursor 继续请求,直到游标为空;
  3. 不要硬编码信任文档数字:若文档声称的 limit 大于实际返回条数,以运行时行为为准,并把偏差反馈为产品问题;
  4. 边界场景自测:空列表、单页即止、恰好一页满、多页数据、游标特殊字符等情况,均可参考 ts/packages/core/test/utils/pagination.test.ts 中的用例设计自己的测试;
  5. 优先复用 SDK 工具:TypeScript 侧可直接使用 getAllPages 完成全量拉取,避免手写循环遗漏终止条件。

小结

Composio 的分页设计围绕“端点特定限制 + cursor 游标翻页”展开:没有全局 page-size,auth configs 列表实测每页 50 条,Tool Router、日志、计费等其他端点则各有各的规则。无论文档如何描述,正确的集成方式始终是信任 next_cursor 并完整翻页——这一点既有官方文档背书(docs/kb/source/platform/pagination/public.md),也有 SDK 源码与测试用例的完整实现佐证,是构建可靠、不丢数据的 Agent 集成的基础能力。

热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
396
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
527