AI

RAGによるSERPスクレイピングAPIを使用したCrewAIエージェントの強化

SERPスクレイピングAPIを統合することで、CrewAIエージェントを新鮮なウェブデータで強化し、リアルタイムで正確なAI応答を実現します。
8 分読
CrewAI + Bright Data's SERP API

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

  • CrewAIとは何か、他のAIエージェントライブラリとの違いは何か。
  • その最大の限界と、RAGワークフローでそれを克服する方法。
  • スクレイピングAPIと統合し、AIエージェントにSERPデータを提供することで、より正確なレスポンスを実現する方法。

さあ、飛び込もう!

CrewAIとは何か?

CrewAIはオープンソースのPythonフレームワークで、複雑なタスクを完了するために協働する自律的なAIエージェントをオーケストレーションし、管理するためのものです。Browser Useのような単一エージェントシステムとは異なり、CrewAIはエージェントの集合である「クルー」を中心に構築されています。

クルーでは、各エージェントは、定義された役割、目標、ツールのセットを持っています。詳細には、ウェブスクレイピング、データベース接続などのような特殊なタスクのためのカスタムツールをAIエージェントに装備させることができます。このアプローチは、AIを活用した専門的な問題解決と効果的な意思決定への扉を開きます。

CrewAIのマルチエージェントアーキテクチャは、効率性と拡張性の両方を促進します。Qwenモデルや並列関数呼び出しのサポートなど、新機能が定期的に追加され、急速に進化するエコシステムとなっています。

CrewAIの限界と新鮮なウェブデータで克服する方法

CrewAIは、マルチエージェントシステムを構築するための機能豊富なフレームワークである。しかし、LLMからいくつかの重要な制限を受け継いでいる。LLMは通常、静的なデータセットで事前に訓練されているため、リアルタイムの認識に欠け、最新のニュースやライブのウェブコンテンツにアクセスできない。

その結果、時代遅れの回答や、最悪の場合、幻覚を見ることになりかねない。このような問題は、検索-拡張生成のセットアップにおいて、エージェントに制約がなかったり、最新の信頼できるデータが提供されていない場合に特に起こりやすい。

このような制限に対処するためには、エージェント(ひいてはそのLLM)に信頼できる外部データを提供する必要がある。ウェブは最も包括的で動的なデータソースであり、理想的なターゲットです。従って、一つの効果的なアプローチは、CrewAIエージェントがGoogleや他の検索エンジンのようなプラットフォームでライブ検索クエリを実行できるようにすることです。

これは、エージェントが学習するために関連するウェブページを取得することができるカスタムCrewAIツールを構築することによって行うことができます。しかし、SERP(検索エンジンの結果ページ)をスクレイピングすることは、JavaScriptのレンダリング、CAPTCHAの解決、IPローテーション、常に変化するサイト構造などの必要性から、技術的に困難である。

そのすべてを社内で管理することは、CrewAIのロジックそのものを開発するよりも複雑になる可能性があります。より良い解決策は、Bright DataのSERP APIのような、トップクラスのSERPスクレイピングAPIに頼ることです。これらのサービスは、ウェブからクリーンで構造化されたデータを抽出する重労働を処理します。

このようなAPIをCrewAIのワークフローに統合することで、エージェントは運用のオーバーヘッドなしに新鮮で正確な情報にアクセスできるようになります。エージェントをドメイン固有のスクレイピングAPIに接続することで、同じ戦略を他のドメインに適用することもできます。

CrewAIとSERP APIを統合してリアルタイムでデータにアクセスする方法

このガイドセクションでは、CrewAIで構築したAIエージェントに、Bright Data SERP APIを介してSERPエンジンから直接データを取得する機能を与える方法を説明します。

このRAGの統合により、CrewAIエージェントは、より文脈に沿った最新の結果を、さらに読むための実際のリンクとともに提供することができます。

以下のステップに従って、Bright DataのSERP API統合で強力なスタッフを構築してください!

前提条件

このチュートリアルについて行くには、以下を確認してください:

詳細については、CrewAIのドキュメントのインストールページをご覧ください。最新の前提条件が記載されています。

