本記事は
AWSアワード受賞者祭り
1日目の記事です。
✨🏆
告知記事
▶▶ 本記事 ▶▶
2日目
🏆✨
こんにちは、そろそろ人間ドックの日が近づいているので運動する準備を始めている志水です。シアトル帰りで英語の勉強の準備も今始めてます。
はじめに
2025年のAWS受賞者が発表され、NRIネットコムからも多くの方が受賞されて感慨深いですね。私も引き続きAmbassadorとして継続できて安心しています。
まずは、今年のNRIネットコムのAll Cert取得者が何人だったか聞いてみましょう。
なんと今年は21名も全冠取得者がいるようですね!これだけで252個の資格が取得されているというのはすごいです。
ということで、今回はこんな感じでチャットでAWS受賞者の分析ができるエージェントを作ってみた話をしようと思います。
何を作ったか
今回作ったのは、AWS受賞者データをチャットで分析できるエージェントです。Strands Agentsを使って、自然言語で質問すると、AWS受賞者のデータを分析してくれるシステムを作りました。
このエージェントを簡単に使えるように、StreamlitでUIも作りました。ブラウザでチャットのように質問を投げかけると、リアルタイムで分析結果が返ってくる仕組みです。
でも、この分析エージェントを動かすためには、AWS受賞者のデータをCSV形式でAmazon S3に配置する必要がありました。そこで、HTMLからCSVへの変換エージェントも別途作りました。
この変換エージェントを事前に実行することで、7年分(2019〜2025年)のAWS受賞者データを自動抽出して、S3に配置できるようになりました。データの品質を保つための検証システムも組み込んで、重複データや欠損データ、フォーマットの不統一などを自動でチェックしてくれる仕組みです。
処理したデータは2019年から2025年までの7年間で、4つのプログラム(AWS Ambassadors、AWS Top Engineers、AWS Jr. Champions、All AWS Certifications Engineers)を対象に、2,000名以上の受賞者データを扱いました。
システムアーキテクチャ
システムの全体構成は以下のようになっています。まず、変換エージェントが事前にAWS受賞ブログからHTMLを取得してCSVに変換し、S3に配置します。次に、ユーザーが質問を投げかけると、分析エージェントがS3のCSVデータをAWS Glue Data Catalogのメタデータを参照してAmazon Athenaでクエリし、分析を行います。
このアーキテクチャにより、サーバーレスでスケーラブルな分析システムを実現できました。S3にデータを保存し、AthenaでSQLクエリを実行することで、年度別・受賞タイプ別の柔軟な分析が可能になります。
7年分のデータを統合するまでに起きたこと
実際に作ってみると、データの泥沼にハマってしまいました。まず、HTMLの構造が年度によって微妙に異なります。テーブルの構造が変わっているため、同じ抽出ロジックでは対応できませんでした。これはエージェント側にテーブル構成を認識させて抽出用スクリプトを適宜作成してもらうことで対処しました。
さらに、例外データとの格闘もありました。「他2名」とか「会社名不明」みたいな特殊なケースが結構あって、これらをどう処理するかで頭を悩ませました。例えば、2022年のデータでは会社名が空になっているケースがありました。これを「その他」として統一するルールを作ってエージェント側に対応してもらいました。
期待値と実際の値の微妙なズレもありました。例えば、253名を期待していたのに対し、実際は252名+1名という形で1名分一致しませんでした。これは「他○名」の表現が実際の人数と一致しないことが原因で、ここに関しては特にルール化はせずにエージェント本来の賢さで突破していました。やはりClaude4は賢いですね。
あと、curl
とhttp_request
ツールの処理方式の違いも発見しました。http_request
ツールだと、実行しているディレクトリに一時的にファイルが保存されて、そこからmv
コマンドやファイル書き込みで目的のディレクトリに移動する必要がありました。でも、curl
コマンドなら出力先を直接指定できるので、一撃で目的のディレクトリに保存できちゃいます。この違いで処理がずいぶん効率化されて、その分リクエスト数も少なくなり、コストも抑えられました。この方式もルール化してエージェントにcurl
で出力先を指定するようにしてもらいました。
データ抽出の過程で、様々な品質問題にも直面しました。重複データの検出や、会社名の表記ゆれ(「株式会社○○」vs「○○株式会社」)、文字エンコーディングの問題など、予想以上に細かい調整が必要でしたが、これもまたエージェントでいい感じにやってくれました。
データ補正に関するルール
今回のプロジェクトを通じて、データ抽出・検証のためのルール体系を構築しました。これらのルールは、エージェントがHTMLからCSVを抽出する際の品質保証として活用されています。
エージェントでの活用方法
エージェントは、HTMLを解析する際に以下のルールを自動適用します。
- 数値チェック: 期待値と実際のデータ行数を照合し、不一致があれば警告
- 重複チェック: 同一レコードの重複を検出して自動除去
- フィールド数統一: 全行のカラム数が一致するかを確認
- 文字エンコーディング: UTF-8での正常な文字化を保証
最終的に、これらのルールをdata-validation-rules.mdとして文書化し、エージェントが参照できる形で標準化しました。そのルールの内容自体もCSVの作成過程で詰まったりするとアップデートするようにして、エージェントにルールの調整もある程度お任せしていました。
エージェント設計の試行錯誤
エージェントの設計も試行錯誤の連続でした。最初はシンプルに作ろうと思ったんですが、どんどん複雑になっていきました。
自然言語質問の解釈
最初の課題は、ユーザーの自然言語質問を正確に解釈することでした。「NRIネットコムのアンバサダー受賞者数の推移を教えて」という質問から、適切なSQLクエリを生成する必要がありました。
これに対して、企業名正規化マッピングを作りました。具体的には、企業名の表記ゆれを解決するための辞書ファイルを作成し、エージェントに参照させることで、「NRI」「ネットコム」→「NRIネットコム株式会社」のように、様々な表記を正規名に自動変換する仕組みを実装しました。
データスキーマの複雑さ
年度によってデータ構造が異なることが大きな課題でした。2019年のAmbassadorは「会社名、お名前」の2カラムですが、2025年は「会社名、パートナーパス、お名前、就任年度、タイプ」の5カラムになっています。
これに対して、年度別個別テーブルと統合ビューの2段階アプローチを採用しました。まず年度別にテーブルを作成し、そこから統合ビューを作って横断分析を可能にしました。
システムプロンプトの進化
最初は簡単なプロンプトでしたが、どんどん詳細になっていきました。最終的には425行のシステムプロンプトになり、自然言語質問の解釈、データスキーマ、Athenaテーブル戦略、エラーハンドリングなど、様々な要素を含むようになりました。
結果的に何ができたか
苦労の末、7年分のデータを統合して長期トレンド分析ができるようになりました。以下が分析画面です。
これで受賞者数の変化を時系列で見ることができます。
all certの人数が多少異なるのは、名前非公開の方々がCSVとして抽出しづらく、データに含まれていないためです。分析結果を見ると、ネットコムの割合や増加量などについても興味深い洞察が得られました。特に2020年のネットコムの割合は驚くほど高いですね。一方で、今年は人数の増減が少なく伸び悩んでいるようです。皆さんの応援お待ちしております。
また、プログラム間の相関関係も分析できるようになりました。例えば、AmbassadorとTop Engineerを両方受賞している人の割合などです。
このように、自然言語で質問するだけで様々な分析が可能になりました。
他にも企業別の受賞者数ランキングや、All CertificationsやTop Engineerの継続年数なども分析できるようになりました。これらの分析結果も同様に、自然言語で質問するだけで取得できます。
さいごに
今回はAIエージェントのユースケースとしてAWS受賞者分析のエージェントを作ってみました。
Strands Agentsを同僚に説明した時に、「AIエージェントを作るってどういうこと?」と言われて確かに想像つかないなぁと思ったことがきっかけで、たまたま良さそうな題材を思いついたので作ってみました。
作ってみると、HTMLから分析可能なデータに変換するまでのデータクレンジングが非常に大変で、正しくデータを抽出できるようになるまでに時間がかかりました。また、分析時も想定通りに動作しないエージェントに対して、プロンプトを様々な方法で調整していく作業も困難でした。
今後は、今回学んだエージェント設計のノウハウを活かして、他のデータ分析プロジェクトにも応用していきたいと思います。特に、HTMLからのデータ抽出とAIエージェントの組み合わせは、様々な場面で活用できそうです。
最後に、今年のAWSアワードウィークで、あと何名の記事が後から続くか確認して終わりましょう。
ということで、あと23名の強者達のブログが毎日出てくるのでお楽しみに! では!