00 环境准备
准备好你的环境,从一开始就接通 OpenRouter、ClickHouse 和 Langfuse。
产出
一个已克隆的仓库,装好 Python virtualenv,一份填入了 OpenRouter、ClickHouse Cloud 和
Langfuse Cloud 凭据的 .env,一个在 ClickHouse Cloud 中用合成电商数据初始化好的 arena
数据库,以及运行在 http://localhost:5174 的本地 dashboard,
Leaderboard 标签页目前是空的,这是正常的,直到
模块 01 才会有数据。
为什么
基准测试框架和线上服务 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_KEY | openrouter.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 会按顺序打印:
ClickHouse: business database + read-only agent user:创建arena数据库和 专用的arena_ro用户。Seeding ClickHouse directly + views + schema context:每张表一行clickhouse: inserted <N> into <table>(customers、products、orders、order_items、events),然后是done,接着构建v_*视图和 agent 要读取的 schema context。Starting dashboard API (:8000) + web UI (:5174):两行[ready]。如果其中任何一行 显示[NOT up],很可能是端口已被占用;查看它打印出的日志路径 (.run/dashboard-api.log或.run/web.log)。


以上任何一项之后都可以用 scripts/arena.sh status 复查,它会打印
服务器是否在运行,以及每个 v_* 视图的行数。
如何确认你已完成
.env中CLICKHOUSE_CLOUD_*、OPENROUTER_*和LANGFUSE_*都是真实值 (不是占位值)。scripts/arena.sh up无错误跑完。http://localhost:5174能在浏览器里打开,显示出一个 Leaderboard 标签页(现在是空的 才对)。
练习:故意弄坏一个连接并诊断它
趁着代价为零的时候,故意练习通过失败特征认出一个填错的 .env
值:
- 打开
.env,把ARENA_RO_PASSWORD改掉一个字符(或者临时把它 注释掉)。 - 重新运行
source .env && scripts/arena.sh up。它应该仍然能走完 ClickHouse admin 那些步骤(那些用的是admin凭据),但注意 只读路径,任何以arena_ro身份连接的地方,从哪里开始报错。 - 仔细读错误信息:它是认证错误、"user does not exist" 错误,还是先没有反应然后超时?记下你遇到的是哪一种。
- 恢复正确的
ARENA_RO_PASSWORD并重新运行scripts/arena.sh up。确认它 又能干净地跑完。
以后当同事的环境"跑不起来"时,你需要的正是同一种诊断 本能,把错误文本对应到三个服务中哪一个配置错了, 而不是把所有东西重新检查一遍。
小结
你已经有了一个初始化好的 ClickHouse 数据库、三个服务的全部凭据,包括 在任何模型被选定之前就接好的 Langfuse,以及运行中的本地 dashboard。 本模块之后的一切都复用同一套环境和同一个 Langfuse 项目;不再需要额外的准备步骤。
终态
环境就绪。继续前往 01 选出基座模型,在这份数据上跑竞赛。