AI

PythonでAWS CDK経由のBedrock AgentをBright DataのSERP APIと併用

このガイドでは、PythonでAWS CDKを使用し、Bright DataのSERP APIを活用したリアルタイムWeb検索データ取得機能を備えたAWS Bedrockエージェントを構築する方法を示します。
3 分読
AWS CDK_SERP API blog image

この記事では以下の内容を確認できます:

  • AWS Cloud Development Kit (CDK) の概要と、クラウドインフラストラクチャの定義・デプロイへの活用方法
  • – AWS CDKで構築したAWS Bedrock AIエージェントに、Bright DataのSERP APIのようなAI対応ツールを通じてウェブ検索結果へのアクセス権を与えるべき理由
  • PythonでAWS CDKを使用し、SERP APIと統合されたAWS Bedrockエージェントを構築する方法。

それでは始めましょう!

AWS Cloud Development Kit(CDK)とは?

AWS Cloud Development Kit(AWS CDK)は、現代的なプログラミング言語を使用してクラウドインフラストラクチャをコードとして構築するためのオープンソースフレームワークです。TypeScript、Python、Java、C#、Goなどのプログラミング言語を使用して、AWSリソースをプロビジョニングし、AWS CloudFormation経由でアプリケーションをデプロイするために必要な機能を提供します。

AWS CDKを利用すれば、Amazon Bedrock向けAIエージェントもプログラムで構築できます。まさにこのチュートリアルで実現する内容です!

大規模言語モデルは、特定の時点までの知識しか反映していないデータセットで訓練されます。その結果、不正確な回答や幻覚的な回答を生成しがちです。これは最新情報を必要とするAIエージェントにとって特に問題となります。

この問題は、RAG(Retrieval-Augmented Generation)構成でAIエージェントに最新かつ信頼性の高いデータを取得させる機能を与えることで解決できます。例えば、AIエージェントがウェブ検索を実行して検証可能な情報を収集し、知識を拡張して精度を向上させることが可能です。

検索エンジンをスクレイピングするカスタムAWS Lambda関数の構築は可能ですが、非常に困難です。JavaScriptレンダリング、CAPTCHA、サイト構造の変更、IPブロックへの対応が必要となります。

より優れたアプローチは、Bright DataのSERP APIのような機能豊富なSERP APIを利用することです。これによりプロキシ処理、ブロック解除、スケーラビリティ、データフォーマットなどが自動的に管理されます。Lambda関数を用いてAWS Bedrockと統合することで、AWS CDKで構築したAIエージェントはリアルタイム検索結果にアクセスし、より信頼性の高い応答が可能になります。

PythonでAWS CDKとSERP API統合によるAIエージェント開発方法

このステップバイステップセクションでは、PythonとAWS CDKを使用してAWS Bedrock AIエージェントを構築する方法を学びます。このエージェントはBright Data SERP APIを介して検索エンジンからデータを取得できます。

統合は、エージェントがツールとして呼び出せるLambda関数(SERP APIを呼び出す)を通じて実装されます。具体的には、Amazon Bedrockエージェントを作成するための主要コンポーネントは以下の通りです:

  • アクショングループ: エージェントが認識・呼び出し可能な関数を定義します。
  • Lambda関数:Bright Data SERP APIをクエリするロジックを実装します。
  • AIエージェント:基盤モデル、関数、ユーザーリクエスト間の相互作用を調整します。

この設定はPythonのAWS CDKで完全に実装されます。ビジュアルなAWS Bedrockコンソールで同様の結果を得るには、Amazon Bedrock + Bright Dataガイドを参照してください。

以下の手順に従い、AWS CDKを使用したAWS Bedrock AIエージェントを構築し、SERP APIを介したリアルタイムWeb検索機能で強化しましょう!

前提条件

このチュートリアルを実行するには、以下が必要です:

ステップ #1: AWS CLI のインストールと認証

AWS CDKを進める前に、AWS CLIをインストールし、ターミナルがAWSアカウントと認証できるように設定する必要があります。

: AWS CLIが既にインストールされ、認証設定が完了している場合は、この手順をスキップして次の手順に進んでください。

お使いのオペレーティングシステムに対応した公式インストールガイドに従ってAWS CLIをインストールしてください。インストール後、以下のコマンドを実行してインストールを確認します:

aws --version

以下のような出力が表示されるはずです:

aws-cli/2.31.32 Python/3.13.9 Windows/11 exe/AMD64

次に、資格情報を設定するためにconfigureコマンドを実行します:

aws configure

