Agent ArenaClickHouse Workshops

00 环境准备

准备好你的环境,从一开始就接通 OpenRouter、ClickHouse 和 Langfuse。

产出

一个已克隆的仓库,装好 Python virtualenv,一份填入了 OpenRouter、ClickHouse Cloud 和 Langfuse Cloud 凭据的 .env,一个在 ClickHouse Cloud 中用合成电商数据初始化好的 arena 数据库,以及运行在 http://localhost:5174 的本地 dashboard, Leaderboard 标签页目前是空的,这是正常的,直到 模块 01 才会有数据。

为什么

Benchmark 框架eval/harness.py · 竞赛服务 APIserving/api.py · 生产环境一个内核 · 两个调用方复用它Agent 内核agents/prompt · 模型客户端 · SQL guardOpenRouter一个 API → 所有模型家族ClickHouse业务数据 · v_* 视图(只读)Langfuseexperiments · 结果 · scores · traces,leaderboard 的唯一事实来源向模型提问 → SQLSELECT · v_* 视图存下每一条结果

基准测试框架和线上服务 API 共用同一套智能体核心逻辑。它通过 OpenRouter 调用模型,并通过 ClickHouse 的只读 v_* 视图查询数据。 Langfuse 会保存每次基准测试的结果,并通过 Public API 为排行榜提供数据。

Agent Arena 的核心是一套自然语言转 SQL 的智能体逻辑(agents/)。基准测试框架 (eval/harness.py)和线上服务 API(serving/api.py)都会调用这套逻辑。因此, 演示环境与基准测试使用完全相同的代码路径,包括提示词模板、模型客户端和只读 SQL 沙箱。这种设计确保基准测试结果能够反映线上表现,避免测试逻辑与实际部署的逻辑逐渐偏离。

Langfuse 是第一个模块中就要配置的三个账号之一。此时你还没有选定模型, 也没有运行第一个问题。这是有意安排的: Langfuse 不是等聊天机器人运行后才补上的监控工具。模块 01 用它组织评测, 模块 02 用它分析最佳方案的质量,模块 03 用它推动持续改进,模块 04 则用它监控 生产环境。同一个项目会保存统一的追踪记录和数据集,贯穿整个流程。后续模块都依赖 这条共享代码路径和同一个 Langfuse 项目,因此必须在这里正确配置三个账号并完成 数据库初始化,才能顺利完成后续练习。

概念:底层原理

三根支柱,三项职责,从第一个模块起就串在一起:

  • OpenRouter:一个 OpenAI 兼容的 API,挡在本课程涉及的每个模型家族之前 (Anthropic、OpenAI、Google、DeepSeek、Qwen、Z.ai)。 agent 内核(agents/)不必周旋于六套 provider SDK 和六套凭据,只用一个客户端就能访问 config.yaml 里的全部六个模型。这正是让 模块 01 中 公平、可横向对比的竞赛得以成立的原因:每个模型只差一个 model= 字符串,背后是同一个端点、同样的请求形态。
  • ClickHouse:应用数据库。它保存业务数据(你马上要初始化的 合成电商表),并置于 v_* 视图之后。agent 永远只被 允许对 v_* 视图执行 SELECT,不能碰原始表,不能写入,一方面 因为这是一份稳定、有文档的只读契约,便于 agent 推理, 另一方面因为 agents/sqlguard.py 会把它作为只允许 SELECT 的沙箱强制执行:它会解析 生成的 SQL,拒绝任何不是单条 SELECT/WITH…SELECT 语句的内容,并且即使在一条本来合法的语句里,也会拦截写入/DDL 关键字的黑名单(INSERT、UPDATE、DELETE、 DROP、ALTER、SYSTEM……)。
  • Langfuse:eval、leaderboard 与可观测性的存储。它是现在就接好的,在你 选定模型或问出第一个问题之前,因为它不是留到以后再加的附件, 它就是在模块 01 里给竞赛打分、在模块 02 里让你深挖质量、 在模块 04 里观测生产环境的工具。一个项目,一条连续的 trace 与数据集轨迹,从第一次模型选择开始一路延续。

截图: Langfuse Cloud 项目的 Settings → API Keys 页面,展示 你要粘贴进 .env 的 public/secret 密钥对来自哪里,请从实际 UI 上截取。

坑,占位的 OPENROUTER_API_KEY。 .env.example 里带的 OPENROUTER_API_KEY=sk-or-... 是模板,不是真实密钥。如果你忘了覆盖它,模块 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 里改了这个值,却没有重新跑一遍 setup(或者删掉并 重建该用户),agent 的只读连接就会开始认证失败, 哪怕 .env 看上去"没错"。

