アジャイル事業部の佐藤です。
先日社内イベントとして「AWS×生成AIハッカソン」がもくもく会メンバー主導で開催されました。

オンライン、オフラインのハイブリッド開催で、今回も会場内の音響やカメラ映像などの配信回りを担当しています!

ハッカソンというものに憧れがありつつも普段インフラの運用保守をメインであつかているため、開発をしたことが無いわたし…。
社内かつ開発初心者向け、そして生成AIということもあり、今回はせっかくなので参加者としても参戦しました!

AWS×生成AIハッカソン:当日の流れ

生成AI基盤 製作開始

まずはみのるんさんの記事を参考に生成AIの基盤部分を作成します。

  • ナレッジベース(モデルはCohere社:Embed Multilingualを利用)
  • S3バケット(社内文書等の保存に利用)
  • ベースモデルの有効化
  • CloudShell上にPythonアプリの構築

トラブル発生

ハッカソンの最中に3つのトラブルが発生しました。トラブルシューティングが大好きなわたしにはたまりません。
講師のこまきち先生も真剣な面持ちです。

トラブルの内容は以下でした。

【CloudShell】

  • CloudShellの同時起動の上限に到達し、CloudShellが起動出来ない参加者が続出
  • 構築したPythonアプリがデモタイミングで動作しなくなる

原因は「CloudShellの機能上限」「セッション切れ」が影響していました。

- 同時シェル : アカウント AWS リージョン ごとに 10 個のシェルを同時に実行できます。
- AWS CloudShell はインタラクティブなシェル環境です。キーボードまたはポインタを使用して 20~30 分間操作しない場合、シェルセッションは終了します。実行中のプロセスは、操作数としてカウントされません。
引用:Service quotas and restrictions for AWS CloudShell

今回のハッカソンでは、1つのAWSアカウントで同じリージョンのCloudShellを利用していたため、同時実行数の上限に引っかかりました。
ハッカソン中はCloudShellを各チーム一人が起動など、閉じれる人は閉じて利用者を制限する方針でしのぎました。

【ナレッジベース for Bedrock】

  • S3の同期が出来ない
  • Pythonアプリから質問を行うが回答がValidationErrorの返答となる

エラーはこちら

ValidationError:
1 validation error for AmazonKnowledgeBasesRetriever root Could not load credentials to authenticate with AWS client. 
Please check that credentials in the specified profile name are valid. (type=value_error)

原因は「利用するモデルが有効化されていない」点でした。

利用出来る人と出来ない人が混在していたため原因特定に時間がかかりましたが、原因が分かるととても単純なものでした。
手順通りにちゃんとやらない。ダメ、絶対。

ハッカソン内でアイディア出しや実装の時間は削れてしまいましたが、全員でどこが原因だ??と、仕事で関係無いところでトラブルシューティングのディスカッションが出来たのはある意味貴重な経験です。

アイディア出しを形にする

わたしのチームでは「ランチで人数を決めて日付は決めずに空いているお店を探せるツール」を目標としました。

ランチ情報を収集する

今回は2024/10月現在ベータ機能である「ナレッジベース:Web Crawler」機能を利用しました。

Web Crawler は、シード から始まるHTMLページに接続してクロールしURL、同じ上位のプライマリドメインとパスのすべての子リンクをトラバースします。
サポートされているドキュメントを参照するHTMLページがある場合、ウェブクローラーは、これらのドキュメントが同じ上位のプライマリドメイン内にあるかどうかにかかわらず、それらのドキュメントを取得します。
引用:Amazon Bedrock ナレッジベースのウェブページをクロールする

全情報を収集しようとすると時間がかかりすぎるため、本社近辺「虎ノ門」に絞った情報で収集を行いハッカソン時間中に同期を完了させました。

プロンプトテンプレートを定義する

ハッカソン時間内での作り込みは限界があります。
講師こまきちさんからもハッカソン開始時の解説で以下のお言葉を頂きました。

プロンプトはインフラに勝る。
インフラに色々追加しなくても、プロンプトだけで賢くなる。

みのるんさん記事のプロンプト箇所をいじっていただきました。
どこを修正すれば良いのだろう…と思ってメンバーの方が触っているところを覗くことが出来て色々勉強させていただきました。

# プロンプトのテンプレートを定義
prompt = ChatPromptTemplate.from_template("以下のcontextに基づいて回答してください: {context} / 質問: {question} / フォーマット: 「ジャンル:[ジャンル]\n人数:[人数]人\n時間帯:[時間帯]」 / 制約: 東京都虎ノ門周辺、具体的な店名を答える、住所を含む、電話番号を含む、予約枠も含む、虎ノ門ヒルズ森タワーからの徒歩の移動時間も含める、生ビール一杯の値段も含める、情報が不明な場合は架空の店舗を答えてください。架空の店舗であることは出力に含めないでください。")

上記のようなプロンプトを設定して、回答に関して制御を行うように調整しました。

いざ実行

それっぽい返答で情報を拾ってきてくれました!

ちなみに出力結果のお店を検索してみますが、一切見当たりません。ハルシネーション発生です。
もしかしてクロールした情報が同期出来てない?など懸念事項がありますが、時間切れです。

このあたりのチューニングのために情報精査やプロンプトに設定する情報を考えていく必要があるなど、さらに深堀りする箇所が見えました。

結果発表

各チームのアプリを確認してアイディアや実装状態を共有しました。
その後に結果発表まで行い、1位はちゃぷちゃぷトリオの「ばぶー!ぷろんぷと保育士さん」が見事優勝です!

保育士の先生が、難しい用語を全部赤ちゃん向けに砕いて教えてくれるという、疲れたエンジニアに癒やしを与えながらも役に立つアプリにプロンプトを改造されてました。

例)
コンテキストとは?
- コンテキストは、お話をする時のお約束みたいなものでちゅ📚

遊び心を取り入れられる余裕を感じられ、こういった視点も大事だなと他の皆さんの発表で新しい視点が見えるのも面白かったです。

最後に

今回のハッカソンのために、投票システムやチーム分けなどの管理画面を構築してくれたみちのすけさん
このシステムのおかげでチーム分けの管理、参加者用のIAMユーザの払い出し、アクセス先など画面上で完結したため、運営もスムーズに進めることができました。

ユーザ情報もSlackと紐づいているのでアイコン登録や名前も不要。今回限りの利用はもったいない代物を作ってくれました。
これの作り方も知りたいと思う今日このごろ。こういったイベントでの支援を思うとインフラ側だけではなく、開発も分かるようになりたいですね。
若手の皆さんが凄すぎて脱帽です。

そしていつもイベント開催を主導してくれる檜山さんから差し入れのドーナツも頂きました!

ハロウィン仕様kawaii。
差し入れのドーナツを食べている時に、一服含めてチーム内外でコミュニケーションがうまれました。

ハッカソンとしてチーム戦だったこともあり、手を止めてコミュニケーション出来る時間は貴重だなと感じました。
(イベントの休憩でひとりぼーっとしながら差し入れを食べること多数だったので少し新鮮でした。)