1. 主要ページへ移動
  2. メニューへ移動
  3. ページ下へ移動

QES ブログ

記事公開日

AWS-SAA学習サポートAI Agentを作ってみた

  • このエントリーをはてなブックマークに追加

こんにちは!DXソリューション営業本部の菊池です。

7月にAWSグループへ配属されてから、AWS-SAA(AWS Certified Solutions Architect - Associate)試験受験に向け、Gemini等の汎用的なAIを使用しながら、学習を進めていました。
しかし、根拠が不明確な情報や、誤った内容を生成することがあり、学習効率が悪いと感じていました。
そこで、信頼できるデータソースからAWS-SAAの問題を作成してくれるAI Agentがあれば、学習効率向上につながると考え、「SAA学習サポートAI Agent」を作成してみました!

SAAサポートAI Agent実装

それでは、SAAサポートAI Agentについて、解説していきます。
今回実装したAIは、ツール判断用と回答生成用の3つで、各AIの役割は以下の表の通りです。

エージェント名 SDK 役割
intent_agent
strands ユーザーの質問からkb,mcpどちらのエージェントを起動するか判断する
kb_agent boto3 ナレッジベースで検索をかけ回答を生成する。
mcp_agent strands mcpサーバーを介しAWS公式ドキュメントから回答を生成する。

処理の流れ

SAAサポートAI Agentは、下図の流れで質問に回答します。



1.ユーザーの質問を受け付けます。
2.ユーザーの質問から、使用するツールを使用ツール選択用AIに選択してもらいます。
3.選択したツールを持つAIを起動します。
4.MCP、もしくはナレッジベースで検索をかけ、回答を生成します。

細かな処理については、コードの説明で補足します。

ファイル構成

実装したAI Agentは、環境変数を設定する .env と、メインの処理を記述した Agent.py の2つのファイルで定義しています。
.envに記述した環境変数は以下の通りです。

環境変数名
概要(今回使用した値)
KNOWLEDGE_BASE_ID
使用するナレッジベースのID
AWS_REGION
使用するAWSリージョン(us-west-2)
MODEL_ID
使用するAIモデル(Claude 3.5 Sonnet)

Agent.py

Agent.pyのコードは以下の通りとなります。

import os
import boto3
from dotenv import load_dotenv
from strands import Agent
from strands.tools.mcp import MCPClient
from mcp import stdio_client, StdioServerParameters

# .envから環境変数を読み込む
load_dotenv()

# 環境変数を変数に代入
KNOWLEDGE_BASE_ID = os.environ.get("KNOWLEDGE_BASE_ID")
AWS_REGION = os.environ.get("AWS_REGION")
MODEL_ID = os.environ.get("MODEL_ID")

# 意図判断用AIのシステムプロンプト
INTENT_SYSTEM_PROMPT = """ユーザーの質問を分析し、
             以下のどちらのカテゴリに分類されるか判断してください。
                     回答は必ず "KNOWLEDGE_BASE" または "TOOL" の
             どちらか一方の単語だけにしてください。
                     "KNOWLEDGE_BASE": AWS認定に関する事実や情報を問う質問の場合のみ
             使用してください。
                     "TOOL": サービスの詳細な情報や、
             何かを思考し生成する必要がある質問の場合。
                     """

# KnowledgeBaseを使用するAIのシステムプロンプト
KB_SYSTEM_PROMPT = """以下のコンテキスト情報のみを厳密に参照して、
          ユーザーの質問に回答してください。
                 必ず日本語で回答してください。
                 コンテキストに含まれない情報は、絶対に回答に含めてはいけません。
                 コンテキストから予想される、情報及び解説を含めずに回答してください。
                 ---
                 コンテキスト:
                 $search_results$
                 ---
                 ユーザーの質問: $user_input$
                 """

# MCPサーバーを使用するAIのシステムプロンプト
MCP_SYSTEM_PROMPT = """あなたは優秀なAWS学習サポートです。
                  ユーザーの質問に対して、MCPサーバーを介して、
                  読み込んだドキュメントに記載されている内容のみを出力してください。
                  必ず日本語で出力してください。
                  """


# 使用ツール選択用関数
def get_intent(user_question: str) -> str:

    # 使用ツール判別用AIの作成
    intent_agent = Agent(model=MODEL_ID, system_prompt=INTENT_SYSTEM_PROMPT)

    # 作成したAIを使用し回答を取得
    intent_response = intent_agent(user_question)

    # 応答を成形し、ツールを返す
    intent = str(intent_response).strip().upper()
    if "KNOWLEDGE_BASE" in intent:
        return "KNOWLEDGE_BASE"
    else:
        return "TOOL"


