【Agno】 Agentic RAGで強化するF1データ分析 【Agno SQL F1 sample】

AIエージェント

本記事では、F1(Formula 1)データを対象にした「テキスト→SQL変換エージェント」の動作概要や、エージェントが参照するナレッジベース(Knowledge Base)の詳細を解説します。さらに、実際のStreamlitアプリでの実行結果ログも交えて、エージェントがどのようにSQLを生成・実行し、どのような回答を返すのかを示します。

プロジェクト概要

このサンプルプロジェクトの目的は、自然言語での質問を自動的にSQLクエリへ変換し、F1データ(1950年~2020年)に対して実行→結果を返すというエージェントを構築することです。
具体的には以下のような特徴があります。

  1. F1の歴史的データ
    1950年~2020年までのレース結果やドライバー情報、チーム(コンストラクターズ)情報、最速ラップなどを一括管理。

  2. Agentic RAG
    エージェントが自身でナレッジベースに問い合わせ、テーブルのメタデータやサンプルクエリを参照する仕組み。より正確なSQLクエリを生成できるようになります。

  3. Streamlit + Docker Compose

    • StreamlitによるUI(チャット形式のインターフェース)。
    • Docker Composeでpgvector(PostgreSQL拡張)とアプリが同時起動。
    • 簡単にローカル環境で試せます。

ディレクトリ構成と主なファイル

リポジトリのディレクトリ構成はざっくり以下の通りです。

├── agents.py                <-- エージェントの定義・設定
├── app.py                   <-- Streamlitアプリ(UI部)
├── docker-compose.yml       <-- DBとアプリの起動設定
├── Dockerfile               <-- コンテナのビルド設定
├── load_f1_data.py          <-- CSVをPostgreSQLにロード
├── load_knowledge.py        <-- ナレッジベースをベクトルDBにロード
├── knowledge/               <-- テーブルメタデータやサンプルSQL, JSONファイル
└── utils.py                 <-- Streamlit用ユーティリティ等

2.1 agents.py

  • Agnoの Agent クラスを継承し、「SQLエージェント」を実装。
  • LLM(OpenAI GPT-4など)を選択し、SQLツールファイル操作ツールを追加。
  • ナレッジベース(後述)やセッション管理(PostgresAgentStorage)を設定し、エージェントの「振る舞いのルール」(instructions)を詳細に記述。

2.2 app.py

  • Streamlitでチャット形式のUIを作成。
  • agents.py のエージェントを呼び出し、ユーザーからの質問を受け取り、エージェントが生成する回答やSQLをリアルタイム表示。

2.3 load_f1_data.py / load_knowledge.py

  • load_f1_data.py: F1データ(CSV形式)をS3からダウンロード → pandas で読み込み → PostgreSQLにテーブルとして保存。
  • load_knowledge.py: knowledge/ ディレクトリのファイル(テーブルJSONやサンプルSQL)をベクトルDB(pgvector)に取り込み、エージェントの検索用ナレッジベースを構築。

2.4 knowledge/

  • テーブル構造を記したJSONファイル (例: drivers_championship.jsonrace_wins.json など)
  • サンプルクエリが書かれたSQLファイル (例: sample_queries.sql)
  • このフォルダに入っている情報がエージェントの問い合わせ元となる。

ナレッジベースの詳細

本プロジェクトが特に特徴的なのは、「Agentic RAGを活用し、エージェントがナレッジベースを随時検索して適切なSQLを組み立てる」という点です。

3.1 ナレッジベースの構成

  1. テーブルのメタデータ (JSON)

    • 各テーブルのカラム名・型・意味を記載。
    • 例: race_wins.json
      {
      "table_name": "race_wins",
      "table_description": "...",
      "table_columns": [
       { "name": "index", "type": "int", ... },
       { "name": "venue", "type": "text", ... },
       ...
      ]
      }
  2. サンプルSQL (sample_queries.sql)

    • よくある分析例(「チャンピオンが何回優勝したか」「コンストラクターの順位とレース勝利数の比較」など)をクエリ例として記載。
  3. 補足情報(テキストベース)

    • たとえば「date 列は DD Mon YYYY フォーマットなので TO_DATE 関数を使うと良い」といった注意事項。

3.2 読み込みと活用フロー

  1. CombinedKnowledgeBase
    TextKnowledgeBaseJSONKnowledgeBase をまとめた複合KBで、ファイル内容を全て取り込みます。

  2. PgVector
    取り込んだテキストをベクトルとして変換し、pgvectorテーブルに格納。

    • ユーザー質問の意図に合うテーブルやサンプルクエリをベクトル検索で素早く見つけ出す。
  3. エージェントのツール呼び出し

    • search_knowledge_base(table_name): エージェントが、自分でこのツールを呼び出し、対象テーブルやルールを検索。
    • describe_table(table_name): データベース側の実テーブル定義を確認。
  4. サンプルクエリを参考にSQL組み立て

    • 例: date 列から年を抽出する場合 → EXTRACT(YEAR FROM TO_DATE(date, 'DD Mon YYYY')) を流用。

実行手順

4.1 環境変数の設定

