单项目深读

Composio:用统一接口让 agent 真正操作 GitHub 与 Slack

Composio 是 TypeScript 编写的 LLMOps 工具包,内置大量 toolkit、tool search 与认证管理,让 agent 通过统一接口连接 GitHu

|INS-0016

让 agent 调一个 GitHub API 不难。难的是:当它要代表 user_123 去读这个人的私有邮件、往这个人的 Slack 频道发消息、在属于这个人的 GitHub 仓库里开 issue 时,凭证从哪来、权限怎么隔离、几百个工具的 schema 怎么塞进上下文。

Composio 的答案是把这三件事从 agent 代码里剥出去,做成一层独立的运行时。

问题不在「调用」,在「会话」

大多数 agent 框架把工具当成静态数组:你在启动时定义一堆 function,模型选一个,你执行,返回结果。这套模型在 demo 里够用,接真实 SaaS 就崩了。

原因有三层。第一,工具数量。Composio 的 README 说的是 1000+ pre-authenticated toolkits,把它们全量塞进 prompt 是不可能的。第二,认证。GitHub 的 OAuth token 属于某个具体用户,不属于你的进程,而且会过期、会被撤销。第三,多用户。你的服务同时服务一万个用户,每个人的 Slack 工作区都不一样,工具列表不能是全局常量。

Composio 的核心抽象是 session,不是 tool。README 里那句注释写得很直白:

typescript
// Each session is scoped to one of your users const session = await composio.create("user_123");

一个 session 绑定一个终端用户。工具列表、认证状态、已连接的账号,全都挂在这个 session 上。这是整个库的设计支点 —— 后面所有架构选择都能从这里推出来。

架构:四层,一条从意图到副作用的链路

README 没有贴架构图,但从 monorepo 的目录结构、包清单和 quickstart 的调用链,可以还原出清晰的分层。

text
ts/ TypeScript SDK workspace packages/core/ @composio/core packages/providers/ Provider adapters packages/cli/ Composio CLI python/ Python SDK and provider packages docs/ Documentation site (docs.composio.dev)

按职责切,是四层:

第一层:SDK 核心(@composio/core / composio)

持有 API key,负责和 Composio 后端通信,管理 session 生命周期。composio.create(userId) 和 composio.use(sessionId) 是这一层的两个入口 —— 前者新建,后者复用。README 明确要求「Store session.session_id and reuse it with composio.use() across turns」,也就是说 session 是跨对话轮次持久的,不是一次性的。

第二层:Session 与工具发现

session.tools() 返回给 agent 用的工具集合。关键设计在 README 这段:

By default a session gets meta tools that discover, authenticate, and execute app tools at runtime, so you don't load hundreds of tool definitions into context.

默认给 agent 的不是 1000 个工具,而是元工具(meta tools):一个负责搜索有哪些工具可用,一个负责发起认证,一个负责执行。这是典型的「工具检索」模式 —— 模型先用自然语言描述意图,检索层返回少量候选,再执行。1000+ toolkit 的问题在这一层被消解掉。

第三层:Provider 适配层

这是整个仓库里最庞大的一块。Provider 的职责,README 定义得很清楚:「A provider adapts Composio tools to your agent framework's native tool format」。同一个 session,同一个 tools 对象,通过不同的 provider 包,变成 OpenAI Agents 的 tool、LangChain 的 tool、Vercel AI SDK 的 tool。agent 框架不需要知道 Composio 的存在。

第四层:执行与认证后端

真正拿着用户凭证去调 GitHub / Slack 的地方。这一层在 SDK 之外,由 Composio 托管。README 里「hosted MCP endpoint」和「sandbox」两个词都指向它 —— session 不仅产出工具定义,还提供一个可直接连接的远程执行端点。

数据流是这样的:

  1. 你的服务用 API key 初始化 Composio,指定 provider;
  2. composio.create("user_123") 向 Composio 后端申请一个绑定该用户的 session;
  3. session.tools() 拿到元工具(或按配置裁剪后的工具子集);
  4. 你把 tools 交给 agent 框架,框架按自己的格式运行;
  5. 模型决定调用 → 元工具执行 → 后端用该用户已连接的账号凭证真正调用 GitHub/Slack;
  6. 结果按 provider 约定回传给框架。

值得注意的是第 5 步:凭证从未进入你的进程。这是 session 抽象最重要的副产品。

能力边界:一张表看清它给了什么

README 开篇一句话列全了能力面:「1000+ pre-authenticated toolkits, per-user sessions, authentication, triggers, and a sandbox」。