Bright Data APIキーをまだお持ちでない方も、次のステップで作成方法をご案内しますのでご安心ください。LLM APIキーについては、お持ちでない場合は、Googleの公式ガイドに従ってGemini APIキーを設定することをお勧めします。

ステップ1:CrewAIのインストール

ターミナルで以下のコマンドを実行し、CrewAIをグローバルにインストールすることから始めます:

pip install crewai

:いくつかのパッケージをダウンロードして設定するので、少し時間がかかるかもしれません。

インストール中や使用中に問題が発生した場合は、公式ドキュメントのトラブルシューティングのセクションを参照してください。

インストールされると、crewaiCLIコマンドにアクセスできるようになります。ターミナルで以下を実行して確認してください:

crewai

次のような出力が表示されるはずだ:

Usage: crewai [OPTIONS] COMMAND [ARGS]...

  Top-level command group for crewai.

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  chat               Start a conversation with the Crew, collecting...
  create             Create a new crew, or flow.
  deploy             Deploy the Crew CLI group.
  flow               Flow related commands.
  install            Install the Crew.
  log-tasks-outputs  Retrieve your latest crew.kickoff() task outputs.
  login              Sign Up/Login to CrewAI+.
  replay             Replay the crew execution from a specific task.
  reset-memories     Reset the crew memories (long, short, entity,...
  run                Run the Crew.
  signup             Sign Up/Login to CrewAI+.
  test               Test the crew and evaluate the results.
  tool               Tool Repository related commands.
  train              Train the crew.
  update             Update the pyproject.toml of the Crew project to use...
  version            Show the installed version of crewai.

素晴らしい!これでプロジェクトを初期化するCrewAI CLIの準備ができました。

ステップ2:プロジェクトのセットアップ

以下のコマンドを実行して、serp_agent という新しい CrewAI プロジェクトを作成します:

crewai create crew serp_agent

セットアップ中に、ご希望のLLMプロバイダーを選択するよう促されます:

Select a provider to set up:
1. openai
2. anthropic
3. gemini
4. nvidia_nim
5. groq
6. huggingface
7. ollama
8. watson
9. bedrock
10. azure
11. cerebras
12. sambanova
13. other
q. Quit
Enter the number of your choice or 'q' to quit:

今回は、API経由の統合が無料であるGeminiのオプション「3」を選択する。

次に、使用するジェミニのモデルを選択します:

Select a model to use for Gemini:
1. gemini/gemini-1.5-flash
2. gemini/gemini-1.5-pro
3. gemini/gemini-2.0-flash-lite-001
4. gemini/gemini-2.0-flash-001
5. gemini/gemini-2.0-flash-thinking-exp-01-21
6. gemini/gemini-2.5-flash-preview-04-17
7. gemini/gemini-2.5-pro-exp-03-25
8. gemini/gemini-gemma-2-9b-it
9. gemini/gemini-gemma-2-27b-it
10. gemini/gemma-3-1b-it
11. gemini/gemma-3-4b-it
12. gemini/gemma-3-12b-it
13. gemini/gemma-3-27b-it
q. Quit

この例では、無料のgemini/gemini-1.5-flashモデルで十分です。ですから、”1 “を選択すればよいのです。

次に、Gemini APIキーの入力を求められます:

Enter your GEMINI API key from https://ai.dev/apikey (press Enter to skip):

これを貼り付けると、期待通りにいけば、次のような出力が表示されるはずだ:

API keys and model saved to .env file
Selected model: gemini/gemini-1.5-flash
  - Created serp_agent.gitignore
  - Created serp_agentpyproject.toml
  - Created serp_agentREADME.md
  - Created serp_agentknowledgeuser_preference.txt
  - Created serp_agentsrcserp_agent__init__.py
  - Created serp_agentsrcserp_agentmain.py
  - Created serp_agentsrcserp_agentcrew.py
  - Created serp_agentsrcserp_agenttoolscustom_tool.py
  - Created serp_agentsrcserp_agenttools__init__.py
  - Created serp_agentsrcserp_agentconfigagents.yaml
  - Created serp_agentsrcserp_agentconfigtasks.yaml
Crew serp_agent created successfully!

この手順により、以下のようなプロジェクト構造が生成される:

serp_agent/
├── .gitignore
├── pyproject.toml
├── README.md
├── .env
├── knowledge/
├── tests/
└── src/
    └── serp_agent/
        ├── __init__.py
        ├── main.py
        ├── crew.py
        ├── tools/
        │   ├── custom_tool.py
        │   └── __init__.py
        └── config/
            ├── agents.yaml
            └── tasks.yaml

ここだよ:

  • main.pyはプロジェクトのメインエントリーポイントです。
  • crew.pyはクルーのロジックを定義する場所です。
  • config/agents.yamlはAIエージェントを定義します。
  • config/tasks.yamlはエージェントが処理するタスクを定義します。
  • tools/custom_tool.pyは、エージェントが使用できるカスタムツールを追加します。
  • .envにはAPIキーやその他の環境変数が格納される。

プロジェクトフォルダに移動し、CrewAIの依存関係をインストールします:

cd serp_agent
crewai install

最後のコマンドは、プロジェクトディレクトリ内にローカル仮想環境.venvフォルダを作成します。これでCrewAIをローカルで実行できるようになります。

完璧です!これで、Gemini APIを使ったCrewAIプロジェクトが完全に初期化されました。これで、インテリジェントなSERPエージェントを構築し、実行する準備が整いました。

ステップ#3: SERP APIを使い始める

前述の通り、我々はBright DataのSERP APIを使って検索エンジンの結果ページからコンテンツを取得し、CrewAIのエージェントに供給する。具体的には、ユーザーの入力に基づいて正確なGoogle検索を行い、エージェントの応答を改善するためにライブスクレイピングデータを活用します。

SERP APIを設定するには、公式ドキュメントを参照してください。または、以下の手順に従ってください。

まだの方は、ブライト・データにアカウントを登録してください。そうでなければ、ログインしてください。ログインしたら、”My Zones “セクションに行き、”SERP API “の行をクリックします:

SERP API」行の選択

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

SERP APIゾーンの設定

SERP API製品ページで、”Activate “スイッチを切り替えて製品を有効にします:

次に、公式ガイドに従ってBright Data APIキーを生成します。そして、以下のように.envファイルに追加します:

BRIGHT_DATA_API_KEY=<YOUR_BRIGHT_DATA_API_KEY>

プレースホルダを プレースホルダを Bright Data API キーの実際の値に置き換えてください。

これです!これでCrewAIとの連携でBright DataのSERP APIが使えるようになりました。

ステップ#4: CrewAI SERP検索ツールの作成

Bright Data SERP APIと対話し、検索結果データを取得するためにエージェントが使用できるSERP検索ツールを定義する時が来ました。

そのためには、tools/フォルダ内のcustom_tool.pyファイルを開き、その内容を以下のように置き換える:

# src/search_agent/tools/custom_tool.py

import os
import json
from typing import Type
import requests
from pydantic import BaseModel, PrivateAttr
from crewai.tools import BaseTool


class SerpSearchToolInput(BaseModel):
    query: str


class SerpSearchTool(BaseTool):
    _api_key: str = PrivateAttr()

    name: str = "Bright Data SERP Search Tool"
    description: str = """
    Uses Bright Data's SERP API to retrieve real-time Google search results based on the user's query.
    This tool fetches organic search listings to support agent responses with live data.
    """
    args_schema: Type[BaseModel] = SerpSearchToolInput

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # Read the Bright Data API key from the envs
        self._api_key = os.environ.get("BRIGHT_DATA_API_KEY")

        if not self._api_key:
            raise ValueError("Missing Bright Data API key. Please set BRIGHT_DATA_API_KEY in your .env file")

    def _run(self, query: str) -> str:
        url = "https://api.brightdata.com/request"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self._api_key}"
        }
        payload = {
            "zone": "serp", # Replace with the name of your actual Bright Data SERP API zone
            "format": "json",
            "url": f"https://www.google.com/search?q={query}&brd_json=1"
        }

        try:
            response = requests.post(url, json=payload, headers=headers)
            # Raise exceptions in case of errors
            response.raise_for_status()

            # Parse the JSON response
            json_response = response.json()
            response_body = json.loads(json_response.get("body", "{}"))

            if "organic" not in response_body:
                return "The response did not include organic search results."

            # Return the SERP data as a JSON string
            return json.dumps(response_body["organic"], indent=4)

        except requests.exceptions.HTTPError as http_err:
            return f"HTTP error occurred while querying Bright Data SERP API: {http_err}"
        except requests.exceptions.RequestException as req_err:
            return f"Network error occurred while connecting to Bright Data: {req_err}"
        except (json.JSONDecodeError, KeyError) as parse_err:
            return f"Error parsing Bright Data SERP API response: {parse_err}"

