Agent ArenaClickHouse Workshops

00 セットアップ

環境を整える — OpenRouter、ClickHouse、Langfuse を最初から接続します。

成果

Python の virtualenv がインストールされたクローン済みリポジトリ、OpenRouter・ClickHouse Cloud・ Langfuse Cloud の認証情報を入れた .env、合成 e-commerce データをシードした ClickHouse Cloud の arena データベース、そして http://localhost:5174 で動くローカルダッシュボード。Leaderboard タブは 今の時点では空ですが、それは想定どおりで、Module 01 までは空のままです。

なぜ

ベンチマークハーネスeval/harness.py · コンテストサービング APIserving/api.py · 本番1 つのコア · 2 つの呼び出し元が再利用エージェントコアagents/プロンプト · モデルクライアント · SQL ガードOpenRouter1 つの API → すべてのモデルファミリーClickHouse業務データ · v_* views(読み取り専用)Langfuseexperiments · results · scores · traces — leaderboard の唯一の情報源モデルに問う → SQLSELECT · v_* viewsすべての結果を保存

1 つのエージェントコアを 2 つの呼び出し元(ベンチマークハーネスとサービング API)が再利用します。コアは OpenRouter 経由でモデルに問い、ClickHouse の読み取り専用 v_* views からデータを読みます。 Langfuse は各ベンチマーク結果を保存し、Public API を通じて leaderboard を駆動します。

Agent Arena は 1 つの NL→SQL エージェントコア (agents/) を 2 つの呼び出し元 — ベンチマーク ハーネス (eval/harness.py) とライブのサービング API (serving/api.py) — が再利用する構成です。 デモとベンチマークがまったく同じコードパスを共有します。同じプロンプトテンプレート、同じモデル クライアント、同じ読み取り専用 SQL サンドボックスです。だからこそベンチマークの数値は本番の挙動を 信頼して予測できるものになります。実際に出荷されるものから静かに乖離していく別個の「eval harness」 ではありません。

Langfuse がこの最初のモジュールでセットアップする 3 つのアカウントのひとつであることに注目してください — モデルを選ぶ前、質問を 1 つも実行する前です。これは意図的です。Langfuse はチャットボットが動いてから 後付けするものではなく、Module 01 でコンテストを 実行し、Module 02 で勝者の品質を測定し、Module 03 で 改善ループを駆動し、Module 04 で本番を監視するツールです。1 つのプロジェクト、1 組の traces と データセットで、最初から最後まで貫きます。この先のすべてのモジュールはその 1 つのコードパスとその 1 つの Langfuse プロジェクトの上に積み上がるので、ここで 3 つのアカウントとシードしたデータベースを正しく 用意しておくことが、残りのワークショップをすんなり動かす鍵になります。

コンセプト — 内側の仕組み

3 本の柱、3 つの役割。この最初のモジュールから配線されています。

  • OpenRouter — このワークショップで使うすべてのモデルファミリー(Anthropic、OpenAI、Google、 DeepSeek、Qwen、Z.ai)の前に立つ 1 つの OpenAI 互換 API です。 6 つのプロバイダー SDK と 6 組の認証情報をやりくりする代わりに、エージェントコア (agents/) は 1 つのクライアントで config.yaml の 6 モデルすべてに到達します。それが Module 01 での公平で同条件のコンテストを可能にします。どのモデルも model= の文字列 1 つ分の距離にあり、同じエンドポイント、同じリクエスト形状の背後にいます。
  • ClickHouse — アプリケーションのデータベースです。業務 データ(これからシードする合成 e-commerce テーブル)を v_* views の背後に保持します。エージェントに許されているのは v_* views から SELECT することだけです。生テーブルは決して触れず、書き込みも決してしません。これはエージェントが 推論するための安定した、ドキュメント化された読み取り専用の契約であるからでもあり、 agents/sqlguard.py がそれを SELECT 専用サンドボックスとして強制するからでもあります。生成された SQL をパースし、単一の SELECT/WITH…SELECT 文でないものを拒否し、それ以外は妥当な文の中に あっても書き込み/DDL キーワードの denylist(INSERT、UPDATE、DELETE、 DROP、ALTER、SYSTEM、…)をブロックします。
  • Langfuse — eval、leaderboard、オブザーバビリティのストアです。モデルを選ぶ前、質問を 1 つも 投げる前の いま 接続します。あとで後付けするものではないからです。Module 01 でコンテストを採点し、 Module 02 で品質を掘り下げられるようにし、Module 04 で本番を監視するツールです。1 つのプロジェクト、 最初のモデル選択から続く traces とデータセットの 1 本の連続した軌跡です。

スクリーンショット: Langfuse Cloud プロジェクトの Settings → API Keys ページ。.env に貼り付ける public/secret のキーペアがどこから来るかを示します — ライブ UI から取得してください。