try:
    user_question = input("質問内容を入力してください:")

    # 定義した関数から使うツールを指定
    intent = get_intent(user_question)
    print(f"--- 司令塔の判断: {intent} ---")

    # 使用するデータソースごとの処理
    # ナレッジベースを使用する場合
    if intent == "KNOWLEDGE_BASE":

        print(f"▶️ ナレッジベースをboto3で検索し、回答を生成しています...")

        kb_agent = boto3.client(
            "bedrock-agent-runtime", region_name=AWS_REGION
        )

        # ナレッジベースから検索を行う
        response = kb_agent.retrieve_and_generate(
            input={"text": user_question},
            retrieveAndGenerateConfiguration={
                "type": "KNOWLEDGE_BASE",
                "knowledgeBaseConfiguration": {
                    "knowledgeBaseId": KNOWLEDGE_BASE_ID,
                    "modelArn": f"arn:aws:bedrock:{AWS_REGION}::foundation-
          model/{MODEL_ID}",
                    "generationConfiguration": {
                        "promptTemplate": {"textPromptTemplate": KB_SYSTEM_PROMPT}
                    },
                },
            },
        )

        # レスポンスから回答部分を成形して表示
        final_answer = response["output"]["text"]
        print("\n--- AIの回答 ---\n" + final_answer)

    # MCPサーバーを使用する場合
    else:
        # MCPツール処理:MCPサーバーを起動し、ツールを備えたAgentで処理する
        print("▶️ MCPサーバーを起動し、ツールエージェントで処理します...")

        # MCPサーバーの設定
        mcp = MCPClient(
            lambda: stdio_client(
                StdioServerParameters(
                    # 実行コマンドの指定
                    command="uvx",
                    # AWS公式のtoolを指定
                    args=[
                        "--from",
                        "awslabs.aws-documentation-mcp-server@latest",
                        "awslabs.aws-documentation-mcp-server.exe",
                    ],
                )
            )
        )
        # MCPサーバー起動と回答生成
        with mcp:
            # AI Agentの設定
            mcp_agent = Agent(
                # AIモデルを指定
                model=MODEL_ID,
                # MCPツールを指定
                tools=mcp.list_tools_sync(),
                # システムプロンプト設定
                system_prompt=MCP_SYSTEM_PROMPT,
            )
            # 回答を生成
            mcp_agent(user_question)

# エラー処理
except Exception as e:
    print(f"\n❌ 処理中にエラーが発生しました: {e}")

else:
    print("\n\n✅ 処理が完了しました。")

システムプロンプトの設定

環境変数を読み込んだ後、システムプロンプトの設定を行っています。
各システムプロンプトの設定対象は、以下の表の通りです。

変数名
設定対象
INTENT_SYSTEM_PROMPT
intent_agent
KB_SYSTEM_PROMPT
kb_agent
MCP_SYSTEM_PROMPT
mcp_agent

INTENT_SYSTEM_PROMPT:ツールの用途を明確にするため、事実のみを知りたい場合と、それ以外の2種類の回答に絞っています。また、後に回答を戻り値として使うため、回答を"KNOWLEDGE_BASE","TOOL"に固定しています。

KB_SYSTEM_PROMPT:ナレッジベースで検索をかけ得た結果(search_result)をコンテキストとしてプロンプトに組み込み、それ以外の情報は回答に含まないように制限しています。

MCP_SYSTEM_PROMPT:MCPサーバーを介し、公式ドキュメントを検索して得た内容のみを出力するように、制限しています。

def get_intent

# 質問の意図判別用AIの関数
def get_intent(user_question: str) -> str:

    # 意図判別用AIの作成
    intent_agent = Agent(model=MODEL_ID, system_prompt=INTENT_SYSTEM_PROMPT)

    # 作成したAIを使用し回答を取得
    intent_response = intent_agent(user_question)

    # 応答を成形し、ツール名を返す
    intent = str(intent_response).strip().upper()
    if "KNOWLEDGE_BASE" in intent:
        return "KNOWLEDGE_BASE"
    else:
        return "TOOL"

ユーザーの質問に対して、AIが使用するツールを選択し、戻り値として返す関数を定義しています。

質問の受付