このCrewAIツールは、ユーザークエリを受け取り、 リクエットを介してBright Data SERP APIからSERPの結果を取得する関数を定義しています。

brd_json=1クエリパラメータが使用され、フォーマットがjsonに設定されている場合、SERP APIはこの構造で応答することに注意してください:

{
  "status_code": 200,
  "headers": {
    "content-type": "application/json",
    // omitted for brevity...
  },
  "body": "{"general":{"search_engine":"google","query":"pizza","results_cnt":1980000000, ...}}"
}

特に、JSON文字列を含むbodyフィールドをパースすると、次のようなデータ構造になる:

{
  "general": {
    "search_engine": "google",
    "query": "pizza",
    "results_cnt": 1980000000,
    "search_time": 0.57,
    "language": "en",
    "mobile": false,
    "basic_view": false,
    "search_type": "text",
    "page_title": "pizza - Google Search",
    "timestamp": "2023-06-30T08:58:41.786Z"
  },
  "input": {
    "original_url": "https://www.google.com/search?q=pizza&brd_json=1",
    "request_id": "hl_1a1be908_i00lwqqxt1"
  },
  "organic": [
    {
      "link": "https://www.pizzahut.com/",
      "display_link": "https://www.pizzahut.com",
      "title": "Pizza Hut | Delivery & Carryout - No One OutPizzas The Hut!",
      "rank": 1,
      "global_rank": 1
    },
    {
      "link": "https://www.dominos.com/en/",
      "display_link": "https://www.dominos.com",
      "title": "Domino's: Pizza Delivery & Carryout, Pasta, Chicken & More",
      "description": "Order pizza, pasta, sandwiches & more online...",
      "rank": 2,
      "global_rank": 3
    },
    // ...additional organic results omitted for brevity
  ]
}