能力载体说明
预认证 toolkit1000+ 应用集成开箱即用的工具集,无需自己写 API 封装
Per-user sessioncomposio.create(userId)工具、认证、连接账号都绑定到单个终端用户
认证管理session 内建 + composio linkOAuth 等连接流程由平台处理,凭证不进你的进程
工具检索默认 meta tools运行时发现/认证/执行,避免全量工具定义占上下文
TriggersREADME 首段列出事件触发能力
SandboxREADME 首段列出托管执行环境
托管 MCP 端点composio.create(..., { mcp: true })session.mcp.url 可直接给 Claude、Cursor 等 MCP 客户端
CLIcomposio 二进制在 shell 里搜索、执行、连接账号、脚本化 workflow
多语言TypeScript + Python两套 SDK,包名不同,API 形状对齐

这张表里最容易被低估的是「工具检索」。它不是一个便利功能,而是让 1000+ 这个数字在工程上成立的前提。如果每次对话都要把上千个工具 schema 序列化进 system prompt,token 成本和模型选择准确率都会失控。Composio 把这个负担挪到了运行时的检索调用上。

怎么跑起来:两种接入姿势

姿势一:SDK + Provider

TypeScript 侧,先装三个包:

bash
npm install @composio/core @composio/openai-agents @openai/agents

然后:

typescript
import { Composio } from "@composio/core"; import { OpenAIAgentsProvider } from "@composio/openai-agents"; import { Agent, run } from "@openai/agents"; const composio = new Composio({ provider: new OpenAIAgentsProvider() }); // Each session is scoped to one of your users const session = await composio.create("user_123"); const tools = await session.tools(); const agent = new Agent({ name: "Personal Assistant", instructions: "You are a helpful assistant. Use Composio tools to take action.", tools, }); const result = await run(agent, "Summarize my emails from today"); console.log(result.finalOutput);

Python 侧是同一套逻辑的镜像:

bash
pip install composio composio-openai-agents openai-agents
python
from composio import Composio from composio_openai_agents import OpenAIAgentsProvider from agents import Agent, Runner composio = Composio(provider=OpenAIAgentsProvider()) session = composio.create(user_id="user_123") tools = session.tools() agent = Agent( name="Personal Assistant", instructions="You are a helpful assistant. Use Composio tools to take action.", tools=tools, ) result = Runner.run_sync(starting_agent=agent, input="Summarize my emails from today") print(result.final_output)

两个片段里,agent 框架的代码和原生写法几乎一致 —— 唯一多出来的是 provider 参数和 session.tools()。这正是 provider 层的目的:侵入性最小。

有个细节值得单独说。README 对 @composio/core 的安装体积做了说明:

@composio/core intentionally packages its TypeScript source and SDK docs so the installed package is inspectable to coding agents. If you want a smaller install with the same API, use @composio/slim.

这是个有趣的取舍:默认包把 TS 源码和文档一起打进去,为的是让 Claude Code 这类编码 agent 能直接读源码理解 API。如果你的场景不需要,换 @composio/slim,API 一样,体积更小。这个设计本身说明了项目的目标用户 —— 大量是在用编码 agent 写 agent 的人。

姿势二:MCP,绕过 SDK

如果你的客户端是 Claude、Cursor 或任何 MCP 客户端,不需要写代码。给 composio.create() 传 mcp: true,然后指向 session.mcp.url 即可。README 的说法是:

Every session also exposes a hosted MCP endpoint.

这意味着 session 抽象不只服务于代码集成,也服务于「人直接在 AI 客户端里操作」的场景。同一个 session 概念,两种消费方式。

CLI:把工具面暴露到 shell

bash
curl -fsSL https://composio.dev/install | sh

装完后新开终端,composio login。四个子命令覆盖主要动作:composio search 找工具,composio execute 跑工具,composio link 连账号,composio run 用 TypeScript 脚本化 workflow。README 对 CLI 的定位说得很明确 —— 给 Claude Code 这类编码 agent 一个本地工具面。

Provider 矩阵:这才是真正的护城河

翻一遍 provider 表格,会发现一个规律:几乎所有主流 agent 框架都被覆盖了,而且 TypeScript 和 Python 两侧尽量对称。

