0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elasticsearch Agent Builder で Agentic RAG アシスタントを構築

0
Posted at

はじめに

「LeBron James と Stephen Curry、どちらをファンタジーバスケのチームに入れるべき?」——こんな質問に、リアルデータに基づいて 的確に答えてくれる AI アシスタントを作ってみましょう。

本記事では、Elasticsearch の Agent Builder を使って、NBA のスタッツデータを検索・分析し、ファンタジーバスケットボールのアドバイスを返す Agentic RAG アシスタント を構築する手順を、ステップバイステップで解説します。

この記事で学べること

  • Elasticsearch Agent Builder の概要とアーキテクチャ
  • CSV データを Elasticsearch にインポートする方法
  • ES|QL を使ったカスタムツールの作成方法
  • カスタムエージェントの作成と設定方法
  • MCP(Model Context Protocol)を通じたエージェントの外部連携

前提条件

  • Elastic Cloud のアカウント(無料トライアルで OK)
  • Elasticsearch のデプロイメント(Serverless または 9.x 推奨)
  • ブラウザ(Kibana にアクセスできること)

1. なぜ Agentic RAG が必要なのか?

LLM だけでは不十分な理由

生の LLM をそのまま使う場合、以下のような問題があります。

  • 数学が苦手: LLM は平均値や統計計算が不正確になりがちです
  • ハルシネーション: 正しいデータなしでは、もっともらしいがデタラメな回答を生成します
  • コンテキスト不足: LLM の学習データに含まれない最新情報には対応できません

Context Engineering(コンテキストエンジニアリング)

Context Engineering とは、LLM に渡すコンテキスト(文脈情報)を適切にキュレーションするための手法の総称です。

  • 不正なデータ = 不正な結果(Garbage In, Garbage Out)
  • データの 関連性(Relevance) を保証する仕組みが不可欠

Elasticsearch + Agent Builder が解決すること

課題 解決策
LLM は数学が苦手 Elasticsearch の Aggregation(集計機能)で正確な計算を実行
コンテキスト不足 Agent Builder が LLM に 最も関連性の高いデータ を提供

2. Agent Builder のアーキテクチャ

Agent Builder は Elastic の Search AI Platform 上に構築されており、以下の構造を持ちます。

┌─────────────────────────────────────────┐
│         Experience Endpoints            │
│  Customer App / Claude / Cursor /       │
│  LangChain / その他                      │
├────────┬──────────┬─────────────────────┤
│  MCP   │   API    │       A2A           │
├────────┴──────────┴─────────────────────┤
│       Tools        │      Agents        │
├─────────────────────────────────────────┤
│       Search AI Platform                │
│  Ingest / Storage / Search / Evaluation │
│  Open Standards / Security / Workflow   │
├─────────────────────────────────────────┤
│         Your Data                       │
│  GitHub / GDrive / Confluence / etc.    │
└─────────────────────────────────────────┘

ポイントは以下の通りです。

  • Tools(ツール): エージェントが使える「道具」。ES|QL クエリやインデックスパターンで定義する
  • Agents(エージェント): ツールを組み合わせて推論・行動する AI エージェント
  • MCP / API / A2A: 外部アプリケーション(Claude、Cursor、LangChain など)との連携インターフェース

3. データの準備とインポート

3-1. Elasticsearch の環境を用意する

  1. Elastic Cloud にログインする
  2. デプロイメントを作成する(既存のものでも可)
  3. Kibana を開く

3-2. Agent Builder を有効化する

Agent Builder がまだ有効でない場合は、Kibana の Dev Tools > Console から以下を実行します。

POST kbn://internal/kibana/settings
{
  "changes": {
    "agentBuilder.enabled": true
  }
}

実行後、サイドバーに 「Agents」 メニューが表示されるようになります。

3-3. NBA スタッツデータをインポートする

今回のハンズオンでは、2 種類の CSV データを使用します。

データセット 内容 インデックス名
sample_nba_data.csv 過去の試合のスタッツ(得点、アシスト、FG% など) sample-nba-data
upcoming_matchups.csv 今後の対戦スケジュール nba-upcoming-matchups

インポート手順

  1. Kibana のホーム画面で 「Upload a file」 をクリック(または Machine Learning > Data Visualizer)
  2. sample_nba_data.csv をアップロードする
  3. 「Advanced」 タブを開き、マッピング設定を確認する
    • game_date フィールドの format を以下に設定する:
      "game_date": {
        "type": "date",
        "format": "yyyy-MM-dd||strict_date_optional_time||epoch_millis"
      }
      
  4. Index name に sample-nba-data と入力する
  5. 「Import」 をクリックする