だから、あなたは主にオーガニック・フィールドに興味がある。これは、コードでアクセスされ、JSON文字列に解析され、ツールによって返されるフィールドである。

素晴らしい!あなたのCrewAIエージェントは、このツールを使って新鮮なSERPデータを取得することができます。

ステップ5:エージェントの定義

このタスクを達成するためには、2つのCrewAIエージェントが必要です:

  1. リサーチャー:グーグルから検索結果を収集し、有用なインサイトをフィルタリングする。
  2. 報告アナリスト:調査結果を構造化し、読みやすい要約にまとめる。

agents.ymlファイルに次のように記入することで定義できる:

# src/search_agent/configs/agents.yml

researcher:
  role: >
    Online Research Specialist
  goal: >
    Conduct smart Google searches and collect relevant, trustworthy details from the top results.
  backstory: >
    You have a knack for phrasing search queries that deliver the most accurate and insightful content.
    Your expertise lies in quickly identifying high-quality information from reputable sources.

reporting_analyst:
  role: >
    Strategic Report Creator
  goal: >
    Organize collected data into a clear, informative narrative that’s easy to understand and act on.
  backstory: >
    You excel at digesting raw information and turning it into meaningful analysis. Your work helps
    teams make sense of data by presenting it in a well-structured and strategic format.

この構成がいかに各エージェントのやるべきことを捉えているか、注目してほしい。ただ、彼らの役割ゴールバックストーリーを定義するだけだ。とても良い!

ステップ#6: 各エージェントのタスクを指定する

