Contents
概要とユースケース
Slack上で短期間に稼働するAIボットを、実装から運用まで実務レベルで導入するためのガイドです。
最小構成で動かす手順と、運用で必要になる具体的な実装例・コマンドを中心にまとめます。
実務で使えるユースケース
ここでは短期間で効果が出やすい代表ユースケースを示します。
- FAQの一次対応(社内ヘルプデスク窓口の負荷削減)
- 会議議事録の要約・アクション抽出
- メール・文書のリライト/テンプレ自動生成
- 定期通知や承認ワークフローの自動化
- コード差分要約や簡易レビュー支援
- オンボーディング資料の自動生成
導入はまず最小構成(Slash → Modal → 非同期ワーカー → LLM → 投稿)で動かし、ログやプロンプトを見ながら段階的に改良してください。
Slackアプリ設計と認証(Slack AI ボット 作成 方法)
Slackアプリ設計と認証の選択が安全性と運用性を左右します。ここでは必要な考え方と必須作業を整理します。
アプリ作成とManifest/OAuthの基本
Manifestで設定を管理すると再現性が上がります。OAuthはインストール時にコードを交換してトークンを取得する標準フローです。
参考ドキュメント: Slack OAuth v2(https://api.slack.com/authentication/oauth-v2)
- Slack Appをワークスペースで作成し、Manifestにcommands, interactivity, oauth_scopesを定義して管理する。
- 必須情報: Signing Secret(リクエスト検証)、Client ID / Client Secret(OAuth)、Bot Token(xoxb-...)。
- スコープの変更は再インストールが必要なので、最小権限に絞って段階的に拡張する。
BotトークンとUserトークンの違いと使い分け
BotトークンとUserトークンは権限モデルが異なります。基本はBotトークンで運用し、特別な操作のみUserトークンを使います。
- Botトークン(xoxb-): ボットユーザーとしての投稿・イベント購読に使用。通常はこちらで十分。
- Userトークン(xoxp-): 個別ユーザーの代行操作が必要なケースで限定使用。不要な権限は付与しない。
必須スコープ例と確認手順
スコープはアプリの用途に応じて最小化します。最新のスコープ名は公式ドキュメントで確認してください(https://api.slack.com/scopes)。
- よく使うスコープ例: commands, chat:write, users:read, channels:read, groups:read, im:write, chat:write.public
- スコープ追加後はアプリを再インストールして、実際に権限が足りるか検証する。
イベントとインタラクション設計(Events API / Block Kit / モーダル)
イベント処理とUI設計はUXと信頼性に直結します。短時間応答と非同期化の設計が重要です。
Events API と RTM の選択
Events APIはHTTPプッシュ型でサーバレスやWebhookで扱いやすく、多くのユースケースで推奨されます。RTMはWebSocketベースで低レイテンシやプレゼンス情報が必要な場合に検討します。
- Events API は容易にスケールし、Webhook受信向き。
- RTM は常時接続が必要なアプリやリアルタイム性重視の特殊ケース向け。
Block Kit とモーダル設計の要点
Block Kitは動的な入力UXに適しています。要件に応じてテンプレート化して再利用してください。アクセシビリティと入力検証を忘れないでください。
- block_id / action_id を明確にし、バリデーションルールをサーバ側でも実装する。
- 長いBlock JSONはテンプレート化して管理する。
ack と非同期処理のベストプラクティス
Slackのインタラクションハンドラは短時間でackを返す必要があります。長時間処理は必ずack後にワーカーに委譲してください。
- ハンドラ内では即座にack()(またはHTTP 200)を返す。
- 実際のLLM呼び出しや重い処理はジョブキュー(Redis/Bull、SQS等)に登録してワーカーで処理する。
- ack忘れや長時間同期処理はタイムアウト・ユーザーUX障害の主因となるため必須確認項目です。
ハンズオン:サンプルリポジトリで最小構成を動かす(Slash→Modal→LLM→投稿)
ここでは初心者がそのまま実行できる手順とコマンドを示します。まずローカル検証を目指してください。
推奨サンプルリポジトリとクローン手順
Bolt公式のサンプルは導入が早く、カスタマイズしやすいです。まずはこれをベースにしてください。
- Bolt for JavaScript(公式サンプル): https://github.com/slackapi/bolt-js
- クローン例: git clone https://github.com/slackapi/bolt-js.git
- Bolt for Python(公式サンプル): https://github.com/slackapi/bolt-python
- クローン例: git clone https://github.com/slackapi/bolt-python.git
- ngrok(ローカル公開): https://ngrok.com
上記をクローン/参照し、examples フォルダの簡易サンプルから始めるとよいです。
ローカル環境構築と実行コマンド(Node.js版)
ここでは最小構成をゼロから作るコマンドを示します。コピーして実行できます。
- プロジェクト作成と依存インストール:
|
1 2 3 4 |
mkdir slack-ai-bot && cd slack-ai-bot npm init -y npm install @slack/bolt axios bull ioredis dotenv |
- 必須環境変数(.env)例:
|
1 2 3 4 5 6 7 |
SIGNING_SECRET=(SlackのSigning Secret) SLACK_BOT_TOKEN=xoxb-(Bot Token) LLM_API_KEY=(LLMプロバイダのAPIキー) LLM_PROXY_URL=https://api.openai.com/v1/chat/completions REDIS_URL=redis://localhost:6379 PORT=3000 |
- ローカル起動(開発時):
|
1 2 3 4 |
node index.js # 別ターミナルで ngrok ngrok http 3000 |
ngrokで出力されたhttps URLをSlack AppのEvent Subscriptions / InteractivityのRequest URLに設定してください。
実用的なNodeサンプル(ack, ジョブキュー, 429/リトライ対応)
以下は要点を追記した実装スケルトンです。実運用ではエラーログやトレースIDを追加してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
// index.js(簡易例) require('dotenv').config(); const { App, ExpressReceiver } = require('@slack/bolt'); const Queue = require('bull'); const axios = require('axios'); const receiver = new ExpressReceiver({ signingSecret: process.env.SIGNING_SECRET, endpoints: '/slack/events' }); const app = new App({ token: process.env.SLACK_BOT_TOKEN, receiver }); const llmQueue = new Queue('llm', process.env.REDIS_URL); // /ask-ai コマンドでモーダルを開く app.command('/ask-ai', async ({ ack, body, client }) => { await ack(); // 即時ack await client.views.open({ trigger_id: body.trigger_id, view: { type: 'modal', callback_id: 'ai_modal', title: { type: 'plain_text', text: 'AIに質問' }, blocks: [{ type: 'input', block_id: 'q_block', element: { type: 'plain_text_input', action_id: 'q_input' }, label: { type: 'plain_text', text: '質問' } }], submit: { type: 'plain_text', text: '送信' } } }); }); // モーダル送信ハンドラは即時ackしてジョブを登録 app.view('ai_modal', async ({ ack, view, body }) => { await ack(); const question = view.state.values['q_block']['q_input'].value; await llmQueue.add({ userId: body.user.id, question }, { attempts: 5, backoff: { type: 'exponential', delay: 1000 } }); }); // ワーカー: LLM呼び出しとSlack投稿 llmQueue.process(async (job) => { const { userId, question } = job.data; const result = await callLLMWithRetry(question); await app.client.chat.postMessage({ channel: userId, text: result }); }); async function callLLMWithRetry(question) { const max = 5; let attempt = 0; while (attempt < max) { try { const res = await axios.post(process.env.LLM_PROXY_URL, { model: 'gpt-4o-mini', // 例 messages: [{ role: 'user', content: question }] }, { headers: { Authorization: `Bearer ${process.env.LLM_API_KEY}` }, timeout: 30000 }); // プロバイダに応じてレスポンス取り出しを調整 return res.data.choices?.[0]?.message?.content || res.data.result || JSON.stringify(res.data); } catch (err) { const status = err.response?.status; const retryAfter = parseInt(err.response?.headers?.['retry-after'] || '0', 10); if (status === 429) { const wait = (retryAfter || (2 ** attempt)) * 1000; await new Promise(r => setTimeout(r, wait)); attempt++; continue; } if (err.code === 'ECONNABORTED' || err.code === 'ETIMEDOUT') { await new Promise(r => setTimeout(r, 1000 * (2 ** attempt))); attempt++; continue; } throw err; } } throw new Error('LLM call failed after retries'); } (async () => { await app.start(process.env.PORT || 3000); console.log('⚡ Slack AI bot running'); })(); |
Python 環境と実行コマンド(簡易)
- 仮想環境と依存:
|
1 2 3 4 |
python -m venv venv source venv/bin/activate pip install slack-bolt flask rq redis python-dotenv requests |
- .env はNodeと同様に準備し、Flask受信+RQでワーカーを分離して実行します。Bolt Pythonの公式examplesを参照してください(https://github.com/slackapi/bolt-python)。
実装パターンと LLM 統合
LLM統合は運用性・コスト・セキュリティのバランスが重要です。用途に応じてアーキテクチャを選んでください。
アーキテクチャ選択(直接呼び出し・プロキシ・非同期ワーカー)
各選択肢の特徴を理解し、要件に合わせて決めます。
- 直接API呼び出し: 実装が早い。小規模かつ低レイテンシ要件のケースに向く。
- プロキシ/APIゲートウェイ(推奨): 認可・レート制御・モデレーション・メトリクス集約を一元化できる。
- 非同期ワーカー: 長時間処理やリトライ、コスト制御に向く(SQS/Redis/Celery/Bull等を活用)。
プロンプト設計とコンテキスト管理
プロンプトで振る舞いを固定化し、履歴はトークン制限に合わせて圧縮・要約します。
- システムプロンプトで応答フォーマットを明示する(JSONレスポンス等)。
- 履歴は要約(スナップショット)やRAG(Retrieval-Augmented Generation)で管理する。
- トークンコストを計測し、低コストモデルで前処理を行うなどの工夫を行う。
モデレーションと PII(個人情報)対策
有害コンテンツやPIIの扱いは自動化とルールの組合せで対処します。必ずサーバ側で検査・遮断を行ってください。
- LLMプロバイダのモデレーションAPIを投入前に呼ぶ(例: OpenAI Moderation)。
- PIIの自動検知とマスキング: メール、電話番号、ID等は正規表現や専用ライブラリ(Microsoft Presidio等)で脱識別化してから送信する。
- 高リスクな入力(機密情報、パスワード等)は送信不可として明示的に拒否する運用ルールを作る。
- 送信前のログにPIIを残さないよう必ずマスキングを行う。
RAG(検索統合)と履歴圧縮の実装パターン
長いコンテキストはRAGで補強し、履歴は定期的に要約してトークン消費を抑えます。
- ドキュメントはチャンク化(例: 500〜1000トークン、重複20%)して埋め込みを生成。
- ベクターストアはPinecone / Weaviate / Milvus / FAISS等を選定。
- 検索→要約→合成のフローを作り、コストが高いモデルは最終ステップのみに使う。
- LangChain / LlamaIndex等の既存ライブラリを活用すると開発速度が上がる(https://github.com/langchain-ai/langchain)。
セキュリティ・シークレット管理と法務
シークレット管理や法務対応は運用リスクを下げるため必須です。自動化と定期レビューを組み合わせてください。
シークレット管理(KMS / Vaultの利用とローテーション)
シークレットは平文ファイルやリポジトリに置かず、KMSやVaultで管理します。ローテーション手順を定義してください。
- HashiCorp Vault(CLI例):
- 保存: vault kv put secret/slack-bot LLM_API_KEY=xxxx
- 取得: vault kv get -field=LLM_API_KEY secret/slack-bot
- AWS KMS + Secrets Manager: Secrets Managerにキーを保管し、KMSで暗号化。アプリはIAMロールでSecrets Managerから読み取る。
- ローテーション手順例: 新シークレットをVaultへ登録→段階的にアプリを切替→旧シークレットを無効化→削除。自動ローテーションを検討する。
NodeでのKMS復号(例)
|
1 2 3 4 5 6 7 8 |
// AWS SDK v3 の例(概念) const { KMSClient, DecryptCommand } = require('@aws-sdk/client-kms'); const kms = new KMSClient(); async function decryptBase64(cipherBase64) { const res = await kms.send(new DecryptCommand({ CiphertextBlob: Buffer.from(cipherBase64, 'base64') })); return Buffer.from(res.Plaintext).toString('utf-8'); } |
TLS と通信要件、ログマスキング
通信は常にTLS 1.2以上を必須とし、相互TLSが必要なレベルはアーキテクチャ要件で決めます。ログは構造化にしてPIIを除去してください。
- ログ例(JSON): {"ts":"...","service":"slack-ai","env":"prod","trace_id":"...","level":"error","user_id":"U123","channel":"C123","msg":"...","latency_ms":1200}
- マスキング例: メール・電話は正規表現で置換してログに残す。
法務・コンプライアンス(同意取得とDPA対応)
個人データを外部モデルへ送信する場合は必ず法務確認を行い、同意フローと保持方針を定めます。
- 明示的同意の取得フローを設計し、ログで同意を証跡化する。
- データ保持期間(例: 30〜90日)とアクセス制御を定義する。
- LLMプロバイダとのDPA(Data Processing Agreement)や利用規約を確認し、必要に応じて契約を締結する。リーガルレビューを必須化してください。
デプロイとスケーリング
稼働形態は要件に応じて選びます。コストと可用性のバランスを考慮してください。
サーバレス vs コンテナ / Kubernetes の比較
次表は選定の簡易比較です。
| 特性 | サーバレス (Lambda等) | コンテナ / Kubernetes |
|---|---|---|
| 導入速度 | 高い | 中〜低 |
| 長時間処理 | 向かない(タイムアウト) | 向く |
| 運用コスト | 小〜中(短時間負荷) | 高め(常時稼働) |
| スケール柔軟性 | 自動スケール | オートスケール可、制御性高 |
長時間処理やワーカーはコンテナ/Kubernetesや専用ワーカーで運用することを推奨します。
CI/CD とシークレット伝播
- GitHub Actions等でテスト→ビルド→デプロイを自動化する。
- SecretsはActions Secretsやパラメータストア/Vault経由で環境に注入し、ビルドログには出さない。
- プロンプトや権限に関する変更はプルリクエストでコードレビューを義務化する。
スケーリングとコスト対策
- キャッシュ(最近の回答、埋め込み)でAPI呼び出しを削減。
- 低コストモデルで前処理し、必要時に高性能モデルへフォールバックする。
- ユーザー別クォータやレート制御で予算制御を行う。
監視・ロギング・SLO 設計
運用での信頼性を維持するための監視指標と目標値例、ログフォーマットを示します。
推奨メトリクスとログフォーマット
サービス監視に必要な主要メトリクスとログ項目を示します。
- 必須メトリクス: リクエスト数、エラー率(4xx/5xx)、ack成功率、LLM呼び出し回数、トークン消費量、ワーカーキュー長、平均/パーセンタイルレイテンシ。
- ログフォーマット(JSON推奨例): timestamp, service, env, trace_id, level, user_id, channel_id, request_type, status, latency_ms, error_code, token_count
SLO/SLI の目標例とアラート閾値
以下は運用開始時のサンプル目標です。実際の要件に合わせて調整してください。
- Slackイベント ack 成功率: 99.9%(3秒以内にackを返す)
- LLM呼び出し成功率: 99%(再試行込み)
- LLMレスポンスレイテンシ: p95 ≤ 5s(キャッシュ・小モデル)、p95 ≤ 15s(フル生成)
- エラー率アラート: エラー率 > 1% が 5 分続く場合に通知
- キュー長アラート: ワーカーキュー長 > 100 が 10 分継続
ダッシュボード/アラート例
- ダッシュボード: リクエスト数、p50/p95/p99 レイテンシ、エラー率、トークン消費推移、コスト推移、キュー長を表示。
- インシデント通知: PagerDuty / Opsgenie / Slack の専用チャンネルへアラートを送る。アラートにはtrace_idを含める。
運用チェックリストとトラブルシューティング
運用初期に必ず確認する項目と、代表的な障害の対応を簡潔にまとめます。
運用開始チェックリスト(簡潔)
- アプリのスコープとインストール状況をレビューする
- Signing Secret / Bot Token の配置とアクセス制御を確認する
- ack の実装と非同期処理の動作確認を行う
- モデレーションとPIIマスキングを導入する
- SLO/SLI を定義し、監視ダッシュボードを作成する
- シークレットのVault/KMS管理とローテーション手順を確立する
- 法務による同意フローとDPA確認を完了する
代表的なトラブルと対処手順
- 認証エラー(401/403): Bot Token / Signing Secret のスペルや環境設定を確認。スコープ不足なら再インストール。
- イベント未到着: ngrok URLの更新確認、署名検証ログ、Event Subscriptionsの有効化を確認。
- ack忘れでタイムアウト: ハンドラ内で必ずackを呼ぶようコントラクト化する。
- 429(Rate Limit): Retry-Afterヘッダを尊重し、ジョブキューでレート制御を行う。緊急時は一時的にクォータを減らす。
- LLM応答遅延/失敗: 再試行・バックオフ、代替モデルやキャッシュの利用、ユーザーへの進行中メッセージを表示する。
参考資料と公式ドキュメント
設計やスコープ名、API仕様は頻繁に更新されます。必ず公式ドキュメントを直接参照してください。以下は主要な参照先です。
- Slack OAuth / 認証: https://api.slack.com/authentication/oauth-v2
- Slack スコープ一覧: https://api.slack.com/scopes
- Events API: https://api.slack.com/apis/connections/events-api
- Block Kit: https://api.slack.com/block-kit
- Bolt for JavaScript: https://github.com/slackapi/bolt-js
- Bolt for Python: https://github.com/slackapi/bolt-python
- Slack Rate Limits(公式): https://api.slack.com/docs/rate-limits
- ngrok(ローカルトンネル): https://ngrok.com
- OpenAI Moderation(例): https://platform.openai.com/docs/guides/moderation
- LangChain(RAG等のライブラリ): https://github.com/langchain-ai/langchain
- Pinecone(ベクタDB): https://www.pinecone.io
- HashiCorp Vault: https://www.vaultproject.io
- AWS KMS / Secrets Manager: https://aws.amazon.com/kms/ , https://aws.amazon.com/secrets-manager/
各プロバイダの利用規約やDPAの締結状況は必ず確認してください。
まとめ
最小構成で早く検証し、運用要件を満たすために段階的に拡張することが重要です。まずは公式Boltサンプルをベースにローカルで動作確認を行い、非同期ワーカー・プロキシ・モデレーションを順次導入してください。
- まずは Slash → Modal → 非同期ワーカー → LLM → 投稿 の最小構成を動かす。
- ack の即時応答とジョブキュー化で信頼性を確保する。
- シークレットは Vault/KMS、ログはPII除去の上で構造化して出力する。
- モデレーションと同意フローを実装し、法務チェックを必須化する。
- 監視(SLO/SLI)、レート制御、コスト管理を導入して本番運用へ移行する。
上記を踏まえ、まずは上で示したBolt公式リポジトリと手順でローカル検証を行ってください。必要であれば、具体的な環境(Node/Python)やクラウド先(AWS/GCP/Azure)に合わせた設定例も提供します。