跳到主要内容

Channels 概览

新增于: @mastra/core@1.22.0

Channels 将 Agent 连接到 Slack、Microsoft Teams、Discord、Telegram、WhatsApp、GitHub 和 Linear 等消息与协作平台。当用户在平台上发送消息或评论时,Agent 会接收该内容,通过常规 Agent 流水线进行处理,并将响应流式传回对话。Mastra 使用 Chat SDK 提供这一 Channel 层。

请从对应平台的页面开始:

更多适配器列出了其他平台。除这里列出的平台外,Mastra Channels 也适用于兼容的 Chat SDK 适配器,并且所有适配器都采用相同的 Mastra 配置模式。

何时使用 Channels
何时使用 Channels的直接链接

当 Agent 需要完成以下任务时,请使用 Channels:

  • 在用户已经交流或工作的地方与其互动。
  • 在 Slack、Microsoft Teams、Discord、Telegram 和 WhatsApp 等聊天平台中响应。
  • 支持多人 Agent,让多个人在共享 Channel 或线程中与同一个 Agent 交互。
  • 与 GitHub issue、pull request 线程和 Linear 评论等协作工作流集成。

配置 Agent
配置 Agent的直接链接

Channels 使用 Chat SDK 适配器,并遵循相同的 Mastra 侧模式:创建 Channel 适配器并将其添加到 Agent。

src/mastra/agents/your-agent.ts
import { Agent } from '@mastra/core/agent'
import { createSlackAdapter } from '@chat-adapter/slack'

export const yourAgent = new Agent({
id: 'your-agent',
name: 'Your Agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5.6-sol',
channels: {
adapters: {
slack: createSlackAdapter(),
},
},
})
备注

Channel 适配器需要 Provider 特有的环境变量,以提供凭据并验证请求,例如机器人 token、签名 secret、应用 ID 和 webhook 验证 token。请查看对应平台的指南或 Chat SDK 适配器目录,了解确切的变量名称。

建议为 Channels 配置 Storage。Storage 让 Mastra 能够跨重启持久保存 Channel state、线程订阅、Tool 审批和 Memory:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'
import { yourAgent } from './agents/your-agent'

export const mastra = new Mastra({
agents: { yourAgent },
storage: new LibSQLStore({
id: 'mastra-storage',
url: process.env.DATABASE_URL,
}),
})

Webhook 路由
Webhook 路由的直接链接

平台通过 webhook 将 Channel 活动发送到 Mastra。Webhook 是平台在发生事件时调用的 HTTP 端点,例如出现新消息、有人提及 Agent,或用户在交互式 Tool 审批卡片上选择“Approve”。Agent 正是通过这种方式接收新消息、开始处理,并在同一 Channel 中响应。

Mastra 会为每个已配置的适配器注册 webhook 路由,并代你处理请求:

/api/agents/<AGENT_ID>/channels/<PLATFORM>/webhook

例如,ID 为 your-agent 的 Agent 上的 Slack 适配器会使用:

/api/agents/your-agent/channels/slack/webhook

将平台的 webhook、事件或交互 URL 指向此路径。请遵循对应平台的指南或 Chat SDK 文档

本地开发期间,平台 webhook 需要公开 URL 才能访问本地 Server。请使用 cloudflaredngrok 等隧道公开 Server,默认地址为 localhost:4111

npx cloudflared tunnel --url http://localhost:4111

使用生成的公开 URL 作为 webhook 路径的基础 URL,例如 https://abc123.trycloudflare.com/api/agents/your-agent/channels/slack/webhook

备注

隧道 URL 仅用于本地开发。部署 Mastra Server 后,请将平台的 webhook、事件或交互 URL 更新为生产环境 URL。

线程上下文
线程上下文的直接链接

当用户在 Channel 线程的对话中途提及 Agent 时,Agent 可能没有此前的上下文。默认情况下,Mastra 会在首次被提及时从平台获取最近 10 条消息。

  1. 在线程中首次被提及时,Agent 从平台获取最近的消息。
  2. 这些消息会作为对话上下文添加到用户消息之前。
  3. 响应后,Agent 会订阅该线程,并通过 Mastra Memory 获得完整历史记录。
  4. 该线程中的后续消息不会再次从平台获取历史记录。

设置 threadContext: { maxMessages: 0 } 可禁用此行为。这仅适用于非私信线程。

Mastra 还会添加一条简短的系统消息,告知 Agent 请求来自哪个 Channel 和平台,例如该消息来自私信还是公开 Channel。设置 threadContext: { addSystemMessage: false } 可跳过此消息。

Tool 审批
Tool 审批的直接链接

设置了 requireApproval: true 的 Tool 会呈现为带有 Approve 和 Deny 按钮的交互式卡片:

src/mastra/tools/delete-file.ts
import { promises as fs } from 'node:fs'
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const deleteFile = createTool({
id: 'delete-file',
description: 'Delete a file from the system',
inputSchema: z.object({
path: z.string().describe('Path to the file to delete'),
}),
requireApproval: true,
execute: async ({ path }) => {
await fs.unlink(path)
return { deleted: path }
},
})

当 Agent 调用此 Tool 时,用户会看到一张包含 Tool 名称、参数以及 Approve 和 Deny 操作的卡片。Tool 只会在获得批准后执行。

在适配器上设置 toolDisplay: 'text',可将 Tool 调用呈现为纯文本而不是交互式卡片。在 'hidden' 模式下,之后有用户消息到达同一线程时,autoResumeSuspendedTools 可以恢复已暂停的 Tool。这需要 Memory。隐藏模式只会隐藏审批按钮。

回复格式
回复格式的直接链接

