---
title: "Bright Dataを使ったLinkedIn就活AIアシスタントの構築"
slug: linkedin-job-hunting-agent
date: 2025-08-28T08:19:38+00:00
modified: 2025-11-04T08:45:54+00:00
permalink: https://brightdata.jp/blog/ai/linkedin-job-hunting-agent
type: blog
---

[ ブログ ](https://brightdata.jp/blog "ブログ") / [AI](https://brightdata.jp/blog/ai)







 [AI](https://brightdata.jp/blog/ai)

# Bright Dataを使ったLinkedIn就活AIアシスタントの構築

Bright DataとOpenAIを使用して強力なLinkedIn就活アシスタントを構築し、求人検索の自動化、AIスコアマッチ、就活の効率化を実現する方法をご覧ください。

 12 分読





 [ ![Antonello Zanini](https://media.brightdata.jp/2022/12/Antonello-Zanini-2-50x50.jpg) ](https://brightdata.com/blog/authors/antonello-zanini)

 [Antonello Zanini

Technical Writer

 ](https://brightdata.com/blog/authors/antonello-zanini)





 ![LinkedIn Job Hunting AI Assistant with Bright Data blog image](https://media.brightdata.jp/2025/08/LinkedIn-Job-Hunting-AI-Assistant-with-Bright-Data-blog-image.png)





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

1. AIを搭載したLinkedIn就活アシスタントがどのように機能するか。
2. Bright DataからのLinkedInの求人データをOpenAIを搭載したワークフローと統合して構築する方法。
3. このワークフローを改善し、堅牢な就活アシスタントに拡張する方法。

最終的なプロジェクトファイルは[ここで](https://github.com/brightdata/linkedin-job-hunting-assistant)見ることができます。

さあ、飛び込もう！

## LinkedIn就活AIアシスタントワークフローの説明

まず最初に、LinkedInの求人情報データにアクセスしなければ、LinkedIn就活AIアシスタントを構築することはできません。そこでBright Dataの出番です！

[LinkedIn Jobs Scraperの](/products/web-scraper/linkedin/jobs)おかげで、LinkedInの公開求人情報をウェブスクレイピングで取得することができます。LinkedInジョブズポータルで検索するのと同じような体験ができます。しかし、ウェブページの代わりに、構造化された求人データをJSONまたはCSV形式で直接受け取ることができます。

そのデータがあれば、AIにあなたのスキルと希望する職種に基づいて各求人に点数をつけてもらうことができる。これが、LinkedIn Job AI Assistantがあなたのためにしてくれることです。

## 技術的なステップ

LinkedInの求人AIワークフローを実装するために必要なステップは以下の通りです：

1. **CLIの引数をロード**する：コマンドライン引数を解析し、実行時のパラメーターを取得する。これにより、コードを変更することなく、柔軟な実行と簡単なカスタマイズが可能になる。
2. **環境変数をロードする：**環境変数からOpenAIとBright Data APIキーをロードします。これらは、このAIワークフローを動かすサードパーティの統合に接続するために必要です。
3. **設定ファイルを読み込む**：求人検索パラメータ、候補者プロファイルの詳細、希望する求人情報を含むJSON設定ファイルを読み込みます。この設定情報は、求人の検索とAIのスコアリングの指針となる。
4. **LinkedInから求人をスクレイピングする**：LinkedIn Jobs Scraper APIから、設定に従ってフィルタリングされた求人情報を取得します。
5. **AIによるスコアリング**：求人情報の各バッチをOpenAIに送信します。AIは、あなたのプロフィールと希望する仕事に基づいて、`0`点から`100`点まで採点します。また、各スコアを説明する短いコメントも追加され、マッチングの質を理解するのに役立ちます。
6. **AIのスコアとコメントで求人情報を拡大**します：\*\*\*\*AIが生成したスコアとコメントを元の求人情報にマージし、AIが生成した新しいフィールドで各求人記録を充実させます。
7. **スコアリングされた求人データをエクスポート**します：エンリッチされた求人データをCSVファイルにエクスポートし、さらなる分析と処理を行います。
8. **上位の求人情報を印刷**コンソールにマッチした上位の求人案件を主な詳細とともに直接表示し、最も関連性の高い案件を即座に把握することができます。

PythonでこのAIワークフローを実装する方法をご覧ください！

## OpenAIとBright Dataを使ってLinkedInの就活AIワークフローを構築する方法

このチュートリアルでは、LinkedInで求人を見つけるためのAIワークフローを構築する方法を学びます。LinkedInの求人データはBright Dataから、AI機能はOpenAIから提供されます。他のLLMを使うこともできる。

このセクションが終わる頃には、コマンドラインから実行できる完全なPython AIワークフローが完成しているはずだ。これは、LinkedInの最適な求人ポジションを特定し、求職活動という過酷でエネルギーを消耗する作業の時間と労力を節約してくれる。

LinkedInの求職AIアシスタントを作ってみよう！

### 前提条件

このチュートリアルに従うには、以下のものがあることを確認してください：

- [Python 3.8以上がローカルにインストールされている](https://www.python.org/downloads/)こと（最新バージョンの使用を推奨します）。
- Bright Data APIキー
- OpenAI API キー。

Bright Data APIキーをまだお持ちでない場合は、[Bright Dataアカウントを作成し、公式のセットアップガイドに従って](https://docs.brightdata.com/api-reference/authentication)ください。同様に、OpenAIの公式手順に従って[OpenAI APIキーを取得して](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key)ください。

### ステップ #0: Pythonプロジェクトのセットアップ

ターミナルを開き、LinkedIn就活AIアシスタント用の新しいディレクトリを作成します：

```none
mkdir linkedin-job-hunting-ai-assistant/
```

`linkedin-job-hunting-ai-assistant`フォルダは、あなたのAIワークフローのためのすべてのPythonコードを保持します。

次に、プロジェクトディレクトリに移動し、[その中で仮想環境を初期化する](https://docs.python.org/3/library/venv.html)：

```none
cd linkedin-job-hunting-ai-assistant/
python -m venv venv
```

次に、お気に入りのPython IDEでプロジェクトを開きます。[Python拡張機能付きのVisual Studio Codeか](https://code.visualstudio.com/docs/languages/python)、[PyCharm Community Editionを](https://www.jetbrains.com/pycharm/download/)お勧めします。

プロジェクトフォルダの中に、`assistant.pyという`名前の新しいファイルを作成します。ディレクトリ構造はこのようになっているはずです：

```none
linkedin-job-hunting-ai-assistant/」のようになります。
├─ venv/
└── assistant.py
```

ターミナルで仮想環境を起動します。LinuxやmacOSの場合、以下のように実行します：

```none
ソース venv/bin/activate
```

Windowsの場合は、以下のコマンドを実行します：

```none
venv/Scripts/activate
```

次のステップでは、必要なPythonパッケージのインストールを案内します。アクティベートされた仮想環境で今すぐインストールしたい場合は、次のコマンドを実行してください：

```none
pip install python-dotenv requests openai pydantic
```

特に必要なライブラリは以下の通りです：

- `python-dotenv`：`.env`ファイルから環境変数をロードし、APIキーの安全な管理を容易にする。
- `pydantic`：設定ファイルを検証し、構造化されたPythonオブジェクトにパースする。
- `requests`：Bright DataのようなAPIを呼び出してデータを取得するためのHTTPリクエストを処理する。
- `openai`AIジョブスコアリングのためのOpenAIの言語モデルと対話するためのOpenAIクライアントを提供します。

**注**：このチュートリアルでは言語モデルプロバイダとしてOpenAIに依存しているため、ここで`openai`ライブラリをインストールしています。もし別のLLMプロバイダーを使うつもりなら、対応するSDKか依存関係をインストールしてください。

これで準備は完了です！これで、OpenAIとBright Dataを使ってAIワークフローを構築するためのPython開発環境が整いました。

### ステップ #1: CLI引数をロードする

LinkedIn就活AIスクリプトにはいくつかの引数が必要です。コードを変更することなく、再利用性とカスタマイズ性を保つために、CLI経由でそれらを読み込む必要があります。

具体的には、以下のCLI引数が必要です：

- `-config_file`：-config\_file：求人検索のパラメータ、候補者のプロフィール詳細、希望する求人情報を含むJSON設定ファイルへのパス。デフォルトは`config.json`です。
- `-batch_size`：一度にAIにスコアリングのために送信する求人数。デフォルトは`5`。
- `--jobs_number`：Bright Data LinkedIn Jobs Scraperが返すジョブエントリーの最大数。デフォルトは`20`です。
- `--output_csv`: AIのスコアとコメントを含むエンリッチされた求人データを含む出力CSVファイルの名前。デフォルトは`jobs_scored.csv`。

これらの引数をコマンドラインインターフェイスから読み込むには、以下の関数を使用します：

```none
def parse_cli_args()：
    # config と runtime オプションのコマンドライン引数を解析します。
    parser = argparse.ArgumentParser(description="LinkedIn 就活アシスタント")
    parser.add_argument("--config_file", type=str, default="config.json", help="設定JSONファイルへのパス")
    parser.add_argument("--jobs_number", type=int, default=20, help="ブライトデータスクレイパーAPIが返すジョブ数を制限する")
    parser.add_argument("---batch_size", type=int, default=5, help="各バッチで採点するジョブ数")
    parser.add_argument("--output_csv", type=str, default="jobs_scored.csv", help="出力CSVファイル名")

    return parser.parse_args()
```

Python標準ライブラリから[`argparseを`](https://docs.python.org/3/library/argparse.html)インポートすることを忘れないでください：

```none
import argparse
```

素晴らしい！これでCLIから引数にアクセスできるようになりました。

### ステップ2: 環境変数の読み込み

環境変数から秘密を読み込むようにスクリプトを設定します。環境変数の読み込みを簡単にするために、[`python-dotenv`](https://pypi.org/project/python-dotenv/)パッケージを使います。仮想環境を起動した状態で、次のコマンドを実行してインストールします：

```none
pip install python-dotenv
```

次に、`assistant.py`ファイルでライブラリをインポートし、環境変数をロードするために`load_dotenv() を`呼び出します：

```none
from dotenv import load_dotenv

load_dotenv()
```

これでアシスタントはローカルの`.env`ファイルから変数を読み込めるようになりました。このように、プロジェクトディレクトリのルートに`.env`ファイルを追加します：

```none
linkedin-job-hunting-ai-assistant/に追加します。
├─ venv/
├── .env # <-----------
└── assistant.py
```

`.env`ファイルを開き、`OPENAI_API_KEYと` `BRIGHT_DATA_API_KEYを`追加します：

```none
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
bright_data_api_key="<your_bright_data_api_key>"
```

`<YOUR_OPENAI_API_KEY>`プレースホルダーを[実際のOpenAI APIキーに](https://platform.openai.com/api-keys)置き換えます。同様に、`<YOUR_BRIGHT_DATA_API_KEY>`プレースホルダをあなたの[Bright Data APIキーに置き換えて](https://docs.brightdata.com/api-reference/authentication#generating-an-api-key%3A)ください。

そして、スクリプトに以下の関数を追加して、これら2つの環境変数をロードします：

```none
def load_env_vars()：
    # 環境変数から必要なAPIキーを読み込み、存在を確認します。
    openai_api_key = os.getenv("OPENAI_API_KEY")
    brightdata_api_key = os.getenv("BRIGHT_DATA_API_KEY")

    missing = [].
    if not openai_api_key：
        missing.append("OPENAI_API_KEY")
    if not brightdata_api_key：
        missing.append("BRIGHT_DATA_API_KEY")。
    if missing：
        raise EnvironmentError(
            f "必要な環境変数がありません：{'、'.join(missing)}n"
            "あなたの.envまたは環境で設定してください。"
        )

    return openai_api_key, brightdata_api_key
```

Python Standard Libraryから必要なimportを追加します：

```none
import os
```

素晴らしい！これで環境変数を使ったサードパーティ統合シークレットの安全なロードができました。

### ステップ #3: 設定ファイルを読み込む

さて、どの求人に興味があるかをアシスタントに伝えるプログラム的な方法が必要です。正確な結果を得るためには、アシスタントはあなたの職歴とどのような仕事を探しているかも知っていなければなりません。

その情報をコードに直接ハードコーディングするのを避けるために、JSON設定ファイルから読み取るのが理にかなっています。具体的には、このファイルには

- `場所`：求人を検索したい地理的な場所。求人情報が収集される主な地域を定義します。
- `keyword`: 「Python Developer」のように、探している職種や役割に関連する特定の単語やフレーズ。完全に一致させる場合は引用符を使用してください。
- `国`2文字の国コード（例：米国は`US`、フランスは`FR`）で、求人情報を特定の国に絞り込むことができます。
- `time_range`：求人情報が掲載された時間枠。最近の求人や関連性のある求人を絞り込む（例：`過去1週間`、`過去1ヶ月など`）。
- `job_type`：`フルタイム`、`パートタイムなどの`雇用形態。
- `経験レベル`：`エントリーレベル`、`アソシエイトなど`、必要な職業経験レベル。
- `リモート`勤務地のモード（例：`リモート`、`オンサイト`、`ハイブリッド`）に基づいて求人情報をフィルタリングします。
- `会社`特定の企業や雇用主からの求人情報に焦点を絞って検索します。
- `selective_search`：有効にすると、指定したキーワードを含まない求人情報を除外し、より的を絞った検索結果を得ることができます。
- `jobs_to_not_include`：検索結果から除外する特定の求人IDのリスト。重複や不要な掲載を除外するのに便利です。
- `location_radius`：指定した場所の周辺を含む、検索範囲を定義します。
- `profile_summary`: プロフィールの概要。この情報はAIが各求人があなたにどの程度マッチするかを評価するために使用されます。
- `desired_job_summary`: 求めている職種についての簡単な説明で、AIが求人リストを適合性に基づいてスコアリングするのに役立ちます。

これらは、[Bright DataのLinkedIn求人リスト「キーワードで検索」API](/cp/scrapers/api/gd_lpfll7v5hcqtkxl6l/keyword/api)（LinkedIn Jobs Scraperソリューションの一部）で必要とされる引数に正確に対応しています：

![Note the source arguments in the Bright Data LinkedIn job listings “discover by keyword”  page](https://media.brightdata.com/2025/08/image-155-1024x548.png)これらのフィールドの詳細と想定される値については、[公式ドキュメントを参照してください](https://docs.brightdata.com/api-reference/web-scraper-api/social-media-apis/linkedin#discover-by-keyword)。

最後の2つのフィールド`（profile_summaryと` `difired_job_summary`）は、あなたが職業上どのような人物で、何を探しているかを記述します。これらはAIに渡され、Bright Dataから返される各求人情報を採点します。

コード内で設定ファイルを扱いやすくするために、[Pydanticモデルにマッピング](https://docs.pydantic.dev/2.3/usage/types/dicts_mapping/)することをお勧めします。まず、Pydanticを仮想環境にインストールします：

```none
pip install pydantic
```

次に、JSON設定ファイルをマッピングするPydanticモデルを以下のように定義します：

```none
class JobSearchConfig(BaseModel)：
    location: str
    キーワードOptional[str] = None
    country：オプション[str] = なし
    時間範囲：任意[str] = なし
    job_type：任意[str] = なし
    経験レベルオプション[str] = なし
    リモート任意[str] = なし
    会社オプション[str] = なし
    selective_search：オプション[bool] = Field(デフォルト=False)
    jobs_to_not_include：オプション[リスト[str]] = フィールド(default_factory=list)
    location_radius：オプション[str] = None
    # 追加フィールド
    profile_summary: str # AIスコアリングのための候補者のプロフィールサマリー
    desired_job_summary: str # AIスコアリングのための希望職種の説明
```

最初と最後の2つの設定フィールドだけが必須であることに注意してください。

次に、`-config_file`ファイルパスからJSONコンフィグを読み込む関数を作成します。それを`JobSearchConfig`インスタンスにデシリアライズします：

```none
def load_and_validate_config(filename: str) -> JobSearchConfig：
    # JSON コンフィグファイルを読み込む
    try：
        with open(filename, "r", encoding="utf-8") as f：
            data = json.load(f)
    except FileNotFoundError：
        raise FileNotFoundError(f "Config file '{filename}'が見つかりません。")

    try：
        # 入力された JSON データを JobSearchConfig インスタンスにデシリアライズします。
        config = JobSearchConfig(**data)
    except ValidationError as e：
        raise ValueError(f "Config deserialization error:˶n{e}")

    return config
```

今回はこれらのインポートが必要です：

```none
from pydantic import BaseModel, Field, ValidationError
from typing import Optional, List
インポート json
```

すごい！これで設定ファイルが正しく読み込まれ、意図したとおりにデシリアライズされました。

### ステップ #4: LinkedInから求人をスクレイピングする

先ほど読み込んだ設定を使って、Bright Data LinkedIn Jobs Scraper APIを呼び出します。

Bright DataのWebスクレイパーAPIがどのように動作するのかよく知らない場合は、[まずドキュメントをチェックする](https://docs.brightdata.com/datasets/scrapers/scrapers-library/overview)価値がある。

要するに、[Web Scraper APIは](/products/web-scraper)、特定のドメインから公開データを取得できるAPIエンドポイントを提供する。舞台裏では、Bright Dataがサーバー上で既製のスクレイピング・タスクを初期化して実行する。これらのAPIは[、IPローテーション、CAPTCHA、および](/blog/ウェブデータ/anti-scraping-techniques)ウェブページから公開データを効果的かつ倫理的に収集するための[その他の手段を処理](/blog/ウェブデータ/anti-scraping-techniques)します。タスクが完了すると、スクレイピングされたデータは構造化されたフォーマットに解析され、スナップショットとして利用できるようになります。

したがって、一般的なワークフローは次のようになる：

1. APIコールをトリガーしてウェブスクレイピングタスクを開始する。
2. スクレイピングされたデータを含むスナップショットの準備ができているか定期的にチェックする。
3. スナップショットが利用可能になったら、スナップショットからデータを取得する。

上記のロジックは数行のコードで実装できる：

```none
def trigger_and_poll_linkedin_jobs(config：jobSearchConfig, brightdata_api_key: str, jobs_number: int, polling_timeout=10)：
    # Bright Data LinkedInの求人検索をトリガーする
    url = "https://api.brightdata.com/datasets/v3/trigger"
    ヘッダー = {
        "Authorization": f "ベアラ {brightdata_api_key}"、
        "Content-Type"："application/json"、
    }
    params = {
        "dataset_id"："gd_lpfll7v5hcqtkxl6l", # Bright Data "Linkedin job listings information - discover by keyword" dataset ID
        "include_errors"："true"、
        "type"："discover_new": "discover_new"、
        "discover_by"：「キーワード
        「limit_per_input": str(jobs_number)、
    }

    # ユーザー設定に基づき、Bright Data API用のペイロードを準備する。
    data = [{ {" location": config.location, } # Bright Data API用のペイロードを準備する
        "location": config.location、
        "keyword": config.keyword または ""、
        "country": config.country または ""、
        "time_range": config.time_range または ""、
        「job_type": config.job_typeまたは""、
        「経験レベル(experience_level)": config.experience_levelまたは""、
        "remote": config.remoteまたは""、
        "company": config.companyまたは""、
        "selective_search": config.selective_search、
        「jobs_to_not_include": config.jobs_to_not_includeまたは""、
        「location_radius": config.location_radiusまたは""、
    }]

    response = requests.post(url, headers=headers, params=params, json=data)
    if response.status_code != 200：
        raise RuntimeError(f "Trigger request failed: {response.status_code} - {response.text}")

    snapshot_id = response.json().get("snapshot_id")
    if not snapshot_id：
        raise RuntimeError("No snapshot_id returned from Bright Data trigger.")

    print(f "LinkedIn job search triggered! Snapshot ID: {snapshot_id}")

    # データが準備できるかタイムアウトするまでスナップショットエンドポイントをポーリングする
    snapshot_url = f "https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
    headers = {"Authorization": f "ベアラ{brightdata_api_key}"}。

    print(f "Polling snapshot for ID: {snapshot_id}")

    while True：
        snap_resp = requests.get(snapshot_url, headers=headers)
        if snap_resp.status_code == 200：
            # スナップショットの準備完了：求人情報のJSONデータを返す
            print("Snapshot is ready")

            return snap_resp.json()
        elif snap_resp.status_code == 202：
            # スナップショットの準備ができていない：待機して再試行する
            print(f "スナップショットの準備ができていません。 {polling_timeout}秒後に再試行します...")
            time.sleep(polling_timeout)
        さもなければ
            raise RuntimeError(f "Snapshot polling failed: {snap_resp.status_code} - {snap_resp.text}")
```

この関数は設定ファイルの検索パラメーターを使用してBright DataのLinkedIn Jobs Scraperを起動します。そして、データスナップショットの準備ができるまでポーリングし、利用可能になるとJSON形式で求人情報を返します。[認証は、](https://docs.brightdata.com/api-reference/authentication)先に環境変数から読み込んだ[Bright Data API キーを使用して処理されることに](https://docs.brightdata.com/api-reference/authentication)注意してください。

LinkedIn Jobs Scraperで取得したスナップショットには、以下のようなJSON形式の求人情報が含まれます：

![The resulting JSON snapshot containing LinkedIn job listings produced by the LinkedIn Jobs Scraper](https://media.brightdata.com/2025/08/image-156-1024x723.png)**注意**: 作成されたJSONスナップショットには、`--jobs_numberまでの`求人情報が含まれています。この場合、20件の求人情報が含まれています。

上記の機能を動作させるには、`requestsを`インストールする必要がある：

```none
pip install requests
```

どのように動作するかの詳細については、[Python HTTP Requestsのアドバンスガイドを](/blog/ウェブデータ/python-requests-guide)参照してください。

次に、[`timeと`](https://docs.python.org/3/library/time.html)一緒にPython標準ライブラリからインポートすることを忘れないでください：

```none
import requests
import time
```

素晴らしい！あなたはBright Dataと統合し、新鮮で具体的なLinkedInの求人データを収集しました。

### ステップ #5: AIを使って求人情報をスコアリングする

今度は、LLM（[OpenAIのモデルなど](https://platform.openai.com/docs/models)）にスクレイピングされた各求人情報を評価してもらう番だ。
ゴールは、求人がどれだけマッチしているかに基づいて、短いコメントとともに`0から` `100までの`スコアを割り当てることだ：

1. あなたの職務経験`（profile_summary）`
2. 希望職種`（希望職種サマリー）`

APIのラウンドトリップを減らしてスピードアップするために、求人をバッチで処理することは理にかなっています。特に、一度に`--batch_size`個のジョブを評価することになります。

[`openai`](https://pypi.org/project/openai/)パッケージをインストールすることから始めよう：

```none
pip install openai
```

そして、OpenAIをインポートし、クライアントを初期化します：

```none
from openai import OpenAI

# ...

# OpenAIクライアントを初期化する
client = OpenAI()
```

`OpenAI の`コンストラクタに API キーを手動で渡す必要はないことに注意してください。ライブラリは自動的に`OPENAI_API_KEY`環境変数からそれを読み込みます。

AIを使ったジョブスコアリング関数を作成します：

```none
def score_jobs_batch(jobs_batch: List[dict], profile_summary: str, desired_job_summary: str) -> List[JobScore]：
    # AIが候補者のプロファイルに基づいてマッチする仕事をスコアリングするためのプロンプトを構築する
    prompt = f""
        "あなたは採用のエキスパートです。次のような候補者プロフィールがあるとします。
        "{profile_summary}nn"
        "希望する職務内容:ⅳ{desired_job_summary}ⅳ"" "各求人広告を正確に採点してください。
        "各求人情報に対して、プロフィールと希望職種との一致度を0から100まで正確に採点する。
        "各求人に対して、スコアとマッチの質を説明する短いコメント（最大50文字）を追加します。"
        "キー'job_posting_id'、'score'、'comment'を持つオブジェクトの配列を返す.˶"
        "ジョブ:{json.dumps(jobs_batch)}}n".
    """
    メッセージ = [
        {"role"："system", "content"："you are a helpful job scoring assistant." }、
        {"role"："user", "content": prompt}、
    ]

    # OpenAI APIを使って、構造化されたレスポンスをJobScoresResponseモデルにパースする
    response = client.responses.parse(
        model="gpt-5-mini"、
        input=messages、
        text_format=JobScoresResponse、
    )

    # スコアされたジョブのリストを返す
    return response.output_parsed.scores
```

これは新しい[`gpt-5-mini`](https://platform.openai.com/docs/models/gpt-5-mini)モデルを使って、OpenAIにスクレイピングされた各求人投稿を`0から` `100の`間でスコアリングさせ、短い説明コメントとともに返します。

レスポンスが常に必要なフォーマットで返されることを確認するために、`parse()`メソッドが呼び出されます。このメソッドは[構造化された出力モデルを強制し](https://platform.openai.com/docs/guides/structured-outputs)、ここでは以下のPydanticモデルで定義されています：

```none
class JobScore(BaseModel)：
    job_posting_id: str
    score: int = Field(..., ge=0, le=100)
    comment: str

class JobScoresResponse(BaseModel)：
    score: intリスト[JobScore］
```

基本的に、AI は以下のような構造化された JSON データを返します：

```none
{
  "scores": [
    {
      "job_posting_id"："4271494891",
      "score"：80,
      "comment"："エンドツーエンドのオーナーシップ、API、クロスファンクショナルワークを持つ強力なSaaSプロダクトフィットは、あなたのスタートアップPMと顧客第一の経験と一致します。このポジションは2-4年目をターゲットとしており、7年目としてはやや若手です。"
    },
    // 簡略化のため省略...
    {
      "job_posting_id"："4273328527",
      "score"：65,
      "comment"："データ/技術に重きを置いたプロダクトの役割。アジャイルでクロスファンクショナルな責任は一致するが、定量的/技術的なドメイン経験（金融/統計モデリング）を好む。" "フィットしないかもしれない。
    }
  ]
}
```

`parse()`メソッドは、JSONレスポンスを`JobScoresResponse`インスタンスに変換します。そして、あなたのコードでスコアとコメントの両方にプログラムでアクセスできるようになります。

**注意**: もし別の LLM プロバイダを使いたい場合は、上記のコードを調整してください。

さあ、始めましょう！これでAIによるジョブ評価は完了です。

### ステップ #6: AIアコアとコメントでジョブを拡張する

先ほどのAIが返した生のJSON出力を見てみましょう。各求人スコアに`job_posting_id`フィールドが含まれていることがわかります。これはLinkedInが求人リストを識別するために使用するIDに対応しています。

これらのIDは、Bright Data LinkedIn Jobs Scraperによって生成されたスナップショットデータにも表示されるので、それを使って次のことができます：

1. スクレイピングされた求人情報の配列から元の求人情報オブジェクトを見つける。
2. AIが生成したスコアとコメントを追加することで、求人情報オブジェクトを充実させます。

以下の関数で実現できます：

```none
def extend_jobs_with_scores(jobs: List[dict], all_scores: List[JobScore]) -> List[dict]：
    # エンリッチされたデータを格納する場所
    extended_jobs = [].

    # 元のジョブにAIスコアとコメントを組み合わせる
    for score_obj in all_scores：
        matched_job = None
        for job in jobs：
            if job.get("job_posting_id") == score_obj.job_posting_id：
                matched_job = job
                ブレーク
        if matched_job：
            job_with_score = dict(matched_job)
            job_with_score["ai_score"] = score_obj.score
            job_with_score["ai_comment"] = score_obj.comment
            extended_jobs.append(job_with_score)

    # AIスコアで拡張ジョブをソートする（最も高いものからソートする）
    extended_jobs.sort(key=lambda j: j["ai_score"], reverse=True)

    return extended_jobs
```

お分かりのように、タスクに取り組むには2つの`for`ループで十分だ。エンリッチされたデータを返す前に、リストを`ai_scoreの`降順でソートする。そうすることで、ベストマッチの求人が一番上に表示され、素早く簡単に見つけることができます。

素晴らしい！これでLinkedIn就活AIアシスタントの準備はほぼ整いました！

### ステップ #7: スコアされた求人データをエクスポートする

Pythonの組み込み[`csv`](https://docs.python.org/3/library/csv.html)パッケージを使って、スクレイピングされエンリッチされた求人データをCSVファイルにエクスポートします。

```none
def export_extended_jobs(extended_jobs: List[dict], output_csv: str)：
    # 配列の最初の要素からフィールド名を動的に取得する
    fieldnames = list(extended_jobs[0].keys())
    with open(output_csv, mode="w", newline="", encoding="utf-8") as csvfile：
         # AIスコアを含む拡張ジョブデータをCSVに書き込む
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for job in extended_jobs：
            writer.writerow(job)

    print(f"{len(extended_jobs)}ジョブを{output_csv}にエクスポート")
```

上記の関数は、`output_csvを` `--output_csv`CLI引数に置き換えて呼び出されます。

`csvの`インポートを忘れないでください：

```none
インポートcsv
```

完璧だ！LinkedIn就活AIアシスタントは、AIで強化されたデータを出力CSVファイルにエクスポートします。

### ステップ #8: トップマッチを印刷する

出力されたCSVファイルを開かずにターミナルですぐにフィードバックを得るには、上位3つの求人から主要な詳細を印刷する関数を書きます：

```none
def print_top_jobs(extended_jobs: List[dict], top: int = 3)：
    print(f"n*** Top {top} job matches ***")
    for job in extended_jobs[:3]：
        print(f "URL：{job.get('url', 'N/A')}")
        print(f "Title：print(f "タイトル: {job.get('job_title', 'N/A')}")
        print(f "AIスコア：{job.get('ai_score')}")
        print(f "AIコメント：print(f "AIコメント：{job.get('ai_comment', 'N/A')}")
        print("-" * 40)
```

### ステップ#9：すべてをまとめる

前のステップのすべての関数をLinkedIn就活アシスタントのメインロジックにまとめます：

```none
# CLIから実行時のパラメーターを取得する
args = parse_cli_args()

tryする：
     # 環境からAPIキーを読み込む
    _, brightdata_api_key = load_env_vars()

     # ジョブ検索の設定ファイルをロードする
    config = load_and_validate_config(args.config_file)

    # ジョブの取得
    jobs_data = trigger_and_poll_linkedin_jobs(config, brightdata_api_key, args.jobs_number)

    print(f"{len(jobs_data)} jobs found!")
except Exception as e：
    print(f"[Error] {e}")
    リターン

all_scores = [].
# APIへの過負荷を避け、大きなデータセットを扱うためにジョブをバッチ処理する
for i in range(0, len(jobs_data), args.batch_size)：
    バッチ = jobs_data[i : i + args.batch_size].

    print(f "Scoring batch {i // args.batch_size + 1} with {len(batch)} jobs...")

    scores = score_jobs_batch(batch, config.profile_summary, config.desired_job_summary)
    all_scores.extend(scores)

    time.sleep(1) # APIレート制限のトリガーを回避するため

# スコアをスクレイピングされたジョブにマージする
extended_jobs = extend_jobs_with_scores(jobs_data, all_scores)

# 結果をCSVに保存
export_extended_jobs(extended_jobs, args.output_csv)

# クイックレビューのために、キー情報とマッチしたトップジョブを印刷する
print_top_jobs(extended_jobs)
```

信じられない！あとはアシスタントの完全なコードを確認し、期待通りに動作することを確認するだけです。

### ステップ#10: 完全なコードと最初の実行

最終的な`assistant.py`ファイルには

```none
# pip install python-dotenv requests openai pydantic

import argparse
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field, ValidationError
from typing import Optional, List
json をインポート
import requests
import time
from openai import OpenAI
インポート csv

# .env ファイルから環境変数をロードする
load_dotenv()

# プロジェクトをサポートする Pydantic モデル
class JobSearchConfig(BaseModel)：
    ソース: https://docs.brightdata.com/api-reference/web-scraper-api/social-media-apis/linkedin#discover-by-keyword
    location: str
    キーワードオプション[str] = なし
    country：オプション[str] = なし
    時間範囲：任意[str] = なし
    job_type：任意[str] = なし
    経験レベルオプション[str] = なし
    リモート任意[str] = なし
    会社オプション[str] = なし
    selective_search：オプション[bool] = Field(デフォルト=False)
    jobs_to_not_include：オプション[リスト[str]] = フィールド(default_factory=list)
    location_radius：オプション[str] = None
    # 追加フィールド
    profile_summary: str # AIスコアリングのための候補者のプロフィールサマリー
    desired_job_summary: str # AIスコアリングのための希望職種の説明

class JobScore(BaseModel)：
    job_posting_id: str
    score: int = Field(..., ge=0, le=100)
    コメント: str

class JobScoresResponse(BaseModel)：
    score: intリスト[JobScore］

def parse_cli_args()：
    # config と runtime オプションのコマンドライン引数を解析する
    parser = argparse.ArgumentParser(description="LinkedIn 就活アシスタント")
    parser.add_argument("--config_file", type=str, default="config.json", help="設定JSONファイルへのパス")
    parser.add_argument("--jobs_number", type=int, default=20, help="ブライトデータスクレイパーAPIが返すジョブ数を制限する")
    parser.add_argument("---batch_size", type=int, default=5, help="各バッチで採点するジョブ数")
    parser.add_argument("--output_csv", type=str, default="jobs_scored.csv", help="出力CSVファイル名")

    return parser.parse_args()

def load_env_vars()：
    # 環境から必要なAPIキーを読み込み、存在を確認する
    openai_api_key = os.getenv("OPENAI_API_KEY")
    brightdata_api_key = os.getenv("BRIGHT_DATA_API_KEY")

    missing = [].
    if not openai_api_key：
        missing.append("OPENAI_API_KEY")
    if not brightdata_api_key：
        missing.append("BRIGHT_DATA_API_KEY")。
    if missing：
        raise EnvironmentError(
            f "必要な環境変数がありません：{'、'.join(missing)}n"
            "あなたの.envまたは環境で設定してください。"
        )

    return openai_api_key, brightdata_api_key

def load_and_validate_config(filename: str) -> JobSearchConfig：
    # JSON コンフィグファイルをロードする
    try：
        with open(filename, "r", encoding="utf-8") as f：
            data = json.load(f)
    except FileNotFoundError：
        raise FileNotFoundError(f "Config file '{filename}'が見つかりません。")

    try：
        # 入力されたJSONデータをJobSearchConfigインスタンスにデシリアライズします。
        config = JobSearchConfig(**data)
    except ValidationError as e：
        raise ValueError(f "Config deserialization error:˶n{e}")

    return config

def trigger_and_poll_linkedin_jobs(config：JobSearchConfig, brightdata_api_key: str, jobs_number: int, polling_timeout=10)：
    # Bright Data LinkedInの求人検索をトリガーする
    url = "https://api.brightdata.com/datasets/v3/trigger"
    ヘッダー = {
        "Authorization": f "ベアラ {brightdata_api_key}"、
        "Content-Type"："application/json"、
    }
    params = {
        "dataset_id"："gd_lpfll7v5hcqtkxl6l", # Bright Data "Linkedin job listings information - discover by keyword" dataset ID
        "include_errors"："true"、
        "type"："discover_new": "discover_by"、
        "discover_by"：「キーワード
        「limit_per_input": str(jobs_number)、
    }

    # ユーザー設定に基づき、Bright Data API用のペイロードを準備する。
    data = [{ {" location": config.location, } # Bright Data API用のペイロードを準備する
        "location": config.location、
        "keyword": config.keyword または ""、
        "country": config.country または ""、
        "time_range": config.time_range または ""、
        「job_type": config.job_typeまたは""、
        「経験レベル(experience_level)": config.experience_levelまたは""、
        "remote": config.remoteまたは""、
        "company": config.companyまたは""、
        "selective_search": config.selective_search、
        「jobs_to_not_include": config.jobs_to_not_includeまたは""、
        「location_radius": config.location_radiusまたは""、
    }]

    response = requests.post(url, headers=headers, params=params, json=data)
    if response.status_code != 200：
        raise RuntimeError(f "Trigger request failed: {response.status_code} - {response.text}")

    snapshot_id = response.json().get("snapshot_id")
    if not snapshot_id：
        raise RuntimeError("No snapshot_id returned from Bright Data trigger.")

    print(f "LinkedIn job search triggered! Snapshot ID: {snapshot_id}")

    # データが準備できるかタイムアウトするまでスナップショットエンドポイントをポーリングする
    snapshot_url = f "https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
    headers = {"Authorization": f "ベアラ{brightdata_api_key}"}。

    print(f "Polling snapshot for ID: {snapshot_id}")

    while True：
        snap_resp = requests.get(snapshot_url, headers=headers)
        if snap_resp.status_code == 200：
            # スナップショットの準備完了：求人情報のJSONデータを返す
            print("Snapshot is ready")

            return snap_resp.json()
        elif snap_resp.status_code == 202：
            # スナップショットの準備ができていない：待機して再試行する
            print(f "スナップショットの準備ができていません。 {polling_timeout}秒後に再試行します...")
            time.sleep(polling_timeout)
        さもなければ
            raise RuntimeError(f "Snapshot polling failed: {snap_resp.status_code} - {snap_resp.text}")

# OpenAIクライアントを初期化する
client = OpenAI()

def score_jobs_batch(jobs_batch: List[dict], profile_summary: str, desired_job_summary: str) -> List[JobScore]：
    # AIが候補者のプロファイルに基づいてマッチした仕事をスコアリングするためのプロンプトを構築する
    prompt = f""
        "あなたは採用のエキスパートです。次のような候補者プロフィールがあるとします。
        "{profile_summary}nn"
        "希望する職務内容:ⅳ{desired_job_summary}ⅳ"" "各求人広告を正確に採点してください。
        "各求人情報に対して、プロフィールと希望職種との一致度を0から100まで正確に採点する。
        "各求人に対して、スコアとマッチの質を説明する短いコメント（最大50文字）を追加します。"
        "キー'job_posting_id'、'score'、'comment'を持つオブジェクトの配列を返す.˶"
        "ジョブ:{json.dumps(jobs_batch)}}n".
    """
    メッセージ = [
        {"role"："system", "content"："you are a helpful job scoring assistant." }、
        {"role"："user", "content": prompt}、
    ]

    # OpenAI APIを使って、構造化されたレスポンスをJobScoresResponseモデルにパースする
    response = client.responses.parse(
        model="gpt-5-mini"、
        input=messages、
        text_format=JobScoresResponse、
    )

    # スコアされたジョブのリストを返す
    return response.output_parsed.scores

def extend_jobs_with_scores(jobs: List[dict], all_scores: List[JobScore]) -> List[dict]：
    # エンリッチされたデータを格納する場所
    extended_jobs = [].

    # 元のジョブにAIスコアとコメントを組み合わせる
    for score_obj in all_scores：
        matched_job = None
        for job in jobs：
            if job.get("job_posting_id") == score_obj.job_posting_id：
                matched_job = job
                ブレーク
        if matched_job：
            job_with_score = dict(matched_job)
            job_with_score["ai_score"] = score_obj.score
            job_with_score["ai_comment"] = score_obj.comment
            extended_jobs.append(job_with_score)

    # AIスコアで拡張ジョブをソートする（最も高いものからソートする）
    extended_jobs.sort(key=lambda j: j["ai_score"], reverse=True)
    return extended_jobs

def export_extended_jobs(extended_jobs: List[dict], output_csv: str)：
    # 配列の最初の要素からフィールド名を動的に取得する
    fieldnames = list(extended_jobs[0].keys())
    with open(output_csv, mode="w", newline="", encoding="utf-8") as csvfile：
         # AIスコアを含む拡張ジョブデータをCSVに書き込む
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        for job in extended_jobs：
            writer.writerow(job)

    print(f"{len(extended_jobs)}ジョブを{output_csv}にエクスポート")

def print_top_jobs(extended_jobs: List[dict], top: int = 3)：
    print(f"n*** Top {top} job matches ***")
    for job in extended_jobs[:3]：
        print(f "URL：{job.get('url', 'N/A')}")
        print(f "Title：print(f "タイトル: {job.get('job_title', 'N/A')}")
        print(f "AIスコア：{job.get('ai_score')}")
        print(f "AIコメント：print(f "AIコメント：{job.get('ai_comment', 'N/A')}")
        print("-" * 40)

def main()：
    # CLIからランタイムパラメータを取得
    args = parse_cli_args()

    try：
         # 環境からAPIキーをロードする
        _, brightdata_api_key = load_env_vars()

         # ジョブ検索の設定ファイルをロードする
        config = load_and_validate_config(args.config_file)

        # ジョブの取得
        jobs_data = trigger_and_poll_linkedin_jobs(config, brightdata_api_key, args.jobs_number)

        print(f"{len(jobs_data)} jobs found!")
    except Exception as e：
        print(f"[Error] {e}")
        リターン

    all_scores = [].
    # APIへの過負荷を避け、大きなデータセットを扱うためにジョブをバッチ処理する
    for i in range(0, len(jobs_data), args.batch_size)：
        バッチ = jobs_data[i : i + args.batch_size].

        print(f "Scoring batch {i // args.batch_size + 1} with {len(batch)} jobs...")

        scores = score_jobs_batch(batch, config.profile_summary, config.desired_job_summary)
        all_scores.extend(scores)

        time.sleep(1) # APIレート制限のトリガーを回避するため

    # スコアをスクレイピングされたジョブにマージする
    extended_jobs = extend_jobs_with_scores(jobs_data, all_scores)

    # 結果をCSVに保存
    export_extended_jobs(extended_jobs, args.output_csv)

    # クイックレビューのために、キー情報とマッチしたトップジョブを印刷する
    print_top_jobs(extended_jobs)

if __name__ == "__main__"：
    main()
```

あなたがニューヨークでハイブリッドジョブのポジションを探している7年の経験を持つプロダクトマネージャーだとします。`config.json`ファイルを以下のように設定する：

```none
{
  "location"："New York"、
  「キーワード"："Product Manager": "プロダクトマネージャー"、
  "country"：「アメリカ
  "time_range"：「過去1カ月
  "job_type": "フルタイム"：full-time": "フルタイム"、
  "experience_level": "ミッドシニアレベル"："Mid-Senior level": "ミッドシニアレベル"、
  "remote"：「ハイブリッド
  "profile_summary"："アジャイル方法論とクロスファンクショナルチームリーダーシップに特化した、技術系スタートアップで7年の経験を持つ経験豊富なプロダクトマネージャー"、
  "desired_job_summary"："SaaS製品や顧客中心の開発を中心としたフルタイムのプロダクトマネージャー職を探している。", "Hope_job_summary": "アジャイル手法や部門横断的なチームリーダーを専門とする。
}
```

次に、LinkedInの就活アシスタントを実行します：

```none
python assistant.py
```

**オプションです**：カスタマイズして実行する場合は、次のように記述します：

```none
python assistant.py --config_file=config.json --batch_size=10 --jobs_number=40 --output_csv=results.csv
```

このコマンドは指定した`config.json`ファイルを使用してアシスタントを実行します。このコマンドは`10`バッチでジョブを処理し、Bright Dataから最大`40の`ジョブリストを取得し、AIスコアとコメントでエンリッチされた結果を`results.csvに`保存します。

さて、デフォルトのCLI引数でアシスタントを実行すると、ターミナルにこのようなものが表示されるはずです：

```none
LinkedInの仕事検索がトリガーされました！スナップショットID: s_me6x0s3qldm9zz0wv
ID:s_me6x0s3qldm9zz0wvのスナップショットをポーリングしています。
スナップショットの準備ができていません。10秒後に再試行します。
# 簡潔にするため省略...
スナップショットの準備ができていません。10秒後に再試行...
スナップショットの準備ができました。
20のジョブが見つかりました！
バッチ1を5ジョブで採点...
バッチ2を5ジョブで採点...
バッチ3を5ジョブで採点...
バッチ 4 を 5 件で採点...
20のジョブをjobs.csvにエクスポート
```

すると、上位3つのジョブのインサイトが以下のように出力されます：

```none
*** トップ3ジョブマッチ
URL: https://www.linkedin.com/jobs/view/product-manager-growth-at-yext-4267903356?_l=en
タイトルプロダクトマネージャー、グロース
AIスコア： 92
AIコメント素晴らしいフィット感：SaaSに特化したグロースPMで、顧客中心の目標、製品主導のグロース、実験、部門横断的なコラボレーションがあり、候補者の経験と希望する役割に直接マッチする。
----------------------------------------
URL: https://www.linkedin.com/jobs/view/product-manager-at-industrial-color-4271494891?_l=en
タイトルプロダクトマネージャー
AIスコア： 90
AIコメント強力なマッチング：SaaS製品、API/インテグレーション、アジャイル、クロスファンクショナルリーダーシップを重視。唯一の小さなミスマッチは、2-4年のターゲット（あなたは7を持っている）と記載されていることです。
----------------------------------------
URL: https://www.linkedin.com/jobs/view/product-manager-at-resourceful-talent-group-4277945862?_l=en
タイトルプロダクトマネージャー
AIスコア： 88
AIコメントアジャイルプラクティスと顧客主導のイテレーションを伴う非常に類似したSaaS/統合の役割。採用担当者のリストでは2-4年をターゲットにしているが、あなたの7年間のスタートアップPM経験とクロスファンクショナルリーダーシップはうまくマッピングされる。
----------------------------------------
```

生成された`jobs_scored.csv`ファイルを開く。主な列が表示されます：

![The output in the jobs_scored.csv file](https://media.brightdata.com/2025/08/image-157-1024x320.png)各ジョブがAIによってどのように採点され、コメントされているかに注目してください。これで、成功する可能性のある仕事だけに集中することができます！

ほら！このAIを活用したLinkedInの就活ワークフローのおかげで、次の仕事を見つけるのがかつてないほど簡単になりました。

## 次のステップ

LinkedInの就活アシスタントは、チャットのように機能しますが、いくつかの改良点があります：

1. **同じ求人を繰り返し評価しない**スクリプトを実行するたびに異なる求人を評価するには、`config.json`ファイルに`jobs_to_not_include`配列を設定します。この配列には、アシスタントがすでに分析したジョブの`job_posting_idが`含まれます。例えば、現在のスクレイピングされたジョブを除外するために、設定は次のようになります：

```none
{
 "location"："New York"、
 "keyword"：「プロダクトマネージャー
 "country"："US"、
 "time_range"：「過去1カ月
 "job_type": "フルタイム"：full-time": "フルタイム"、
 "experience_level": "ミッドシニアレベル"："Mid-Senior level": "ミッドシニアレベル"、
 "remote"："Hybrid": "ハイブリッド"、
 "jobs_to_not_include": ["4267903356", "4271494891", "4277945862", "4267906118", "4255405781", "4267537560", "4245709356", "4265355147", "4277751182", "4256914967", "4281336197", "4232207277", "4273328527", "4277435772", "4253823512", "4279286518", "4224506933", "4250788498", "4256023955", "4252894407"], // <--- NOTE: The IDs of the jobs to exclude
 "profile_summary"："アジャイル方法論とクロスファンクショナルチームリーダーシップを専門とする、技術系スタートアップで7年の経験を持つ経験豊富なプロダクトマネージャー。"、
 "desired_job_summary"："SaaS製品や顧客中心の開発に焦点を当てたフルタイムのプロダクトマネージャーの役割を探しています。"
}
```

2. **定期的なスクリプト実行の自動化**：Cronのようなツールを使って、スクリプトを定期的（毎日など）に実行するようにスケジュールする。この場合、適切な`time_range`引数（「過去24時間」など）を設定し、`jobs_to_not_include`リストを更新して、すでに評価したジョブを除外することを忘れないようにします。こうすることで、新鮮な求人情報に集中することができます。
3. **専用のAIジャッジモデルを使用する**：一般的なGPT-5モデルの代わりに、[求人情報のマッチングとスコアリングのために微調整された](https://huggingface.co/learn/cookbook/en/llm_judge)専用の[AIモデルを](https://huggingface.co/learn/cookbook/en/llm_judge)使用することを検討してください。この単純な変更により、求人評価の精度と関連性を大幅に向上させることができます。

## まとめ

この記事では、Bright DataのLinkedIn求人スクレイピング機能を活用して、AIを活用した求人検索アシスタントを構築する方法を学びました。

ここで構築されたAIワークフローは、新しい仕事を探していて、最高の機会だけに集中することでチャンスを最大化したい人に最適です。自分のキャリア目標に本当にマッチし、採用の可能性が高い求人に応募することで、時間と労力を節約することができます。

[より高度なワークフローを](/ai/web-access)構築するには、[Bright DataのAIインフラストラクチャで](/ai)ライブウェブデータを取得、検証、変換するためのあらゆるソリューションをお試しください。

無料のBright Dataアカウントを作成し、AI対応データツールの実験を開始してください！

## よくある質問

**なぜIndeedや他の求人プラットフォームではなく、LinkedInの就活に焦点を当てるのですか？**上記の例ではLinkedInをデータソースとして使用していますが、スクリプトを簡単に拡張してIndeedやBright Dataで利用可能なその他の求人情報ソースと連携させることができます。Indeedとの統合の詳細については、[Indeed Jobs Scraperを](/products/web-scraper/indeed/job)参照してください。

**なぜGeminiや他のLLMプロバイダーではなくOpenAIなのですか？**このAIワークフローは、広く採用され人気があるOpenAIに依存しています。しかし、Gemini、Anthropic、Cohereなどの他のLLMプロバイダーや、APIが利用可能な大規模言語モデルでも簡単にワークフローを適応させることができます。

**なぜ専用のAIエージェントではなくAIワークフローなのか？**LinkedIn Jobs Scraperから返されるデータは非常に高品質で構造化されているため、LLMを直接使用してスコアリングのために処理することができます。そのため、推論や意思決定機能を持つ自律型エージェントのような複雑さは必ずしも必要ではありません。
それでも、より高度なLinkedIn就活AIエージェントを構築したい場合は、次のような[マルチエージェントアーキテクチャを](/blog/ai/ai-agent-tech-stack)検討することができます。
**Job fetcher agent**：(ツール[またはMCPを介して](/ai/mcp-server))Bright Dataインフラストラクチャと統合されたAIエージェントで、LinkedIn Jobs Scraper APIを呼び出して求人情報を継続的にフェッチして更新する。
**Job scorerエージェント**：
**オーケストレーターエージェント**：他の2つのエージェントを調整するトップレベルのエージェントで、高得点で関連性の高い求人情報が希望する数得られるまで、データ検索とスコアリングのサイクルを繰り返しトリガーします。
エージェントにプログラムして、自動的に求人情報に応募してもらうことも可能です。このようなLinkedIn就活システムの構築を考えているのであれば、[CrewAIのようなマルチエージェントプラットフォームを使うことを](/blog/ai/crewai-with-serp-api)お勧めします。



お問い合わせ無料トライアル![google social icon](/wp-content/themes/brightdata/assets/images/ic_google.svg)









 目次







LinkedIn Scrapers

Easily scrape LinkedIn with our LinkedIn Scraper API or LinkedIn No-Code Scraper.

[See pricing](/pricing/web-scraper "See pricing")

LinkedIn Datasets

Skip scraping. Purchase our LinkedIn profiles, companies, jobs, or posts datasets.

[See pricing](/pricing/datasets "See pricing")







 [ ](https://news.ycombinator.com/submitlink?t=Bright+Data%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FLinkedIn%E5%B0%B1%E6%B4%BBAI%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88%E3%81%AE%E6%A7%8B%E7%AF%89&u=https://brightdata.jp/blog/ai/linkedin-job-hunting-agent) [ ](https://www.linkedin.com/shareArticle?mini=true&title=Bright+Data%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FLinkedIn%E5%B0%B1%E6%B4%BBAI%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88%E3%81%AE%E6%A7%8B%E7%AF%89&url=https://brightdata.jp/blog/ai/linkedin-job-hunting-agent) [ ](http://www.reddit.com/submit?title=Bright+Data%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FLinkedIn%E5%B0%B1%E6%B4%BBAI%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88%E3%81%AE%E6%A7%8B%E7%AF%89&url=https://brightdata.jp/blog/ai/linkedin-job-hunting-agent)







##  あなたは下記にもご興味がおありかもしれません

 [ ![OpenHuman with Bright Data](https://media.brightdata.jp/2026/09/OpenHuman-with-Bright-Data.png) ](https://brightdata.jp/blog/ai/openhuman-with-bright-data "Bright Data CLIを通じたOpenHumanにおける本番対応ウェブアクセス")

 [AI



 ![Antonello Zanini](https://media.brightdata.jp/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### Bright Data CLIを通じたOpenHumanにおける本番対応ウェブアクセス

Bright Data CLIをOpenHumanに統合して、AIエージェント向けの本番対応ウェブアクセスとデータ収集を実現します。



 09-Sep-2026

 3 分読

 ](https://brightdata.jp/blog/ai/openhuman-with-bright-data)

 [ ![Multimodal Web Scraping with MiniMax](https://media.brightdata.jp/2026/09/Multimodal-Web-Scraping-with-MiniMax.png) ](https://brightdata.jp/blog/%e3%82%a6%e3%82%a7%e3%83%96%e3%83%87%e3%83%bc%e3%82%bf/multimodal-web-scraping-with-minimax "MiniMaxによるマルチモーダルウェブスクレイピング")

 [ウェブデータ



 ![Antonello Zanini](https://media.brightdata.jp/2022/12/Antonello-Zanini-2-50x50.jpg)

Antonello Zanini

Technical Writer





### MiniMaxによるマルチモーダルウェブスクレイピング

Bright Data Web UnlockerとMiniMax M3ビジョンを組み合わせて、画像やウェブページのスクリーンショットから構造化データを抽出します。



 09-Sep-2026

 1 分読

 ](https://brightdata.jp/blog/%e3%82%a6%e3%82%a7%e3%83%96%e3%83%87%e3%83%bc%e3%82%bf/multimodal-web-scraping-with-minimax)

 [ ![The 10 Best CLI Tools for Codex in 2026](https://media.brightdata.jp/2026/08/The-10-Best-CLI-Tools-for-Codex-in-2026.png) ](https://brightdata.jp/blog/ai/best-cli-tools-for-codex "2026年版 Codex向けCLIツール10選 – テスト＆ランキング")

 [AI



 ![Daniel Shashko](https://media.brightdata.jp/2022/04/Daniel-Shashko-2-50x50.png)

Daniel Shashko

Web Data &amp; AI Expert





### 2026年版 Codex向けCLIツール10選 – テスト＆ランキング

Codexをより速く、より有能にする10のCLIツール。サンドボックス内から実際のウェブアクセスを提供するBright Data CLIから始まります。



 06-Sep-2026

 4 分読

 ](https://brightdata.jp/blog/ai/best-cli-tools-for-codex)
