TensorZero UI 前端开发指南:基于 React Router 7 的工程规范与 Autopilot 内部功能调试
2026/9/15 12:06:41 网站建设 项目流程

TensorZero UI 前端开发指南:基于 React Router 7 的工程规范与 Autopilot 内部功能调试

【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero

TensorZero 是一个开源的 LLMOps 平台,将 LLM 网关、可观测性、评测、优化与实验能力统一为一体。本文基于仓库中 ui/AGENTS.md 这一面向开发者的工程指南,系统梳理 TensorZero UI(Web 管理界面)的技术栈、路由组织方式、日志与数据获取规范、代码质量校验命令,并重点讲解仅供内部使用的 Autopilot 功能从环境准备、依赖启动到 E2E 测试的完整调试流程。读完本文,你可以快速上手 TensorZero UI 的开发环境,理解其前后端路由架构,并能在本地搭建起 Autopilot 的联调与测试环境。

技术栈与工程结构总览

根据 ui/AGENTS.md 的第一条约定,TensorZero UI 使用以下技术栈:

  • React Router 7:负责页面路由与 API 路由的统一管理(本项目实际使用 React Router 7 的框架模式);
  • Tailwind:原子化 CSS 框架,用于界面样式;
  • Node + pnpm:包管理与脚本执行环境。

从 ui/package.json 可以看到具体的依赖构成:核心运行时包括react19、react-router7、@react-router/node@react-router/serve,UI 组件层使用radix-ui@ariakit/reactreact-hook-formzodrecharts,数据请求层使用@tanstack/react-query@clickhouse/client,同时以 file 依赖形式引用了本地 crate 编译产物@tensorzero/tensorzero-node(指向 crates/tensorzero-node)。开发侧还集成了oxfmt(格式化)、oxlint+eslint(静态检查)、typescript(类型检查)、vitest(单元测试)与playwright(E2E 测试)。

工程约定里还包含一条被 ui/README.md 再次强调的编码习惯:新代码优先使用undefined而不是null,唯一允许使用null的场景是与napi-rs兼容(它用null表示 Rust 侧的Option<T>),并且永远不要写出T | undefined | null这样的联合类型。

路由体系:页面与 API 统一定义在 routes.ts

AGENTS.md 明确指出:UI 的路由(页面与 API)统一定义在./app/routes.ts,以仓库根目录为基准即 ui/app/routes.ts。这份文件是理解整个 UI 功能面的最佳入口,它通过@react-router/dev/routes提供的indexprefixroute三个辅助函数声明全部路由。

从源码看,路由分为几大类:

  • 首页与基础页面index指向 ui/app/routes/index.tsx,另有 Playground(routes/playground/route.tsx)、API Keys(routes/api-keys/route.tsx)、配置编辑器(routes/config/route.tsx)与健康检查(routes/health/route.tsx)。
  • API 路由:统一挂在api前缀下,例如认证用的api/auth/set_gateway_key、推理与状态查询api/tensorzero/inferenceapi/tensorzero/status、反馈api/feedback,以及数据集、评测、工作流评测等数据接口。注意 API 路由与页面路由共用同一份声明,这是 React Router 7 框架模式下"前端路由 + 后端 handler"一体化的典型形态。
  • 功能模块页面:数据集(datasets)、数据点(datapoints)、评测(evaluations)、工作流评测(workflow-evaluations,注释标明原称 Dynamic Evaluations)、Autopilot、可观测性(observability,含 functions、inferences、episodes、models 四块)、优化(optimization/supervised-fine-tuning)。

其中 Autopilot 在路由层面被完整呈现:页面路由autopilot下挂有会话列表与sessions/:session_id详情页(new在该详情路由中被特殊处理);API 路由则提供了会话事件流(events/stream)、授权(events/authorize)、问答(events/answer-questions)、消息(events/message)、中断(actions/interrupt)、配置应用(config-apply/applyapply-all)、全部批准(actions/approve_all)等一系列接口,对应的实现文件位于 ui/app/routes/api/autopilot 目录下。新增页面或接口时,只要遵循这套声明方式在 routes.ts 中登记即可被 React Router 7 识别。

日志规范:统一使用 ~/utils/logger

AGENTS.md 要求:优先使用~/utils/logger导出的logger,而不是直接调用console.errorconsole.warnconsole.logconsole.debug。该模块的实现位于 ui/app/utils/logger.ts,从源码可以看到它提供了几个值得注意的能力:

  • 分级过滤:内部维护debuginfowarnerror四个级别。在浏览器环境默认输出debug级别;在服务端则读取TENSORZERO_UI_LOG_LEVEL环境变量,非法值会给出告警并回退到info
  • 统一消息格式化:通过getErrorMessage把 Error 对象、字符串、普通值统一序列化,避免直接打印对象导致的信息丢失;非序列化值应作为参数传入。
  • 版本前缀:日志会自动携带[TensorZero UI ${APP_VERSION}]前缀(取编译期__APP_VERSION__npm_package_version),便于在生产日志中定位版本来源。