try:
    user_question = input("質問内容を入力してください:")

    # 定義した関数から使うツールを指定
    intent = get_intent(user_question)
    print(f"--- 司令塔の判断: {intent} ---")

ここから、メインの処理に入ります。
ユーザーの入力を先ほど定義したget_intentで処理し、使用するツールを選択しています。

kb_agent

 if intent == "KNOWLEDGE_BASE":

        print(f"▶️ ナレッジベースをboto3で検索し、回答を生成しています...")

        kb_agent = boto3.client("bedrock-agent-runtime", region_name=AWS_REGION)

        # ナレッジベースから検索を行い、結果から回答生成
        response = kb_agent.retrieve_and_generate(
            input={"text": user_question},
            retrieveAndGenerateConfiguration={
                "type": "KNOWLEDGE_BASE",
                "knowledgeBaseConfiguration": {
                    "knowledgeBaseId": KNOWLEDGE_BASE_ID,
                    "modelArn": f"arn:aws:bedrock:{AWS_REGION}::foundation-
          model/{MODEL_ID}",
                    "generationConfiguration": {
                        "promptTemplate": {"textPromptTemplate": KB_SYSTEM_PROMPT}
                    },
                },
            },
        )

        # レスポンスから回答部分を整形して表示
        final_answer = response["output"]["text"]
        print("\n--- AIの回答 ---\n" + final_answer)

ナレッジベースを選択した場合の処理を行っています。
まずboto3を使用して、Bedrock Agent Runtimeに接続します。
次にretrieve_and_generateで、検索と回答の生成を行い、整形された最終的な回答をfinal_answerに格納します。

mcp_agent

else:
        # MCPツール処理:MCPサーバーを起動し、ツールを備えたAgentで処理する
        print("▶️ MCPサーバーを起動し、ツールエージェントで処理します...")

        # MCPサーバーの設定
        mcp = MCPClient(
            lambda: stdio_client(
                StdioServerParameters(
                    # 実行コマンドの指定
                    command="uvx",
                    # AWS公式のtoolを指定
                    args=[
                        "--from",
                        "awslabs.aws-documentation-mcp-server@latest",
                        "awslabs.aws-documentation-mcp-server.exe",
                    ],
                )
            )
        )
        # MCPサーバー起動と回答生成
        with mcp:
            # AI Agentの設定
            mcp_agent = Agent(
                # AIモデルを指定
                model=MODEL_ID,
                # MCPツールを指定
                tools=mcp.list_tools_sync(),
                # システムプロンプト設定
                system_prompt=MCP_SYSTEM_PROMPT,
            )
            # 回答を生成
            mcp_agent(user_question)

mcpを選択した場合の処理を行っています。
はじめに、MCPClient()で、MCPサーバーの起動設定を行っています。
args=[]内のawslabs.....は、AWS公式から提供されている、AWS公式ドキュメント検索用のツールを指定しています。
最後に、mcp_agentを定義して、回答を生成しています。

サポートAIによる回答

kb_agentの回答

質問内容を入力してください:SAA試験の採点について教えて
KNOWLEDGE_BASE--- 司令塔の判断: KNOWLEDGE_BASE ---
▶️ ナレッジベースをboto3で検索し、回答を生成しています...

--- AIの回答 ---
SAA試験の採点について、以下の情報をお伝えできます:
1. 試験は合否判定方式です。
2. 結果は100~1,000の換算スコアで示されます。
3. 合格スコアは720点です。
4. スコアレポートには、各セクションの成績を示す分類表が含まれる場合がありますが、セクションごとの合否ラインは設定されていません。
5. 試験には採点対象外の設問が15問含まれており、これらはスコアに影響しません。ただし、どの設問が採点対象外かは受験者にはわかりません。
6. 未解答の設問は不正解とみなされます。
7. 推測による解答にペナルティはありません。

✅ 処理が完了しました。

「SAA試験の採点について教えて」という質問に対して、エージェントは適切にナレッジベースを選択しました。
回答本文については、公式のSAA試験ガイドと比較して、間違いの無い文章が出力されました。
回答の出力までにかかった時間は、約15秒でした。

mcp_agentの回答

質問内容を入力してください:SAA試験範囲でストレージについて問題を1問作って
TOOL--- 司令塔の判断: TOOL ---
▶️ MCPサーバーを起動し、ツールエージェントで処理します...