ProviderTypeScriptPython
OpenAI@composio/openaicomposio-openai
OpenAI Agents@composio/openai-agentscomposio-openai-agents
Anthropic@composio/anthropiccomposio-anthropic
Claude Agent SDK@composio/claude-agent-sdkcomposio-claude-agent-sdk
Vercel AI SDK@composio/vercel—
Google GenAI@composio/googlecomposio-gemini / composio-google
Google ADK—composio-google-adk
LangChain@composio/langchaincomposio-langchain
LangGraph经 @composio/langchaincomposio-langgraph
LlamaIndex@composio/llamaindexcomposio-llamaindex
Mastra@composio/mastra—
Cloudflare Workers AI@composio/cloudflare—
CrewAI—composio-crewai
AutoGen—composio-autogen

不对称的地方是刻意的:Vercel AI SDK、Mastra、Cloudflare Workers 是 TS 生态的产物,CrewAI、AutoGen、Google ADK 是 Python 生态的产物。仓库没有为了对称而硬造包。

这张表也解释了为什么 Composio 的定位不是「又一个 agent 框架」。它不和你抢编排层,它把自己插在编排层和外部世界之间。你继续用 LangGraph 画图、用 CrewAI 组角色,工具那一层交给它。README 末尾还留了出口:「Don't see your framework? Build a custom provider, or skip providers entirely and connect over MCP.」

和同主题项目比,它站的位置不一样

LLMOps 这个标签下挤了一堆项目,但切面差别很大。拿素材里的几个对照项目放一起看,Composio 的位置就清楚了。

mlflow 和 opik 管的是「可观测与评估」:追踪每次 LLM 调用的输入输出,跑自动化评估,看 dashboard。它们回答的问题是「我的 agent 表现怎么样」。Composio 不碰这个。

promptfoo 管的是「回归测试与红队」:声明式配置测试用例,改 prompt 或换模型后跑对比,进 CI。它回答的是「这次改动有没有变差」。

llm-app 管的是「数据管道」:让索引和 Sharepoint、Google Drive、S3、Kafka 保持同步,解决 RAG 的实时数据接入。

llm-action 是中文工程化资料,不是可运行系统。

Composio 管的是「执行」。它回答的问题是:模型决定了要做什么之后,谁去真正做,用谁的权限做。

这个切面差异带来一个实际后果:Composio 和上面这些项目不是替代关系,是叠放关系。你可以用 promptfoo 测你的 agent,用 opik 追踪它的调用,用 Composio 让它真的能发 Slack 消息。素材里这些项目没有一个在做「per-user 认证 + 工具检索 + 多框架适配」这套组合。

如果一定要找最接近的对照,是 opik 和 mlflow 所在的「平台」生态 —— 它们都想做 agent 生命周期的中心。但 Composio 选择不做中心,做接口层。这个选择的代价是它必须持续维护 provider 矩阵和 1000+ 集成,好处是它不和任何框架竞争。

仓库事实与工程细节

几个可以直接核对的事实:

项值
源码github.com/ComposioHQ/composio
官网/文档docs.composio.dev
许可MIT
主语言TypeScript
Stars30615
Forks4860
Open Issues114
创建时间2024-02-23
最近推送2026-10-18
运行时要求TS SDK 测试于 Node 22+;Python SDK 支持 3.10+

topics 列表里同时出现了 mcp 和 remote-mcp-server,印证了 MCP 不是附加功能,是产品的一等公民。function-calling、llmops、agentic-ai 则标出了它所在的赛道。

本地开发用 mise 固定工具链:

bash
mise install # pinned toolchain (Node, Python, pnpm) pnpm install pnpm build pnpm test

Python 相关命令要在 python/ 目录下跑。

这个设计适合谁,不适合谁

从架构能反推出适用边界。

适合:你的产品要服务多个终端用户,每个用户要连自己的 SaaS 账号;你的 agent 需要接的工具超过十几个,全量塞上下文不现实;你在用某个主流框架,不想为了接工具换掉编排层。

不适合:你只需要接一两个固定的内部 API,自己写两个 function 更快;你的凭证管理有强合规要求,不能接受托管执行;你要的是评估和可观测,那应该去看 opik 或 mlflow。

还有一点值得留意。整个设计把「凭证」和「执行」都推到了 Composio 托管的后端。session 抽象带来的隔离性是真的,但代价是信任边界外移 —— 你的用户 OAuth token 存在对方那里。MIT 许可覆盖的是这个 monorepo 里的 SDK、CLI、provider 代码,不覆盖托管服务。读 README 时要分清这两件事:开源的是接入层,运行的是服务。

这也解释了为什么 @composio/core 要把源码打包进去 —— 在一个信任边界外移的架构里,让接入层完全可读,是一种必要的透明度补偿。