Agent ArenaClickHouse Workshops

00 환경 준비

실습 환경을 준비합니다 — 시작부터 OpenRouter, ClickHouse, Langfuse를 연결합니다.

결과

Python 가상환경이 설치된 클론된 저장소, OpenRouter·ClickHouse Cloud·Langfuse Cloud 자격 증명이 채워진 .env, 합성 이커머스 데이터가 시딩된 ClickHouse Cloud의 arena 데이터베이스, 그리고 http://localhost:5174에서 실행 중인 로컬 대시보드 — Leaderboard 탭은 아직 비어 있으며, Module 01까지는 그게 정상입니다.

왜

벤치마크 하네스eval/harness.py · 경쟁서빙 APIserving/api.py · 프로덕션하나의 코어 · 두 호출자가 재사용에이전트 코어agents/프롬프트 · 모델 클라이언트 · SQL 가드OpenRouter하나의 API → 모든 모델 패밀리ClickHouse비즈니스 데이터 · v_* 뷰 (읽기 전용)Langfuseexperiments · 결과 · 점수 · 트레이스 — 리더보드의 단일 진실 공급원모델에 질의 → SQLSELECT · v_* 뷰모든 결과를 저장

하나의 에이전트 코어를 두 호출자(벤치마크 하네스와 서빙 API)가 재사용합니다. 코어는 OpenRouter를 통해 모델에 질의하고 ClickHouse의 읽기 전용 v_* 뷰로 데이터를 읽습니다. Langfuse는 각 벤치마크 결과를 저장하고 Public API를 통해 리더보드를 구동합니다.

Agent Arena는 하나의 NL→SQL 에이전트 코어(agents/)를 두 호출자 — 벤치마크 하네스(eval/harness.py)와 라이브 서빙 API(serving/api.py) — 가 재사용하는 구조입니다. 그래서 데모와 벤치마크가 정확히 같은 코드 경로를 공유합니다. 같은 프롬프트 템플릿, 같은 모델 클라이언트, 같은 읽기 전용 SQL 샌드박스를 씁니다. 이것이 벤치마크의 수치를 프로덕션 동작에 대한 신뢰할 수 있는 예측값으로 만들어 줍니다. 실제로 출시되는 것과 조용히 갈라지는 별도의 "eval 하네스"와는 다릅니다.

Langfuse가 이 첫 모듈에서 설정하는 세 계정 중 하나라는 점에 주목하세요. 모델을 고르기 전, 단 하나의 질문도 실행해 보기 전입니다. 이것은 의도된 것입니다. Langfuse는 챗봇이 동작한 뒤에 덧붙이는 것이 아니라, Module 01에서 경쟁을 실행하고, Module 02에서 승자의 품질을 측정하고, Module 03에서 개선 루프를 이끌고, Module 04에서 프로덕션을 관찰하는 도구입니다. 하나의 프로젝트, 하나의 트레이스와 데이터셋 세트로 처음부터 끝까지 갑니다. 이후 모든 모듈이 그 하나의 코드 경로와 그 하나의 Langfuse 프로젝트 위에 쌓이므로, 여기서 세 계정과 시딩된 데이터베이스를 제대로 준비하는 것이 워크숍의 나머지 과정을 순조롭게 만듭니다.

개념 — 내부 동작