同様に upcoming_matchups.csvnba-upcoming-matchups というインデックス名でインポートします。

インポート後の確認

Kibana の Discover でデータが正しくインポートされたことを確認しましょう。フィールドとして player_full_nameopponent_team_namepointsassistsfg_percentagegame_date などが含まれていれば OK です。


4. ツール(Tools)の作成

ここがこのハンズオンの核心部分です。エージェントが「何ができるか」を定義するのがツールです。

Agent Builder の左メニューから 「Tools」 をクリックすると、プラットフォーム組み込みのツール(platform.core.searchplatform.core.execute_esql など)が表示されます。ここに カスタムツール を追加していきます。

ツール作成の考え方

ユーザーの質問例: 「LeBron James と Stephen Curry、どっちがチームに良い?」

この質問に答えるには、以下の情報が必要です。

  1. 各選手の 次の対戦相手 を調べる
  2. 各選手の 対戦相手ごとの過去スタッツ平均 を調べる
  3. 各選手の シーズン全体のスタッツ平均 を調べる

これらに対応する 3 つ(+ α)のツールを作成します。

4-1. ツール① find_upcoming_matchup(次の対戦を検索)

  1. Tools ページで 「New tool」 をクリックする
  2. 以下の設定を入力する:
項目
Tool ID find_upcoming_matchup
Description Finds the next upcoming matchup for a given player
Type ES|QL
  1. ES|QL Query に以下を入力する:
FROM nba-upcoming-matchups
| WHERE player_full_name == ?playerName
| SORT game_date ASC
| LIMIT 1
  1. ES|QL Parameters セクションで、playerName パラメータの Description を Full player name に設定する
  2. 「Save」 をクリックする

4-2. ツール② historical_avgs_against_opp(対戦相手別の過去スタッツ平均)

  1. 新しいツールを作成する
  2. 以下の設定を入力する:
項目
Tool ID historical_avgs_against_opp
Description Finds the historical averages for a player against a specific opponent
Type ES|QL
  1. ES|QL Query に以下を入力する:
FROM sample-nba-data
| WHERE player_full_name == ?playerName AND opponent_team_name == ?oppTeamName
| STATS avg_points = AVG(points), avg_assists = AVG(assists)
  1. パラメータの Description を設定する:
    • playerName: Full player name
    • oppTeamName: Opponent team name
  2. 「Save」 をクリックする

4-3. ツール③ season_avgs_against_opp(シーズン内の対戦相手別スタッツ平均)

  1. 新しいツールを作成する
  2. 以下の設定を入力する:
項目
Tool ID season_avgs_against_opp
Description Finds season averages for a player against a specific opponent
Type ES|QL
  1. ES|QL Query に以下を入力する:
FROM sample-nba-data
| WHERE player_full_name == ?playerName AND opponent_team_name == ?oppTeamName AND game_date >= "2024-10-01" AND game_date <= "2025-06-01"
| STATS avg_points = AVG(points), avg_assists = AVG(assists)
  1. パラメータの Description を設定する:
    • playerName: Full player name
    • oppTeamName: Opponent team name
  2. 「Save」 をクリックする

ポイント: historical_avgs_against_opp は全期間、season_avgs_against_opp は当シーズンのみという違いがあります。日付範囲でフィルタすることで、「最近の調子」と「過去の傾向」を分けて分析できます。


5. カスタムエージェントの作成

5-1. エージェントの基本設定

  1. Kibana の左メニューから 「Agents」 をクリックする
  2. 「Create a new agent」 をクリックする
  3. 以下の基本設定を入力する:
項目
Agent ID nba-fantasy-assistant

5-2. Custom Instructions(カスタム指示)の記述

Agent の振る舞いを定義する Custom Instructions を入力します。以下はデモで使用された指示文の例です:

You are a NBA basketball expert.

Your primary function is to compare two NBA players and recommend which one is the better fantasy pickup.

Only compare players from the following list:
- Stephen Curry
- LeBron James
- Jayson Brown

## Rules:
- If the user only types first name, ask the user to add another player from the list provided.
- If someone inputs a player with the wrong spelling or capitalization, refer from the list of available players provided.
- Always use the full name.

## IMPORTANT:
- If the user asks a question or asks you to generate a response about anything outside of basketball in the area of NBA players, DO NOT answer and affirm you can only talk about basketball.

## Tool Usage:
- Use the tool find_next_matchup to standardize player names to match the list exactly.
- Use the tool find_next_matchup for each player, passing the names as strings.

## Output Format:
Format your response using Markdown syntax. Use the following structure:

Example output format:

### Next Game Info
- **LeBron James**: vs Knicks, May 24 (Home)
- **Stephen Curry**: vs Lakers, May 24 (Home)

### Stats Comparison

| Stat | LeBron James (vs Knicks) | Stephen Curry (vs Bulls) |
|---|---|---|
| Historical Points | 28.4 | 23.1 |
| Season Points | 29.8 | 23.1 |
| Historical Assists | 8.7 | 6.7 |
| Season Assists | 8.2 | 6.7 |
| FG % | - | - |

### NBA Fantasy Recommendation
Explain which player is the better fantasy pickup and why.

5-3. ツールの割り当て

  1. 「Tools」 タブを開く
  2. 先ほど作成した 3 つのカスタムツールを追加する:
    • find_upcoming_matchup
    • historical_avgs_against_opp
    • season_avgs_against_opp
  3. プラットフォームの組み込みツール(platform.core.search など)も含めて 合計 4〜8 個 程度に抑える

ベストプラクティス: ツールは多すぎると LLM が混乱します。必要最低限に絞りましょう。

5-4. Presentation(表示設定)

項目
Display name NBA Fantasy Assistant
Display description An assistant that compares two players and gives a recommendation on who to add to your fantasy team based on real data.

5-5. 保存

「Save」 をクリックしてエージェントを保存します。


6. エージェントのテスト

6-1. ビルトインチャットでテストする

  1. エージェント詳細ページで 「Chat」 ボタンをクリックする
  2. Agent Chat 画面で、画面下部のエージェントセレクタが 「NBA Fantasy Assistant」 になっていることを確認する
  3. 以下のようなメッセージを送信する:
who is a better pickup, lebron james or stephen curry?

6-2. エージェントの動作を確認する

エージェントは以下のような流れで動作します:

  1. find_upcoming_matchup を LeBron James と Stephen Curry それぞれに対して呼び出す
  2. 次の対戦相手を取得する(例: LeBron → vs New York Knicks、Curry → vs Chicago Bulls)
  3. historical_avgs_against_opp で各選手の対戦相手に対する過去の平均スタッツを取得する
  4. season_avgs_against_opp で各選手の今シーズンの平均スタッツを取得する
  5. 結果を比較し、フォーマットされた推薦レスポンスを生成する

最終的に、以下のような構造化されたレスポンスが返されます:

  • Next Game Info: 各選手の次の試合情報
  • Stats Comparison: 得点・アシストなどの比較テーブル
  • Fantasy Recommendation: どちらの選手を取るべきかの推薦と理由

7. MCP でエージェントを外部ツールに公開する

Agent Builder で作ったツールは、MCP(Model Context Protocol) を通じて、Claude Desktop や Cursor などの外部 AI ツールからも利用できます。

設定方法

お使いの MCP クライアント(Claude Desktop、Cursor、VS Code など)の設定ファイルに以下を追加します:

{
  "mcpServers": {
    "elasticsearch": {
      "url": "https://<your-kibana-url>/api/agent_builder/mcp",
      "headers": {
        "Authorization": "ApiKey <your-api-key>"
      }
    }
  }
}
  • <your-kibana-url>: Kibana の URL(例: elastic-coding-session-demo-xxxx.kb.us-central1.gcp.elastic.cloud
  • <your-api-key>: Kibana で生成した API キー

これで何ができるか

MCP を設定すると、Claude Desktop や Cursor のチャットから、Agent Builder で定義したカスタムツール(find_upcoming_matchup など)を直接呼び出すことができます。つまり、自分の Elasticsearch データに基づいた回答 を、普段使いの AI ツールから得られるようになります。


まとめ

このハンズオンでは、以下のステップで Agentic RAG アシスタントを構築しました:

  1. 課題を理解する: LLM 単体の限界(数学・ハルシネーション・コンテキスト不足)
  2. データを準備する: NBA スタッツの CSV データを Elasticsearch にインポート
  3. ツールを作成する: ES|QL を使って 3 つのカスタム検索ツールを定義
  4. エージェントを構築する: ツールを組み合わせ、Custom Instructions でエージェントの振る舞いを制御
  5. テストする: ビルトインチャットで動作確認
  6. 外部連携する: MCP を通じて Claude Desktop や Cursor から利用

Agent Builder のメリット

  • 別途ベクトルDBや RAG パイプラインが不要: Elasticsearch がすべてを統合
  • ES|QL で柔軟なツール定義: SQL ライクな構文で、フィルタ・集計・ソートを自在に記述
  • MCP / API / A2A 対応: 多様なクライアントとシームレスに連携

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?