ワークフロー内での各エージェントの役割を明確に示す具体的なタスクを定義する準備をしましょう。CrewAIのドキュメントによると、正確な結果を得るためには、エージェントの定義よりもタスクの定義の方が重要です

したがって、tasks.ymlでは、エージェントが何をする必要があるのかを、以下のように正確に伝える必要がある:

# src/search_agent/configs/tasks.yml

research_task:
  description: >
    Leverage SerpSearchTool to perform a targeted search based on the user's {query}.
    Build API parameters like:
    - 'query': develop a short, Google-like, keyword-optimized search phrase for search engines.
    From the returned data, identify the most relevant and factual content.

  expected_output: >
    A file containing well-structured raw JSON content with the data from search results.
    Avoid rewriting, summarizing, or modifying any content.

  agent: researcher
  output_file: output/serp_data.json

report_task:
  description: >
    Turn the collected data into a digestible, insight-rich report.
    Address the user's {query} with fact-based findings. Add links for further reading. Do not fabricate or guess any information.

  expected_output: >
    A Markdown report with key takeaways and meaningful insights.
    Keep the content brief and clearly, visually structured.

  agent: reporting_analyst
  context: [research_task]
  output_file: output/report.md

このセットアップでは、2つのタスクを定義している:

  • research_task:クエリに基づいて動的に API パラメータを構築する方法など、ツールを介して Bright Data SERP API を使用する方法を研究者に伝えます。
  • report_task:最終的な出力が、収集されたデータから厳密に作成された、読みやすく、有益なレポートであることを指定する。

このtasks.yml定義は、CrewAIエージェントがSERPデータを収集し、実際の検索結果に基づいたレポートを作成するために必要なものです。

CrewAIエージェントをコードに統合し、仕事をさせる時が来ました!

ステップ7:クルーを作る

これですべてのコンポーネントが揃ったので、crew.pyファイルですべてをつなげて完全に機能するクルーを作りましょう。具体的には、このようにcrew.pyを定義します:

# src/search_agent/crew.py

from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from .tools.custom_tool import SerpSearchTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List

@CrewBase
class SerpAgent():
    """SerpAgent crew"""

    agents: List[BaseAgent]
    tasks: List[Task]

    @agent
    def researcher(self) -> Agent:
        return Agent(
            config=self.agents_config["researcher"],
            tools=[SerpSearchTool()],
            verbose=True
        )

    @agent
    def reporting_analyst(self) -> Agent:
        return Agent(
            config=self.agents_config["reporting_analyst"],
            verbose=True
        )

    @task
    def research_task(self) -> Task:
        return Task(
            config=self.tasks_config["research_task"],
            output_file="output/serp_data.json"
        )

    @task
    def report_task(self) -> Task:
        return Task(
            config=self.tasks_config["report_task"],
            output_file="output/report.md"
        )

    @crew
    def crew(self) -> Crew:
        """Creates the SerpAgent crew"""
        return Crew(
            agents=self.agents,
            tasks=self.tasks,
            process=Process.sequential,
            verbose=True,
        )

crew.pyではCrewAIデコレーター(ここでは@agent@task@crew)を使って、YAMLファイルからロジックをリンクし、実際の機能を配線する必要があります。

この例では

  • リサーチャーエージェントは SerpSearchToolにアクセスし、Bright DataのSERP APIを使用して実際のGoogle検索クエリを実行することができます。
  • reporting_analystエージェントは、研究者からの出力を使用して、最終レポートを生成するように構成されている。
  • 各タスクはtasks.ymlで定義されたものに対応し、適切な出力ファイルに明示的に結びつけられている。
  • プロセスはシーケンシャルに設定され、リサーチャーが最初に実行され、そのデータをreporting_analystに渡す。

いくぞSerpAgentのクルーは、実行の準備が整いました。

ステップ#8: メインループの作成

main.pyで、ユーザーのクエリを入力として渡してクルーにトリガーをかけます:

# src/search_crew/main.py

import os
from serp_agent.crew import SerpAgent

# Create the output/ folder if it doesn"t already exist
os.makedirs("output", exist_ok=True)