세 개의 축, 세 가지 역할, 이 첫 모듈부터 함께 연결됩니다.

  • OpenRouter — 이 워크숍에서 쓰는 모든 모델 패밀리(Anthropic, OpenAI, Google, DeepSeek, Qwen, Z.ai) 앞에 놓인 하나의 OpenAI 호환 API입니다. 여섯 개 프로바이더 SDK와 여섯 세트의 자격 증명을 다루는 대신, 에이전트 코어(agents/)는 하나의 클라이언트로 config.yaml의 여섯 모델 모두에 도달합니다. 이것이 Module 01의 공정한 동일 조건 비교 경쟁을 가능하게 합니다. 모든 모델이 같은 엔드포인트, 같은 요청 형태 뒤에서 model= 문자열 하나만 바꾸면 됩니다.
  • ClickHouse — 애플리케이션 데이터베이스입니다. 비즈니스 데이터(곧 시딩할 합성 이커머스 테이블)를 v_* 뷰 뒤에 보관합니다. 에이전트는 오직 v_* 뷰에서만 SELECT할 수 있습니다. 원시 테이블은 절대 안 되고, 쓰기도 절대 안 됩니다. 그것이 에이전트가 추론할 수 있는 안정적이고 문서화된 읽기 전용 계약이기 때문이며, 또한 agents/sqlguard.py가 이를 SELECT 전용 샌드박스로 강제하기 때문입니다. 이 가드는 생성된 SQL을 파싱해 단일 SELECT/WITH…SELECT 문이 아닌 것은 거부하고, 그 밖에는 유효한 문장 안에 들어 있더라도 쓰기/DDL 키워드 거부 목록(INSERT, UPDATE, DELETE, DROP, ALTER, SYSTEM, …)을 차단합니다.
  • Langfuse — eval, 리더보드, 옵저버빌리티 저장소입니다. 모델을 고르거나 질문 하나를 던지기도 전인 지금 연결합니다. 나중에 덧붙이는 부가물이 아니기 때문입니다. Langfuse는 Module 01에서 경쟁을 채점하고, Module 02에서 품질을 파고들게 해주고, Module 04에서 프로덕션을 관찰하는 도구입니다. 하나의 프로젝트, 첫 모델 선택부터 이어지는 하나의 연속된 트레이스와 데이터셋 흐름입니다.

스크린샷: Langfuse Cloud 프로젝트의 Settings → API Keys 페이지. .env에 붙여 넣을 public/secret 키 쌍이 어디서 나오는지 보여줍니다 — 실제 UI에서 캡처하세요.

함정 — 자리표시자 OPENROUTER_API_KEY. .env.example은 OPENROUTER_API_KEY=sk-or-...를 템플릿으로 제공하며, 실제 키가 아닙니다. 이를 덮어쓰는 것을 잊으면 Module 01의 모든 모델 호출이 ClickHouse나 Langfuse 오류가 아니라 OpenRouter 인증 오류로 실패합니다. 그런 증상이 보이면 .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에 담긴 세 세트의 자격 증명, 에이전트가 질의할 v_* 뷰가 포함된 시딩된 arena 데이터베이스, 그리고 브라우저에서 접근 가능한 로컬 대시보드.

Step 1 — 세 개의 계정 만들기

터미널을 열기 전에 세 서비스의 API 자격 증명이 필요합니다.

서비스필요한 것얻는 곳.env 변수
OpenRouterOPENROUTER_API_KEYopenrouter.ai → Keys. OpenRouter는 이 워크숍에서 쓰는 모든 모델 패밀리(Anthropic, OpenAI, Google, DeepSeek, Qwen, Z.ai)를 하나의 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호스트, 관리자 사용자, 관리자 비밀번호clickhouse.com/cloud → 서비스 생성 → 연결 정보.CLICKHOUSE_CLOUD_HOST, CLICKHOUSE_CLOUD_USER, CLICKHOUSE_CLOUD_PASSWORD

세 가지를 모두 옆에 두세요. 잠시 뒤 .env에 붙여 넣습니다.

Qwen에 필요한 OpenRouter 개인정보 설정

OpenRouter에서 Settings → Privacy → Data Policies → Zero Data Retention을 열고 Non-frontier를 끄세요(토글이 회색/off여야 합니다). 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로 실패합니다.

이 워크숍은 합성 이커머스 질문과 스키마만 전송합니다. 실제 워크로드에서는 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 — 가상환경 생성과 의존성 설치

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 서비스의 관리자 자격 증명입니다. 셋업은 관리자 사용자를 한 번만 사용해 arena 데이터베이스와, 워크숍의 나머지 기간 동안 에이전트가 질의에 사용할 전용 읽기 전용 사용자(arena_ro)를 만듭니다.
  • ARENA_RO_PASSWORD — 아무 비밀번호나 정하세요. 읽기 전용 사용자가 생성될 때 arena_ro의 비밀번호가 됩니다.
  • OPENROUTER_* — OpenRouter 키와 그 base URL입니다. config.yaml의 모든 모델은 이 하나의 엔드포인트를 통해 지정됩니다.
  • LANGFUSE_* — Langfuse Cloud 프로젝트의 호스트와 키입니다. Module 01의 첫 Arena 실행부터 Module 04의 프로덕션까지, 워크숍의 모든 트레이스, 점수, 데이터셋이 여기에 저장됩니다.