入力が求められます:

  1. AWS アクセスキー ID
  2. AWS シークレットアクセスキー
  3. デフォルトのリージョン名(例:us-east-1
  4. デフォルト出力形式(オプション、例:json

CDKの開発とデプロイに必要なため、最初の3つのフィールドは必ず入力してください。これらの情報の入手方法がわからない場合は:

  1. AWSにアクセスしてサインインします。
  2. 右上のアカウント名をクリックしてアカウントメニューを開き、「セキュリティ認証情報」を選択します。
  3. 「アクセスキー」セクションで、新しいキーを作成します。「アクセスキーID」と「シークレットアクセスキー」の両方を安全な場所に保存してください。

完了!これでマシンがCLI経由でAWSアカウントに接続可能になります。AWS CDK開発を進める準備が整いました。

ステップ #2: AWS CDK のインストール

aws-cdknpmパッケージを使用して、システムにAWS CDKをグローバルにインストールします

npm install -g aws-cdk

次に、インストールされたバージョンを以下で確認します:

cdk --version

以下のような出力が表示されるはずです:

2.1031.2 (build 779352d)

: Pythonを使用したAWS CDKによるAIエージェントの開発およびデプロイには、バージョン2.174.3以降が必要です。

完了!これでAWS CDK CLIがローカルにインストールされました。

ステップ #3: AWS CDK Python プロジェクトの設定

まず、AWS CDK + Bright Data SERP API AI エージェント用の新しいプロジェクトフォルダを作成します。
たとえば、のように命名できます:

mkdir aws-cdk-bright-data-web-search-agent

フォルダに移動します:

cd aws-cdk-bright-data-web-search-agent

次に、initコマンドでPythonベースの新しいAWS CDKアプリケーションを初期化します:

cdk init app --language python

CDK CLIがプロジェクト構造を設定するまで時間がかかる場合がありますので、しばらくお待ちください。

初期化が完了すると、プロジェクトフォルダは次のようになります:

aws-cdk-bright-data-web-search-agent
├── .git/
├── venv/
├── aws_cdk_bright_data_web_search_agent/
│   ├── __init__.py
│   └── aws_cdk_bright_data_web_search_agent_stack.py
├── tests/
│   ├── __init__.py
│   └── unit/
│       ├── __init__.py
│       └── test_aws_cdk_bright_data_web_search_agent_stack.py
├── .gitignore
├── app.py
├── cdk.json
├── README.md
├── requirements.txt
├── requirements-dev.txt
└── source.bat

注目すべきは次の2つのファイルです:

  • app.py: AWS CDK アプリケーションのトップレベル定義を含みます。
  • aws_cdk_bright_data_web_search_agent/aws_cdk_bright_data_web_search_agent_stack.py: Web検索エージェント用のスタックを定義します(AIエージェントのロジックを実装する場所です)。

詳細は、PythonでのCDK操作に関する公式AWSガイドを参照してください。

次に、PyCharm やPython拡張機能を搭載したVisual Studio Codeなど、お好みのPython IDEでプロジェクトを読み込みます。

cdk initコマンドはプロジェクト内にPython 仮想環境を自動的に作成します。Linux または macOS では、以下で有効化してください:

source .venv/bin/activate

Windowsでは同等の操作として以下を実行:

.venvScriptsactivate

次に、アクティブ化した仮想環境内で必要な依存関係をすべてインストールします:

python -m pip install -r requirements.txt

素晴らしい!これでAIエージェント開発用のAWS CDK Python環境が設定されました。

ステップ #4: AWS CDK ブートストラップの実行

ブートストラップとは、AWS Cloud Development Kit(CDK)の使用に備えてAWS環境を準備するプロセスです。CDKスタックをデプロイする前に、環境のブートストラップが必須です。

簡単に言えば、このプロセスではAWSアカウントに以下のリソースを設定します:

  • Amazon S3 バケット: AWS Lambda 関数コードやその他のアセットなど、CDK プロジェクトファイルを保存します。
  • Amazon ECRリポジトリ: Dockerイメージを保存します。
  • AWS IAMロール: AWS CDKがデプロイを実行するために必要な権限を付与します(詳細は、ブートストラップ中に作成されるIAMロールに関するAWSドキュメントを参照)。

CDKブートストラッププロセスを開始するには、プロジェクトフォルダで次のコマンドを実行します:

cdk bootstrap

このコマンドは、AWS CloudFormationサービス内で「CDKToolkit」というスタックを作成します。このスタックには、CDK アプリケーションのデプロイに必要なすべてのリソースが含まれます。

CloudFormationコンソールにアクセスし、「スタック」ページで確認してください:
Note the “CDKToolkit” stack in CloudFormation

「CDKToolkit」スタックが表示されます。そのリンクをクリックすると、以下のような内容が表示されます:
The “CDKToolkit” stack generated by the bootstrapping process
ブートストラッププロセスの動作、必要性、および内部処理の詳細については、公式の AWS CDK ドキュメントを参照してください。

ステップ #5: Bright Data の SERP API 準備

AWS CDK環境の開発・デプロイ準備が整ったところで、Bright Dataアカウントの準備とSERP APIサービスの設定という事前準備を完了させます。公式Bright Dataドキュメントに従うか、以下の手順を実行してください。

アカウントをお持ちでない場合は、Bright Dataアカウントを作成してください。または、ログインするだけで結構です。Bright Dataアカウントで、「Proxy & Scraping」ページにアクセスします。「My Zones」セクションで、テーブル内に「SERP API」行があるか確認してください:
Note the “serp_api” row in the table
「SERP API」ラベルの行が表示されない場合、ゾーンがまだ設定されていないことを意味します。「SERP API」セクションまでスクロールし、「ゾーンを作成」をクリックして追加します:
Configuring the SERP API zone
SERP APIゾーンを作成し、serp_api(または任意の名前)などの名前を付けます。API経由でサービスにアクセスする際に必要となるため、選択したゾーン名を覚えておいてください。

SERP API製品ページで「有効化」スイッチを切り替えてゾーンを有効化してください:
Activating the SERP API zone
最後に、公式ガイドに従ってBright Data APIキーを生成してください。すぐに必要となるため、安全な場所に保管してください。

これで、AWS CDKで開発したAWS Bedrock AIエージェントでBright DataのSERP APIを使用するための準備が整いました。

ステップ #6: CDKアプリケーションのシークレットをAWS Secrets Managerに保存

機密情報(例:Bright Data APIキーやSERP APIゾーン名)を取得しました。これらの値をLambda関数のコードにハードコーディングする代わりに、AWS Secrets Managerから安全に読み取る必要があります。

以下のBashコマンドを実行し、Bright Data APIキーとSERP APIゾーンを含む「BRIGHT_DATA」という名前のシークレットを作成します:

aws secretsmanager create-secret 
  --name "BRIGHT_DATA" 
  --description "API credentials for Bright Data SERP API integration" 
  --secret-string '{
    "BRIGHT_DATA_API_KEY": "<YOUR_BRIGHT_DATA_API_KEY>",
    "BRIGHT_DATA_SERP_API_ZONE": "<YOUR_BRIGHT_DATA_SERP_API_ZONE>"
  }'

または、PowerShell では同等な方法で:

aws secretsmanager create-secret `
  --name "BRIGHT_DATA" `
  --description "Bright Data SERP API 統合用 API 認証情報" `
  --secret-string '{"BRIGHT_DATA_API_KEY":"<YOUR_BRIGHT_DATA_API_KEY>","BRIGHT_DATA_SERP_API_ZONE":"<YOUR_BRIGHT_DATA_SERP_API_ZONE>"}'

<YOUR_BRIGHT_DATA_API_KEY>および<YOUR_BRIGHT_DATA_SERP_API_ZONE>は、事前に取得した実際の値に置き換えてください。

このコマンドによりBRIGHT_DATAシークレットが設定されます。AWS Secrets Managerコンソールの「シークレット」ページで確認できます:
Note the “BRIGHT_DATA” secret in AWS Secrets Manager

「シークレット値を取得」ボタンをクリックすると、BRIGHT_DATA_API_KEYおよびBRIGHT_DATA_SERP_API_ZONEシークレットが表示されます:
Note the "BRIGHT_DATA_API_KEY” and “BRIGHT_DATA_SERP_API_ZONE” secrets
素晴らしい!これらのシークレットは、まもなく定義するLambda関数内でSERP APIへのリクエスト認証に使用されます。

ステップ #7: AWS CDK スタックの実装

AIエージェント構築に必要なすべての準備が整ったので、次のステップはPythonでAWS CDKスタックを実装することです。まず、AWS CDKスタックとは何かを理解することが重要です。

スタックはCDKにおける最小のデプロイ可能単位です。CDKコンストラクトを使用して定義されたAWSリソースの集合体を表します。CDKアプリケーションをデプロイすると、スタック内の全リソースが単一のCloudFormationスタックとして一括デプロイされます。

デフォルトのスタックファイルは次の場所にあります:

aws_cdk_bright_data_web_search_agent/aws_cdk_bright_data_web_search_agent_stack.py

Visual Studio Codeで確認します:
The CDK stack script in Visual Studio Code
これは汎用スタックテンプレートを含み、ここにロジックを定義します。あなたのタスクは、Lambda関数、IAMロール、アクショングループ、Bedrock AIエージェントを含む、Bright Data SERP APIを統合したAIエージェントを構築するための完全なAWS CDKスタックを実装することです。

以下の方法で全てを実現してください:

import aws_cdk.aws_iam as iam
from aws_cdk import (
  Aws,
  CfnOutput,
  Duration,
  Stack)

from aws_cdk import aws_bedrock as bedrock
from aws_cdk import aws_lambda as _lambda
from constructs import Construct

# 必要な定数を定義
AI_MODEL_ID = "amazon.nova-lite-v1:0" # エージェントを駆動するLLMの名前
ACTION_GROUP_NAME = "action_group_web_search"
LAMBDA_FUNCTION_NAME = "serp_api_lambda"
AGENT_NAME = "web_search_agent"

# Bright Data搭載Web検索エージェント展開用CDKスタック定義
class AwsCdkBrightDataWebSearchAgentStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # ログ記録とシークレット読み取りのためのLambda権限を付与
        lambda_policy = iam.Policy(
            self,
            "LambdaPolicy",
            statements=[
                # CloudWatchロググループの作成権限
                iam.PolicyStatement(
                    sid="CreateLogGroup",
                    effect=iam.Effect.ALLOW,
                    actions=["logs:CreateLogGroup"],
                    resources=[f"arn:aws:logs:{Aws.REGION}:{Aws.ACCOUNT_ID}:*"],
                ),
                # ログストリームの作成とログイベントの書き込み権限
                iam.PolicyStatement(
                    sid="CreateLogStreamAndPutLogEvents",
                    effect=iam.Effect.ALLOW,
                    actions=["logs:CreateLogStream", "logs:PutLogEvents"],
                    resources=[
                        f"arn:aws:logs:{Aws.REGION}:{Aws.ACCOUNT_ID}:log-group:/aws/lambda/{LAMBDA_FUNCTION_NAME}",
                        f"arn:aws:logs:{Aws.REGION}:{Aws.ACCOUNT_ID}:log-group:/aws/lambda/{LAMBDA_FUNCTION_NAME}:log-stream:*",
                    ],
                ),
                # Secrets Manager から BRIGHT_DATA シークレットを読み取る権限
                iam.PolicyStatement(
                    sid="GetSecretsManagerSecret",
                    effect=iam.Effect.ALLOW,
                    actions=["secretsmanager:GetSecretValue"],
                    resources=[
                        f"arn:aws:secretsmanager:{Aws.REGION}:{Aws.ACCOUNT_ID}:secret:BRIGHT_DATA*",
                    ],
                ),
            ],
        )

        # Lambda関数用のIAMロールを定義
        lambda_role = iam.Role(
            self,
            "LambdaRole",
            role_name=f"{LAMBDA_FUNCTION_NAME}_role",
            assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
        )

        # Lambdaロールにポリシーをアタッチ
        lambda_role.attach_inline_policy(lambda_policy)

        # Lambda関数の定義
        lambda_function = _lambda.Function(
            self,
            LAMBDA_FUNCTION_NAME,
            function_name=LAMBDA_FUNCTION_NAME,
            runtime=_lambda.Runtime.PYTHON_3_12,  # Pythonランタイム
            architecture=_lambda.Architecture.ARM_64,
            code=_lambda.Code.from_asset("lambda"),  # "lambda/"フォルダからLambdaコードを読み込む
            handler=f"{LAMBDA_FUNCTION_NAME}.lambda_handler",
            timeout=Duration.seconds(120),
            role=lambda_role,  # IAMロールをアタッチ
            environment={"LOG_LEVEL": "DEBUG", "ACTION_GROUP": f"{ACTION_GROUP_NAME}"},
        )

        # BedrockサービスがLambda関数を呼び出せるように許可
        bedrock_account_principal = iam.PrincipalWithConditions(
            iam.ServicePrincipal("bedrock.amazonaws.com"),
            conditions={
                "StringEquals": {"aws:SourceAccount": f"{Aws.ACCOUNT_ID}"},
            },
        )
        lambda_function.add_permission(
            id="LambdaResourcePolicyAgentsInvokeFunction",
            principal=bedrock_account_principal,
            action="lambda:invokeFunction",
        )

        # Bedrock エージェント用の IAM ポリシーを定義
        agent_policy = iam.Policy(
            self,
            "AgentPolicy",
            statements=[
                iam.PolicyStatement(
                    sid="AmazonBedrockAgentBedrockFoundationModelPolicy",
                    effect=iam.Effect.ALLOW,
                    actions=["bedrock:InvokeModel"],  # 基盤モデルの呼び出し権限を付与
                    resources=[f"arn:aws:bedrock:{Aws.REGION}::foundation-model/{AI_MODEL_ID}"],
                ),
            ],
        )

        # エージェントロールに対する信頼関係(Bedrockがロールをアサインできるようにするため)
        agent_role_trust = iam.PrincipalWithConditions(
            iam.ServicePrincipal("bedrock.amazonaws.com"),
            conditions={
                "StringLike": {"aws:SourceAccount": f"{Aws.ACCOUNT_ID}"},
                "ArnLike": {"aws:SourceArn": f"arn:aws:bedrock:{Aws.REGION}:{Aws.ACCOUNT_ID}:agent/*"},
            },
        )

        # Bedrockエージェント用のIAMロールを定義
        agent_role = iam.Role(
            self,
            "AmazonBedrockExecutionRoleForAgents",
            role_name=f"AmazonBedrockExecutionRoleForAgents_{AGENT_NAME}",
            assumed_by=agent_role_trust,
        )
        agent_role.attach_inline_policy(agent_policy)

        # AIエージェントのアクショングループを定義
        action_group = bedrock.CfnAgent.AgentActionGroupProperty(
            action_group_name=ACTION_GROUP_NAME,
            description="Bright DataのSERP APIを呼び出し、ウェブ検索を実行し、検索エンジンから最新の情報を取得します。",
            action_group_executor=bedrock.CfnAgent.ActionGroupExecutorProperty(lambda_=lambda_function.function_arn),
            function_schema=bedrock.CfnAgent.FunctionSchemaProperty(
                functions=[
                    bedrock.CfnAgent.FunctionProperty(
                        name=LAMBDA_FUNCTION_NAME,
                        description="Bright DataのSERP APIと連携し、ウェブ検索を実行します。",
                        parameters={
                            "search_query": bedrock.CfnAgent.ParameterDetailProperty(
                                type="string",
                                description="Googleウェブ検索の検索クエリ。",
                                required=True,
                            )
                        },
                    ),
                ]
            ),
        )

        # Bedrock AIエージェントの作成と指定
        agent_description = """
            Bright DataのSERP APIに接続し、検索エンジンから最新のウェブ検索コンテキストを取得できるAIエージェント。
        """

        agent_instruction = """
            あなたは、最新情報の取得と処理を必要とするユースケースを扱うために設計されたエージェントです。
            Bright DataのSERP APIを活用したウェブ検索を通じて、ニュースや検索エンジン結果を含む最新データにアクセスできます。
        """

        agent = bedrock.CfnAgent(
            self,
            AGENT_NAME,
            description=agent_description,
            agent_name=AGENT_NAME,
            foundation_model=AI_MODEL_ID,
            action_groups=[action_group],
            auto_prepare=True,
            instruction=agent_instruction,
            agent_resource_role_arn=agent_role.role_arn,
        )

        # 展開用の主要出力をエクスポート
        CfnOutput(self, "agent_id", value=agent.attr_agent_id)
        CfnOutput(self, "agent_version", value=agent.attr_agent_version)

上記のコードは、ウェブ検索AIエージェント向けの公式AWS CDKスタック実装を修正したものです。

この150行以上のコードで実行される処理は、ガイドで先に説明した手順(記事「Bright Data SERP API を AWS Bedrock AI エージェントに統合する方法」のステップ #1、ステップ #2、ステップ #3)を反映しています。

このファイルの動作をより深く理解するために、コードを5つの機能ブロックに分解しましょう:

  1. Lambda IAMポリシーとロール:Lambda関数の権限を設定します。Lambdaは、実行詳細を記録するためにCloudWatchログへのアクセスと、Bright Data APIキーとゾーンを安全に読み取るためにAWS Secrets Managerへのアクセスを必要とします。Lambda用にIAMロールが作成され、適切なポリシーがアタッチされ、必要な権限のみを持って安全に動作することが保証されます。
  2. Lambda関数定義:ここでLambda関数自体を定義・設定します。Pythonランタイムとアーキテクチャを指定し、Lambdaコードを含むフォルダ(次ステップで実装)を指し示し、ログレベルやアクショングループ名などの環境変数を設定します。AWS BedrockがLambdaを呼び出せる権限を付与し、AIエージェントがBright DataのSERP APIを通じてウェブ検索をトリガーできるようにします。
  3. BedrockエージェントIAMロール: Bedrock AIエージェントの実行ロールを作成します。エージェントはサポート対象の 基盤AIモデル(本例ではamazon.nova-lite-v1:0)を呼び出す権限を必要とします。アカウント内でBedrockのみがロールを引き継げるよう信頼関係が定義され、モデルへのアクセス権を付与するポリシーがアタッチされます。
  4. アクショングループ定義: AIエージェントが実行可能な具体的なアクションを定義します。エージェントをLambda関数にリンクし、Bright DataのSERP API経由でのウェブ検索を可能にします。また入力パラメータのメタデータを含み、エージェントが関数との連携方法や各検索に必要な情報を理解できるようにします。
  5. Bedrock AIエージェント定義:AIエージェント自体を定義します。エージェントをアクショングループおよび実行ロールにリンクし、その使用に関する明確な説明と指示を提供します。

CDKスタックをデプロイすると、AWSコンソールにAIエージェントが表示されます。このエージェントはLambda関数内のBright Data SERP API統合を活用し、自律的にウェブ検索を実行して最新情報を取得できます。素晴らしい!

ステップ #8: SERP API 統合のための Lambda を実装する

以前のコードからこのスニペットをご覧ください:

lambda_function = _lambda.Function(
    self,
    LAMBDA_FUNCTION_NAME,
    function_name=LAMBDA_FUNCTION_NAME,
    runtime=_lambda.Runtime.PYTHON_3_12,  # Pythonランタイム
    architecture=_lambda.Architecture.ARM_64,
    code=_lambda.Code.from_asset("lambda"),  # "lambda/"フォルダからLambdaコードを読み込み
    handler=f"{LAMBDA_FUNCTION_NAME}.lambda_handler",
    timeout=Duration.seconds(120),
    role=lambda_role,  # IAMロールをアタッチ
    environment={"LOG_LEVEL": "DEBUG", "ACTION_GROUP": f"{ACTION_GROUP_NAME}"},
)

コード行 `code=_lambda.Code.from_asset("lambda")` は、Lambda関数コードをlambda/ フォルダから読み込むことを指定します。したがって、プロジェクト内にlambda/フォルダを作成し、その中にserp_api_lambda.pyという名前のファイルを追加してください:
The serp_api_lambda.py file inside the lambda/ folder
serp_api_lambda.pyファイルには、先に定義したAIエージェントが使用するLambda関数の実装を含める必要があります。Bright Data SERP APIとの連携を処理するこの関数を以下のように実装してください:

import json
import logging
import os
import urllib.parse
import urllib.request

import boto3

# ----------------------------
# ログ設定
# ----------------------------
log_level = os.environ.get("LOG_LEVEL", "INFO").strip().upper()
logging.basicConfig(
    format="[%(asctime)s] p%(process)s {%(filename)s:%(lineno)d} %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
logger.setLevel(log_level)

# ----------------------------
# 環境変数からAWSリージョンを取得
# ----------------------------
AWS_REGION = os.environ.get("AWS_REGION")
if not AWS_REGION:
    logger.warning("AWS_REGION環境変数が設定されていません。boto3はデフォルトリージョンを使用します")

# ----------------------------
# AWS Secrets Managerからシークレットオブジェクトを取得
# ----------------------------
def get_secret_object(key: str) -> str:
    """
    AWS Secrets Manager からシークレット値を取得します。
    """
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=AWS_REGION
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=key
        )
    except Exception as e:
        logger.error(f"Secrets Managerからシークレット '{key}' を取得できませんでした: {e}")
        raise e

    secret = json.loads(get_secret_value_response["SecretString"])

    return secret


# Bright Data 認証情報の取得
bright_data_secret = get_secret_object("BRIGHT_DATA")
BRIGHT_DATA_API_KEY = bright_data_secret["BRIGHT_DATA_API_KEY"]
BRIGHT_DATA_SERP_API_ZONE = bright_data_secret["BRIGHT_DATA_SERP_API_ZONE"]

# ----------------------------
# SERP API Web検索
# ----------------------------
def serp_api_web_search(search_query: str) -> str:
    """
    Bright Data SERP APIを呼び出し、Google検索結果を取得します。
    """
    logger.info(f"search_query='{search_query}' に対する Bright Data SERP API 検索を実行中")

    # クエリをURL用にエンコード
    encoded_query = urllib.parse.quote(search_query)
    # SERPをスクレイピングするGoogle URLを構築
    search_engine_url = f"https://www.google.com/search?q={encoded_query}"

    # Bright Data APIリクエスト (ドキュメント: https://docs.brightdata.com/scraping-automation/serp-api/send-your-first-request)
    url = "https://api.brightdata.com/request"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {BRIGHT_DATA_API_KEY}"
    }
    data = {
        "zone": BRIGHT_DATA_SERP_API_ZONE,
        "url": search_engine_url,
        "format": "raw",
        "data_format": "markdown" # SERPをAI対応のMarkdown文書として取得するため
    }

    payload = json.dumps(data).encode("utf-8")
    request = urllib.request.Request(url, data=payload, headers=headers)

    try:
        response = urllib.request.urlopen(request)
        response_data = str(response.read().decode("utf-8"))
        logger.debug(f"SERP APIからの応答: {response_data}")
        return response_data
    except urllib.error.HTTPError as e:
        logger.error(f"Bright Data SERP APIの呼び出しに失敗しました。HTTPエラー {e.code}: {e.reason}")
    except urllib.error.URLError as e:
        logger.error(f"Bright Data SERP API の呼び出しに失敗しました。URL エラー: {e.reason}")

    return ""


# ----------------------------
# Lambda ハンドラー
# ----------------------------
def lambda_handler(event, _):
    """
    AWS Lambda ハンドラー。
    actionGroup、function、およびオプションのパラメータ(search_query を含む)を含むイベントを期待します。
    """
    logger.debug(f"lambda_handler がイベント: {event} で呼び出されました")

    action_group = event.get("actionGroup")
    function = event.get("function")
    parameters = event.get("parameters", [])

    # パラメータから検索クエリを抽出
    search_query = next(
        (param["value"] for param in parameters if param.get("name") == "search_query"),
        None,
    )
    logger.debug(f"入力検索クエリ: {search_query}")

    serp_page = serp_api_web_search(search_query) if search_query else ""
    logger.debug(f"検索クエリ結果: {serp_page}")

    # Lambdaレスポンスの準備
    function_response_body = {"TEXT": {"body": serp_page}}

    action_response = {
        "actionGroup": action_group,
        "function": function,
        "functionResponse": {"responseBody": function_response_body},
    }

    response = {"response": action_response, "messageVersion": event.get("messageVersion")}

    logger.debug(f"lambda_handler response: {response}")

    return response

このLambda関数は主に3つのタスクを処理します:

  1. API認証情報を安全に取得: AWS Secrets ManagerからBright Data APIキーとSERP APIゾーンを取得し、機密情報がハードコードされないようにします。
  2. SERP API経由でのウェブ検索の実行: 検索クエリをエンコードし、Google検索URLを構築して、Bright Data SERP APIにリクエストを送信します。APIは検索結果をMarkdown形式で返します。これはAIが消費するのに理想的なデータ形式です
  3. AWS Bedrockへの応答: AIエージェントが利用可能な構造化されたレスポンスとして結果を返します.

これで完了です!Bright Data SERP APIに接続するAWS Lambda関数が正常に定義されました。

ステップ #9: AWS CDK アプリケーションのデプロイ

CDKスタックと関連するLambda関数の実装が完了したので、最終ステップとしてスタックをAWSにデプロイします。プロジェクトフォルダ内で以下のデプロイコマンドを実行してください:

cdk deploy

IAMロール作成の許可を求められたら、yを入力して承認します。

しばらくすると、すべてが正常に動作していれば、次のような出力が表示されます:
The output of the “deploy” command

次に、Amazon Bedrockコンソールに移動します。「エージェント」ページ内に「web_search_agent」エントリが表示されているはずです:
Note the “web_search_agent” entry

エージェントを開くと、デプロイされたエージェントの詳細が表示されます:
The details page for the “web_search_agent”
「編集とエージェントビルダー」ボタンを押して詳細を確認すると、「Bright Data SERP API を AWS Bedrock に統合する方法」で実装した AI エージェントと全く同じ構成が確認できます。

最後に、右隅のチャットインターフェースでエージェントを直接テストできる点に注意してください。これが次の最終ステップで行う作業です!

ステップ #10: AIエージェントのテスト

AIエージェントのウェブ検索とライブデータ取得機能をテストするには、次のようなプロンプトを試してください:

「米国政府閉鎖に関する最新ニュース記事を上位3件提示せよ」

:これは単なる例です。ウェブ検索結果を必要とする任意のプロンプトでテスト可能です)

このプロンプトは理想的です。なぜなら、基盤モデルだけでは知り得ない最新情報を要求しているためです。エージェントはSERP APIと連携したLambda関数を呼び出し、結果を取得し、データを処理して一貫性のある応答を生成します。

エージェントの「エージェントテスト」セクションでこのプロンプトを実行すると、以下のような出力が表示されるはずです:
Running the prompt in the AWS Amazon Bedrock console
内部では、エージェントがSERP API Lambda関数を呼び出し、「米国政府閉鎖」クエリに対する最新のGoogle検索結果を取得し、関連性の高い上位記事(URL付き)を抽出します。これは設定済みのNova Liteのような標準LLMでは単独では不可能な処理です。

詳細には、エージェントが生成した応答は以下の通りです:

The agent’s response
選択されたニュース記事(およびそのURL)は、「米国政府閉鎖」クエリでGoogleを手動検索した場合の結果と一致します(少なくともエージェントテスト時点では):
The SERP for the “US government shutdown” search query
Google検索結果のスクレイピングを試みたことがある方なら、ボット検知、IP禁止、JavaScriptレンダリングなどの課題がどれほど困難かご存知でしょう。Bright Data SERP APIはこれらの問題をすべて処理し、AI最適化Markdown(またはHTML、JSONなど)形式でスクレイピングされたSERPを返します。

エージェントが実際にSERP API Lambda関数を呼び出したことを確認するには、応答ボックス内の「Show trace」ボタンをクリックします。「Trace step 1」セクションでグループ呼び出しログまでスクロールし、Lambda呼び出しの出力を確認してください:
The output of the SERP API Lambda function
これにより、Lambda関数が正常に実行され、エージェントが意図した通りにSERP APIとやり取りしたことを確認できます。Lambda関数のAWS CloudWatchログを確認して実行を検証することも可能です。

エージェントのさらなる進化へ!ファクトチェック、ブランド監視、市場トレンド分析など、様々なシナリオに関連するプロンプトをテストし、異なるエージェント機能やRAGユースケースにおけるパフォーマンスを確認しましょう。

これで完成です!PythonとAWS CDKライブラリを使用して、Bright DataのSERP APIと統合されたAWS Bedrockエージェントを構築しました。このAIエージェントは、要求に応じて最新で信頼性の高い文脈に沿ったウェブ検索データを取得できます。

まとめ

本ブログ記事では、AWS CDK Pythonプロジェクトを用いてBright DataのSERP APIをAWS Bedrock AIエージェントに統合する方法を解説しました。このワークフローは、AWS上でより文脈認識能力の高いAIエージェント構築を目指す開発者に最適です。

さらに高度なAIエージェントを作成するには、Bright DataのAI向けインフラストラクチャをご検討ください。ライブウェブデータの取得、検証、変換を行うツール群を提供しています。

今すぐBright Dataアカウントを無料で作成し、AI対応のウェブデータソリューションの実験を始めましょう!

AI

AWS Bedrock エージェントに、Bright Data SERP API 経由でのウェブ検索機能を提供する。

Bright DataのSERP APIを統合することで、リアルタイムのウェブ検索と、より正確で最新の回答を可能にし、AWS Bedrockエージェントをスーパーチャージする方法を学びましょう。
5 分読
AWS Bedrock Agents with SERP API blog image

このチュートリアルでは、以下のことを学びます:

  • AWS Bedrock AIエージェントとは何か、何ができるのか。
  • Bright DataのSERP APIのようなAI対応ツールを介してエージェントにウェブ検索結果へのアクセスを与えることで、精度とコンテキストが向上する理由。
  • SERPAPIと統合されたAWS BedrockエージェントをAWSコンソールでステップバイステップで構築する方法。
  • AWS CDKを使ったコードで同じことを実現する方法。

さあ、飛び込もう!

AWS Bedrock AIエージェントとは?

AWS Bedrockでは、AIエージェントはLLMを使用して、複数のステップのタスクを論理的なステップに分解して自動化するサービスです。より詳細には、Amazon BedrockのAIエージェントは、ユーザーのリクエストを理解し、関連する情報を収集し、自動的にタスクを完了するために、基礎モデル、API、データを活用するシステムです。

AWS Bedrockエージェントは、タスク継続のためのメモリ、Bedrock Guardrailsを介したビルトインセキュリティをサポートし、複雑なワークフローのために他のエージェントとコラボレーションすることができる。AWSインフラストラクチャのおかげで、エージェントは管理され、スケーラブルで、サーバーレスであり、AI搭載アプリケーションの構築とデプロイのプロセスを簡素化します。

なぜAmazon BedrockのAIエージェントは動的ウェブ検索コンテキストから恩恵を受けるのか?

LLMは、特定の時点までに利用可能な知識を表す大規模なデータセットでトレーニングされます。つまり、LLMがリリースされたとき、LLMはトレーニングデータに含まれるものしか知らず、それはすぐに古くなってしまう。

そのためAIモデルは、時事問題や新たな知識をリアルタイムで認識することができない。その結果、AIエージェントの大きな問題である、時代遅れの、間違った、あるいは幻覚のような応答を出す可能性がある。

この限界は、RAG(Retrieval-Augmented Generation)セットアップで、AIエージェントに新鮮で信頼できる情報を取得する能力を与えることで克服することができます。このアイデアは、推論をサポートし、知識を拡大し、最終的にはより正確な結果を提供するために、ウェブ検索を実行し、検証可能なデータを取得することができる信頼性の高いツールをエージェントに装備することです。

一つの選択肢は、SERP(検索エンジンの結果ページ)をスクレイピングし、LLMの取り込みのためにデータを準備するカスタムAWS Lambda関数を構築することだろう。しかし、このアプローチは技術的に複雑だ。JavaScriptのレンダリング、CAPTCHAの解決、そして常に変化するサイト構造を処理する必要がある。さらに、Googleのような検索エンジンは、数回の自動化されたリクエストの後、すぐにIPをブロックしてしまうため、簡単に拡張できるものではありません。

より良い解決策は、Bright DataのSERP APIのような、トップクラスのSERPとウェブ検索APIを使用することです。このサービスは、プロキシ、ブロック解除、データパース、その他すべての課題を自動的に管理しながら、検索エンジンのデータを返します。

Bright DataのSERP APIをLambda関数経由でAWS Bedrockに統合することで、AIエージェントは運用の負担なしにウェブ検索情報にアクセスできるようになります。その方法を見てみましょう!

Bright Data SERP APIをAWS BedrockのAIエージェントに統合して、検索コンテキストに対応したユースケースを実現する方法

このステップバイステップのセクションでは、Bright Data SERP APIを使用して検索エンジンからリアルタイムのデータを取得する機能をAWS Bedrock AIエージェントに与える方法を学びます。

この統合により、エージェントは、さらに読むための関連リンクを含む、より文脈的で最新の回答を提供することができます。セットアップはAWS Bedrockコンソールで視覚的に行われ、必要なコードはわずかです。

以下のステップに従い、SERP APIを通してAWS Bedrock AIエージェントを構築してください!

前提条件

このチュートリアルに従うには、以下が必要です:

Bright Dataアカウントをまだ作成していなくても心配しないでください。ガイドの後半でそのプロセスを案内します。

ステップ #1: AWS Bedrockエージェントの作成

AWS Bedrock AIエージェントを作成するには、AWSアカウントにログインし、検索バーでサービスを検索してAmazon Bedrockコンソールを開きます:

Reaching the Amazon Bedrock console

次に、Bedrockコンソールで、左側のメニューから “Agent “を選択し、”Create agent “ボタンをクリックします:

Pressing the “Create agent” button

エージェントに名前と説明を付けます

  • 名前:web_search_agent
  • 説明“検索エンジンから新鮮なウェブ検索コンテキストを取得するためにBright DataのSERP APIに接続できるAIエージェント。”

重要: Amazon LLMを使用する場合は、エージェント名や関数などにハイフン(-)ではなくアンダースコア(_)を使用する必要があります。ハイフンを使用すると、”Dependency resource: received model timeout/error exception from Bedrock.この場合、リクエストを再試行してください。” エラーが発生する可能性があります。

Filling out the “Create agent” modal

Create “をクリックして、AIエージェントを確定します。エージェントビルダー “ページにリダイレクトされます:

Reaching the “Agent builder” page

素晴らしい!これでAWS BedrockにAIエージェントが作成できました。

ステップ #2: AIエージェントの設定

エージェントを作成したので、いくつかのオプションを設定し、セットアップを完了する必要があります。

Agent resource role “情報については、デフォルトの “Create and use a new service role “オプションのままにしておきます。これにより、エージェントが想定するAWS Identity and Access Management (IAM)ロールが自動的に作成されます:

Configuring the “Agent resource role” option

次に、”Select model “をクリックし、エージェントを動かす LLM モデルを選択します。この例では、Amazonの “Nova Lite“モデルを使用します(他のモデルでも構いません):

Selecting the “Nova Lite” model

モデルを選択したら、”Apply “をクリックして確定します。

エージェントへの指示 “セクションで、エージェントが何をすべきかを明確に具体的に指示します。このウェブ検索エージェントの場合、次のように入力します:

あなたは、最新情報の取得と処理を必要とするユースケースを処理するために設計されたエージェントです。Bright Data の SERP API を利用したウェブ検索により、ニュースや検索エンジンの結果を含む最新のデータにアクセスすることができます。

説明を完了すると、最終的なエージェントの詳細セクションはこのようになります:

Editing the agent details

トップバーの “Save “をクリックして、全てのエージェント詳細を保存し、エージェント詳細の設定を完了します。

注意: AWS Bedrockには、他にも多くの設定オプションがあります。エージェントを特定のユースケースに適応させるために、それらを検討してください。

ステップ #3: SERP API アクショングループの追加

アクショングループは、エージェントが外部システムやAPIとやりとりして、情報を収集したりアクションを実行したりすることを可能にします。Bright Data の SERP API と統合するために定義する必要があります。

エージェントビルダー “ページで、”アクショングループ “セクションまでスクロールダウンし、”追加 “をクリックします:

Pressing the “Add” button in “Action groups”

アクショングループを定義するフォームが開きます。以下のように入力してください:

  • アクショングループ名を入力:action_group_web_search(ハイフンではなく、アンダースコア_ を使用してください)
  • 説明“Bright DataのSERP APIを呼び出し、ウェブ検索を実行し、検索エンジンから最新情報を取得する”
  • アクショングループの種類Define with function details” オプションを選択します。
  • アクショングループの呼び出し:Quick create a new Lambda function” オプションを選択し、エージェントが呼び出せる基本的なLambda 関数を設定します。この場合、関数は Bright Data の SERP API を呼び出すロジックを処理します。
Filling out the action group form

注意: “Quick create a new Lambda function “オプションで、Amazon Bedrockはエージェント用のLambda関数テンプレートを生成します。この関数は後でLambdaコンソールで変更することができます(後のステップで行います)。

次に、グループ内で関数を設定します。Action group function 1: serp_api」セクションまでスクロールダウンし、以下のように入力します:

  • 名前serp_api(ここでもアンダースコアを使用)。
  • 説明“Bright DataのSERP APIと統合してウェブ検索を実行する”
  • パラメータ search_queryという文字列型のパラメータを追加し、必須とする。このパラメータはLambda関数に渡され、Bright Data SERP APIがウェブ検索のコンテキストを取得するための入力を表します。
Filling out the “Action group function“ form

最後に “Create “をクリックしてアクショングループの設定を完了します:

Pressing the “Create” button to add the action group

最後に、”Save “をクリックしてエージェント設定を保存します。これで完了です!

ステップ #4: Bright Data アカウントの設定

Bright Data アカウントを設定し、SERP API サービスを設定します。Bright Dataの公式ドキュメントに従うか、下記のステップに従うかのどちらかになります。

アカウントをまだお持ちでない場合は、Bright Dataにサインアップしてください。そうでない場合は、既存のアカウントにログインします。ログイン後、”プロキシ&スクレイピング “ページの “マイゾーン “セクションに移動し、テーブル内の “SERP API “行を確認します:

Note the “serp_api” row in the table

SERP APIの行がない場合は、まだゾーンの設定がされていないことを意味します。下にスクロールし、”SERP API “セクションの下にある “Create zone “をクリックする:

Configuring the SERP API zone

SERP APIゾーンを作成し、serp_api(または任意の名前)のような名前を付けます。SERP APIゾーン名は、API経由で接続する際に必要になるので、記録しておいてください。

製品ページで “Activate “スイッチを切り替え、ゾーンを有効にする:

Activating the SERP API zone

最後に、公式ガイドに従ってBright Data APIキーを生成します。すぐに必要になりますので、安全な場所に保管してください。

これで完了です!これで、Bright DataのSERP APIをAWS Bedrock AIエージェントで使用するために必要なものは全て揃いました。

ステップ #5: AWSに秘密を保存する

前のステップでは、Bright Data APIキーやSERP APIゾーン名などの機密情報を取得しました。これらの値をLambda関数コードにハードコードする代わりに、AWS Secrets Managerに安全に保存します。

AWSの検索バーで “Secrets Manager “を検索し、サービスを開きます:

Pressing the “Store a new secret” button

Store a new secret “ボタンをクリックし、”Other type of secret “オプションを選択します。Key/value pairs “セクションで、以下のキーと値のペアを追加する:

  • BRIGHT_DATA_API_KEY: 先ほど取得したBright Data APIキーを入力します。
  • BRIGHT_DATA_SERP_API_ZONE:Bright Data SERP APIゾーン名(例:serp_api)を入力します。
Giving the secret the name

次に、”Next “をクリックし、秘密の名前を入力します。例えば、BRIGHT_DATA とします:

Giving the secret the name

このシークレットには、フィールドBRIGHT_DATA_API_KEYと BRIGHT_DATA_SERP_API_ZONEを含むJSONオブジェクトが格納されます。

残りのプロンプトに従って秘密の作成を完了し、秘密の保存を終了します。完了後、秘密はこのようになります:

The BRIGHT_DATA secret

かっこいいですね!次のステップで設定する Bright Data SERP API に安全に接続するために、Python Lambda 関数でこれらのシークレットにアクセスします。

ステップ #6: SERP API を呼び出す Lambda 関数の作成

ステップ #3 で作成したアクショングループに関連付けられている Lambda 関数を定義するための構成要素がすべて揃いました。この関数には、Bright Data の SERP API を呼び出し、ウェブ検索データを取得する Python コードが含まれます。

Lambdaを作成するには、AWSの検索バーで “Lambda “を検索し、Amazon Lambdaコンソールを開きます。すでにステップ#3でAWS Bedrockによって関数が自動的に作成されていることがわかります:

The “action/_gorup_serp_api_web_serach_XXXX” function

action_group_serp_api_web_search_XXXXという名前の関数をクリックして、概要ページを開きます:

The Lambda function overview page

このページで、Codeタブまでスクロールダウンすると、Lambdaロジックを編集するためのビルトインVisual Studio Codeエディタがあります:

The online IDE to edit the Lambda logic

dummy_lambda.pyファイルの内容を以下のコードに置き換えます:

import json
import logging
import json import logging import os
import urllib.parse
import urllib.request

インポートboto3

# ----------------------------
# ロギング設定
# ----------------------------
log_level = os.environ.get("LOG_LEVEL", "INFO").strip().upper()
logging.basicConfig(
    format="[%(asctime)s] p%(process)s {%(filename)s:%(lineno)d} %(levelname)s - %(message)s" "
)
logger = logging.getLogger(__name__)
logger.setLevel(log_level)

# ----------------------------
# 環境からのAWSリージョン
# ----------------------------
AWS_REGION = os.environ.get("AWS_REGION")
if not AWS_REGION:
    logger.warning("AWS_REGION 環境変数が設定されていません; boto3 はデフォルトのリージョンを使用します")

# ----------------------------
# AWS Secrets Managerからシークレットオブジェクトを取得します。
# ----------------------------
def get_secret_object(key: str) -> str:
    """
    AWS Secrets Managerからシークレット値を取得します。
    """
    セッション = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager'、
        リージョン名=AWS_REGION
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=key
        )
    except Exception as e:
        logger.error(f "Could not get secret '{key}' from Secrets Manager: {e}")
        raise e

    secret = json.loads(get_secret_value_response["SecretString"])

    return secret


# ブライトデータの認証情報を取得する
bright_data_secret = get_secret_object("BRIGHT_DATA")
BRIGHT_DATA_API_KEY = bright_data_secret["BRIGHT_DATA_API_KEY"].
BRIGHT_DATA_SERP_API_ZONE = bright_data_secret["BRIGHT_DATA_SERP_API_ZONE"].

# ----------------------------
# SERP APIウェブ検索
# ----------------------------
def serp_api_web_search(search_query: str) -> str:
    """
    Bright Data SERP API を呼び出し、Google の検索結果を取得します。
    """
    logger.info(f "Executing Bright Data SERP API search for search_query='{search_query}'")

    # URL 用にクエリをエンコードする
    encoded_query = urllib.parse.quote(search_query)
    # SERPをスクレイピングするためのGoogle URLを構築する
    search_engine_url = f "https://www.google.com/search?q={encoded_query}"

    # Bright Data APIリクエスト (docs: https://docs.brightdata.com/scraping-automation/serp-api/send-your-first-request)
    url = "https://api.brightdata.com/request"
    ヘッダー = {
        "Content-Type":"application/json"、
        "Authorization": f "ベアラ {BRIGHT_DATA_API_KEY}"
    }
    data = {
        "zone":bright_data_serp_api_zone、
        "url": search_engine_url、
        "format":"raw"、
        "data_format":"markdown" # AI対応のMarkdownドキュメントとしてSERPを取得する場合
    }

    payload = json.dumps(data).encode("utf-8")
    request = urllib.request.Request(url, data=payload, headers=headers)

    try:
        response = urllib.request.urlopen(request)
        response_data: str = response.read().decode("utf-8")
        logger.debug(f "Response from SERP API: {response_data}")
        return response_data
    except urllib.error.HTTPError as e:
        logger.error(f "Failed to call Bright Data SERP API. HTTP Error {e.code}: {e.reason}")
    except urllib.error.URLError as e:
        logger.error(f "Bright Data SERP APIの呼び出しに失敗しました。 URLエラー: {e.reason}")

    return ""


# ----------------------------
# ラムダハンドラ
# ----------------------------
def lambda_handler(event, _):
    """
    AWS Lambdaハンドラ。
    actionGroup、function、search_queryを含むオプションのパラメータを持つイベントを期待する。
    """
    logger.debug(f "lambda_handler called with event: {event}")

    action_group = event.get("アクショングループ")
    function = event.get("関数")
    parameters = event.get("parameters", [])

    # パラメーターからsearch_queryを取り出す
    search_query = next(
        (param["value"] for param in parameters if param.get("name") == "search_query")、
        なし、
    )
    logger.debug(f "Input search query: {search_query}")

    serp_page = serp_api_web_search(search_query) if search_query else ""
    logger.debug(f "検索クエリの結果: {serp_page}")

    # ラムダのレスポンスを準備する
    function_response_body = {"TEXT":{"body": serp_page}} # ラムダレスポンスの準備

    action_response = {
        "actionGroup": action_group、
        "function": function、
        functionResponse": function, { "responseBody": function_response_body}:{functionResponse": function、"functionResponse": function、"responseBody": function_response_body}、
    }

    response = {"response": action_response, "messageVersion": event.get("messageVersion")}。

    logger.debug(f "lambda_handler response: {response}")

    レスポンスを返す

このスニペットは、AWS Secrets Manager から Bright Data API の認証情報を取得し、Google 検索クエリで SERP API を呼び出し、検索結果を Markdown テキストとして返します。SERP API を呼び出す方法の詳細については、ドキュメントを参照してください

上記のコードをオンラインIDEに貼り付ける:

Updating the Lambda's code

そして、”Deploy “を押してLambda関数を更新する:

Clicking the “Deploy” button to update the Lambda code

期待通りであれば、”Successfully updated the function action_group_serp_api_web_search_XXXX.” のようなメッセージが表示されます。

注意: Lambda関数は、Amazon Bedrockが呼び出すことを許可するリソースベースのポリシーで自動的に設定されます。これは先ほどの “Quick create a new Lambda function “オプションで処理されたので、手動でIAMロールを変更する必要はありません。

完璧です!これで Bright Data SERP API に接続するための AWS Lambda 関数が完成しました。

ステップ #7: Lambda パーミッションの設定

Lambda 関数を呼び出すためにカスタム IAM パーミッションは必要ありませんが、AWS Secrets Manager に保存されている API キーへのアクセスは必要です。

これを設定するには、Lambda関数の詳細ページで “Configuration “タブに移動し、”Permissions “オプションを選択します:

Reaching the AWS Lambda “Permissions” page

Execution role “セクションで、”Role name “リンクをクリックしてIAMコンソールを開きます:

Clicking the role name

役割ページで、添付されている権限ポリシーを見つけて選択する:

Selecting the permission policy

JSON “ビューを開き、”Edit “をクリックして権限ポリシーを更新する準備をする:

Accessing the JSON view of the permission policy

ステートメント配列に以下のブロックが含まれていることを確認する:

{
  "アクション":"secretsmanager:GetSecretValue"、
  「リソース": [
    "arn:aws:secretsmanager:<YOUR_AWS_REGION>:<YOUR_AWS_ACCOUNT_ID>:secret:BRIGHT_DATA*"]。
  ],
  "効果":許可
  "Sid":"GetSecretsManagerSecret"
}

<YOUR_AWS_REGION>と <YOUR_AWS_ACCOUNT_ID>は、セットアップに適した値に置き換えてください。このJSONコードのブロックによって、Lambda関数がSecrets ManagerからBRIGHT_DATAのシークレットにアクセスできるようになります。

そして、”Next “ボタンをクリックし、最後に “Save changes “をクリックします。その結果、Lambda関数にもSecrets Managerへのアクセス権限が付与されていることが確認できるはずです:

Note the “Secrets Manager” option

素晴らしい!素晴らしい!これでLambda関数は適切に設定され、Secrets Managerに保存されたBright Data認証情報にアクセスできるAWS Bedrock AIエージェントから呼び出すことができます。

ステップ #8: AIエージェントの最終確認

Agent builder “セクションに戻り、最後にもう一度 “Save “をクリックし、先ほどの変更を全て適用します:

Saving the changes in your agent

次に、”Prepare” をクリックして、最新の設定でエージェントをテストする準備をします。

Pressing the “Prepare” button

Agent: web_search_agent was successfully prepared.” のような確認メッセージが表示されるはずです。

ミッション完了です!これで Bright Data SERP API を利用した AI エージェントは完全に実装され、すぐに利用できるようになりました。

ステップ #9: AIエージェントのテスト

AWS Bedrock AI エージェントは、ステップ #6 で定義したlambda_handlerLambda 関数によって実装されたserp_apiグループ関数にアクセスできます。簡単に言うと、エージェントはBright Data SERP APIを介してGoogle(そして潜在的には他の検索エンジン)でリアルタイムのウェブ検索を実行し、新鮮なオンラインコンテンツを動的に取得して処理することができます。

この機能をテストするために、ハリケーン「メリッサ」に関する最新ニュースを取得したいとします。エージェントに次のようにプロンプトしてみましょう:

「ハリケーン・メリッサに関する最新のニュース記事のトップ3を教えてください。

(覚えておいてください:これは単なる例であり、リアルタイムのウェブ検索結果を含む他のプロンプトをテストすることができます)。

エージェントの “Test Agent “セクションでこのプロンプトを実行すると、このような出力が表示されるはずです:

The agent execution on the given prompt

裏側では、エージェントは SERP API Lambda を呼び出し、”Hurricane Melissa” の最新の Google 検索結果を取得し、関連する上位のニュース項目をその URL とともに抽出しています。これは、Nova Liteを含むバニラLLMでは実現できないことだ!

これがエージェントによって生成された具体的なテキストレスポンスです(URLは省略されています):

ハリケーン・メリッサに関する最新のニュース記事のトップ3です:
1.1. Jamaica braces for Hurricane Melissa, strongest storm of 2025 - BBC, 6時間前
2.ハリケーン・メリッサの最新情報、追跡-ジャマイカは "壊滅的 "影響に直面 - Newsweek, 7時間前
3.ハリケーン「メリッサ」がジャマイカに上陸、観測史上最強の暴風雨の恐れ - APニュース, 10時間前
記事全文は原典をご覧ください。

これらの結果は幻覚ではない!それどころか、Googleで “Hurricane Melissa”(薬剤がテストされた日現在)を手動で検索したときの結果と一致している:

The SERP for “melissa hurricane news"

Googleの検索結果をスクレイピングしようとしたことがある方なら、ボット検出、IP禁止、JavaScriptレンダリング、その他多くの課題のために、それがいかに難しいかご存知でしょう。

Bright Data SERP APIはそのすべてを効率的に解決し、スクレイピングされたSERPをAIのための最適化されたMarkdownフォーマットで返すことができます(これはLLMインジェストにとって特に価値があります)。

エージェントが実際にSERP API Lambdaを呼び出したことを確認するには、”Show trace “をクリックします:

Following the “Show trace” link

トレースステップ1」セクションで、グループ呼び出しログセクションまでスクロールダウンすると、関数呼び出しの出力が表示されます:

The output of the SERP API Lambda function

これにより、Lambda 関数が正常に実行され、エージェントが意図した通りに SERP API と対話したことが確認できます。同様に、LambdaのAWS CloudWatchログを確認して確認してください。

次に、エージェントをさらにプッシュする!ファクトチェック、ブランドモニタリング、市場トレンド分析、またはその他のシナリオに関連するプロンプトを試してみてください。さまざまなユースケースでエージェントがどのように動作するか見てみましょう。

出来上がりです!あなたはBright DataのSERP APIと統合されたAWS Bedrock AIエージェントを構築し、オンデマンドで最新の、信頼できる、文脈に沿ったウェブ検索データを取得できるようになりました。

[番外編】AWS CDKを使ったウェブ検索によるAmazon Bedrockエージェントの構築

前のセクションでは、Amazon Bedrockコンソールを介して直接SERP APIと統合するAIエージェントを定義して実装する方法を学びました。

コードファーストのアプローチを好むなら、AWS Cloud Development Kit (AWS CDK)を使って同じ結果を得ることができます。この方法は、全体的に同じステップに従いますが、すべてをAWS CDKプロジェクト内でローカルに管理します。

詳細なガイダンスについては、AWSの公式ガイドを参照してください。また、そのチュートリアルをサポートしている GitHub リポジトリにも目を通しておくと良いでしょう。このコードベースは、Bright Data の SERP API で動作するように簡単に適応できる。

まとめ

このブログポストでは、Bright Data の SERP API を AWS Bedrock AI エージェントに統合する方法を見た。このワークフローは、AWSでより強力でコンテキストを意識したAIエージェントを構築したい人に最適です。

さらに高度なAIワークフローを作成するには、Bright DataのAIのためのインフラストラクチャを探索してください。ライブのウェブデータを取得、検証、変換するためのツール群が見つかります。

今すぐBright Dataの無料アカウントにサインアップして、AIのためのウェブデータソリューションの実験を始めましょう!