这意味着团队通过统一的 logger 入口,既控制了日志噪音,又保证了日志格式与级别的可观测性。新代码中如需打印日志,应直接引用logger而非裸的console

数据获取:优先使用 useFetcher 而非 fetch

AGENTS.md 建议在 UI 中优先使用 React Router 的useFetcher而非直接调用fetch(并附有官方 API 文档链接)。useFetcher是 React Router 7 内置的声明式数据交互 Hook,它可以直接调用本应用在routes.ts中注册的 action/loader 而不触发页面导航,从而让表单提交、按钮操作与数据加载天然继承 React Router 的加载态、错误处理与并发保护机制,避免手写 fetch 时的样板代码与竞态问题。

对于需要直连 TensorZero 网关的场景,UI 提供了封装好的客户端工具:~/utils/get-tensorzero-client.server.ts用于普通推理客户端,~/utils/get-autopilot-client.server.ts用于 Autopilot 会话客户端。从 ui/app/utils/get-autopilot-client.server.ts 的实现可以看到,客户端通过 ui/app/utils/env.server.ts 中的getEnv()统一读取环境变量,API Key 优先取环境变量TENSORZERO_API_KEY走缓存单例,否则从 cookie 读取"有效 API Key"逐请求创建客户端,保证安全性与灵活性兼得。

环境变量约定:env.server.ts 是唯一入口

值得补充的是,AGENTS.md 虽未逐条列出环境变量,但 ui/app/utils/env.server.ts 是项目中唯一允许直接访问process.env的文件,它集中管理了以下变量:

  • TENSORZERO_GATEWAY_URL(必填,缺失会在启动时报错);
  • TENSORZERO_POSTGRES_URL(可选,Postgres 连接串);
  • TENSORZERO_UI_READ_ONLY(置为1时启用只读 UI);
  • TENSORZERO_API_KEY(可选,网关 API Key);
  • TENSORZERO_UI_CONFIG_FILE(可选,指向配置文件的本地路径);
  • TENSORZERO_AUTOPILOT_BETA_TOOLS(可选,Autopilot 测试工具开关);
  • TENSORZERO_HEADER_*前缀变量:会被自动转换为tensorzero-*请求头(例如TENSORZERO_HEADER_BETA_TOOLS=valuetensorzero-beta-tools: value),用于向网关传递 Autopilot 所需的附加头部。

同时该文件对旧变量TENSORZERO_UI_CONFIG_PATHTENSORZERO_UI_DEFAULT_CONFIG(2025.12 起弃用)与TENSORZERO_CLICKHOUSE_URL(弃用)给出明确的 deprecation 警告:新版 UI 的所有数据库查询都改由网关转发,无需再向 UI 容器挂载配置文件。这与 AGENTS.md 中 Autopilot 开发时用TENSORZERO_UI_CONFIG_FILE指定配置文件的用法是一致的。

代码质量三道闸:format、lint、typecheck

AGENTS.md 明确规定:修改 UI 代码后,必须在ui/目录下依次运行pnpm run formatpnpm run lintpnpm run typecheck,且三个命令必须全部通过。对应的脚本定义在 ui/package.json:

命令实际执行内容作用
pnpm run formatoxfmt "**/*.{js,jsx,ts,tsx,css,scss,html,json,yaml,md}"用 oxfmt 统一格式化各类源文件与配置文件
pnpm run lintoxlint . --fix --deny-warnings && eslint . --fix --max-warnings=0 --config eslint.config.js --cache先跑 oxlint(warnings 视为错误),再跑 eslint,修复并零警告通过
pnpm run typecheckreact-router typegen && tsc先为路由生成类型声明,再执行 TypeScript 全量类型检查

三者互为补充:format 保证风格统一,lint 拦截静态问题与潜在错误,typecheck 借助react-router typegen让路由路径与参数在编译期即可校验。此外ui/package.json还提供了format:checklint:check只检查不修改的变体,适合 CI 场景;单元测试可运行pnpm test(vitest),E2E 测试则通过pnpm test-e2e(playwright)执行。

Autopilot 功能:内部专用的联调与测试

AGENTS.md 用较大篇幅专门介绍Autopilot 功能,并强调它是Internal Only:该功能依赖一个闭源内部 API,e2e_tests/autopilot/下的测试需要访问私有autopilot仓库,外部贡献者无法运行;这些测试由 autopilot 仓库通过 repository dispatch 在 CI 中触发。如果你是拥有 autopilot 仓库访问权限的内部贡献者,可按以下步骤搭建本地环境。

