> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 채널 개요 **추가된 항목:** `@mastra/core@1.22.0` 채널은 Agent를 Slack, Microsoft Teams, Discord, Telegram, WhatsApp, GitHub, Linear과 같은 메시징 및 협업 플랫폼에 연결합니다. 사용자가 플랫폼에서 메시지나 댓글을 보내면 Agent가 이를 수신하여 일반 Agent 파이프라인으로 처리하고 응답을 대화에 다시 스트리밍합니다. Mastra는 이 채널 계층에 [Chat SDK](https://chat-sdk.dev/)를 사용합니다. 귀하의 플랫폼에 맞는 페이지로 시작하세요: - [느슨하게](https://mastra.zisheng.pro/ko/docs/capabilities/channels/slack) - [마이크로소프트 팀즈](https://mastra.zisheng.pro/ko/docs/capabilities/channels/teams) - [불화](https://mastra.zisheng.pro/ko/docs/capabilities/channels/discord) - [전보](https://mastra.zisheng.pro/ko/docs/capabilities/channels/telegram) - [왓츠앱](https://mastra.zisheng.pro/ko/docs/capabilities/channels/whatsapp) - [아이메시지](https://mastra.zisheng.pro/ko/docs/capabilities/channels/imessage) [기타 어댑터](https://mastra.zisheng.pro/ko/docs/capabilities/channels/other-adapters)에는 추가 플랫폼이 나열되어 있습니다. Mastra 채널은 여기에 나열된 플랫폼 외의 [Chat SDK 어댑터](https://chat-sdk.dev/adapters)와도 호환되며 모든 어댑터에 동일한 Mastra 구성 패턴이 적용됩니다. ## 채널을 사용해야 하는 경우 Agent가 다음을 수행해야 하는 경우 채널을 사용하세요. - 이미 대화하거나 일하고 있는 사용자를 만나보세요. - Slack, Microsoft Teams, Discord, Telegram, WhatsApp 등의 채팅 플랫폼에서 응답하세요. - 여러 사람이 공유 채널 또는 스레드에서 동일한 Agent와 상호 작용하는 멀티플레이어 Agent를 지원합니다. - GitHub 문제, 풀 요청 스레드, 선형 댓글과 같은 협업 Workflow와 통합됩니다. ## Agent 구성 채널은 Chat SDK 어댑터를 사용하고 동일한 Mastra 측 패턴을 따릅니다. 즉, 채널 어댑터를 생성하여 Agent에 추가합니다. ```typescript 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(), }, }, }) ``` > **노트:** 채널 어댑터에는 봇 토큰, 서명 비밀, 앱 ID, 웹훅 검증 토큰 등 자격 증명과 요청 검증을 위한 Provider별 환경 변수가 필요합니다. 정확한 변수 이름은 사용 중인 플랫폼의 가이드와 [Chat SDK 어댑터 카탈로그](https://chat-sdk.dev/adapters)를 확인하세요. 채널에는 [스토리지](https://mastra.zisheng.pro/ko/docs/storage/overview)를 구성하는 것이 좋습니다. 스토리지를 사용하면 Mastra가 채널 상태, 스레드 구독, Tool 승인 및 Memory를 재시작 후에도 유지할 수 있습니다. ```typescript 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, }), }) ``` ## 웹훅 경로 플랫폼은 웹후크를 통해 채널 활동을 Mastra로 보냅니다. 웹후크는 새 메시지, 멘션 또는 사용자가 대화형 Tool 승인 카드에서 "승인"을 선택하는 등 어떤 일이 발생할 때 플랫폼이 호출하는 HTTP 엔드포인트입니다. 이는 Agent가 새 메시지를 수신하고 처리를 시작하며 동일한 채널에서 응답하는 방법입니다. Mastra는 구성된 각 어댑터에 대한 웹훅 경로를 등록하고 요청을 처리합니다. ```text /api/agents//channels//webhook ``` 예를 들어 ID가 `your-agent`인 Agent의 Slack 어댑터는 다음을 사용합니다. ```text /api/agents/your-agent/channels/slack/webhook ``` 플랫폼의 웹훅, 이벤트 또는 상호 작용 URL이 이 경로를 가리키도록 합니다. 귀하의 플랫폼에 대한 가이드를 따르십시오.[Chat SDK docs](https://chat-sdk.dev/adapters). 로컬 개발 중 플랫폼 웹훅을 로컬 서버에 연결하려면 공개 URL이 필요합니다. [cloudflared](https://github.com/cloudflare/cloudflared) 또는 [ngrok](https://ngrok.com/)과 같은 터널을 사용해 기본적으로 `localhost:4111`에서 실행되는 서버를 공개하세요. **npm**: ```bash npx cloudflared tunnel --url http://localhost:4111 ``` **pnpm**: ```bash pnpm dlx cloudflared tunnel --url http://localhost:4111 ``` **Yarn**: ```bash yarn dlx cloudflared tunnel --url http://localhost:4111 ``` **Bun**: ```bash bun x cloudflared tunnel --url http://localhost:4111 ``` 생성된 공개 URL을 웹훅 경로의 기본 URL로 사용합니다. 예를 들면 다음과 같습니다.`https://abc123.trycloudflare.com/api/agents/your-agent/channels/slack/webhook`. > **노트:** 터널 URL은 로컬 개발을 위한 것입니다. Mastra 서버를 배포한 후 플랫폼의 웹훅, 이벤트 또는 상호 작용 URL을 프로덕션 URL로 업데이트하세요. ## 스레드 컨텍스트 사용자가 채널 스레드의 대화 중에 Agent를 언급하는 경우 Agent는 사전 컨텍스트를 갖고 있지 않을 수 있습니다. 기본적으로 Mastra는 첫 번째 언급 시 플랫폼에서 마지막 10개의 메시지를 가져옵니다. 1. 스레드의 첫 번째 언급에서 Agent는 플랫폼에서 최근 메시지를 가져옵니다. 2. 이러한 메시지는 대화 컨텍스트로 사용자의 메시지 앞에 추가됩니다. 3. 응답 후 Agent는 스레드를 구독하고 Mastra Memory를 통해 전체 기록을 갖습니다. 4. 해당 스레드의 후속 메시지는 플랫폼에서 다시 가져오지 않습니다. 이 동작을 비활성화하려면 `threadContext: { maxMessages: 0 }`을 설정하세요. 이는 다이렉트 메시지가 아닌 스레드에만 적용됩니다. Mastra는 메시지가 다이렉트 메시지에서 왔는지 공개 채널에서 왔는지 등 요청이 발생한 채널과 플랫폼을 Agent에 알려주는 짧은 시스템 메시지도 추가합니다. 이를 건너뛰려면 `threadContext: { addSystemMessage: false }`를 설정하세요. ## Tool 승인 `requireApproval: true`인 Tool은 Approve 및 Deny 버튼이 있는 대화형 카드로 렌더링됩니다. ```typescript 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 이름, 인수, 승인 및 거부 작업이 포함된 카드가 표시됩니다. 이 Tool은 승인 후에만 실행됩니다. Tool 호출을 대화형 카드 대신 일반 텍스트로 렌더링하려면 어댑터에 `toolDisplay: 'text'`를 설정하세요. `'hidden'` 모드에서는 같은 스레드에 이후 사용자 메시지가 도착했을 때 `autoResumeSuspendedTools`가 일시 중단된 Tool을 재개할 수 있습니다. 이를 위해서는 Memory가 필요합니다. 숨김 모드는 승인 버튼만 숨깁니다. ## 답장 형식 Agent은 기본적으로 마크다운으로 게시물에 답장을 보냅니다. Slack과 같은 기본 마크다운 렌더링 기능을 갖춘 플랫폼은 굵은 텍스트, 링크 및 테이블을 직접 렌더링합니다. 다른 플랫폼은 마크다운을 자체 형식으로 변환합니다. Agent은 표준 마크다운을 작성하고 Studio에서 동일한 응답이 렌더링되는 방식과 일치하도록 어디에서나 올바르게 렌더링됩니다. 응답을 리터럴 일반 텍스트로 게시하려면 어댑터에 `textFormat: 'plain'`을 설정하세요. ```typescript channels: { adapters: { slack: { adapter: createSlackAdapter(), textFormat: 'plain', }, }, }, ``` Agent에 표준 Markdown 대신 Slack mrkdwn 같은 플랫폼별 언어를 출력하라는 메시지가 표시될 때 이 우회 옵션을 사용하세요. Markdown 렌더링 문제를 해결하기 위해 이러한 Prompt 지침을 직접 추가했다면 제거하세요. 이제 기본적으로 표준 Markdown이 렌더링됩니다. `textFormat`은 최종 응답 텍스트에만 영향을 줍니다. Tool 카드, 오류 메시지, 네이티브 스트리밍 텍스트에는 영향을 주지 않습니다. ## 다중 사용자 인식 그룹 대화에서 Mastra는 Agent가 화자를 구별할 수 있도록 각 메시지 앞에 발신자 이름과 플랫폼 ID를 붙입니다. ```text [Alice (@U123ABC)]: Can you help me with this? [Bob (@U456DEF)]: I have a question too. ``` ## 다중 모드 콘텐츠 Gemini 같은 Model은 이미지, 동영상, 오디오를 기본적으로 처리할 수 있습니다. `inlineMedia`와 `inlineLinks`를 함께 사용하면 사용자가 여러 플랫폼에서 Agent와 리치 콘텐츠를 공유할 수 있습니다. ```typescript 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/*']`). 지원되지 않는 유형은 텍스트 요약으로 설명되므로, 해당 유형을 거부하는 Model에서도 오류를 일으키지 않으면서 Agent가 파일의 존재를 알 수 있습니다. 모든 `inlineMedia` 패턴은 [채널 레퍼런스](https://mastra.zisheng.pro/ko/reference/agents/channels)를, 도메인 일치, HEAD 감지, MIME 유형 강제 지정은 [inlineLinks 레퍼런스](https://mastra.zisheng.pro/ko/reference/agents/channels)를 참조하세요. ## 서버리스 배포 Vercel과 같은 서버리스 플랫폼에서는 각 요청이 별도의 단기 인스턴스에서 실행됩니다. 채널이 해당 환경에서 안정적으로 작동하려면 두 가지가 필요합니다. Agent가 응답하는 동안 함수를 활성 상태로 유지하는 방법과 인스턴스가 조정할 수 있도록 공유 게시/구독이 필요합니다. ### 기능을 계속 유지하십시오.`waitUntil` 채널 웹훅은 즉시 `200` 응답을 반환한 다음, Agent가 백그라운드에서 실행되어 응답을 게시합니다. 대부분의 서버리스 플랫폼에서는 응답을 보내는 즉시 함수가 정지되므로 Agent가 답변하기 전에 실행이 중단됩니다. 플랫폼이 실행 완료 시까지 인스턴스를 유지하도록 `waitUntil` 함수를 전달하세요. Vercel에서는 `@vercel/functions`의 `waitUntil`을 전달하세요. ```typescript 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`을 사용하세요. 자세한 내용은 [채널 레퍼런스](https://mastra.zisheng.pro/ko/reference/agents/channels)를 참조하세요. ### 공유 게시/구독으로 인스턴스 조정 채널은 Agent의 [신호 파이프라인](https://mastra.zisheng.pro/ko/docs/long-running-agents/signals)을 통해 메시지를 라우팅하며, 각 실행은 한 번에 하나의 실행만 대화를 소유하도록 해당 스레드의 임대를 획득합니다. 기본 Memory 내 게시/구독은 인스턴스 경계를 ​​넘을 수 없으므로 서버리스에서는 후속 메시지가 Agent를 실행하는 인스턴스가 아닌 다른 인스턴스로 라우팅될 수 있습니다. 공유 게시/구독이 없으면 해당 인스턴스는 활성 실행에 도달할 수 없으며 자체적으로 시작되므로 원래 실행은 그대로 유지되고 스레드는 두 번 처리됩니다. 인스턴스 간에 임대와 신호를 조정할 수 있도록 Redis Streams 기반의 공유 게시/구독을 `Mastra` 인스턴스에 구성하세요. ```typescript 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 모두 원활하게 작동합니다. 분산 게시/구독이 필요한 경우에 대한 자세한 내용은 [PubSub 가이드](https://mastra.zisheng.pro/ko/docs/server/pubsub)와 [`RedisStreamsPubSub` 레퍼런스](https://mastra.zisheng.pro/ko/reference/pubsub/redis-streams)를 참조하세요. ## 관련된 - [채널 참조](https://mastra.zisheng.pro/ko/reference/agents/channels) - [AgentController 채널](https://mastra.zisheng.pro/ko/docs/harness/agent-controller) - 📹 [Mastra channels workshop](https://www.youtube.com/watch?v=E9KFsZEnQO8\&t=5s)