00 Cài đặt
Chuẩn bị môi trường của bạn — OpenRouter, ClickHouse và Langfuse được kết nối ngay từ đầu.
Kết quả
Một repo đã clone với virtualenv Python đã cài, một file .env đã điền credentials
cho OpenRouter, ClickHouse Cloud và Langfuse Cloud, một database arena trong ClickHouse
Cloud đã seed dữ liệu thương mại điện tử tổng hợp, và dashboard cục bộ đang chạy tại
http://localhost:5174 — tab Leaderboard hiện còn trống, điều đó là bình thường cho đến
Module 01.
Vì sao
Một agent core, được dùng lại bởi hai bên gọi (benchmark harness và serving API); nó hỏi một
model qua OpenRouter và đọc dữ liệu qua các view v_* chỉ đọc của ClickHouse.
Langfuse lưu từng kết quả benchmark và cung cấp dữ liệu cho leaderboard thông qua Public API của nó.
Agent Arena là một agent core NL→SQL (agents/) được dùng lại bởi hai bên gọi — benchmark
harness (eval/harness.py) và serving API chạy thật (serving/api.py) — nên bản demo
và bản benchmark dùng đúng cùng một đường code: cùng prompt template, cùng model
client, cùng sandbox SQL chỉ đọc. Đó là điều làm cho các con số của benchmark trở thành
dự báo đáng tin cho hành vi trên production, thay vì một "eval harness" riêng biệt
âm thầm lệch khỏi những gì thực sự được đưa lên production.
Hãy để ý rằng Langfuse là một trong ba tài khoản bạn thiết lập ngay ở module đầu tiên này — trước khi bạn chọn model, trước khi bạn chạy dù chỉ một câu hỏi. Đó là chủ ý: Langfuse không phải thứ bạn gắn thêm vào sau khi chatbot đã chạy được, nó là công cụ chạy cuộc thi ở Mô-đun 01, đo chất lượng offline của người thắng ở Mô-đun 02, phát hiện điểm mù production ở Mô-đun 03, hỗ trợ điều tra của con người ở Mô-đun 04, rồi chứng minh và giám sát cải tiến ở Mô-đun 05 — một project, một chuỗi bằng chứng xuyên suốt. một đường code duy nhất đó và một project Langfuse duy nhất đó, nên làm đúng ba tài khoản và database đã seed ngay tại đây là điều khiến phần còn lại của workshop chạy trơn tru.
Khái niệm — bên dưới lớp vỏ
Ba trụ cột, ba nhiệm vụ, được nối với nhau ngay từ module đầu tiên này:
- OpenRouter — một API tương thích OpenAI đứng trước mọi họ model trong
workshop này (Anthropic, OpenAI, Google, DeepSeek, Qwen, Z.ai).
Thay vì phải xoay xở với sáu SDK của sáu nhà cung cấp và sáu bộ credentials, agent core
(
agents/) dùng một client duy nhất để chạm tới cả sáu model trongconfig.yaml. Đó là điều làm cho một cuộc thi công bằng, so sánh tương đương ở Module 01 trở nên khả thi: mọi model chỉ cách nhau một chuỗimodel=, sau cùng một endpoint, cùng một dạng request. - ClickHouse — database của ứng dụng. Nó chứa dữ liệu nghiệp vụ (các bảng
thương mại điện tử tổng hợp bạn sắp seed) phía sau các view
v_*. Agent chỉ luôn được phépSELECTtừ các viewv_*— không bao giờ từ bảng gốc, không bao giờ được ghi — vừa vì đó là một hợp đồng chỉ đọc ổn định, có tài liệu để agent suy luận trên đó, vừa vìagents/sqlguard.pycưỡng chế nó như một sandbox chỉ cho SELECT: nó phân tích SQL được sinh ra và từ chối bất cứ thứ gì không phải một câu lệnhSELECT/WITH…SELECTduy nhất, và chặn một danh sách đen các từ khóa ghi/DDL (INSERT,UPDATE,DELETE,DROP,ALTER,SYSTEM, …) kể cả khi chúng nằm bên trong một câu lệnh hợp lệ khác. - Langfuse — nơi lưu eval, leaderboard và observability. Nó được kết nối ngay lúc này, trước khi bạn chọn model hay hỏi dù chỉ một câu, bởi nó không phải thứ gắn thêm để dùng về sau — nó là công cụ chấm điểm cuộc thi ở Module 01, cho bạn đào sâu vào chất lượng ở Mô-đun 02, phát hiện lỗi production ở Mô-đun 03, lưu review của con người ở Mô-đun 04 và xác minh traffic tương lai ở Mô-đun 05. Một project, một chuỗi bằng chứng liên tục.
Ảnh chụp màn hình: trang Settings → API Keys của project Langfuse Cloud, cho thấy cặp
public/secret key bạn dán vào .env đến từ đâu — hãy chụp từ UI thật.
Bẫy — OPENROUTER_API_KEY còn là placeholder. .env.example đi kèm OPENROUTER_API_KEY=sk-or-...
như một mẫu, không phải key thật. Nếu bạn quên ghi đè nó, mọi lệnh gọi model ở
Module 01 sẽ thất bại với lỗi xác thực của OpenRouter, không phải lỗi ClickHouse hay Langfuse — nên
hãy kiểm tra .env trước nếu đó là lỗi bạn thấy.
Bẫy — sai host hoặc region của ClickHouse. CLICKHOUSE_CLOUD_HOST phải là đúng
host trong phần connection details của service của bạn (theo region, ví dụ
abc123.us-east-1.aws.clickhouse.cloud), không phải domain chung clickhouse.cloud.
Host sai sẽ thất bại ngay với lỗi DNS/kết nối trong lúc scripts/arena.sh up —
đó là dấu hiệu cần nhận ra.
Bẫy — ARENA_RO_PASSWORD không khớp. scripts/arena.sh up tạo user chỉ đọc
arena_ro bằng đúng giá trị ARENA_RO_PASSWORD tại thời điểm đó. Nếu bạn
đổi giá trị trong .env sau đó mà không chạy lại phần cài đặt (hoặc xóa và
tạo lại user), kết nối chỉ đọc của agent sẽ bắt đầu xác thực thất bại
dù .env "trông có vẻ đúng".
Mục tiêu
Ba bộ credentials trong .env, một database arena đã seed cùng các view v_* mà
agent sẽ truy vấn, và dashboard cục bộ mở được trong trình duyệt.
Bước 1 — Tạo ba tài khoản
Bạn cần API credentials từ ba service trước khi chạm vào terminal:
| Service | Bạn cần gì | Lấy ở đâu | Biến trong .env |
|---|---|---|---|
| OpenRouter | Một OPENROUTER_API_KEY | openrouter.ai → Keys. OpenRouter đứng trước mọi họ model dùng trong workshop này (Anthropic, OpenAI, Google, DeepSeek, Qwen, Z.ai) sau một API tương thích OpenAI. | OPENROUTER_API_KEY, OPENROUTER_BASE_URL |
| Langfuse Cloud | Public key + secret key của một project | cloud.langfuse.com → tạo một project → Settings → API Keys. | LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL |
| ClickHouse Cloud | Host, admin user, admin password | clickhouse.com/cloud → tạo một service → connection details. | CLICKHOUSE_CLOUD_HOST, CLICKHOUSE_CLOUD_USER, CLICKHOUSE_CLOUD_PASSWORD |
Giữ cả ba ở nơi dễ lấy — bạn sẽ dán chúng vào .env ngay sau đây.
Thiết lập privacy trên OpenRouter cần cho Qwen
Trong OpenRouter, mở Settings → Privacy → Data Policies → Zero Data Retention và
tắt Non-frontier (toggle phải ở trạng thái xám/off). Qwen nằm trong nhóm model
non-frontier của OpenRouter, và endpoint Alibaba khả dụng của nó không đủ điều kiện khi
Zero Data Retention cho non-frontier đang được cưỡng chế. Nếu vẫn để bật,
qwen/qwen3.7-flash sẽ thất bại với No endpoints available matching your guardrail restrictions and data policy dù API key và model slug đều hợp lệ.
Workshop này gửi các câu hỏi và schema thương mại điện tử tổng hợp. Với khối lượng công việc thật, hãy xem lại yêu cầu về quyền riêng tư của tổ chức bạn trước khi nới lỏng một chính sách ZDR.
Bước 2 — Clone repo
Agent Arena nằm trong monorepo ClickHouse_Demos, dưới workshops/agent_arena trên
nhánh build-workshop-v1.
Clone toàn bộ repo, rồi chuyển vào thư mục con đó — mọi lệnh từ đây trở đi
đều giả định bạn đang đứng trong đó:
git clone --branch build-workshop-v1 --single-branch https://github.com/ClickHouse/ClickHouse_Demos.git
cd ClickHouse_Demos/workshops/agent_arenaBước 3 — Tạo virtualenv và cài dependencies
python3.11 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txtBước 4 — Cấu hình .env
Sao chép file mẫu:
cp .env.example .env.env
Điền các giá trị từ Bước 1 — mọi giá trị dưới đây đều đang trống hoặc là placeholder trong
.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-...Từng khối dùng để làm gì:
CLICKHOUSE_CLOUD_*— credentials admin của service ClickHouse Cloud của bạn. Phần cài đặt dùng user admin đúng một lần, để tạo databasearenavà một user chỉ đọc riêng (arena_ro) mà agent sẽ truy vấn qua đó trong suốt phần còn lại của workshop.ARENA_RO_PASSWORD— chọn bất kỳ mật khẩu nào; nó trở thành mật khẩu củaarena_rokhi user chỉ đọc được tạo.OPENROUTER_*— key OpenRouter của bạn và base URL của nó. Mọi model trongconfig.yamlđều được gọi qua đúng endpoint này.LANGFUSE_*— host và các key của project Langfuse Cloud của bạn. Đây là nơi mọi trace, score và dataset trong workshop được lưu, từ lần chạy Arena đầu tiên ở Module 01 cho tới vòng lặp cải tiến được giám sát ở Mô-đun 05.
Bước 5 — Seed ClickHouse bằng dữ liệu thương mại điện tử tổng hợp
Bước này tạo database arena, user chỉ đọc arena_ro, sinh dữ liệu thương mại điện tử
tổng hợp (customers, products, orders, order items, events) trực tiếp vào
ClickHouse, và dựng các view v_* mà agent sẽ truy vấn:
source .env && scripts/arena.sh upMọi agent, mọi prompt và mọi đoạn SQL golden trong workshop này đều truy vấn các view
v_customers, v_products, v_orders, v_order_items và v_events — không bao giờ
truy vấn bảng gốc.
scripts/arena.sh up cũng khởi động dashboard API và web UI cục bộ. Khi
nó chạy xong, mở http://localhost:5174 — tab Leaderboard sẽ trống cho đến khi
bạn chạy cuộc thi ở Module 01.
Một lần chạy khỏe mạnh trông như thế nào. scripts/arena.sh up in ra, theo thứ tự:
ClickHouse: business database + read-only agent user— databasearenavà userarena_roriêng được tạo.Seeding ClickHouse directly + views + schema context— một dòngclickhouse: inserted <N> into <table>cho mỗi bảng (customers,products,orders,order_items,events), rồidone, rồi các viewv_*và schema context mà agent đọc được dựng lên.Starting dashboard API (:8000) + web UI (:5174)— hai dòng[ready]. Nếu một trong hai báo[NOT up], khả năng cao port đã bị chiếm; hãy xem đường dẫn log nó in ra (.run/dashboard-api.loghoặc.run/web.log).