目标

.env 里三套凭据齐备,arena 数据库初始化完成并带有 agent 将要查询的 v_* 视图,本地 dashboard 能在浏览器里打开。

步骤 1:创建三个账号

在动终端之前,你需要拿到三个服务的 API 凭据:

服务你需要什么在哪里获取.env 变量
OpenRouter一个 OPENROUTER_API_KEYopenrouter.ai → Keys。OpenRouter 用一个 OpenAI 兼容 API 挡在本课程用到的每个模型家族之前(Anthropic、OpenAI、Google、DeepSeek、Qwen、Z.ai)。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

三套都放在手边,待会儿要把它们粘贴进 .env。

Qwen 需要的 OpenRouter 隐私设置

在 OpenRouter 里打开 Settings → Privacy → Data Policies → Zero Data Retention, 把 Non-frontier 关掉(开关必须是灰色/关闭状态)。Qwen 属于 OpenRouter 的 non-frontier 模型分组,当 non-frontier 的 Zero Data Retention 被强制执行时,它可用的 Alibaba 端点不符合条件。如果这一项还开着, 即使 API key 和模型 slug 都正确,qwen/qwen3.7-flash 也会以 No endpoints available matching your guardrail restrictions and data policy 失败。

本课程发送的是合成电商问题和 schema。对于真实工作负载, 在放宽 ZDR 策略之前请先审视你所在组织的隐私要求。

步骤 2:克隆仓库

Agent Arena 位于 ClickHouse_Demos monorepo 内部,在 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

步骤 3:创建 virtualenv 并安装依赖

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

步骤 4:配置 .env

复制示例文件:

cp .env.example .env

.env

填入步骤 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 凭据。setup 只用 admin 用户一次,用来创建 arena 数据库和一个专用的只读用户 (arena_ro),后续课程中的 agent 都通过这个用户查询。
  • ARENA_RO_PASSWORD:随便挑一个密码;创建只读用户时它会成为 arena_ro 的 密码。
  • OPENROUTER_*:你的 OpenRouter 密钥及其 base URL。config.yaml 里的每个模型 都通过这一个端点访问。
  • LANGFUSE_*:你的 Langfuse Cloud 项目的主机和密钥。课程中的每一条 trace、 score 和数据集都存在这里,从模块 01 的第一次 Arena 运行 一直到模块 04 的生产环境。

步骤 5:用合成电商数据初始化 ClickHouse

这一步会创建 arena 数据库和 arena_ro 只读用户,直接在 ClickHouse 里生成合成 电商数据(customers、products、orders、order items、events), 并构建 agent 要查询的 v_* 视图:

source .env && scripts/arena.sh up

本课程里的每个 agent、每个 prompt、每一段黄金 SQL 查询的都是 v_customers、v_products、v_orders、v_order_items 和 v_events 视图,从不碰 原始表。

scripts/arena.sh up 还会启动本地 dashboard API 和 web UI。它 跑完之后,打开 **http://localhost:5174**,Leaderboard 标签页会一直是空的,直到 你在 模块 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_* 视图和 agent 要读取的 schema context。
  3. Starting dashboard API (:8000) + web UI (:5174):两行 [ready]。如果其中任何一行 显示 [NOT up],很可能是端口已被占用;查看它打印出的日志路径 (.run/dashboard-api.log 或 .run/web.log)。

终端输出显示 Agent Arena dashboard API 已在 8000 端口就绪、web UI 已在 5174 端口就绪

首次加载的 Agent Arena dashboard,Leaderboard 为空且没有运行数据

以上任何一项之后都可以用 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 admin 那些步骤(那些用的是admin凭据),但注意 只读路径,任何以 arena_ro 身份连接的地方,从哪里开始报错。
  3. 仔细读错误信息:它是认证错误、"user does not exist" 错误,还是先没有反应然后超时?记下你遇到的是哪一种。
  4. 恢复正确的 ARENA_RO_PASSWORD 并重新运行 scripts/arena.sh up。确认它 又能干净地跑完。

以后当同事的环境"跑不起来"时,你需要的正是同一种诊断 本能,把错误文本对应到三个服务中哪一个配置错了, 而不是把所有东西重新检查一遍。

小结

你已经有了一个初始化好的 ClickHouse 数据库、三个服务的全部凭据,包括 在任何模型被选定之前就接好的 Langfuse,以及运行中的本地 dashboard。 本模块之后的一切都复用同一套环境和同一个 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.

ZH