评测体系总览
整体分层
+-----------------------------------------------------------------+
| 第5层: 上线验收 (acceptance/) |
| 业务视角,决定能不能发布 |
+-----------------------------------------------------------------+
| 第4层: Agent 效果评测 (Langfuse + Golden Cases) |
| AI 质量视角,评估 Agent 回答好不好 |
+-----------------------------------------------------------------+
| 第3层: E2E + Live Regression + [Locust 负载测试] + E2E 性能断言 |
| 真实链路视角,前端 + 后端全链路 |
+-----------------------------------------------------------------+
| 第2层: Benchmark (benchmark/) |
| 性能/能力基准,QueryAgent / Text2SQL 准确率 / Bundle / Lighthouse |
+-----------------------------------------------------------------+
| 第1层: CI 质量门禁 (lint + 路由契约测试 + build + bundle-size-check) |
| 代码质量视角,每次 push 自动跑 |
+-----------------------------------------------------------------+
各层之间互不替代:CI 通过不代表前端性能好,前端性能好不代表 Agent 效果好,Agent 效果好不代表业务可发布。每一层有独立的触发条件和判定标准。前端性能评测有独立方案,本文不展开。
第1层: CI 质量门禁
触发方式:GitHub push / PR 到 master 分支,自动执行
配置文件:.github/workflows/ci.yml
1.1 后端 Lint
| 项目 | 说明 |
|---|---|
| 位置 | ruff check app worker --select=F,I,UP,W |
| 工具 | ruff >= 0.15.0 |
| 触发 | GitHub push/PR 自动 |
| 失败处理 | 阻止合并 |
1.2 后端路由契约测试
| 项目 | 说明 |
|---|---|
| 位置 | tests/unit/api/ |
| 工具 | FastAPI TestClient + pytest |
| 覆盖 | 422/404/405/CORS 通用契约(中间件层) |
| 配置 | asyncio_mode = "auto",忽略 tests/manual/ 和 tests/benchmark/ |
| 触发 | GitHub push/PR 自动 |
| 设计 | 通过 app.dependency_overrides 绕过 JWT 中间件,仅验证 HTTP 中间件行为,不连接真实 DB。共 15 条用例,进程内运行,不需要外部服务。 |
中间件契约测试是 CI 中唯一的后端测试。端点 401/422 验证和 seed 数据回归由
tests/api/黑盒测试(需要 server)承担。Agent 评测层(Langfuse + Golden Cases)独立验证 AI 回答质量。
1.3 前端 Lint
| 项目 | 说明 |
|---|---|
| 位置 | web/ |
| 工具 | ESLint + eslint-plugin-playwright |
| 触发 | GitHub push/PR 自动 |
1.4 前端构建
| 项目 | 说明 |
|---|---|
| 位置 | web/ |
| 命令 | pnpm run build (Vite) + pnpm run size-check (Bundle 体积预算) |
| 触发 | GitHub push/PR 自动 |
Lighthouse CI 不在 CI 中运行(SPA static 预渲染为空白页),本地通过
pnpm run lhci手动执行。
1.5 API 黑盒测试(tests/api/)
| 项目 | 说明 |
|---|---|
| 位置 | tests/api/ |
| 工具 | pytest + httpx(复用 tests/utils/api_client.py) |
| 覆盖 | 全部 15 个模块 155 个端点,按 domain 分子目录(auth/dashboard/analysis/chat/config/infra) |
| 触发 | 手动执行,需要 uv run server |
| 设计 | Session 级 token 磁盘缓存,只登录一次。每条端点正确输入->200+seed数据断言 + 错误输入->401/422。 |
API 黑盒测试定位在第3层(真实链路),替代原集成测试。当前 173 条用例(22 个文件),按 domain 分子目录。新增端点时在
tests/api/{domain}/对应文件中添加 test method 即可。CI 暂不自动执行。
第2层: Benchmark
Benchmark 是离线执行的性能/能力基准测试,不阻塞 CI,按需手动运行。
2.1 QueryAgent Benchmark(主项目)
文件结构
tests/benchmark/
run_query_agent_benchmark.py # 主执行脚本
run_full_benchmark.py # 统一入口(API + DuSQL)
query_agent_benchmark_cases.yaml # 17 条测试用例
test_benchmark_utils.py # 工具函数单元测试
用例覆盖
17 条 benchmark case,覆盖 5 个类别:
login_detail- 登录明细查询order_detail- 订单明细查询sql- SQL 生成与执行table_query- 表查询cross_project- 跨项目查询
执行命令
cd server
# 仅跑 QueryAgent benchmark
uv run python tests/benchmark/run_query_agent_benchmark.py
# 跑完整 benchmark(API + DuSQL)
uv run python tests/benchmark/run_full_benchmark.py
设计特点
- 对
/api/v1/agent/query发送真实 HTTP 请求 - 有失败用例时 exit code 为非 0(可用于 CI 决策)
- 通过 pyproject.toml 从默认 pytest 收集中排除
2.2 BI 平台 Benchmark(Java 项目,独立体系)
文件结构
bi-platform/benchmark/
benchmark.py # 主执行脚本
benchmark.md # 文档
requirements.txt # pandas, PyJWT, requests
data/
caiwu.csv # 财务类测试数据
renli.csv # 人力类测试数据
shuce.csv # 数册类测试数据
用途
对运行中的服务进行批量 Q&A 测试,使用 CSV 文件中的真实用户问题。
执行命令
python benchmark.py -u <url> -a <agentId> -c <chatId> -f <filePath> -p <userName>
2.3 BI 平台 Evaluation(Text2SQL 准确率,独立体系)
文件结构
bi-platform/evaluation/
evaluation.py # 主评测脚本(SQL 准确率对比)
evaluation.sh # 一键执行脚本
build_models.py # 模型构造
build_pred_result.py # 预测结果构造
build_tables.py # 表构造
process_sql.py # SQL 解析/归一化
config/
config.yaml # 配置(url: http://localhost:9080)
data/
gold_example_dusql.txt # Golden SQL 标准答案
internet.txt # 测试问题集
tables_dusql.json # Schema 定义
requirements.txt # pysqlite3, PyJWT, PyYAML, sqlparse, nltk
用途
跨模型 Text2SQL 准确率对比评测。将模型生成的 SQL 与 gold standard SQL 进行对比,输出准确率。
执行命令
bash evaluation.sh
输出
- 控制台输出准确率
error_case.json- 错误案例明细
Benchmark 层总结
| 评测 | 项目归属 | 测什么 | 何时跑 |
|---|---|---|---|
| QueryAgent Benchmark | 主项目 Python | QueryAgent 真实 API 能力 | 改 QueryAgent 后 |
| Full Benchmark | 主项目 Python | API + DuSQL 组合 | 发布前 |
| BI 平台 Benchmark | Java 独立 | 批量 Q&A | 按需 |
| BI 平台 Evaluation | Java 独立 | Text2SQL 准确率 | 按需 |
第3层: E2E + Live Regression
真实链路测试,需完整服务运行,手动执行。
3.1 Playwright E2E(前端)
文件结构
web/
playwright.config.ts # Playwright 配置
e2e/ # 33 个 spec 文件 + utils/
utils/
performance.ts # E2E 性能采集(web-vitals)
vue.spec.ts # 根路径重定向
phase1-acceptance.spec.ts # 阶段1 验收测试
frontend-feature-acceptance.spec.ts # 功能面验收
acceptance-runtime.spec.ts # 运行时验收
seeded-feature-workflows.spec.ts # 种子数据工作流
dashboard.spec.ts # Dashboard 完整 E2E(26 个用例)
dashboard-*.spec.ts # 看板专项(loading/tab/preview/ux/operation-normalizer)
event-analysis.spec.ts # 事件分析
data-report.spec.ts # 数据报告
data-report-tags.spec.ts # 报表标签
report-analysis.spec.ts # 报告分析
alert-report-detail.spec.ts # 告警报告详情
loading-experience.spec.ts # 页面加载体验
request-cancel.spec.ts # 请求取消
chart-option-builder.spec.ts # 图表选项构建
brand-alignment.spec.ts # 品牌一致性
layout-styles.spec.ts # 布局样式
ant-card-priority-migration.spec.ts # ant-card 样式迁移
operation-tab-compat.spec.ts # 运营 Tab 兼容
project-context-loading.spec.ts # 项目上下文加载
sdk-card-smoke.spec.ts # SDK 卡片冒烟
coverage-gap-evidence.spec.ts # 覆盖缺口证据
required-risk-evidence.spec.ts # 必需风险证据
permission-enforcement-evidence.spec.ts # 权限强制执行证据
project-space-permission-evidence.spec.ts # 项目空间权限
user-groups-crud-evidence.spec.ts # 用户组 CRUD
config-crud-evidence.spec.ts # 配置 CRUD
配置
// playwright.config.ts 关键参数
{
testDir: "./e2e",
timeout: 30000, // 单测试 30s
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
projects: [
{ name: "chromium" },
{ name: "firefox" },
{ name: "webkit" },
],
webServer: { // 自动管理前端 dev server
command: process.env.CI ? "pnpm run preview" : "pnpm run dev",
port: process.env.CI ? 4173 : 20801,
reuseExistingServer: !process.env.CI,
},
}
执行命令
cd web
pnpm run test:e2e # 全部 E2E
pnpm run test:e2e -- --grep "dashboard" # 按名称过滤
测试分类与详细说明
共 33 个 spec 文件,约 180 个 test case。运行依赖:前端 dev server + 后端 API + 数据库(需 seed 数据)。
1. Dashboard 测试 (dashboard.spec.ts, dashboard-*.spec.ts) - 26 个用例
覆盖固定看板 8 个系统预设 Tab 的全面验收:
| 用例 | 覆盖内容 |
|---|---|
| D0 | Tab 栏可见且含大盘总览 |
| D1 | 大盘总览:时间维度、导出、整体看盘或空态 |
| D2-D8 | 日监控/用户活跃/用户增长/付费分析/用户回流/货币监控/运营报表 Tab 可切换且内容可见 |
| D4.1/D6.1/D8.1 | 增长/回流/运营 Tab 内图表高度一致性(blockHeight/chartHeight 统一) |
| D9-D10 | 总览切换时间维度为周/月后可见对应文案 |
| D11 | GlobalFilter 筛选区可见(渠道/查询/清空/实时更新) |
| D12 | 连续切换多个 Tab 不报错且内容可再次加载 |
| D13 | 各 Tab 切换后均有对应内容区域 |
| D14-D15 | 筛选区点击查询/清空按钮不报错 |
| D16 | 总览有数据时点击导出按钮不报错 |
| D17-D18 | 日监控/增长 Tab 内 DisplayTypeSwitcher dropdown 切换可见 |
| D20 | 无感刷新:定时刷新后内容保持可见、无全块遮罩 |
| D21 | 侧栏发送消息后助手消息可见,图表可固定或保持处理状态 |
| D99 | Dashboard 首屏 Core Web Vitals 性能采集 |
其他 dashboard 专项 spec:
dashboard-loading-ring.spec.ts- 加载时环形进度指示器dashboard-loading-empty.spec.ts- 空态渲染(7 个用例)dashboard-tab-state.spec.ts- Tab 状态保持(3 个用例)dashboard-preview.spec.ts- 看板预览(3 个用例)dashboard-ux-consistency.spec.ts- chart-block 圆角/标题行高度/工具栏顺序/reduced-motion(5 个用例)dashboard-operation-normalizer.spec.ts- 运营数据归一化(6 个用例)
2. 运行时验收 (acceptance-runtime.spec.ts) - 4 个用例
- 12 个核心路由连续切换,检测插入 insertBefore/NotFoundError/Vue Error/Maximum recursive updates 等阻断级 runtime 异常
- 同组件页面连续切换防 DOM 锚点复用异常(21 个路由序列)
- 收集
pageerror和console.error,断言无阻断异常
3. 前端功能面验收 (frontend-feature-acceptance.spec.ts) - 8 个用例
按 16 个功能页逐一巡检的综合性验收:
| 用例 | 覆盖内容 |
|---|---|
| 认证失败与登录态失效 | 错误密码提示不泄露敏感信息;过期 token 自动跳转登录页 |
| 权限路由拦截 | operator1 角色不能访问 /permission 和 /admin |
| 核心页面巡检 | 16 个页面的白屏检测、控件健康检查、安全按钮演练、API 错误监控 |
| AI 对话主链路 | 发送问题 -> 流式助手响应可见且非空 |
每个页面巡检包含:
assertPageIsNotBlank- 检测白屏(visibleTextLength > 10)assertInteractiveElementsHealthy- 可见控件尺寸、可读名称、不被遮挡exerciseEditableTextInputs- 输入框 fill/resetexerciseSafeButtons- 安全按钮点击(刷新/查询/搜索/重置/取消/关闭等)installQualityProbe- 监听 pageerror/console.error/requestfailed/API 4xx-5xx,测试结束断言无误
4. 种子数据工作流 (seeded-feature-workflows.spec.ts) - 11 个用例
完整端到端业务链路,通过 API 创建种子数据 -> 浏览器操作 -> API 验证:
| 用例 | 链路 |
|---|---|
| 明细查询真实数据与空态 | login-by-cube -> 登录明细表格渲染 -> 切换到充值订单 -> 渠道空搜索 -> 空态展示 |
| 灵活看板组件添加与保存 | 创建种子报表 -> 新建看板 -> 搜索报表添加到看板 -> 保存 -> API 验证 component 已挂载 |
| AI 配置端点校验与增删改查 | 验证 5 个 Agent block -> 添加端点(表单校验:缺 Base URL 提示) -> 编辑端点 -> API 验证 -> 删除 |
| 报告视图与公开聊天分享 | 报告实例列表 -> 创建 chat share -> 公开分享页渲染 markdown/code block |
| 分群->事件分析引用保存 | 新建分群(预览->保存) -> 新建事件分析(选择事件->选择分群->保存) -> API 验证 segment_ids |
| 报表->共享空间挂载 | 新建报表 -> 预览导出 CSV -> 添加到共享空间 -> 搜索共享空间 -> 查看列表 -> 返回全部报表 -> 验证所有权不变 |
5. 证据类测试 (6 个文件)
面向合规/安全的验证型测试:
permission-enforcement-evidence.spec.ts- 权限强制执行证据(7 个用例)project-space-permission-evidence.spec.ts- 项目空间权限(6 个用例)user-groups-crud-evidence.spec.ts- 用户组 CRUD(5 个用例)config-crud-evidence.spec.ts- 配置 CRUD(8 个用例)coverage-gap-evidence.spec.ts- E2E 覆盖缺口证据(7 个用例)required-risk-evidence.spec.ts- 必需风险证据(5 个用例)
6. UI/UX 一致性
brand-alignment.spec.ts- 品牌一致性(5 个用例)layout-styles.spec.ts- 布局样式(6 个用例)chart-option-builder.spec.ts- 图表选项构建(5 个用例)ant-card-priority-migration.spec.ts- ant-card 样式优先级迁移(3 个用例)operation-tab-compat.spec.ts- 运营 Tab 兼容性
7. 特定功能专项
event-analysis.spec.ts- 事件分析:分群选择器状态/事件切换/编辑器保存(3 个用例)data-report.spec.ts- 数据报表卡片/编辑预览/引用导出(3 个用例)data-report-tags.spec.ts- 报表标签管理(2 个用例)report-analysis.spec.ts- 报告分析详情alert-report-detail.spec.ts- 告警报告详情loading-experience.spec.ts- 页面加载体验(10 个用例)request-cancel.spec.ts- 请求取消机制(3 个用例)project-context-loading.spec.ts- 项目上下文加载(2 个用例)sdk-card-smoke.spec.ts- SDK 卡片冒烟(2 个用例)
8. 基础测试
vue.spec.ts- 未登录访问根路径重定向到登录页phase1-acceptance.spec.ts- 阶段1 综合验收(18 个用例)
9. 性能采集工具 (utils/performance.ts)
- 注入 web-vitals IIFE 采集 FCP/LCP/TTFB/CLS
collectWebVitals(page)- 在页面 load 后通过 web-vitals API 采集指标assertVitalBudget(metrics, pageName, budgets)- 性能预算断言(warn 级别,不阻塞测试)- 当前性能预算:FCP < 2000ms, LCP < 4000ms, CLS < 0.1
关键设计模式
API 登录注入 - 通过 addInitScript 将 token 写入 localStorage,跳过 UI 登录,加速测试执行:
await page.addInitScript(
({ storedToken, storedUser }) => {
window.localStorage.setItem('token', storedToken)
window.localStorage.setItem('user', JSON.stringify(storedUser))
window.localStorage.setItem('remember_me', '1')
},
{ storedToken: token, storedUser: user },
)
QualityProbe 质量探针 - 监听浏览器运行时事件,测试结束时统一断言:
function installQualityProbe(page: Page) {
const issues: string[] = []
page.on('pageerror', (error) => { issues.push(`pageerror: ${error.message}`) })
page.on('console', (msg) => { /* 过滤已知无害错误,其余记录 */ })
page.on('requestfailed', (request) => { /* 记录非 abort 的失败请求 */ })
page.on('response', (response) => { /* 记录 API 4xx/5xx */ })
return {
waitForApiIdle(timeoutMs) { /* 等待全部 API 完成 */ },
assertClean(label) { expect(issues).toEqual([]) },
}
}
资源清理 - 所有种子数据测试使用 try/finally + deleteResource() 确保不污染数据库。
重试机制 - 登录和认证操作内置 2-3 次重试,应对后端冷启动。
CI 集成状态
当前 CI 未包含 E2E job。E2E 仅支持本地执行:
cd web && pnpm run test:e2e
CI 包含:后端 Lint + 路由契约测试 + 前端 Lint + 构建 + Bundle 检查。
3.2 Live Release Regression(后端全链路)
文件结构
server/scripts/
run_live_release_regression.py # 回归入口
覆盖的 9 组回归
| 组 | 内容 |
|---|---|
| ETL contracts | ETL 数据转换合同 |
| Event Analysis | 事件分析链路 |
| Dashboard Cube | 看板数据立方 |
| MCP | MCP 协议链路 | | Auth | 认证链路 | | Reporting | 报告生成链路 | | Agents | Agent 全链路 | | System | 系统健康检查 |
执行命令
cd server
uv run live-regression
3.2 Locust 负载测试
对数据分析 AI Agent 平台关键 API 执行并发负载测试,验证并发下的响应时间分布、Rate Limiting 效果、数据库连接池压力。
文件结构
server/locust/
locustfile.py # 主入口(5 个 User 类)
perf_thresholds.py # 性能阈值 + @events.quitting 断言钩子
users/
dashboard_user.py # 看板查询(operator 角色)
auth_user.py # 认证链路(operator 角色)
report_user.py # 数据报表(operator 角色)
event_analysis_user.py # 事件分析(operator 角色)
misc_user.py # 基础读接口(operator 角色)
data/
test_accounts.json # 多角色测试账号池
config/
smoke.conf # 冒烟配置(1 用户 / 30s)
base.conf # 基础配置(20 用户 / 2min)
stress.conf # 压力配置(100 用户 / 5min)
性能阈值
| 端点 | P95 阈值 | 错误率阈值 |
|---|---|---|
GET /api/v1/dashboard/overview | < 2s | < 1% |
GET /api/v1/dashboard/currency | < 2s | < 1% |
POST /api/v1/auth/login | < 3s | < 1% |
GET /api/v1/auth/me | < 200ms | < 1% |
GET /api/v1/data-reports | < 2s | < 1% |
GET /api/v1/event-analysis/events | < 2s | < 2% |
GET /api/v1/projects | < 1s | < 1% |
GET /api/v1/user-segments | < 1s | < 1% |
GET /api/v1/token/usage/my | < 1s | < 1% |
GET /api/v1/filter-templates | < 1s | < 1% |
执行命令
cd server
# 安装依赖
uv sync --group load
# 冒烟测试(CI 可用,退出码反映 pass/fail)
uv run locust -f locust/locustfile.py --config locust/config/smoke.conf
# 基础负载(生成 HTML/CSV 报告)
$ts = Get-Date -Format "yyyyMMdd-HHmmss"
uv run locust -f locust/locustfile.py --config locust/config/base.conf `
--html "reports/locust-base-$ts.html" --csv "reports/locust-base-$ts"
# 压力测试(发布前)
$ts = Get-Date -Format "yyyyMMdd-HHmmss"
uv run locust -f locust/locustfile.py --config locust/config/stress.conf `
--html "reports/locust-stress-$ts.html" --csv "reports/locust-stress-$ts"
Locust 定位在第3层(真实链路),冒烟测试可进 CI(退出码驱动),压力测试发布前手动执行。当前阶段不覆盖 AI Agent Chat / SSE 流式场景。
第4层: Agent 效果评测(核心)
这是最复杂的评测层,由三个组件配合工作:Golden Cases(用例真源) + Langfuse Experiment Runner(执行引擎) + Langfuse 平台(可视化 + LLM 评分)。
4.1 架构数据流
tests/data/golden_agent_cases.yaml
(175 条黄金用例,Git 真源)
|
| --seed-from-cases-file
v
+-------------------------------+
| Langfuse Dataset |
| name: native-agent-regression |
| (平台持久化镜像) |
+-------------------------------+
|
| run_experiment()
v
+---------------------------------------------------+
| run_langfuse_agent_experiment.py (执行引擎) |
| |
| 3 条执行 Lane: |
| +-- http_api (默认) /api/v1/agent/chat |
| +-- watcher_worker 真实 worker task 调用 |
| +-- mcp_protocol stdio + SSE call_tool |
| |
| 程序化打分 (确定性 1/0): |
| +-- http_success HTTP 状态码 |
| +-- tool_success 工具调用成功 |
| +-- answer_contract must_include/must_not |
| +-- query_mode_match 查询模式匹配 |
| +-- tool_call_ast_match 工具调用 AST 匹配 |
| +-- answer_contract_qem 准精确匹配 |
| +-- context_propagation 上下文传播检查 |
+--------------------+------------------------------+
| 结果写入
v
+---------------------------------------------------+
| Langfuse UI (http://langfuse.example.com:3000) |
| /evals 页面 - LLM Evaluator 语义评分 (0-10): |
| +-- query_capability 查询能力 |
| +-- answer_correctness 回答正确性 |
| +-- report_quality 报告质量 |
| +-- dashboard_quality 看板质量 |
| +-- tool_choice_quality 工具选择质量 |
| +-- helpfulness 有帮助程度 |
| +-- instruction_following 指令遵循 |
| +-- groundedness 事实扎根 |
| +-- project_scope_safety 项目范围安全 |
| |
| 对比视图: Baseline vs Current Run |
+---------------------------------------------------+
4.2 Golden Cases(黄金用例集)
文件
server/tests/data/golden_agent_cases.yaml - 163 条用例,Git 版本控制
Schema
schema_version: 1
dataset:
name: native-agent-regression
description: Native Agent golden evaluation draft.
cases:
- id: query_metric_dau_yesterday # 唯一标识(snake_case)
agent_type: query # supervisor|query|analyst|report|watcher|mcp
category: tool_choice_query_metric # 分类标签
risk_level: p0 # p0|p1(P0 用于快速回归)
endpoint: /api/v1/agent/chat # 调用的 API 端点
input:
message: 昨天 DAU 是多少 # 用户问题(自然语言)
project_name: 示例业务A # 自然语言项目名(运行时映射为 project_id)
context: {} # 可选:附加上下文
expected_output:
must_include: [DAU] # 回复必须包含的关键词
must_not_include: [Traceback] # 回复禁止包含的关键词
tool_call: # 期望调用的工具及参数
- name: query_agent
arguments: {}
query_mode: metric_query # 可选:期望的查询模式
hard_gates: # 硬门槛(全部通过才算有效)
- permission_safety_pass
- data_scope_pass
complexity: simple # simple|medium|hard
6 种 Agent 类型覆盖
| Agent 类型 | 用例数 | 典型场景 |
|---|---|---|
| supervisor | 34+ | 路由分发(query/analysis/report/alert)、跨项目对比、安全拦截(危险SQL/密钥泄露)、上下文引用、意图澄清 |
| query | 55+ | 指标查询(DAU/WAU/MAU/收入/付费人数/付费率/留存)、渠道/关卡/活动维度、表查询、多项目、不支持指标拒答 |
| analyst | 10+ | 归因分析、异常解释、DAU 下降分析 |
| report | 28+ | 收入趋势报告、活动效果报告、周报/日报、看板/自定义报表创建 |
| watcher | 12+ | 告警规则状态、Worker 级别规则检测(worker://watcher/check_single_rule, worker://watcher/check_alerts) |
| mcp | 14+ | stdio tools/list、stdio tools/call、SSE /auth、SSE call_tool |
Category 分类
| Category | 含义 |
|---|---|
| route_query | Supervisor 路由到 QueryAgent |
| route_analysis | Supervisor 路由到 AnalystAgent |
| route_report | Supervisor 路由到 ReportAgent |
| route_alert | Supervisor 路由到 WatcherAgent |
| clarification | 意图不明确需澄清 |
| context_reference | 引用当前图表/看板上下文 |
| cross_project | 跨项目查询 |
| tool_choice_safety_refusal | 安全检查(危险 SQL / 不存在项目) |
| security | 密钥泄露防护 |
| tool_choice_query_metric | QueryAgent 指标查询 |
| tool_choice_query_table | QueryAgent 表查询 |
| query_* | QueryAgent 各类查询能力 |
| report_* | ReportAgent 各类报告能力 |
| watcher_* | WatcherAgent 各类检测能力 |
| mcp_* | MCP 协议各类能力 |
自然语言项目名映射
| 自然语言名 | 运行时 project_id |
|---|---|
| 示例业务A | game_a:region_a |
| 示例业务B | game_b:region_b |
| 示例业务C | game_d:region_c |
4.3 Langfuse Experiment Runner(执行引擎)
文件
server/scripts/eval/run_langfuse_agent_experiment.py(约 1500 行)
CLI 参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--dataset | str | native-agent-regression | Langfuse Dataset 名称 |
--base-url | str | http://127.0.0.1:21801 | 后端 API 地址 |
--mcp-sse-base-url | str | http://127.0.0.1:21802 | MCP SSE 地址 |
--run-name | str | 自动生成 | 本次 run 的名称 |
--username | str | admin | 登录用户名 |
--password | str | admin123 | 登录密码 |
--token | str | 空(自动登录) | 手动指定 JWT token |
--project-id | str | 环境变量 | 项目 ID |
--timeout | float | 180 | 单请求超时秒数 |
--limit | int | 0(不限) | 限制执行条数 |
--cases-file | str | 空 | 黄金集 YAML 路径 |
--case-lane | choice | http_api | 执行 lane:http_api, watcher_worker, mcp_protocol, report_worker, etl_worker, supervisor_routing, all |
--risk-level | choice | all | 风险过滤:p0, p1, all |
--case-id | str | 空 | 指定 case ID(逗号分隔),用于 smoke 测试 |
--seed-from-cases-file | flag | false | 将黄金集 seed 到 Langfuse Dataset |
--baseline-run-name | str | 空 | Baseline run 名称,用于对比提示 |
三条执行 Lane
| Lane | 前置条件 | 说明 |
|---|---|---|
http_api | 后端 API 运行,LIVE_API_* 可登录 | 默认 lane,覆盖 HTTP 可执行的 supervisor/query/analyst/report/watcher HTTP/tool HTTP 样例 |
watcher_worker | 后端 API + Worker 依赖可导入,账号有告警规则创建/删除权限 | Runner 通过 API 创建临时规则,调用 watcher_check_single_rule 或 watcher_check_alerts |
mcp_protocol | MCP optional 依赖已安装,SSE 需要 uv run mcp-sse 运行中,至少一种有效认证 | stdio tools/list、stdio tools/call、SSE /auth、SSE call_tool |
程序化分数(7 个确定性分数)
| 分数名 | 取值 | 判定逻辑 |
|---|---|---|
http_success | 1/0 | HTTP 状态码 200-299 |
tool_success | 1/0 | 无异常标记(Traceback, Internal Server Error 等) |
answer_contract | 1/0 | must_include 全部包含 且 must_not_include 全部不包含 |
answer_contract_qem | 1/0 | 准精确匹配(数字等价、列表等价、字符串语义等价) |
query_mode_match | 1/0 | 返回的 query_mode 与 expected 一致 |
tool_call_ast_match | 1/0 | 实际 tool.call span 与 expected tool_call 匹配 |
context_propagation | 1/0 | 上下文(session_id / project_id)是否正确传播 |
LLM Evaluator 语义分数(9 个,0-10 分)
| 分数名 | 评估内容 | 注册方式 |
|---|---|---|
query_capability | 查询路径、工具选择、指标/时间/维度正确性、SQL 与项目范围安全 | Langfuse UI 手动注册 |
answer_correctness | 回答是否正确、完整、符合 expected_output | Langfuse UI 手动注册 |
report_quality | 报告结构、数据扎根、结论建议、缺数降级与安全输出质量 | Langfuse UI 手动注册 |
dashboard_quality | 看板/自定义报表资源理解、组件设计、布局/筛选、权限与清理策略 | Langfuse UI 手动注册 |
tool_choice_quality | 是否正确选择了 Agent、工具、查询模式或 MCP lane | Langfuse UI 手动注册 |
helpfulness | 回答是否清晰、有帮助,并说明限制或下一步 | 计划中 |
instruction_following | 是否遵循用户任务、硬门槛语义和输出约束 | 计划中 |
groundedness | 最终回答是否扎根于工具/数据结果,是否避免编造 | 计划中 |
project_scope_safety | 是否尊重项目范围、权限边界和 SQL 安全信号 | Langfuse UI 手动注册 |
Langfuse 公开 API (
/api/public/evaluators) 当前返回 404,因此 LLM Evaluator 通过 Langfuse UI 手动注册,不能通过 API 程序化创建。
常用命令
cd server
# Seed 黄金集到 Langfuse Dataset(首次或用例更新后)
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--cases-file tests/data/golden_agent_cases.yaml `
--seed-from-cases-file --limit 1
# P0 快速回归(http_api lane)
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--case-lane http_api --risk-level p0 `
--baseline-run-name native-agent-regression-baseline-<sha> `
--run-name native-agent-regression-current-<sha>
# 单用例 Smoke
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--case-id query_metric_dau_yesterday `
--run-name smoke-dau
# Watcher Worker lane 全量
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--case-lane watcher_worker `
--run-name watcher-regression-<sha>
# MCP 协议 lane
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--case-lane mcp_protocol `
--mcp-sse-base-url http://127.0.0.1:21802 `
--run-name mcp-regression-<sha>
# MCP SSE call_tool 单用例 smoke
uv run python scripts/eval/run_langfuse_agent_experiment.py `
--project-id game_a:region_a `
--case-lane mcp_protocol `
--case-id mcp_sse_query_data_protocol `
--mcp-sse-base-url http://127.0.0.1:21802 `
--token <ga_api_key_or_mcp_token> `
--run-name mcp-sse-smoke
4.4 Baseline / Current 对比工作流
1. 确认工作区干净,无无关改动
2. 修改 prompt 前 -> 跑 baseline
run-name: native-agent-regression-baseline-<git_sha>
3. 修改 prompt(如 app/modules/agent/prompts/layers/_base.md)
4. 重启后端服务
5. 修改 prompt 后 -> 跑 current
run-name: native-agent-regression-current-<git_sha>
--baseline-run-name native-agent-regression-baseline-<git_sha>
6. 在 Langfuse UI Dataset Run 页面按 run name 打开两次结果对比
- 优先关注低分 item
- 对比确定性 score 和 LLM Evaluator 语义 score
4.5 低分复盘指南
复盘优先级
优先复盘以下低分样本:
answer_contract=0tool_success=0http_success=0query_mode_match=0answer_correctness < 7query_capability < 7report_quality < 7dashboard_quality < 7tool_choice_quality < 7project_scope_safety < 9
answer_contract=0 的处理
| 类型 | 判断方式 | 处理 |
|---|---|---|
| 评估器误判 | HTTP/tool 成功,实际回答满足期望,但 _response_text() 没抽到正文 | 补单测并修正评估器或 expected,不改 Agent |
| 黄金集期望不合理 | 用户问题合理,但 must_include/must_not_include 太窄 | 调整黄金集 expected |
| 真实能力缺口 | 回答选择错误指标/工具/项目或缺少关键语义 | 进入 Agent 能力修复队列 |
工具选择低分的处理
| 低分原因 | 判断方式 | 处理 |
|---|---|---|
| 工具说明边界不清 | tool_choice_quality < 7,相邻工具混淆 | 收紧工具说明和 Supervisor 路由表 |
| 参数缺失 | 工具正确但请求体缺项目、时间或指标 | 给工具 schema/prompt 补 required 参数说明 |
| 越权绕路 | project_scope_safety < 9 | 修业务硬门槛,不用 prompt 兜底 |
| 不支持指标硬答 | query_capability < 7 且输出编造 | 加 unsupported_metric 反馈与受控拒答 |
4.6 运行时 Langfuse 观测(与评测独立)
评测体系之外,Agent 运行时还有一套 Langfuse 观测埋点,遵循"只观测不拦截"原则--观测失败不影响业务。
组件结构
| 组件 | 文件 | 作用 |
|---|---|---|
| 配置桥接 | app/modules/agent/runtime/langfuse_config.py | 将 Settings 同步到 SDK 环境变量 |
| Trace 写入 | app/modules/agent/runtime/trace_writer.py | update_trace(), span(), score_current_trace() |
| 字段定义 | app/modules/agent/runtime/trace_schema.py | 标准 trace/span/score 命名、脱敏规则 |
标准 Trace 名称
agent.chat, agent.chat.stream, agent.query, agent.analyze, agent.report.generate, agent.watcher.detect_all, agent.watcher.detect_rule, mcp.delegate_supervisor, mcp.call_tool
核心 Span 名称
supervisor.llm_round, tool.call, permission.check, query.generate_sql, query.validate_sql, query.execute_sql, analyst.compute_attribution, report.plan, watcher.detect_rule, watcher.llm_confirm
运行时程序化 Score(硬门槛)
| Score | 含义 |
|---|---|
permission_safety_pass | 权限检查是否通过 |
sql_safety_pass | NL2SQL/SQL 校验是否通过 |
data_scope_pass | 项目范围、指标映射或数据 scope 是否可用 |
tool_success | Tool 调用是否成功 |
trace_schema_pass | Trace schema 完整性检查 |
脱敏策略
- 敏感字段(api_key, secret, authorization, password, token, jwt)写入
[REDACTED] - SQL 只记录脱敏摘要(operation, tables, limit, redacted_sql),不记录原始 SQL
- 报告 HTML 只记录长度、标题、状态,不记录正文
- metadata 统一包含
environment,request_id,session_id,user_id,project_id,agent_type,entrypoint,intent
第5层: 上线验收
半自动验收体系,从业务视角判定是否可以发布。
5.1 架构
acceptance/
acceptance.yaml # 主配置:门禁策略、模块列表、报告输出
modules/ # 19 个模块 YAML,每个定义验收场景
auth-session.yaml
permission.yaml
dashboard.yaml
dashboards.yaml
query.yaml
data-reports.yaml
event-analysis.yaml
user-segments.yaml
project-spaces.yaml
chat.yaml
report.yaml
config.yaml
mcp.yaml
workers.yaml
frontend-runtime.yaml
backend-runtime.yaml
data-consistency.yaml
observability.yaml
evidence/ # 证据目录
README.md # 证据类型规则
e2e-coverage-gap-plan.md # E2E 覆盖缺口分析(13 个缺口)
tools/
generate_acceptance_report.py # 报告生成器(只读矩阵和证据,不执行测试)
reports/ # 生成报告目录
验收进度.md
index.html
acceptance-summary.json
final-acceptance-report.md
5.2 门禁策略
gate_policy:
required_priorities: [P0, P1, P2] # 所有优先级都需要
evidence_required_for: [required] # required gate 必须有证据
fail_on_open_blockers: true # 有 open blocker 则不允许发布
5.3 场景定义示例
# acceptance/modules/chat.yaml 中的场景
- id: CHAT-P1-001
name: 用户发送问题后收到 SSE 流式回复并正常结束
priority: P1
gate: required
status: passed
related_modules:
- backend-runtime
evidence:
- type: command
command: uv run pytest tests/api/test_agent_api.py -v
result: passed
report: acceptance/reports/results/backend-pytest-api.json
5.4 证据等级
| 等级 | 含义 | 典型证据 | 要求 |
|---|---|---|---|
| A | 真实链路 | Playwright 真实浏览器 E2E、live regression、带 live 标记的测试 | 前端 required gate 必须达到 |
| B | 集成合同 | 后端 API 黑盒测试、数据库/Worker 合同测试 | 后端/MCP/Worker P0/P1 required gate 至少达到 |
| C | 源码或文档合同 | 源码合同测试、单元测试、日志/文档证据 | 非前端 P2 required gate 至少达到 |
| D | 弱证据 | 人工说明、无有效证据、失败证据 | 不满足发布条件 |
5.5 发布条件
release_gate.can_release = true 必须同时满足:
- 所有 P0/P1/P2 required 场景均为
passed - 所有 required 场景均有有效证据
- 所有 required 场景满足对应证据等级要求
- 不存在 open/blocker/high 级别未关闭缺陷
- P2 未通过项已进入延期或风险清单
5.6 常用命令
# 在后端目录运行,生成验收报告
cd server
uv run python ..\..\acceptance\tools\generate_acceptance_report.py --root ..\..
# 运行 API 黑盒测试
uv run pytest tests/api -v
# 运行路由契约测试(进程内,无需服务)
uv run pytest tests/unit -v
5.7 首轮验收推荐顺序
backend-runtime- 健康检查、API 聚合、错误语义auth-session+permission- 登录、会话、权限边界frontend-runtime- 核心路由无白屏、无 Vue runtime 异常dashboard+dashboards+query- 核心分析入口data-reports+event-analysis+user-segments+project-spaces- 扩展分析与协作chat+report+workers- AI、报告与后台任务mcp- 外部集成入口data-consistency+observability- 跨模块口径和证据归档
日常开发速查
| 场景 | 跑什么 | 命令 |
|---|---|---|
| 提交代码 | CI 自动 (lint + 路由契约 + build) | 无需手动 |
| 改 Agent prompt | P0 快速回归 | --case-lane http_api --risk-level p0 |
| 改 Agent 逻辑 | 全量 Agent 回归 | --case-lane http_api --risk-level all |
| 改路由/API Schema | 路由契约测试 | uv run pytest tests/unit -v |
| 改 API 后端逻辑 | API 黑盒测试 | uv run pytest tests/api -v(需要 server) |
| 改前端页面 | E2E 测试 | pnpm run test:e2e |
| 改前端依赖/大组件 | Bundle 体积分析 | pnpm run build:analyze -> 检查 dist/stats.html;pnpm run size-check 检查预算 |
| 改前端性能敏感页 | Chrome DevTools 性能录制 | F12 -> Performance -> 检查 [vue] 标记 |
| 改 QueryAgent | Benchmark + Agent 回归 | run_query_agent_benchmark.py + Langfuse experiment |
| 改性能敏感接口 | Locust 基础负载 | uv run locust -f locust/locustfile.py --config locust/config/base.conf |
| 发布前 | Live Regression + Locust 压力测试 + 验收报告 | live-regression + locust stress + generate_acceptance_report.py |
| 验收进度查看 | 生成验收报告 | generate_acceptance_report.py --root ../.. |