关于 setup-slack-channel
setup-slack-channel 是将本地 CopilotKit Channels Agent 接入托管 Slack Channel 的设置技能,面向开发者。它说明 Slack 到 Intelligence、再到本地运行时的两段投递方式,并要求验证安装、在线状态和真实回复。
主要功能
- 01说明 Slack 与本地运行时的双段连接
- 02指导配置 Slack 应用和托管 Channel
- 03核对本地运行时及 Agent 配置
- 04以真实提及回复验证完成状态
- 05区分托管适配器不支持的事件
适用场景
- 01从代码检出配置本地 Slack Agent
- 02验证托管 Channel 能响应 Slack 提及
- 03排查应用已安装但没有回复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ copilotkit/ copilotkit --skill setup-slack-channel安装后在 Claude Code 中输入/setup-slack-channel确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/slack-app-manifest.yamlreferences/intelligence-channel.mdlocal-runtime.mdoptional-e2e.mdsecrets-and-credentials.mdslack-workspace-and-app.mdtroubleshooting.md详细介绍
为本地 Channels Agent 设置 Slack 频道
带一位开发者从代码检出到运行一个可用的本地 Slack Agent。五个相互独立的系统必须协同工作,而它们分属四个不同的责任方:
| 系统 | 归属方 | 操作位置 |
|---|---|---|
| Slack 工作区 | 工作区所有者 / 应用管理员 | Slack,在浏览器中 |
| Slack 应用及其令牌 | 开发者 | api.slack.com,在浏览器中 |
| Intelligence 项目、API 密钥、Channel、Slack 适配器 | 开发者 | Intelligence 控制台,在浏览器中 |
| 本地 Channels 运行时 | 开发者 | 本仓库,在命令行中 |
| AG-UI Agent 后端 | 开发者 | 本仓库,在命令行中 |
交付实际是如何运作的 —— 两条链路,两种机制
在这里搞错这一点是代价最昂贵的错误,因为配置错误的 Slack 应用可以干净地安装成功,却什么都回不了。
| 链路 | 机制 | 由什么进行认证 |
|---|---|---|
| Slack → Intelligence | Slack 通过 HTTPS 将事件 POST 到由 Intelligence 托管的 Request URL:https://intelligence.copilotkit.ai/api/channels/adapters/slack/events | 应用的 signing secret,由 Intelligence 持有 |
| Intelligence → 你的运行时 | 你的运行时通过 websocket 向外拨号连接实时网关 | CPK_INTELLIGENCE_API_KEY |
由此产生两个后果:
- 不需要隧道,也不需要你自己的公共 URL —— 但并不是因为 Socket Mode。而是因为 Intelligence 拥有公共 URL,并且因为第二条链路是从你的机器向外发起的。
- Socket Mode 处于关闭状态,而且此工作流中完全没有
xapp-应用级令牌。 托管的 Slack 应用需要socket_mode_enabled: false和一个request_url。如果你在启用 Socket Mode 且没有 Request URL 的情况下创建应用,任何事件都永远无法到达 Intelligence。
因此,Intelligence 中的 Slack 适配器表单只要求两个值:bot token(xoxb-)和 signing secret。没有别的了。
此工作流的绝大部分发生在浏览器中,而不是 shell 中。v1 受支持的路径是 Intelligence 浏览器体验。 copilotkit channels 确实列出了用于创建 Channel、附加适配器和签发密钥的命令 —— 在这里不要使用它们;它们尚未为此工作流做好加固。绝不要为了填补空白而编造命令名,如果你不确定某个命令是否覆盖某项功能,请查看它的 --help,而不是猜测。
由你自己来驱动那个浏览器。这是这里的默认做法,而不是额外福利。 在 Phase 0 之前先确认你实际拥有什么,并说明是哪一种 —— 绝不要想当然地假定任何一种情况。
如果你没有浏览器或计算机使用工具,请在开始之前让开发者安装一个。 弄清楚你正在哪个 harness 中运行,并说出适用的那一条路径,而不是把它们全部背一遍:Claude Code 和 Codex 各自自带浏览器支持,并且启用方式各不相同,而大多数其他 harness 则采用通用的浏览器使用 MCP 服务,例如 Playwright MCP。如果你不确定你的 harness 支持什么,请在猜测之前先查清楚。 告诉他们这能带来什么 —— 驱动浏览器能把这件事变成输入三个密钥,而退路则大约需要十五个手动浏览器步骤。只有当开发者拒绝时,才一步一步地带他们完成那些步骤,每次一个操作。
完成意味着三件事,且全部经过验证
在这三件事全部成立之前,不要报告成功。任何单独一项成立都是误报。
- Slack 应用已安装在工作区中,且机器人是你将要测试的频道的成员。
- 托管 Channel 报告
online—— 来自进程中的controls.status(),或仪表板中的 Online。不是"运行时启动了"。 - 真实的人类提及在 Slack 中得到了真实的回复。
第 2 道关卡是 Agent 失败的地方。await controls.ready() 在
setup_required 状态下也会 resolve —— 该状态被记录为"一种有效的降级状态,而非
失败"。一个完全没有 Slack 连接的运行时可以正常启动,打印其监听行,在 /api/copilotkit/info 上返回 HTTP 200,却什么都回答不了。/api/copilotkit/info 报告的是许可证和运行时信息,而非 channel 状态,所以那里的 200 并不能证明任何与 Slack 相关的事情。
此处断言的 SDK 行为已针对当前发布的
@copilotkit/[email protected] 和 @copilotkit/[email protected] 进行验证。starter 可能固定了更旧或更新的版本,而这个 API 变化很快。如果此处的说法与你观察到的不符,相信已安装的包并重新阅读它 —— 不要与运行时争辩。
范围 —— 规划前请阅读
范围内: 生产环境 CopilotKit Intelligence;一个托管 Channel;一个从 manifest 创建的专用 Slack 应用;一个本地运行时和 Agent。
v1 中范围外。这些是硬性限制,不是可供权衡的默认值:
- 不要切换到直接的 Slack 适配器(
adapters: [slack({ botToken, appToken })])。不作为回退方案,不为节省时间,也不因为仪表板 令人困惑。请参阅下面的禁止事项 —— 这是此工作流出错的最常见方式。 - 不要重用、重新安装或修改一个已经安装并在使用中的 Slack 应用。 创建一个专用的。
- 不要部署任何东西(Railway 或其他)。
- 不要以内部或开发 Intelligence 环境为目标。
- 不要枚举 Slack 工作区、搜索频道,或请求 manifest 之外的作用域。
阶段 0 — 确定路线与约定
首先,检查阶段 1–2 是否已为你完成。 有些组织会在生产 bot 之外运行一个专用的 dev bot,并为开发者提供一个现成的环境文件 — Slack 应用、Channel 和适配器都已存在,dev bot 仅在有人在本地运行它时才上线。
问:这里是否已有现成的 dev bot 和提供的配置,还是我要从零开始搭建一个?
如果已提供配置,完全跳过阶段 1 和 2:将提供的值填入 .env(开发者会从团队的密钥共享 channel 中获取它们 — 绝不要让开发者把内容粘贴到这里),安装并运行。不要创建新的 Slack 应用,也不要创建 Channel。阶段 3–5 仍然适用,三个成功门槛保持不变。
否则,按以下顺序选择起始模板:
-
一个 OpenTag 检出 — 开发者的 cwd 就是其中之一,或者他们指定了其中一个。这是最可能的路径。检测方法:根目录下同时存在
slack-app-manifest.yaml和app/channel.tsx。 -
本仓库中的
examples/OpenTag,如果存在的话。它是一个子模块,因此直接克隆会使其为空:git submodule update --init examples/OpenTag -
两者都没有 → 让开发者克隆它,并以此为基础进行开发:
git clone https://github.com/CopilotKit/OpenTag.git
无论你最终采用哪一个,都应将那个检出视为唯一事实来源。不要在检出之间沿用事实 — 版本、环境变量名和已注册的 handler 在不同 OpenTag 修订版之间各不相同,这就是为什么下一步要读取它们,而不是凭空假设。
然后读取应用自身的环境约定,而不是假设变量名。它们在不同应用之间各不相同,_同一_概念所用的词汇也各不相同:OpenTag 使用 INTELLIGENCE_CHANNEL_NAME,Channels SDK README 的快速开始称其为 CHANNEL_CODE,它也被称为 Channel 的 slug。它们都指传给 createChannel() 的 name,该值必须与仪表盘中的 Channel 逐字符一致。读取应用的解析器;不要猜测这个代码库使用的是哪个词。
cat .env.example
grep -rn "process.env" app/env.ts server.ts 2>/dev/null
grep -n "onMention\|onMessage\|onCommand\|createChannel(" app/channel.tsx
记录,并向开发者复述:确切的环境变量名、代码将声明的 Channel 名称,以及已注册的 handler。
了解托管适配器不提供什么。 生成的 manifest 不声明任何 slash_commands,因此斜杠命令永远不会到达。它确实启用了 interactivity,并且托管入口会处理 block_actions — 因此 HITL 按钮和选择器确实会触发。它不处理的是 view_submission,因此模态框不会触发。按出厂状态,托管的 Slack Channel 会接收提及、消息、表情回应和交互组件点击 — 而不是斜杠命令,也不是模态框提交。一个注册了 onCommand 或 onModalSubmit 的应用会编译、启动、报告 online,但在托管路径上永远不会触发这些 handler。OpenTag 注册了 onModalSubmit 并随附四个命令;这些在这里都不起作用,尽管它的按钮可以。要一开始就说明这一点,而不是让开发者去调试它,并且不要为了填补这一空白而凭空编造命令的 Request URL。
最后这一点甚至决定了“可用”是什么样子。回合路由并不是对称的:一个被提及的回合会进入 onMention(如果已注册),否则回退到 onMessage,而一个未被提及的回合只会进入 onMessage。因此,一个只注册了 onMention 的应用 — 这正是 OpenTag 的做法 — 会响应 channel 提及,并且对于 Intelligence 未标记为提及的任何回合可能会静默不执行任何操作。先用 channel 提及进行验证;这是每个起始模板都会注册的路径。详情见 references/troubleshooting.md。
在你打开浏览器之前,先与开发者确定这些事项
操控并不等于决策。 这些决定权属于开发者,现在问代价很低,之后再改代价高昂。请在一次交流中问清楚,然后继续推进,不要再回头确认。
- 机器人的显示名称。 向导会根据它推导出 Channel Code,这个 Code 就是
createChannel({ name })所声明的,也是他们输入/invite @<code>时所用的。Slack 机器人名称是工作区范围内的,因此一旦冲突就会阻碍安装。可以建议一个,但不要自己拍板 —— 这是机器人在他们工作区中的身份。 - 应用要安装到哪个 Slack 工作区。绝不要假定是他们浏览器会话恰好登录的那个。
- 在哪个频道中测试。 第 3 关是一次真实的提及获得真实的回复,因此这个频道必须既能让他们发帖,又能接受机器人的回复。
- 这是一次性的,还是他们会长期保留的东西,如果他们还没有说明的话。这决定了使用沙盒工作区是否可行。
在第 1 阶段之前,把答案复述回去。如果他们推迟了某一项,请说明你将采用什么默认值,而不是悄悄自行选择。
然后获取一次授权
说明这次授权覆盖的整个流程:生产环境 Intelligence、由向导生成的 manifest 构建的专用 Slack 应用、安装到他们指定的工作区、创建 Channel、附加 Slack 适配器,以及签发项目范围的 API key。
一次同意即可覆盖全部。不要按页面、按目标或按点击反复询问 —— 一个在每个控件前都停下的运行,比它所取代的手动路径还要慢,而正是这个原因让操控成为默认方式。在此之后,只在以下情况下停下:开发者自己输入的密钥、他们推迟的上述某项决定,或这次授权未覆盖的事项。
这两个部分是不同的事情,而且都必不可少。决定是你无法凭空想出的输入;授权是你只需一次即可的许可。省略后者并不意味着可以跳过前者。
第 1 阶段 —— 工作区,并启动 Channel 向导以获取 manifest
Channel 优先,因为 Channel 生成 Slack 应用的 manifest。 不要手写一个,也不要使用 starter 中的 slack-app-manifest.yaml —— 参见下面的禁止事项。
- 使用开发者在第 0 阶段指定的工作区。如果他们没有可用的 → 创建一个免费工作区,或一个 Slack Developer Program 沙盒。切勿在未经批准的机器人会造成干扰的工作区中进行测试。
- 在 Intelligence 仪表盘中,启动 Create a channel。输入开发者在第 0 阶段选择的显示名称 —— 不要替换成你自己的。向导会根据它推导出 Code —— 小写 kebab-case,而这个 Code 正是
createChannel({ name })必须声明的。选择 Slack。 - 前进到 Setup。该步骤包含一个已生成并已指向正确 Request URL 的 manifest("Copy manifest" / "View manifest YAML"),以及你将在第 3 阶段填写的两个凭证字段。在你完成之前不会有任何内容被保存,因此请保持此标签页打开。
在安装任何东西之前,请阅读向导自身的警告:Slack 机器人名称和斜杠命令是工作区范围内的。如果生成的任一名称已被使用,请在安装前选择一个更具针对性的 Channel 显示名称。 此处发生冲突会阻碍安装,因此请通过重命名 Channel 来解决,而不是重命名 manifest。
完整细节见 references/intelligence-channel.md。
阶段 2 — 根据该 manifest 创建并安装 Slack 应用
完整细节见 references/slack-workspace-and-app.md。大致流程如下:
- 根据向导生成的 manifest 创建一个新应用。修改显示名称,让它明显是一个 dev 应用。
- 安装它。安装是受门控的步骤 — 默认情况下只有工作区所有者(Workspace Owner)可以审核应用请求,他们也可以指派应用管理员来执行此操作。创建应用通常不受门控,因此应在任何安装请求待处理时先创建它,而不是等待。
- 收集两个值:
xoxb-bot token(OAuth & Permissions)和 signing secret(Basic Information → App Credentials)。它们要放入 Intelligence — 绝不要放入此仓库。此工作流中没有xapp-token。 - 将机器人邀请到开发者在阶段 0 指定的频道:
/invite @<code>。这一步由开发者执行 — 你无法代替他们邀请机器人,CLI 也无法验证该邀请。
阶段 3 — 完成 Channel:适配器凭据和 API key
回到打开的向导标签页。在开发者自己的会话中进行浏览器操作。四项内容必须一致:Channel Code 与代码声明的内容匹配,Slack 适配器报告已连接,Channel 和 API key 位于同一项目中,端点保持其生产默认值。
开发者自己将 bot token 和 signing secret 输入到 Setup 步骤中,然后 Review → create。接着签发一个项目范围的 API key,并让他们将其粘贴到 .env 中。
这些是在实时仪表板中具有重要影响的变更,因此行动前先阅读页面,绝不点击你未读过的控件。 但阅读并不是中途确认的理由:阶段 0 的授权已经覆盖了这一序列,因此直接完成它并报告你所更改的内容,而不是在每个控件前都询问。
阶段 4 — 配置并启动运行时
完整细节见 references/local-runtime.md。
开发者自己将 CPK_INTELLIGENCE_API_KEY 放入 .env。通过是否存在来验证,绝不要通过打印来验证。然后启动 Agent 后端,再启动运行时 — 并在启动时将日志级别调高,因为运行时的 logger 默认使用 error,而每条 Channel 生命周期面包屑都以 warn 级别发出:
LOG_LEVEL=debug pnpm runtime
该输出中的 channel "<name>" requires setup 意味着阶段 2 未完成。它是整个工作流中单条价值最高的日志行,而在默认日志级别下,它会被写入后丢弃。
阶段 5 — 按顺序验证
controls.status()→overall: "online"。如果应用尚未断言这一点,请添加该断言 —examples/OpenTag的server.ts调用了ready()却从不检查状态,这正是损坏的设置看起来健康的原因。- 进程运行时,仪表板显示 Channel Online。其 Runtime 面板应显示 Connected。忽略 Agent run 列 — 即使一轮成功完成,它也显示
—,因此它不是健康信号。 - 开发者从自己的 Slack 账户发送真实提及,并报告回复。
第 3 步由他们完成。不要代替他们向 Slack 发帖,也不要用 Slack 工具读取工作区来代替真实的往返测试。如果提及没有产生任何结果,请转到 references/troubleshooting.md — 按层诊断,不要开始更改配置。
阶段 6 — 可选的实时 E2E
仅在真实提及可用之后进行。references/optional-e2e.md。这是 Slack token 合法进入 .env 的唯一地方,因为测试装置会作为测试客户端直接驱动 Slack API。
绝对不要做这些事
绝对不要为了解除阻塞而切换到直接 Slack 适配器。 这会把平台凭据移入应用,放弃托管投递的重试/去重/排序能力,仍然需要一个 Intelligence 密钥,而且意味着你验证的架构与开发者所询问的架构并不相同。如果托管路径被阻塞,就说它被阻塞了,并说明原因。
绝对不要用入门项目自带的 slack-app-manifest.yaml 创建 Slack 应用。 OpenTag 的 manifest 设置 socket_mode_enabled: true,并且没有声明 request_url,这是_直接_适配器的形态,而不是托管 Channel 的形态。用它创建的应用能正常安装,在 Slack 中显示为绿色,但永远无法向 Intelligence 投递任何内容。请使用 Channel 向导生成的 manifest。本技能中的 assets/slack-app-manifest.yaml 同样如此——它仅作为直接适配器形态的参考保留。
绝对不要复用生产或共享的 Slack 应用。 一个 Slack 应用只有一个事件订阅 Request URL。把现有应用指向你的 Channel 的 URL,会将该应用的全部事件流转从原本为其提供服务的地方重定向走——你不是在观察生产流量,而是在劫持它,真实用户会由一台笔记本电脑上正在开发中的 Agent 来应答。Slack 不提供将投递范围限定到单个 channel 或单个用户的方式。把 manifest 粘贴覆盖到已安装的应用上还会强制重新安装并轮换其 token,从而破坏所有现有消费方。
绝对不要在聊天中索要密钥,也绝对不要打印密钥。 完整的归属表和处理规则见 references/secrets-and-credentials.md。
绝对不要用运行时 API key 探测 Intelligence 的 HTTP 端点。 它是项目范围的激活密钥,而不是仪表盘会话;仪表盘端点会拒绝它,而且响应体可能携带平台 token。
绝对不要为了让进展显得更快而改动环境。 未经说明改动并获得同意,不要执行 pnpm install,不要杀死不是你启动的进程,不要为开发者编辑 .env。
合理化解释
| 想法 | 现实 |
|---|---|
| “他们有截止日期,直接适配器更快” | 你将会验证一个不同的架构,并在错误的位置把凭据交给他们。截止日期压力正是范围纪律最重要的时候。 |
| “仪表盘令人困惑,代码更可靠” | 这种困惑才是开发者实际的问题。用代码解决它只会把它隐藏起来。 |
| “生产 Slack 应用已经安装了,所以复用它省去了审批” | 重新指向它的 Request URL 会劫持该应用的整个事件流。审批之所以存在,是因为安装会影响其他人。 |
| “只是为了测试 / 只弄一分钟” | 一个应用只有一个事件 URL。当你的 URL 被设置时,生产环境根本收不到它的事件。 |
| “起始模板附带了一个 manifest,所以我就用它创建应用” | 它设置了 socket_mode_enabled: true 却没有 request_url —— 这是直接适配器的形态。应用会显示安装成功,却永远不会投递。请使用向导的 manifest。 |
“我需要生成一个 xapp- 应用级令牌” | 这个工作流里没有 xapp- 令牌,也没有地方放它。适配器需要的是 bot token 和 signing secret。 |
“运行时已启动,/info 返回 200,所以我们连上了” | ready() 在 setup_required 时就会解析,/info 报告的是许可证状态。两者都没有说明任何关于 Slack 的情况。 |
“ready() 解析了且没有抛错,所以 Channel 在线” | 它按设计会在 setup_required 时解析。请读取 status()。 |
| “我用 API key 检查一下 Channel 状态” | 仪表盘端点会拒绝 project key。请使用 status() 或仪表盘。 |
“让我直接读 .env 看看配置了什么” | 从 .env.example 读取名称;只在 .env 中检查是否存在,绝不要引用某个值。 |
| “我自己发测试提及来省一个来回” | 成功标准是真实的人被提及。替他们发帖证明力更弱,而且是在他们的工作区里代表他们行事。 |
| “没有回复 —— 让我试着改配置” | 先按层诊断。LOG_LEVEL=debug 会用一行指出失败原因。 |
危险信号 — 停下
- 你正要输入
adapters: [slack(,或是往.env里添加SLACK_BOT_TOKEN, 而目的不是 Phase 6 的测试装置。 - 你正要从入门模板的 manifest 创建 Slack 应用,或是从任何带有
socket_mode_enabled: true却没有request_url的 manifest 创建。 - 你正要寻找应用级 token、
connections:write或 Socket Mode 开关。它们都不属于托管 Channel。 - 你正要打开应用的 Install App 页面或对其截图。该页面会以明文渲染 bot token;读取它就等于捕获了一份有效凭证。
- 你正要在三道门禁全部通过之前说出“connected”“working”或“done”。
- 你正要让开发者粘贴 token,或是你正要回显一个 token。
- 你正要点击一个你还没读过的仪表盘控件。
- 你正要未经要求就执行
pnpm install、杀掉进程或编辑.env。 - 你已经花了很多次工具调用去推导托管 Channel 的工作方式。停下 — 它就 在本技能及其参考文档里。
参考文档
只读你当前所处阶段对应的参考文档 — 不要一开始就全部读完。 每份文档都是自包含的,而在对开发者说任何话之前先读六个文件,正是这个工作流变慢的原因。
| 文件 | 何时阅读 |
|---|---|
references/intelligence-channel.md | Phase 1 和 3 — 向导、Code、适配器、项目、密钥 |
references/slack-workspace-and-app.md | Phase 2 — 工作区、安装、bot token、签名密钥 |
references/secrets-and-credentials.md | 任何时候涉及凭证 |
references/local-runtime.md | Phase 4 — 环境变量、Agent、运行时、启动、端口 |
references/optional-e2e.md | Phase 6 — 实时 Slack 测试装置 |
references/troubleshooting.md | 任何失败,或是某次提及没有得到回复 |
assets/slack-app-manifest.yaml | 仅供参考 — direct-adapter 形态。不适用于托管 Channel。 |