落とし穴 — プレースホルダーの OPENROUTER_API_KEY。 .env.example は OPENROUTER_API_KEY=sk-or-... をテンプレートとして同梱しています。実際のキーではありません。上書きし忘れると、Module 01 のモデル 呼び出しはすべて OpenRouter の認証エラーで失敗します。ClickHouse や Langfuse のエラーではありません。 それが見えたらまず .env を確認してください。

落とし穴 — ClickHouse のホストやリージョンの間違い。 CLICKHOUSE_CLOUD_HOST はサービスの接続情報に ある正確なホスト(リージョン固有、例: abc123.us-east-1.aws.clickhouse.cloud)でなければならず、汎用の clickhouse.cloud ドメインではありません。 ホストが一致しないと scripts/arena.sh up の途中で DNS/接続エラーとして早く失敗します — それが見分けるべきシグネチャです。

落とし穴 — ARENA_RO_PASSWORD の不一致。 scripts/arena.sh up は その時点で ARENA_RO_PASSWORD に設定されている値を使って arena_ro 読み取り専用ユーザーを作成します。あとで .env の値を変更し、 セットアップを再実行しない(あるいはユーザーを削除して作り直さない)と、.env が「正しく見える」のに エージェントの読み取り専用接続が認証に失敗し始めます。

ゴール

.env に 3 組の認証情報、エージェントがクエリする v_* views を備えたシード済みの arena データベース、そしてブラウザから到達できるローカルダッシュボード。

Step 1 — 3 つのアカウントを作る

ターミナルに触れる前に、3 つのサービスから API 認証情報が必要です。

サービス必要なもの取得場所.env の変数
OpenRouterOPENROUTER_API_KEYopenrouter.ai → Keys。OpenRouter はこのワークショップで使うすべてのモデルファミリー(Anthropic、OpenAI、Google、DeepSeek、Qwen、Z.ai)を 1 つの OpenAI 互換 API の背後に置きます。OPENROUTER_API_KEY, OPENROUTER_BASE_URL
Langfuse Cloudプロジェクトの public + secret キーcloud.langfuse.com → プロジェクトを作成 → Settings → API Keys。LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL
ClickHouse Cloudホスト、admin ユーザー、admin パスワードclickhouse.com/cloud → サービスを作成 → 接続情報。CLICKHOUSE_CLOUD_HOST, CLICKHOUSE_CLOUD_USER, CLICKHOUSE_CLOUD_PASSWORD

3 つとも手元に置いておいてください。すぐに .env へ貼り付けます。

Qwen に必要な OpenRouter のプライバシー設定

OpenRouter で Settings → Privacy → Data Policies → Zero Data Retention を開き、 Non-frontier をオフにしてください(トグルはグレー/オフでなければなりません)。Qwen は OpenRouter の non-frontier モデルグループに属し、利用可能な Alibaba のエンドポイントは non-frontier の Zero Data Retention が強制されていると対象外になります。これを有効にしたままにすると、API キーとモデルスラッグが 妥当でも qwen/qwen3.7-flash は No endpoints available matching your guardrail restrictions and data policy で失敗します。

このワークショップが送るのは合成の e-commerce の質問とスキーマです。実際のワークロードでは、ZDR ポリシーを緩める前に組織のプライバシー要件を確認してください。

Step 2 — リポジトリをクローンする

Agent Arena は ClickHouse_Demos モノレポの中、build-workshop-v1 ブランチの workshops/agent_arena にあります。 リポジトリ全体をクローンし、そのサブディレクトリに移動してください。ここから先のすべてのコマンドは そこに立っていることを前提としています。

git clone --branch build-workshop-v1 --single-branch https://github.com/ClickHouse/ClickHouse_Demos.git
cd ClickHouse_Demos/workshops/agent_arena

Step 3 — virtualenv を作って依存関係をインストールする

python3.11 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt

Step 4 — .env を設定する

サンプルファイルをコピーします。

cp .env.example .env

.env

Step 1 の値を埋めてください。以下の値はすべて .env.example では空かプレースホルダーです。

# ClickHouse Cloud (business data queried by the agent)
export CLICKHOUSE_CLOUD_HOST=xxx.clickhouse.cloud
export CLICKHOUSE_CLOUD_USER=default
export CLICKHOUSE_CLOUD_PASSWORD=
export CLICKHOUSE_CLOUD_DATABASE=arena
export ARENA_RO_PASSWORD=
# OpenRouter (LLM provider)
export OPENROUTER_API_KEY=sk-or-...
export OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
# Langfuse Cloud (eval store + tracing)
export LANGFUSE_BASE_URL=https://us.cloud.langfuse.com
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...

