🐦

SlackにAWSで社内文書RAGボットを作った話【全手順まとめ】

に公開

何を作ったか

社内に規定やマニュアルが増えてくると、「あの規定、どこに書いてあったか思い出せない」となりがち。探すより人に聞いたほうが早い、でも毎回聞くのは聞く側も聞かれる側も地味に手間。

そこで作ったのが、Slackでボットにメンションするだけで社内ドキュメントを検索し、自然言語で答えてくれるボット

  • 質問はSlackのメンション(@kb-bot 出張の精算期限を教えて のような形)で送るだけ
  • 裏側で AWS Bedrock Knowledge Base が関連文書を検索し、AI が文脈に沿った回答を生成
  • 回答には参照したドキュメントのファイル名がボタンとして付く(生のURLは出さない)
  • 同じスレッド内なら会話の続きとして追加質問もできる

検証として、新規のAWSアカウントと新規のSlackワークスペースだけでゼロから構築。実際にSlack上で質問→回答のやり取りが成立するところまで確認した。

主な構成要素はこのあたり。

  • AWS Bedrock — 回答生成と埋め込み(Nova 2 Lite / Cohere Embed v3)
  • Bedrock Knowledge Base — RAG の検索基盤
  • AWS Lambda(Python 3.12) — 処理本体を2関数に分離
  • Slack Events API — メンション受信(app_mention

ポイントは、Lambdaの実行環境に追加の依存ライブラリを一切持たせていないこと。Slackの署名検証は HMAC-SHA256 で書けるので、Python 標準ライブラリと boto3 だけで動く。

システム構成

本記事では社内文書への適用例を示しますが、製品マニュアル・FAQ・技術仕様書など任意のドキュメントコーパスに同じ構成が使えます。

システム構成図
Slack × AWS Bedrock 社内文書RAGシステム 構成図

全体はこんな流れ。

[Slack 利用者]
     │ メンションで質問

[API Gateway]


[Lambda: bot-handler] ── 署名検証・認可・3秒以内に即時応答
     │ 非同期 invoke(fire-and-forget)

[Lambda: rag-processor] ── 検索 + 回答生成

     ├──▶ [Bedrock Knowledge Base] ──▶ [S3 Vectors] / [S3:文書原本]
     ├──▶ [DynamoDB]:会話セッション


[Slack スレッドに回答 + 参照ボタン]

SlackのEvents APIは3秒以内に応答しないとリトライが走る。なので「受信して即返事する Lambda」と「検索・生成という重い処理をする Lambda」を分け、前者が後者を非同期で呼ぶ2段構成にした。

動作デモ

クラウドサービス採用可否について質問すると、参照ドキュメント4件とともに回答が返ってきた
▲ 質問に対して参照ドキュメントを明示しながら回答。引用元を確認できる。

RAGが参照したDS-110解説書(デジタル社会推進実践ガイドブック)のPDF
▲ ボットが参照したドキュメントの実物。社内文書をそのままS3に格納してRAG化している。

前の質問を受けて「そのリストにないサービスは?」と連続質問。文脈を引き継いで回答している
▲ スレッド内の連続質問にも対応。DynamoDBで会話履歴を管理し、文脈を保持している。

実際の画面では、スレッドに回答本文が返り、その下に参照元ドキュメントのファイル名がボタンとして並ぶ。ボタンにはファイル名だけを出し、署名付きURLそのものは画面に出さない設計。(実機スクリーンショットは機微情報のマスク処理のうえで後日追加)

設計のポイント

詳しい実装やコード全体は有料本に回すとして、再現するうえで効いた判断を4つ。

1. 動くものを複製してから余計な依存を削る

ゼロから書き直すのではなく、実機検証済みのロジック(署名検証・セッション管理・プロンプト設計)を複製。そこから対象外のプラットフォーム連携(Azure Bot Service・Entra ID・SharePoint など)を削るやり方。検証済みの部分を変えないので、再検証のコストが小さくて済む。

2. アカウント固有値はコードに埋めず環境変数を必須化

Knowledge BaseのIDやモデル ARN といったアカウント固有の値は、コードのデフォルト値として持たせない。未設定なら起動時にわざと落とす。「前の環境の値が紛れ込んだまま動く」事故を構造で防ぐ狙い。

3. Lambda に追加ライブラリを持たせない

最初の構築で、署名検証ライブラリの pip install が無言で失敗し、同梱されないまま関数が起動不能になった。Slackの署名検証は標準ライブラリだけで記述できるため、外部ライブラリを全廃。「ビルド成果物が静かに壊れる」リスクごと消した。

4. 参照リンクは「ボタン」で渡す

署名付きURLは1本で1,400字近くになることがあり、Slackのテキストリンク記法だと途中から生テキストになって崩れた。リンクを構造化レイアウト(ボタン)で渡す形に変えて、長さに関係なく確実にリンク化した。

この手の「実機でしか出ない崩れ」への対処については、本編のトラブルシューティングにて詳しく解説しています。

詳細・ソースコードの入手

有料本(Zenn)

「Slackに聞いたら社内文書から答えてくれるボットをAWSで作った話」 ¥500
https://zenn.dev/kawasemi_jp/books/aws-bedrock-slack-rag-book

設計の全詳細・環境構築手順・つまずきポイント・拡張方法を収録。

ソースコード等の配布について(検討中)

本構築で使用した各種設定スクリプトや設計ドキュメント一式については、準備が整い次第、外部プラットフォーム等での配布も検討しております(価格や時期は未定です)。

Discussion