00 セットアップ
環境を整える — OpenRouter、ClickHouse、Langfuse を最初から接続します。
成果
Python の virtualenv がインストールされたクローン済みリポジトリ、OpenRouter・ClickHouse Cloud・
Langfuse Cloud の認証情報を入れた .env、合成 e-commerce データをシードした ClickHouse Cloud の
arena データベース、そして http://localhost:5174 で動くローカルダッシュボード。Leaderboard タブは
今の時点では空ですが、それは想定どおりで、Module 01 までは空のままです。
なぜ
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 の変数 |
|---|---|---|---|
| OpenRouter | OPENROUTER_API_KEY | openrouter.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_arenaStep 3 — virtualenv を作って依存関係をインストールする
python3.11 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txtStep 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 は次の順に出力します。
ClickHouse: business database + read-only agent user—arenaデータベースと専用のarena_roユーザーが作成されます。Seeding ClickHouse directly + views + schema context— テーブルごとに 1 行のclickhouse: inserted <N> into <table>(customers、products、orders、order_items、events)、続いてdone、そしてv_*views とエージェントが読む スキーマコンテキストが構築されます。Starting dashboard API (:8000) + web UI (:5174)— 2 行の[ready]。どちらかが[NOT up]と出た場合、ポートがすでに使われている可能性が高いので、出力されるログのパス (.run/dashboard-api.logまたは.run/web.log) を確認してください。


これらはあとから scripts/arena.sh status で再確認できます。サーバーが起動しているかと、各 v_*
view の行数を出力します。
完了したかどうかの確認
.envにCLICKHOUSE_CLOUD_*、OPENROUTER_*、LANGFUSE_*の実際の値 (プレースホルダーではない)が入っている。scripts/arena.sh upがエラーなく完了した。http://localhost:5174がブラウザで読み込まれ、Leaderboard タブが表示される(今は空で 正しい)。
演習 — 接続をわざと壊して診断する
壊れた .env の値をその失敗シグネチャで見分けられるようになりましょう。リスクがゼロのうちに、
意図的に壊します。
.envを開き、ARENA_RO_PASSWORDの 1 文字を変更してください(または一時的にコメントアウト します)。source .env && scripts/arena.sh upを再実行します。ClickHouse の admin ステップは通るはずです (そこは admin 認証情報を使います)が、読み取り専用の経路 —arena_roとして接続するもの — がどこで文句を言い始めるかを見てください。- エラーメッセージをよく読んでください。認証エラーですか、「ユーザーが存在しない」エラーですか、 それとも沈黙のあとのタイムアウトですか。どれだったかを記録してください。
- 正しい
ARENA_RO_PASSWORDに戻し、scripts/arena.sh upを再実行します。またきれいに完了する ことを確認してください。
これはのちにチームメイトのセットアップが「動かない」ときに必要になるのと同じ診断の直感です。 すべてを再確認するのではなく、エラーの文面を 3 つのサービスの どれ の設定ミスかに結びつけます。
まとめ
シード済みの ClickHouse データベース、3 つのサービスすべての認証情報 — モデルを選ぶ前に接続した Langfuse を含む — そしてローカルダッシュボードが動いている状態になりました。 このモジュール以降はすべて、この同じ環境と同じ Langfuse プロジェクトを再利用します。追加の セットアップ手順はありません。
到達状態
環境の準備完了。このデータに対してコンテストを実行するため、 01 ベースモデルを選ぶ に進んでください。