問題:
ある企業が、AWSクラウド上で高性能かつ耐久性のあるブロックストレージソリューションを探しています。
このソリューションは、Amazon EC2インスタンスと共に使用され、アプリケーションの重要なデータを保存する必要があります。
また、特定のアベイラビリティーゾーン内での高可用性が 求められています。 この要件を最もよく満たすAWSのストレージサービスはどれですか? A) Amazon S3 B) Amazon EFS C) Amazon EBS D) AWS Storage Gateway 正解:C) Amazon EBS 解説: Amazon Elastic Block Store(Amazon EBS)は、この要件を最もよく満たすソリューションです。以下の理由から、Amazon EBSが最適な選択となり ます: 1. 永続的なブロックストレージ:EBSは、EC2インスタンスで使用するための永続的なブロックストレージボリュームを提供します。 2. 高性能:EBSは、ワークロードを実行するために必要な一貫した低レイテンシのパフォーマンスを提供します。 3. 耐久性と高可用性:各EBSボリュームは、コンポーネント障害から保護するために、そのアベイラビリティーゾーン内で自動的に複製されます。
これにより、高い耐久性と可用性が確保されます。 4. EC2との統合:EBSはEC2インスタンスと直接統合されており、アプリケーションの重要なデータを保存するのに適しています。 5. スケーラビリティ:EBSを使用すると、数分以内に使用量を上下にスケールできます。 他の選択肢が適切でない理由: A) Amazon S3:オブジェクトストレージサービスであり、ブロックストレージではありません。EC2インスタンスに直接アタッチすることはできません。 B) Amazon EFS:Linux ベースのワークロード向けのファイルシステムであり、ブロックストレージではありません。
  複数のアベイラビリティーゾーンにまたがるため、単一のアベイラビリティーゾーン内での高可用性という要件を満たしません。 D) AWS Storage Gateway:オンプレミスのアプリケーションとAWSのストレージサービスを接続するためのハイブリッドクラウドストレージサービスであり、
  この特定のユースケースには適していません。 したがって、Amazon EBSが要件を最もよく満たすソリューションとなります。 ✅ 処理が完了しました。

「SAA試験範囲内でストレージについて問題を1問作って」という質問に対しては、エージェントは適切にMCPツールを選択しました。
依頼したのは問題の生成だけでしたが、解説まで出力されました。
内容もAWS公式ドキュメントを引用した、正確なものが出力されました。
回答の出力までにかかった時間は、約30秒でした。

使用してみて

使用してみて、実際の試験対策に活用できるAI Agentだと感じました。
冒頭で挙げた問題である、「根拠が不明確な情報」や「誤った回答」を生成してしまう点は、信頼できるデータソースのみを用いることで改善されました。
これにより、ユーザーがAIの回答を信頼し、自ら検索する手間を減らし、効率的に学習を進めることができます。
私自身、SAAの受験を控えているので、試験対策の中で活用していきたいです。

まとめ

今回はSAA試験サポートAI Agentを作ってみました。

AI Agentに、ナレッジベースとMCPサーバーを持たせることで、事実だけを簡潔に知りたい場合と関連情報を広く集めたい場合など、ユーザーの目的に応じた最適な回答を提供できます。
また、プロンプトを厳格に定義することで、ツールの選択ミスやハルシネーションを抑制し、回答の精度を大幅に向上させられます。
この、マルチツール+厳格なプロンプトという手法は、社内の問い合わせ対応やお客様サポートなど、実践的なAIの機能向上につながると考えています。

もし「このサービスについて知りたい」「AWS環境の構築、移行」などのリクエストがございましたら、弊社お問合せフォームまでお気軽にご連絡ください。 のちほど当ブログにてご紹介させていただくか、複雑な内容に関するお問い合わせの内容の場合には直接営業からご連絡を差し上げます。 また、よろしければ以下のリンクもご覧ください!
<QES関連ソリューション/ブログ>

<QESが参画しているAWSのセキュリティ推進コンソーシアムがホワイトペーパーを公開しました>

※Amazon Web Services、”Powered by Amazon Web Services”ロゴ、およびブログで使用されるその他のAWS商標は、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。

  • このエントリーをはてなブックマークに追加

お問い合わせ

Contact

ご質問やご相談、サービスに関する詳細など、何でもお気軽にご連絡ください。下記のお問い合わせフォームよりお気軽に送信ください。

お問い合わせ

資料ダウンロード

Download

当社のサービスに関する詳細情報を掲載した資料を、下記のページよりダウンロードいただけます。より深く理解していただける内容となっております。ぜひご活用ください。

資料ダウンロード