Bạn có thể kiểm tra lại bất cứ điều nào ở trên về sau bằng scripts/arena.sh status, lệnh này in
ra các server có đang chạy không và số dòng của từng view v_*.
Cách xác nhận bạn đã xong
.envcó giá trị thật (không phải placeholder) choCLICKHOUSE_CLOUD_*,OPENROUTER_*vàLANGFUSE_*.scripts/arena.sh upkết thúc không lỗi.http://localhost:5174mở được trong trình duyệt, hiển thị tab Leaderboard (trống là đúng ở thời điểm này).
Bài tập — làm hỏng và chẩn đoán một kết nối
Hãy tập nhận ra một giá trị .env bị sai qua dấu hiệu lỗi của nó, một cách có chủ ý, khi
chưa có gì để mất:
- Mở
.envvà đổi một ký tự trongARENA_RO_PASSWORD(hoặc tạm comment nó lại). - Chạy lại
source .env && scripts/arena.sh up. Nó vẫn nên đi qua được các bước dùng admin ClickHouse (những bước đó dùng credentials admin), nhưng hãy để ý xem đường chỉ đọc — bất cứ thứ gì kết nối bằngarena_ro— bắt đầu báo lỗi ở đâu. - Đọc kỹ thông báo lỗi: đó là lỗi xác thực, lỗi "user does not exist", hay im lặng rồi timeout? Ghi lại bạn nhận được lỗi nào.
- Phục hồi
ARENA_RO_PASSWORDđúng và chạy lạiscripts/arena.sh up. Xác nhận nó hoàn tất sạch sẽ trở lại.
Đây chính là bản năng chẩn đoán bạn sẽ cần về sau khi phần cài đặt của một đồng nghiệp "không chạy" — đối chiếu nội dung lỗi với dịch vụ nào trong ba dịch vụ đang bị cấu hình sai, thay vì kiểm tra lại mọi thứ.
Tổng kết
Bạn đã có một database ClickHouse đã seed, credentials cho cả ba service — bao gồm Langfuse, được kết nối trước khi chọn bất kỳ model nào — và dashboard cục bộ đang chạy. Mọi thứ sau module này đều dùng lại đúng môi trường đó và đúng project Langfuse đó; không còn bước cài đặt nào nữa.
Trạng thái kết thúc
Môi trường đã sẵn sàng. Tiếp tục sang 01 Chọn model nền để chạy cuộc thi trên chính dữ liệu này.