def run():
    try:
        # Read the user's input and pass it to the crew
        inputs = {"query": input("nSearch for: ").strip()}

        # Start the SERP agent crew
        result = SerpAgent().crew().kickoff(
            inputs=inputs
        )
        return result
    except Exception as e:
        print(f"An error occurred: {str(e)}")

if __name__ == "__main__":
    run()

ミッション完了!あなたのCrewAI + SERP API統合(LLMとしてGeminiを使用)はこれで完全に機能します。main.pyを実行し、検索クエリを入力するだけで、クルーがSERPデータを収集・分析し、レポートを作成します。

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

プロジェクトのフォルダで、以下のコマンドでCrewAIアプリケーションを実行します:

crewai run

さて、次のようなクエリーを入力する:

"What are the new AI protocols?"

これは、典型的なLLMが正確に答えるのに苦労するような質問だ。なぜなら、CMP、A2A、AGP、ACPといった最新のAIプロトコルのほとんどは、モデルが最初にトレーニングされたときには存在していなかったからだ。

何が起こるのか、詳しく説明しよう:

上にあるように、CrewAIはこのようにリクエストを処理する:

  1. 研究エージェントは実行される:
    1. ユーザー入力を構造化されたクエリー"新しいAIプロトコル "に変換する。
    2. SerpSearchTool を介して Bright Data の SERP API にクエリを送信します。
    3. APIから結果を受け取り、output/serp_data.jsonファイルに保存する。
  2. その後、reporting_analystエージェントが起動する:
    1. serp_data.jsonファイルから構造化データを読み込む。
    2. その新鮮な情報を使って、コンテキストを意識したレポートをMarkdownで作成する。
    3. 最終的な構造化レポートをoutput/report.mdに保存する。

Markdownビューアーを使ってreport.mdを開くと、次のように表示される:

CrewAIが作成した最終的なMarkdownレポート

レポートには、関連する文脈情報や、より深く掘り下げるためのリンクも含まれている。

出来上がり!SERP APIとの統合により、CrewAIにRAGワークフローが実装されました。

次のステップ

Crewに統合されたBright Data SERP APIツールにより、エージェントは新鮮な検索エンジンの結果を受け取ることができます。これらのSERPのURLがあれば、他のスクレイピングAPIを呼び出して、リンクされたページから生のコンテンツを抽出することができます。

このアイデアは、エージェントが信頼できるソースを自動的に発見し、そこから最新の情報を取得することを可能にします。さらに、エージェントブラウザのようなソリューションを統合することで、エージェントはライブのウェブページと動的に対話することができます。

これらはほんの一例に過ぎないが、潜在的なシナリオやユースケースは事実上無限である

結論

このブログポストでは、Bright DataのSERP APIを使用してRAGセットアップを統合することで、CrewAIエージェントをよりコンテキストに対応したものにする方法を学びました。

説明したように、これはエージェントを外部のスクレイピングAPIや自動化ツールと接続することで探求できる多くの可能性の一つに過ぎません。特に、Bright Dataのソリューションは、インテリジェントなAIワークフローのための強力なビルディングブロックとして機能します。

ブライトデータのツールでAIインフラをレベルアップ:

  • 自律型AIエージェント:強力なAPIセットを使って、あらゆるウェブサイトをリアルタイムで検索、アクセス、対話。
  • 業種別AIアプリ:信頼性の高いカスタムデータパイプラインを構築し、業種固有のソースからウェブデータを抽出します。
  • 基礎モデル:ウェブスケールのデータセットにアクセスし、事前学習、評価、微調整を行うことができます。
  • マルチモーダルAI:AIに最適化された世界最大の画像、動画、音声のリポジトリを利用できます。
  • データプロバイダー:信頼できるプロバイダーと接続し、高品質でAIに対応したデータセットを大規模に調達。
  • データパッケージ:キュレーションされた、すぐに使える、構造化された、エンリッチされた、注釈付きのデータセットを入手。

詳しくはAIハブをご覧ください。

ブライトデータのアカウントを作成し、AIエージェント開発のためのすべての製品とサービスをお試しください!