ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

VoltAgent + Chat SDK 构建 Slack AI Agent:Webhook 托管、线程订阅与工具调用全链路实战

VoltAgent + Chat SDK 构建 Slack AI Agent:Webhook 托管、线程订阅与工具调用全链路实战 人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆【免费下载链接】voltagentAI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework项目地址https://gitcode.com/gh_mirrors/vo/voltagent点击查看免费下载本篇指南讲解如何在 VoltAgent 开源仓库的 with-chat-sdk 示例 中用 Chat SDK 承担 Slack webhook 接收、线程订阅与交互按钮等传输层工作用 VoltAgent 承担 AI 推理与工具调用并借助 Next.js 动态路由完成 webhook 托管。读完本文你可以完整搭建一个“被 后自动订阅线程、逐条回复消息、支持按钮动作”的 Slack 机器人并理解每个环节在源码中的实现位置。1. 整体架构与技术栈该方案由四个组件协同完成各自职责边界清晰组件职责对应依赖Chat SDKSlack webhook 处理、线程订阅、交互动作按钮分发chat^4.14.0Slack 适配器将 Chat SDK 事件桥接到 Slack APIchat-adapter/slack^4.14.0Redis 状态适配器线程订阅状态持久化chat-adapter/state-redis^4.14.0VoltAgentAgent 定义、模型推理、工具tool调用voltagent/core^2.9.2Next.js以 Route Handler 形式托管 webhooknext^16.0.7上述版本号来自示例的 package.json。另外还引入了zod工具参数校验、aiVercel AI SDK作为voltagent/core的底层依赖以及voltagent/cli提供volt tunnel本地隧道命令。从数据流看一次完整交互的链路是Slack 将app_mention等事件 POST 到/api/webhooks/slackNext.js 动态路由把请求交给 Chat SDK 的bot.webhooks.slack处理器onNewMention触发thread.subscribe()Chat SDK 把订阅关系写入 Redis用户在该线程内继续发消息Slack 的message.*事件再次进入同一 webhookonSubscribedMessage调用 VoltAgent 的generateText生成回复并thread.post回线程按钮点击由onAction处理器响应。2. 第一步从官方示例创建项目仓库提供了一键脚手架直接选用with-chat-sdk模板npm create voltagent-applatest -- --example with-chat-sdk cd with-chat-sdk pnpm install脚手架拉取的内容对应仓库中的 examples/with-chat-sdk 目录。示例README中列出的运行前提是 Node.js 20、pnpm、一个可安装应用的 Slack 工作区以及一个 Redis 实例详见 examples/with-chat-sdk/README.md。3. 第二步配置环境变量复制模板并填写四个变量cp .env.example .env.local模板文件 examples/with-chat-sdk/.env.example 中预置了这四项# OpenAI model provider for VoltAgent OPENAI_API_KEYyour_openai_api_key # Slack app credentials SLACK_BOT_TOKENxoxb-your-bot-token SLACK_SIGNING_SECRETyour-signing-secret # Redis used by Chat SDK state adapter REDIS_URLredis://localhost:6379逐项说明OPENAI_API_KEYVoltAgent 示例 Agent 使用openai/gpt-4o-mini作为模型该 key 是模型调用的前提SLACK_BOT_TOKENSlack App 的 Bot User OAuth Tokenxoxb-开头用于调用 Slack Web API 发消息、订阅线程SLACK_SIGNING_SECRET用于校验 Slack 发来的请求签名防止伪造 webhookREDIS_URLChat SDK 的chat-adapter/state-redis状态适配器连接地址默认redis://localhost:6379。一个关键细节缺少 Slack 凭据时webhook 路由会在运行时返回清晰的 500 错误响应而不是导致构建失败。这一点在下一节的源码分析中会看到具体实现。4. 第三步创建并配置 Slack App在 api.slack.com/apps 创建新应用后使用如下 manifest继承自 关联文档display_information: name: VoltAgent Chat SDK Bot description: Slack bot built with Chat SDK and VoltAgent features: bot_user: display_name: VoltAgentBot always_online: true oauth_config: scopes: bot: - app_mentions:read - channels:history - channels:read - chat:write - groups:history - groups:read - im:history - im:read - mpim:history - mpim:read - reactions:read - reactions:write - users:read settings: event_subscriptions: request_url: https://your-domain.com/api/webhooks/slack bot_events: - app_mention - message.channels - message.groups - message.im - message.mpim interactivity: is_enabled: true request_url: https://your-domain.com/api/webhooks/slack org_deploy_enabled: false socket_mode_enabled: false token_rotation_enabled: false各部分与示例代码的对应关系Bot scopesapp_mentions:read让机器人能感知被 的事件message.*相关的im:history、mpim:history等支撑 DM 和群组线程的消息读取chat:write用于回帖users:read支撑按钮回调中获取event.user.fullName见第 8 节bot_eventsapp_mention触发订阅动作message.channels / message.groups / message.im / message.mpim四类事件覆盖公共频道、私有频道、单聊、群聊中被订阅线程的后续消息两个 request_urlEvent Subscriptions 与 Interactivity 必须都指向同一个 webhook 地址https://your-domain.com/api/webhooks/slack因为示例用一个动态路由同时处理事件与交互动作socket_mode_enabled: false本方案走 HTTP webhook 而非 Socket Mode所以你的服务必须暴露公网可达的 HTTPS 地址。将应用安装到你的工作区后收集两个凭据填入第 3 节的环境变量Bot User OAuth Tokenxoxb-...→SLACK_BOT_TOKENSigning Secret →SLACK_SIGNING_SECRET。5. 第四步本地运行并用 Volt Tunnel 暴露 Webhook启动 Next.js 开发服务示例的dev脚本为next dev --turbopackpnpm dev再用voltagent/cli提供的隧道命令暴露本地 3000 端口pnpm volt tunnel 3000volt tunnel的实现位于 packages/cli/src/commands/tunnel.ts从源码结构看端口参数默认值为3141本示例显式传3000以匹配 Next.js 默认端口端口非法非数字或 ≤ 0时会打印错误并退出可选--prefix指定子域名前缀校验规则为 1–20 个字符、仅限小写字母、数字和连字符且不能是www、mail、admin、console、api-voltagent等保留前缀隧道服务域名为tunnel.voltagent.dev。拿到生成的 HTTPS 隧道地址后回到 Slack App 设置把两处 URL 同时更新为Event Subscriptions → Request URLInteractivity → Request URL两者都指向https://your-tunnel-url/api/webhooks/slack。6. 第五步测试机器人按以下顺序验证完整链路在频道中邀请机器人/invite VoltAgentBot在频道或线程中 机器人机器人调用thread.subscribe()订阅该线程并回复一张欢迎卡片卡片带 Say Hello 与 Show Info 两个按钮在该线程内继续发消息机器人通过 VoltAgent 生成的回复逐条响应点击按钮分别触发hello与info两个 action 处理器。如果第 2 步之后机器人没有任何反应优先排查socket_mode是否仍为关闭、两个 request URL 是否都填了隧道地址、.env.local四个变量是否齐全、Redis 是否已启动状态适配器连不上 Redis 会导致订阅状态无法持久化。7. 源码深读一VoltAgent Agent 与 getCurrentTime 工具Agent 定义在 examples/with-chat-sdk/lib/agent.ts全部核心逻辑只有 49 行import { Agent, createTool } from voltagent/core; import { z } from zod; const getCurrentTimeTool createTool({ name: getCurrentTime, description: Get the current date and time for a given IANA timezone., parameters: z.object({ timeZone: z .string() .default(UTC) .describe(IANA timezone. Example: Europe/Istanbul, America/New_York), }), execute: async ({ timeZone }) { const date new Date(); // Intl.DateTimeFormat 格式化失败时兜底回退 UTC ... }, }); export const slackAssistantAgent new Agent({ name: ChatSDKSlackAssistant, instructions: [ You are a helpful assistant inside Slack., Keep replies concise and practical., If the user asks for time in a city/timezone, call getCurrentTime., ].join(\n), model: openai/gpt-4o-mini, tools: [getCurrentTimeTool], });几个值得注意的实现细节createTool使用 zod schema 声明参数timeZone有默认值UTC并在describe中给出 IANA 时区示例——这些描述会进入模型的 function calling 上下文直接影响模型何时、以什么参数调用工具execute 的容错设计Intl.DateTimeFormat对非法时区会抛异常代码用try/catch兜底回退到 UTC 返回保证工具执行永不以异常中断 Agent 循环instructions 与工具的联动第三条指令明确告诉模型“用户问城市时间时调用 getCurrentTime”这是让工具真正被触发的关键提示。你可以在 Slack 里问 “What time is it in Tokyo?” 来验证工具调用路径。slackAssistantAgent是一个模块级单例导出lib/bot.ts直接 import 复用避免每次请求重建 Agent 实例。8. 源码深读二Chat SDK 机器人装配Chat SDK 的装配逻辑在 examples/with-chat-sdk/lib/bot.ts。先创建 Chat 实例const bot new Chat({ userName: voltagentbot, adapters: { slack: createSlackAdapter(), }, state: createRedisState(), });createSlackAdapter()来自chat-adapter/slackcreateRedisState()来自chat-adapter/state-redis——前者负责事件解析与 Slack API 调用后者负责把“哪些线程已被订阅”等状态写进 Redis这样多实例部署或重启后订阅关系不丢失。四个事件处理器分别对应测试步骤中的五种交互// 1) 被 时订阅线程 回复带按钮的欢迎卡片 bot.onNewMention(async (thread) { await thread.subscribe(); await thread.post( Card({ title: VoltAgent Chat SDK, children: [ CardText(I am now subscribed to this thread.), ... Actions([ Button({ id: hello, label: Say Hello, style: primary }), Button({ id: info, label: Show Info }), ]), ], }), ); }); // 2) 已订阅线程内的后续消息交给 VoltAgent 生成回复 bot.onSubscribedMessage(async (thread, message) { const incomingText message.text?.trim(); if (!incomingText) { await thread.post(I can only process text messages for now.); return; } const { text } await slackAssistantAgent.generateText( [ Respond to this Slack message as a concise and friendly teammate., Message: ${incomingText}, ].join(\n), ); await thread.post(text || I could not generate a response. Please try again.); }); // 3) 按钮动作 bot.onAction(hello, async (event) { await event.thread.post(Hello, ${event.user.fullName}!); }); bot.onAction(info, async (event) { await event.thread.post(You are chatting over ${event.thread.adapter.name}.); });onNewMention里的thread.subscribe()是整个方案的核心动作只有订阅后Slack 的message.*事件才会被 Chat SDK 路由到onSubscribedMessage实现“一次 建立会话、线程内持续对话”的交互模式onSubscribedMessage用generateText一次性拿到完整文本而非流式接口这符合 Slack 消息“一次贴出完整内容”的场景info按钮展示event.thread.adapter.name验证事件确实来自 slack 适配器——这也是 Chat SDK 多平台架构的体现同一套 handler 代码可平移到其他平台适配器。文件末尾的getBot()是一个懒加载单例let botInstance: Chat | null null; export function getBot() { if (!botInstance) { botInstance createBot(); } return botInstance; }这样 Chat 实例含 Slack 客户端、Redis 连接在整个 Node 进程生命周期内只创建一次跨请求复用。9. 源码深读三动态 Webhook 路由与 waitUntilWebhook 托管在 examples/with-chat-sdk/app/api/webhooks/[platform]/route.ts是一个 Next.js 动态路由export async function POST(request: Request, context: RouteParams) { let bot: ReturnTypetypeof getBot; try { bot getBot(); } catch (error) { console.error(Failed to initialize Chat SDK bot:, error); return new Response( Chat SDK bot is not configured. Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET., { status: 500 }, ); } const { platform } await context.params; const handler bot.webhooks[platform as keyof typeof bot.webhooks]; if (!handler) { return new Response(Unknown platform: ${platform}, { status: 404 }); } return handler(request, { waitUntil: (task) after(() task), }); }三个设计点值得拆解[platform]动态段/api/webhooks/slack中slack作为路径参数传入路由通过bot.webhooks[platform]取对应平台的 webhook 处理器。这意味着同一应用未来挂/api/webhooks/其他平台即可扩展多平台无需新写路由未知平台返回 404而不是静默吞掉getBot()放在 try/catch 中这正是文档所说“缺少 Slack 凭据时返回清晰的运行时错误而不是让构建失败”的实现——初始化抛错时直接返回 500 并附缺失变量的提示文案Slack 控制台也能看到这条消息waitUntil桥接到 Next.jsafterChat SDK 的处理器接口要求接收一个waitUntil(task)回调用于把“响应返回后仍需继续跑”的后台任务如异步回帖纳入请求生命周期。这里用next/server的after(() task)实现Route Handler 先快速返回响应给 SlackSlack 对 webhook 有超时要求回复消息等耗时操作在after中后台完成不会被 HTTP 响应提前截断。首页 examples/with-chat-sdk/app/page.tsx 只是一个静态说明页明确 webhook 端点位于/api/webhooks/slack对功能无影响。10. 项目结构总览与扩展方向examples/with-chat-sdk/ ├── app/ │ ├── api/webhooks/[platform]/route.ts # Chat SDK webhook 端点动态平台 │ ├── layout.tsx # 根布局 │ └── page.tsx # 首页说明页 ├── lib/ │ ├── agent.ts # VoltAgent Agent getCurrentTime 工具 │ └── bot.ts # Chat SDK 装配与事件处理器 ├── .env.example # 环境变量模板 ├── next.config.ts ├── package.json └── tsconfig.json在此骨架上自然的扩展方向均只需改动lib/下两个文件包括在agent.ts中替换模型或追加工具检索、日历等在bot.ts中修改欢迎卡片内容、增加更多onAction按钮把createRedisState()指向生产 Redis 实现多实例部署。由于订阅状态由 Redis 承载且 Agent 是单例示例在单实例与多实例部署下的行为差异主要体现在 webhook 并发处理上生产环境建议配合 Next.js 平台的路由托管能力自行评估。完整参考入口关联文档、示例 README 与 CLI tunnel 命令实现。赞分享人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆【免费下载链接】voltagentAI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework项目地址https://gitcode.com/gh_mirrors/vo/voltagent点击查看免费下载相关推荐VoltAgent 与 Chat SDKSlack集成实战构建具备线程订阅与工具调用的聊天机器人VoltAgent 与 Chat SDKSlack集成实战构建具备线程订阅与工具调用的聊天机器人 导读 本文基于 VoltAgent 仓库中的 with人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音amis 辅助类之 Floats 浮动样式float-left / float-right / float-none 使用与实现原理amis 辅助类之 Floats 浮动样式float left / float right / float none 使用与实现原理 浮动float是 C人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音VoltAgent Slack Actions 实战指南用 VoltOps 托管动作让 AI Agent 收发 Slack 消息VoltAgent Slack Actions 实战指南用 VoltOps 托管动作让 AI Agent 收发 Slack 消息 VoltOps 为 Volt人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音上一篇aws-shell Secrets Manager敏感信息管理的命令行工具下一篇Dagger空模块处理如何优雅地处理没有提供方法的Module创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表