.env ファイル内にOpenAIのAPIキーなどを記載します(例: OPENAI_API_KEY="sk-...")。

4.2 Docker Composeで起動

docker compose up -d
  • 初回起動時、load_f1_data.pyload_knowledge.py が自動実行され、F1データとナレッジベースがDBに取り込まれます。
  • 数分かかる場合があるので完了を待ちます。

4.3 アプリにアクセス

ブラウザで http://localhost:8509 を開くと、StreamlitチャットUIが表示されます。
自然言語で質問すると、エージェントが最適なSQLを組み立てて実行→結果を返すフローを体験できます。

4.4 停止

docker compose down

永続化ボリュームを含め完全削除したい場合は docker compose down -v を使います。

実際の処理ログ(一例)

以下は、Streamlitアプリ上で行われたユーザーとのやりとりの抜粋です。
(ログには「どのテーブルをdescribeしたか」「実行したSQL」「結果」が表示されています。)

5.1 テーブル一覧を問い合わせる

利用可能なテーブルを教えてください

エージェントの回答例:

以下のテーブルが利用可能です:
constructors_championship ...
drivers_championship ...
fastest_laps ...
race_results ...
race_wins ...

5.2 各テーブルのカラム詳細を取得

これらのテーブルについて詳しく説明してください

エージェントは search_knowledge_base および describe_table を呼び出し、メタデータをまとめて表示します。
ログのツール呼び出し例:

🛠️ Describe Table
Arguments:
{
  "table_name":"drivers_championship"
}
Results:
[ "index: BIGINT()", "year: BIGINT()", "position: TEXT()", ... ]

5.3 「最も多くレースに勝ったドライバーは?」

最も多くのレースに優勝したドライバーは誰ですか?

エージェントが自動生成したSQLの例(ログより):

SELECT name, COUNT(*) AS win_count
FROM race_wins
GROUP BY name
ORDER BY win_count DESC
LIMIT 1

結果:
「ルイス・ハミルトン」 95回の優勝

5.4 「年間のレース数の推移を表示して」

race_wins テーブルには「year」列がないため、date列から年を抽出する必要があると判断。
エージェントはサンプルSQLを検索して TO_DATE(date, 'DD Mon YYYY') を活用し、年ごとのレース数をカウント。
結果として、1950年に7レース、2019年に21レースなど、年ごとの増減が一覧表示されます。

5.5 「2010年以降、最も多くのレースに勝利したドライバーとチームの順位は?」

以下のように、driversチャンピオンシップrace_winsを結合しながら、さらにconstructors_championshipの順位を取得する複雑なクエリを作成。ログにはツール呼び出し(knowledge base検索やSQL実行)が順次記録されています。

最終表示例:

ドライバー チーム 勝利数 チーム順位
2010 Fernando Alonso Ferrari 5 2
2011 Sebastian Vettel Red Bull Racing Renault 11 1
2012 Sebastian Vettel Red Bull Racing Renault 5 1
2013 Sebastian Vettel Red Bull Racing Renault 13 1
2014 Lewis Hamilton Mercedes 11 1
2015 Lewis Hamilton Mercedes 10 1
2016 Lewis Hamilton Mercedes 10 2
2017 Lewis Hamilton Mercedes 9 1
2018 Lewis Hamilton Mercedes 11 1
2019 Lewis Hamilton Mercedes 11 1
2020 Lewis Hamilton Mercedes 11 1

まとめと応用

  1. ナレッジベース

    • テーブルのメタデータ・サンプルSQL・日付フォーマット注意点などを格納し、エージェントは質問に応じて必要な情報を検索・取得。
    • これにより、ユーザーが「年ごとの推移が見たい」と要望したとき、自動的に適切なクエリを組み立てられます。
  2. エージェントの流れ

    1. ユーザー質問を受け取り
    2. ナレッジベースからテーブル定義・ルールを参照
    3. クエリを生成しSQLを実行
    4. 結果を整形して返す
  3. 拡張・応用

    • F1以外のデータも、同じ形式(JSONでテーブル情報、サンプルSQL)でナレッジベースを整備すれば、同じ仕組みで動かせます。
    • 質問例やサンプルクエリが豊富になるほど、エージェントの回答精度は高まります。

おわりに

本記事では、Docker Composeで動くSQLエージェントAgentic RAGを通じてナレッジベースから情報を取得し、F1データを自由に分析できるしくみをまとめました。
実際のログにある通り、ユーザーは自然言語で「最も多く優勝したドライバーは?」「2010年以降で一番勝ったドライバーは?」などと尋ねるだけで、エージェントが適切なクエリを組み立てて結果を返します。

もし本プロジェクトを試してみたい場合は、手元でリポジトリをgit cloneし、.envに自分のAPIキーをセット → docker compose up -d すればすぐにF1データの分析を始められます。ぜひご活用ください。

リポジトリ

GitHub - Sunwood-ai-labs/agno-sql-f1-sample: F1データ分析用のSQLエージェント - テキストからSQLクエリを生成し、F1レース統計を分析
F1データ分析用のSQLエージェント - テキストからSQLクエリを生成し、F1レース統計を分析. Contribute to Sunwood-ai-labs/agno-sql-f1-sample development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました