Composio × Google GenAI(Gemini)集成实战:从工具获取到函数调用的完整链路
Composio × Google GenAIGemini集成实战从工具获取到函数调用的完整链路【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio导读本文基于仓库中的 ts/examples/google 示例完整演示如何在 TypeScript 项目中用 Composio SDK 与 Google 的 GenAIGemini模型集成包括环境准备、依赖安装、工具获取以及把 Composio 工具包装为 Gemini 的 Function Declaration 并执行函数调用的完整链路。读完本文你将掌握GoogleProvider的底层工作原理工具 Schema 转换、参数归一化、工具执行并能独立搭建一个任务输入 → Gemini 决策 → Composio 执行工具 → 返回结果的可用 Agent 程序同时了解如何通过会话Session与 MCP 端点做进阶集成。示例概览Composio 如何与 Gemini 协同工作Composio 本身提供 1000 工具集成但 Gemini 这类模型并不知道这些工具的存在。示例的核心思路是**格式适配 回调执行**通过 Composio SDK 获取工具定义由GoogleProvider把工具定义转换成 Gemini 能识别的FunctionDeclaration函数声明格式把声明随提示词一起交给 Gemini模型在需要时返回functionCalls程序把函数调用转交composio.provider.executeToolCall实际执行并把结果回传给模型。整个示例位于 ts/examples/google/src/index.ts目录结构如下ts/examples/google/ ├── .env.example # 环境变量模板 ├── README.md # 官方示例说明 ├── package.json # 依赖与运行脚本 ├── tsconfig.json # TypeScript 配置 ├── CHANGELOG.md # 版本变更记录 └── src/ ├── index.ts # 主示例函数调用流程 └── experimental.mcp.ts # 进阶基于 Session MCP 的示例第一步安装依赖示例使用 pnpm 工作区管理依赖进入示例目录后执行pnpm install从 ts/examples/google/package.json 可以看到本示例的核心依赖依赖包作用composio/coreComposio SDK 核心提供Composio客户端composio/googleGoogle GenAI Provider负责工具格式适配与执行google/genaiGoogle 官方 GenAI SDK用于调用 Gemini 模型dotenv从.env文件加载环境变量示例脚本同样定义在 package.json 中start使用 Bun 直接运行src/index.tsdev则开启文件监听模式二者均在仓库根目录的 pnpm workspace 环境下可用。第二步配置环境变量复制环境变量模板并填入密钥cp .env.example .env根据 ts/examples/google/.env.example需要配置两个变量变量说明COMPOSIO_API_KEY在 Composio 控制台app.composio.dev创建用于身份认证与工具访问GEMINI_API_KEY在 Google AI Studioaistudio.google.com创建用于调用 Gemini 模型注意composio/google的 READMEts/packages/providers/google/README.md中提到的变量名为GOOGLE_API_KEY而本示例使用GEMINI_API_KEY——两者指向同一个密钥只是命名习惯不同。实际项目中请与你的代码读取方式保持一致。第三步运行示例# 运行示例 pnpm start # 开发模式文件变更自动重启 pnpm dev示例运行时控制台会依次输出初始化信息 → 获取到的工具数量 → 待执行任务 → Gemini 的响应 → 工具调用名称 → 最终执行结果。深入主流程Composio × Gemini 函数调用全解析ts/examples/google/src/index.ts 完整展示了上述链路下面拆解每一步。1. 初始化两个客户端const ai new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY, }); const composio new Composio({ apiKey: process.env.COMPOSIO_API_KEY, provider: new GoogleProvider(), });关键点在于Composio构造函数中传入的provider: new GoogleProvider()。GoogleProvider是 ts/packages/providers/google/src/index.ts 中定义的核心适配器它继承了BaseNonAgenticProvider负责把 Composio 工具翻译成 Gemini 的 Function Declaration以及执行 Gemini 返回的函数调用两个方向的工作。2. 获取 Composio 工具const tools await composio.tools.get(default, HACKERNEWS_GET_USER); console.log(✅ Found ${tools.length} tools);composio.tools.get按名称获取工具定义此处获取的是 Hacker News 的HACKERNEWS_GET_USER工具用于查询指定用户的信息。工具定义中包含了slug、description、inputParametersJSON Schema 格式的参数描述等字段这些正是后续转换 Function Declaration 所需的原始素材。3. 把工具声明交给 Geminiconst task Fetch the details of the user pg; const response await ai.models.generateContent({ model: gemini-2.0-flash-001, contents: task, config: { tools: [{ functionDeclarations: tools }], }, });tools数组被放进config.tools[0].functionDeclarations这正是 Google GenAI 函数调用Function Calling的标准用法。模型会基于声明判断完成该任务是否需要调用工具、调用哪个、参数传什么。4. 执行模型返回的函数调用if (response.functionCalls) { const functionCall { name: response.functionCalls[0].name || , args: response.functionCalls[0].args || {}, }; const result await composio.provider.executeToolCall(default, functionCall); console.log(JSON.parse(result).data); } else { console.log(response.text); }这是非 Agent 型Non-Agentic集成的典型形态模型只负责决策不负责执行。当response.functionCalls存在时程序取出函数名与参数交给composio.provider.executeToolCall(default, functionCall)执行返回的 JSON 字符串中.data字段即工具执行结果此处为 Hacker News 用户pg的详情。源码级剖析GoogleProvider 如何完成双向适配理解了主流程后再看 ts/packages/providers/google/src/index.ts 中GoogleProvider的三个关键方法就能彻底明白示例背后的原理。wrapToolComposio 工具 → Gemini Function DeclarationwrapTool(tool: Tool): GoogleTool { const inputParameters ensureObjectTypeOnProperties( deduplicateJsonSchemaRequiredArrays( dereferenceJsonSchema(tool.inputParameters ?? { type: object, properties: {} }, { onUnresolved: sentinel, }) ) ); return { name: tool.slug, description: tool.description || , parameters: { type: object, description: tool.description || , properties: inputParameters?.properties || {}, required: inputParameters?.required || [], } as unknown as Schema, }; }这里完成了一次关键的Schema 管道处理保证转换后的参数描述能被 Gemini 正确解析dereferenceJsonSchema把 JSON Schema 中的$ref引用解析为内联定义onUnresolved: sentinel表示无法解析时保留哨兵值避免报错中断deduplicateJsonSchemaRequiredArrays去重required数组中重复的字段名ensureObjectTypeOnProperties确保带properties的对象节点显式声明type: objectGemini 的 Schema 校验对此有严格要求。转换后工具的name取tool.slugparameters则直接映射为 Gemini 的Schema。对应测试见 ts/packages/providers/google/test/google.test.ts其中验证了工具被包装为 Function Declaration 格式以及无inputParameters的工具也能安全处理两种场景。executeToolCallGemini 函数调用 → Composio 工具执行async executeToolCall( userId: string, tool: GoogleGenAIFunctionCall, options?: ExecuteToolFnOptions, modifiers?: ExecuteToolModifiers ): Promisestring { const payload: ToolExecuteParams { // Models occasionally emit tool args as a JSON string rather than an object (issue #2406). arguments: normalizeToolArguments(tool.args, tool.name), connectedAccountId: options?.connectedAccountId, customAuthParams: options?.customAuthParams, customConnectionData: options?.customConnectionData, userId: userId, }; const result await this.executeTool(tool.name, payload, modifiers); return JSON.stringify(result); }executeToolCall的入参tool即 Gemini 返回的{ name, args }。值得注意的两点normalizeToolArguments(tool.args, tool.name)模型偶尔会把参数以 JSON字符串而非对象的形式返回源码注释中标注了 issue #2406该工具函数负责把字符串参数归一化为对象确保下游执行不会因类型不符而失败返回结果统一JSON.stringify为字符串方便回传给模型作为functionResponse也便于上层JSON.parse(result)使用。此外options支持connectedAccountId指定已连接账号、customAuthParams自定义认证参数、customConnectionData自定义连接数据这些是接入需鉴权工具如 Gmail、GitHub时的关键扩展点。_isAgentic false为什么需要手动循环GoogleProvider是非 Agent 型Providerts/packages/providers/google/test/google.test.ts 中明确断言provider._isAgentic为false。这意味着 Composio 不会替模型自动调度多轮工具调用模型返回函数调用 → 程序执行 → 结果回传 → 模型再决策的循环必须由你编写。这也是示例主流程只处理一次functionCalls的原因——它演示的是单次调用生产环境需要的是下面这种完整循环。实战升级完整的 Agentic Loop 写法ts/packages/providers/google/README.md 给出了生产可用的多轮循环模板它比示例更进一步先把工具绑定到会话再用while循环反复执行直到模型输出纯文本import { Composio } from composio/core; import { GoogleProvider } from composio/google; import { GoogleGenAI, type Part } from google/genai; const composio new Composio({ provider: new GoogleProvider(), }); const ai new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY! }); // 为你的用户创建会话绑定工具 const session await composio.create(user_123); const tools await session.tools(); const chat ai.chats.create({ model: gemini-3-pro-preview, config: { tools: [{ functionDeclarations: tools }], }, }); let response await chat.sendMessage({ message: Send an email to johnexample.com with the subject Hello and body Hello from Composio!, }); // Agentic loop不断执行工具调用直到模型以文本作答 while (response.functionCalls response.functionCalls.length 0) { const parts: Part[] []; for (const fc of response.functionCalls) { const result await composio.provider.executeToolCall(user_123, { name: fc.name || , args: (fc.args || {}) as Recordstring, unknown, }); parts.push({ functionResponse: { id: fc.id, name: fc.name, response: JSON.parse(result), }, }); } response await chat.sendMessage({ message: parts }); } console.log(response.text);与示例主流程相比这个版本有两个重要差异会话Session抽象composio.create(user_123)为指定用户创建会话并挂载工具executeToolCall的第一个参数即该用户 ID——这是多用户场景下隔离连接与权限的正确姿势多轮循环while循环支持一次任务需要连续调用多个工具例如查邮件 → 写摘要 → 发消息的情况functionResponse携带id与 Gemini 返回的函数调用一一对应保证多工具并发时结果不错位。进阶路径通过 Session MCP 端点集成如果不想手动做 Schema 转换ts/examples/google/src/experimental.mcp.ts 展示了一条更声明式的路径让 Composio 托管一个 MCPModel Context Protocol端点再通过标准 MCP 客户端把工具交给 Gemini。核心步骤// 1. 创建绑定 Gmail 工具包的会话暴露托管 MCP 端点 const session await composio.sessions.create(externalUserId, { toolkits: [gmail], manageConnections: false, // 关闭连接管理工具本示例用不到 mcp: true, }); // 2. 用 Streamable HTTP 传输连接 MCP 端点 const serverParams new StreamableHTTPClientTransport(new URL(session.mcp.url), { requestInit: { headers: session.mcp.headers }, // 端点凭据 }); const mcpClient new MCPClient({ name: composio-mcp-client, version: 1.0.0 }); await mcpClient.connect(serverParams); // 3. 用 google/genai 提供的 mcpToTool 把 MCP 工具转成 Gemini 工具 const tools [mcpToTool(mcpClient)]; // 4. 交给 Gemini 流式执行 const stream await gemini.models.generateContentStream({ model: gemini-2.5-flash, contents: Fetch the latest 2 emails and provide a detailed summary..., config: { tools }, });几个值得注意的实现细节sessions.create的mcp: true让会话返回session.mcp.url与session.mcp.headers前者是端点地址后者携带访问凭据缺一不可manageConnections: false会关闭自动注入的连接管理工具避免无关工具干扰模型MCP 客户端对象必须保持存活不能被 GC 回收直到从它上面取完工具该文件注释为experimental说明 Session MCP 属于演进中的能力接入时建议锁定所依赖的modelcontextprotocol/sdk版本。这种方式的好处是工具集的获取、鉴权、生命周期由 Composio 托管客户端代码只需关心连接 MCP → 转工具 → 调模型适合接入 Gmail 这类需要 OAuth 鉴权的重型工具包。自定义与继续探索按 ts/examples/google/README.md 的指引你可以基于此示例做三类改造更换工具把HACKERNEWS_GET_USER换成其他工具 slug或改用session.tools()/ 工具包toolkit方式批量挂载例如 Gmail、GitHub、Slack 等实现业务逻辑在main()中扩展多轮对话、结果格式化、持久化等逻辑增强健壮性为executeToolCall增加错误捕获与重试处理connectedAccountId、customAuthParams等鉴权参数。仓库中还提供了同源对比示例帮助你理解不同 Provider 的适配差异OpenAI 示例展示与 OpenAI 的集成方式LangChain 示例展示与 LangChain 框架的集成方式更多示例浏览完整的示例集合包括工具路由tool-router、触发器triggers、会话管理session-management等场景。如果你要深入源码建议按以下顺序阅读先看 示例主文件 理解使用形态再读 GoogleProvider 实现 掌握 Schema 管道与执行细节最后对照 Provider 测试 验证各行为的预期即可完整把握 Composio 与 Gemini 的集成全貌。【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考