第一步:设置 AUTOPILOT_REPO 环境变量

AUTOPILOT_REPO指向本地 autopilot 仓库的检出路径:

export AUTOPILOT_REPO=/path/to/autopilot

第二步:启动 Autopilot 依赖

$AUTOPILOT_REPO目录下执行,或在任意目录下通过-f显式指定其 docker-compose 文件:

docker compose --profile e2e up -d

或:

docker compose -f "$AUTOPILOT_REPO/docker-compose.yml" --profile e2e up -d

--profile e2e会拉起 Autopilot 联调所需的全部依赖容器(含网关等),保持常驻即可。

第三步:以 Autopilot 配置启动 UI 开发服务器

ui/目录下执行:

TENSORZERO_UI_CONFIG_FILE="$AUTOPILOT_REPO/e2e_tests/fixtures/config/tensorzero.toml" \ TENSORZERO_GATEWAY_URL=http://localhost:3040 \ pnpm dev

这里TENSORZERO_UI_CONFIG_FILE指向 autopilot 仓库中的测试配置文件(tensorzero.toml),TENSORZERO_GATEWAY_URL指向本地启动的网关(端口 3040)。pnpm dev对应 ui/package.json 中的react-router dev,会在本地启动带热更新的开发服务器。从 ui/playwright.config.ts 可以看到,非 CI 场景下 Playwright 的webServer也会默认执行pnpm run dev并等待http://localhost:5173就绪,因此本地开发与 E2E 测试复用同一套 dev server 流程。

第四步:运行 Autopilot E2E 测试

ui/目录下运行全部 Autopilot 测试:

TENSORZERO_UI_CONFIG_FILE="$AUTOPILOT_REPO/e2e_tests/fixtures/config/tensorzero.toml" \ TENSORZERO_GATEWAY_URL=http://localhost:3040 \ TENSORZERO_PLAYWRIGHT_INCLUDE_AUTOPILOT=1 \ pnpm exec playwright test e2e_tests/autopilot/

只运行单个测试文件,例如:

TENSORZERO_UI_CONFIG_FILE="$AUTOPILOT_REPO/e2e_tests/fixtures/config/tensorzero.toml" \ TENSORZERO_GATEWAY_URL=http://localhost:3040 \ TENSORZERO_PLAYWRIGHT_INCLUDE_AUTOPILOT=1 \ pnpm exec playwright test e2e_tests/autopilot/autopilot.spec.ts

关键点在于环境变量TENSORZERO_PLAYWRIGHT_INCLUDE_AUTOPILOT=1:从 ui/playwright.config.ts 的源码可以看到,Autopilot 测试默认被testIgnore: "autopilot/**"排除,只有显式设置该变量后才会取消排除并纳入测试。这也是为什么外部贡献者的普通 E2E 测试(如pnpm test-e2e)不会触碰这些用例。

当前仓库中 ui/e2e_tests/autopilot 目录实际包含以下测试文件,可供对照了解覆盖范围:

  • autopilot.spec.ts:Autopilot 主流程测试;
  • config-apply.spec.ts:配置应用(apply/apply-all)相关测试;
  • user-questions.spec.ts:用户问答(answer-questions)相关测试;
  • topk-visualization.spec.tsvariant-performance-visualization.spec.ts:Top-K 与变体性能可视化测试。

目录下的辅助模块 ui/e2e_tests/autopilot/helpers.ts 提供了两个值得注意的工具函数:deterministicTestAndAttemptuniqueDatasetName。它们基于"测试标题 + 重试次数"生成确定性的数据集名称——注释中明确说明这是 Rust 侧deterministic_test_and_attemptunique_dataset_name的 Playwright 等价实现,目的是保证同一测试每次产生相同名称,从而充分利用提示词/模型缓存,降低 E2E 测试的推理成本。

总结

TensorZero UI 的工程规范可以概括为三条主线:以 ui/app/routes.ts 为中心的页面与 API 统一路由、以~/utils/loggeruseFetcher为代表的统一基础设施、以 format/lint/typecheck 为底线的提交前自检。而 Autopilot 作为内部功能,其调试路径围绕AUTOPILOT_REPOTENSORZERO_UI_CONFIG_FILETENSORZERO_GATEWAY_URLTENSORZERO_PLAYWRIGHT_INCLUDE_AUTOPILOT四个关键配置展开:先启动 autopilot 仓库的 docker 依赖,再以测试配置启动 UI dev server,最后显式放开 Playwright 的测试排除项运行 E2E 用例。对内部贡献者而言,这套流程可以完整还原 Autopilot 的本地联调环境;对外部贡献者而言,理解这份约定也有助于把握 UI 的整体架构,并绕开无法运行的内部测试来贡献其余功能。

【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询