Agent 回复默认以 markdown 形式发送。Slack 等原生支持 markdown 渲染的平台会直接渲染粗体文本、链接和表格。其他平台会将 markdown 转换为自己的格式。Agent 编写标准 markdown 后,可以在所有平台上正确渲染,与同一回复在 Studio 中的渲染效果一致。

在适配器上设置 textFormat: 'plain',可改为按字面意义的纯文本发送回复:

src/mastra/agents/your-agent.ts
channels: {
adapters: {
slack: {
adapter: createSlackAdapter(),
textFormat: 'plain',
},
},
},

如果通过提示词要求 Agent 输出平台特有语法(例如 Slack mrkdwn),而非标准 markdown,可使用此应急选项。如果你曾添加此类提示词指令来规避 markdown 被按字面渲染的问题,请改为移除这些指令。现在默认行为会以原生方式渲染标准 markdown。textFormat 只影响最终回复文本,不会影响 Tool 卡片、错误消息和以原生方式流式传输的文本。

多用户感知
多用户感知的直接链接

在群组对话中,Mastra 会为每条消息添加发送者姓名和平台 ID 前缀,以便 Agent 区分不同发言者:

[Alice (@U123ABC)]: Can you help me with this?
[Bob (@U456DEF)]: I have a question too.

多模态内容
多模态内容的直接链接

Gemini 等模型可以原生处理图像、视频和音频。结合使用 inlineMediainlineLinks,让用户可以跨平台与 Agent 分享富媒体内容:

src/mastra/agents/vision-agent.ts
import { Agent } from '@mastra/core/agent'
import { createDiscordAdapter } from '@chat-adapter/discord'

export const visionAgent = new Agent({
id: 'vision-agent',
name: 'Vision Agent',
instructions: 'You can see images, watch videos, and listen to audio.',
model: 'google/gemini-2.5-flash',
channels: {
adapters: {
discord: createDiscordAdapter(),
},
inlineMedia: ['image/*', 'video/*', 'audio/*'],
inlineLinks: [
{ match: 'youtube.com', mimeType: 'video/*' },
{ match: 'youtu.be', mimeType: 'video/*' },
'imgur.com',
],
},
})

采用此配置后:

  • 用户上传截图,Agent 会描述其中的内容。
  • 用户上传 .mp4 剪辑,Agent 会总结视频内容。
  • 用户粘贴 YouTube 链接,Agent 会观看并讨论该视频。
  • 用户粘贴 imgur 链接,Agent 会直接看到图像。

默认情况下,只会以内联形式发送图像(inlineMedia: ['image/*'])。不支持的类型会以文本摘要描述,这样 Agent 既能知道文件的存在,又不会让拒绝这些类型的模型失败。有关所有 inlineMedia 模式,请参阅 Channels Reference;有关域名匹配、HEAD 检测和强制 MIME 类型,请参阅 inlineLinks Reference

Serverless 部署
Serverless 部署的直接链接

在 Vercel 等 serverless 平台上,每个请求都会在独立且短暂存活的实例中运行。Channels 要在这种环境中可靠工作,需要满足两个条件:在 Agent 响应期间保持函数存活,以及使用共享 pub/sub 让实例能够协调。

使用 waitUntil 保持函数存活
keep-the-function-alive-with-waituntil的直接链接

Channel webhook 会立即返回 200 响应,随后 Agent 在后台运行并发送回复。在大多数 serverless 平台上,函数会在响应后立即冻结,导致运行在 Agent 回复前停止。请传入 waitUntil 函数,让平台保持实例存活,直到运行结束。

在 Vercel 上,从 @vercel/functions 传入 waitUntil

src/mastra/agents/your-agent.ts
import { Agent } from '@mastra/core/agent'
import { createSlackAdapter } from '@chat-adapter/slack'
import { waitUntil } from '@vercel/functions'

export const yourAgent = new Agent({
id: 'your-agent',
name: 'Your Agent',
instructions: 'You are a helpful assistant.',
model: 'openai/gpt-5.6-sol',
channels: {
adapters: {
slack: createSlackAdapter(),
},
waitUntil,
},
})

Vercel 和 AWS Lambda 需要 waitUntil,因为它们会在发送响应后立即冻结函数。Cloudflare Workers 和 Netlify Functions 会根据请求上下文自动检测,因此不需要传入。对于 waitUntil 位于请求上下文中但无法自动检测的运行时,请使用 resolveWaitUntil。详情请参阅 Channels Reference

使用共享 pub/sub 协调实例
使用共享 pub/sub 协调实例的直接链接

Channels 通过 Agent 的 signal 流水线路由消息,每次运行都会获取其线程的租约,因此同一时间只有一次运行拥有该对话。

默认的内存 pub/sub 无法跨越实例边界,因此在 serverless 环境中,后续消息可能被路由到与 Agent 当前运行所在实例不同的实例。

如果没有共享 pub/sub,该实例无法联系正在进行的运行,于是会启动自己的运行,导致原始运行不受影响,而线程被处理两次。

请在 Mastra 实例上配置由 Redis Streams 支持的共享 pub/sub,让租约和 signal 能够跨实例协调:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { RedisStreamsPubSub } from '@mastra/redis-streams'
import { yourAgent } from './agents/your-agent'

export const mastra = new Mastra({
agents: { yourAgent },
pubsub: new RedisStreamsPubSub({
url: process.env.REDIS_URL,
keyPrefix: 'mastra:my-app',
}),
})

Vercel 托管的 Redis 集成和 Upstash Redis 都很合适。如需进一步了解何时需要分布式 pub/sub,请参阅 PubSub 指南RedisStreamsPubSub Reference