Step 5 — 합성 이커머스 데이터로 ClickHouse 시딩

이 명령은 arena 데이터베이스와 arena_ro 읽기 전용 사용자를 만들고, 합성 이커머스 데이터(customers, products, orders, order items, events)를 ClickHouse에 직접 생성하고, 에이전트가 질의할 v_* 뷰를 만듭니다.

source .env && scripts/arena.sh up

이 워크숍의 모든 에이전트, 프롬프트, 골든 SQL은 v_customers, v_products, v_orders, v_order_items, v_events 뷰에 질의하며, 원시 테이블은 절대 사용하지 않습니다.

scripts/arena.sh up은 로컬 대시보드 API와 웹 UI도 시작합니다. 완료되면 **http://localhost:5174**를 열어 보세요. Leaderboard 탭은 Module 01에서 경쟁을 실행할 때까지 비어 있습니다.

정상적인 실행은 어떤 모습인가. scripts/arena.sh up은 다음 순서로 출력합니다.

  1. ClickHouse: business database + read-only agent user — arena 데이터베이스와 전용 arena_ro 사용자가 생성됩니다.
  2. Seeding ClickHouse directly + views + schema context — 테이블마다 한 줄씩 clickhouse: inserted <N> into <table> (customers, products, orders, order_items, events)이 나오고, 이어서 done, 그다음 v_* 뷰와 에이전트가 읽는 스키마 컨텍스트가 만들어집니다.
  3. Starting dashboard API (:8000) + web UI (:5174) — 두 개의 [ready] 줄. 둘 중 하나가 [NOT up]이라면 해당 포트가 이미 사용 중일 가능성이 큽니다. 출력된 로그 경로 (.run/dashboard-api.log 또는 .run/web.log)를 확인하세요.

Agent Arena 대시보드 API가 8000 포트에서, 웹 UI가 5174 포트에서 준비 완료된 터미널 출력

Leaderboard가 비어 있고 실행 데이터가 없는 첫 로드 상태의 Agent Arena 대시보드

이 내용은 나중에 scripts/arena.sh status로 언제든 다시 확인할 수 있습니다. 서버가 올라와 있는지와 각 v_* 뷰의 행 수를 출력합니다.

완료 확인 방법

  • .env에 CLICKHOUSE_CLOUD_*, OPENROUTER_*, LANGFUSE_*의 실제 값(자리표시자가 아닌)이 들어 있다.
  • scripts/arena.sh up이 오류 없이 완료되었다.
  • 브라우저에서 http://localhost:5174가 로드되고 Leaderboard 탭이 보인다(지금은 비어 있는 것이 정상).

실습 — 연결을 일부러 망가뜨리고 진단하기

부담 없는 상황에서, 일부러 .env 값을 망가뜨려 그 실패 시그니처를 알아보는 연습을 하세요.

  1. .env를 열고 ARENA_RO_PASSWORD의 한 글자를 바꾸세요(또는 잠시 주석 처리하세요).
  2. source .env && scripts/arena.sh up을 다시 실행하세요. ClickHouse 관리자 단계는 여전히 통과해야 합니다(관리자 자격 증명을 쓰므로). 대신 읽기 전용 경로 — arena_ro로 연결하는 부분 — 이 어디서 불만을 토하기 시작하는지 지켜보세요.
  3. 오류 메시지를 자세히 읽으세요. 인증 오류인가요, "user does not exist" 오류인가요, 아니면 아무 말 없이 타임아웃되나요? 어떤 것이었는지 적어 두세요.
  4. 올바른 ARENA_RO_PASSWORD를 복원하고 scripts/arena.sh up을 다시 실행하세요. 다시 깔끔하게 완료되는지 확인하세요.

이것은 나중에 동료의 환경이 "안 된다"고 할 때 필요한 진단 감각과 같습니다. 모든 것을 다시 점검하는 대신, 오류 문구를 세 서비스 중 어느 것의 설정 문제인지에 맞춰 보는 것입니다.

정리

시딩된 ClickHouse 데이터베이스, 세 서비스 전부의 자격 증명 — 모델을 고르기도 전에 연결한 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.

KO