各ブロックの役割:

  • CLICKHOUSE_CLOUD_* — ClickHouse Cloud サービスの admin 認証情報。セットアップは admin ユーザーを 1 度だけ使い、arena データベースと、以降のワークショップでエージェントがクエリに使う専用の 読み取り専用 ユーザー (arena_ro) を作成します。
  • ARENA_RO_PASSWORD — 任意のパスワードを決めてください。読み取り専用ユーザーが作成されるときに arena_ro のパスワードになります。
  • OPENROUTER_* — OpenRouter のキーとそのベース URL。config.yaml のすべてのモデルはこの 1 つの エンドポイント経由でアドレス指定されます。
  • LANGFUSE_* — Langfuse Cloud プロジェクトのホストとキー。ワークショップのすべての trace、 score、データセットがここに入ります。Module 01 の最初の Arena 実行から Module 04 の本番までです。

Step 5 — 合成 e-commerce データを ClickHouse にシードする

これは arena データベースと arena_ro 読み取り専用ユーザーを作成し、合成の e-commerce データ (customers、products、orders、order items、events)を ClickHouse に直接生成し、エージェントが クエリする v_* views を構築します。

source .env && scripts/arena.sh up

このワークショップのすべてのエージェント、プロンプト、ゴールデン SQL は v_customers、v_products、v_orders、v_order_items、v_events の views にクエリします。 生テーブルには決してクエリしません。

scripts/arena.sh up はローカルのダッシュボード API と web UI も起動します。完了したら http://localhost:5174 を開いてください。Module 01 で コンテストを実行するまで、Leaderboard タブは空です。

健全な実行はこう見えます。 scripts/arena.sh up は次の順に出力します。

  1. ClickHouse: business database + read-only agent user — arena データベースと専用の arena_ro ユーザーが作成されます。
  2. Seeding ClickHouse directly + views + schema context — テーブルごとに 1 行の clickhouse: inserted <N> into <table>(customers、products、 orders、order_items、events)、続いて done、そして v_* views とエージェントが読む スキーマコンテキストが構築されます。
  3. Starting dashboard API (:8000) + web UI (:5174) — 2 行の [ready]。どちらかが [NOT up] と出た場合、ポートがすでに使われている可能性が高いので、出力されるログのパス (.run/dashboard-api.log または .run/web.log) を確認してください。

Agent Arena のダッシュボード API がポート 8000 で ready、web UI がポート 5174 で ready と表示されるターミナル出力

初回ロード時の Agent Arena ダッシュボード。Leaderboard は空で実行データがない状態

これらはあとから scripts/arena.sh status で再確認できます。サーバーが起動しているかと、各 v_* view の行数を出力します。

完了したかどうかの確認

  • .env に CLICKHOUSE_CLOUD_*、OPENROUTER_*、LANGFUSE_* の実際の値 (プレースホルダーではない)が入っている。
  • scripts/arena.sh up がエラーなく完了した。
  • http://localhost:5174 がブラウザで読み込まれ、Leaderboard タブが表示される(今は空で 正しい)。

演習 — 接続をわざと壊して診断する

壊れた .env の値をその失敗シグネチャで見分けられるようになりましょう。リスクがゼロのうちに、 意図的に壊します。

  1. .env を開き、ARENA_RO_PASSWORD の 1 文字を変更してください(または一時的にコメントアウト します)。
  2. source .env && scripts/arena.sh up を再実行します。ClickHouse の admin ステップは通るはずです (そこは admin 認証情報を使います)が、読み取り専用の経路 — arena_ro として接続するもの — がどこで文句を言い始めるかを見てください。
  3. エラーメッセージをよく読んでください。認証エラーですか、「ユーザーが存在しない」エラーですか、 それとも沈黙のあとのタイムアウトですか。どれだったかを記録してください。
  4. 正しい ARENA_RO_PASSWORD に戻し、scripts/arena.sh up を再実行します。またきれいに完了する ことを確認してください。

これはのちにチームメイトのセットアップが「動かない」ときに必要になるのと同じ診断の直感です。 すべてを再確認するのではなく、エラーの文面を 3 つのサービスの どれ の設定ミスかに結びつけます。

まとめ

シード済みの ClickHouse データベース、3 つのサービスすべての認証情報 — モデルを選ぶ前に接続した Langfuse を含む — そしてローカルダッシュボードが動いている状態になりました。 このモジュール以降はすべて、この同じ環境と同じ Langfuse プロジェクトを再利用します。追加の セットアップ手順はありません。

到達状態

環境の準備完了。このデータに対してコンテストを実行するため、 01 ベースモデルを選ぶ に進んでください。

このページの内容

Track your progress?

Optional. We email a link to confirm your address; progress records once you open it.

Please use your work email address, not a personal one.

Progress tracking also requires accepting the current Terms of Service in Privacy settings.

JA