PostHog AI Observability 在线评测查询指南:深入 system.evaluations 与评估目录数据模型
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
本篇围绕 PostHog 仓库中querying-posthog-data技能内置的参考文档 models-ai-observability-evaluations 展开,讲解如何用 SQL 查询 AI observability 的在线评测(online evaluations)配置数据:两张system.*表的职责划分、关键过滤约定(deleted = false、directory_id IS NULL等)、可直接复用的查询模式,并结合 Evaluation 模型 与 EvaluationDirectory 模型 的源码,说明这些约定背后的实现依据。读完后你能够在数据仓库(data warehouse)中正确查询评测配置、统计各目录下的活跃评测数量,并理解评测生命周期字段的语义。
一、背景:评测配置表与评测结果分离的设计
PostHog 的 AI observability 提供“在线评测”能力:对 AI 生成内容(generation)或整条 trace 自动打分。参考文档明确了两张表的核心分工:
system.evaluations(Evaluation 表):存储评测的配置(名称、类型、输出类型、条件、目标单元等)。注意文档特别强调——评测结果(评分)不在这张表里,而是作为$ai_evaluation事件写入事件数据;system.evaluation_directories(目录表):用于组织在线评测,目录是扁平的(flat),没有嵌套层级;未指定目录的评测位于顶层(top level)。
这个“配置与结果分离”的设计与后端模型一致:evaluations.py 中的Evaluation模型只承载配置字段,而评分流水走事件链路,因此统计评测“跑过多少次、得分如何”应去查$ai_evaluation事件,统计“配置了哪些评测、启用了哪些”才查system.evaluations。
另外需要说明:该参考文档本身是一个 Jinja 模板(.j2后缀),其中的{{ schema_columns('system.evaluations') }}会在技能渲染时自动展开为两表的精确字段列表;下文的字段说明以仓库中的模型定义为准,与实际渲染结果互为印证。
二、评估目录:system.evaluation_directories
对应后端模型 EvaluationDirectory,其数据库表为llm_analytics_evaluationdirectory,核心字段为:
| 字段 | 说明 |
|---|---|
id | 主键(UUID) |
team_id | 所属项目,级联删除 |
name | 目录名,最长 400 字符 |
created_by | 创建者(用户删除后置 NULL) |
created_at/updated_at | 创建/更新时间 |
从源码结构看有两个对查询者重要的约束:
- 目录名在同一 team 内大小写不敏感唯一(约束
uniq_llma_eval_dir_team_name_ci,作用于Lower("name")+team),即Bug 分类与bug 分类不能并存于同一项目——按名称聚合时不必担心大小写重复行; - 默认排序为
["name", "id"],目录列表按名称字典序呈现,与参考文档中示例查询的ORDER BY d.name ASC保持一致。
REST 层面,目录通过 /api/projects/{team_id}/evaluation_directories/ 端点管理(路由定义见 routes.py),SQL 查询与 API 看到的是同一份数据。
三、评测配置表:system.evaluations与生命周期语义
system.evaluations对应的 Evaluation 模型 字段较为丰富,按语义分组如下:
核心字段
| 字段 | 说明 |
|---|---|
id/team_id/name/description | 主键、所属项目、名称(≤400)、描述 |
directory_id | 外键指向目录,可为 NULL(顶层评测),目录删除时置 NULL(on_delete=SET_NULL) |
deleted | 软删除标记,默认false |
created_at/updated_at/created_by | 时间戳与创建者 |
生命周期状态
模型定义了status三态(EvaluationStatus):active/paused/error,并保留了一个布尔投影enabled用于向后兼容。_coerce_status_and_enabled()在保存时强制不变量:
ACTIVE→enabled=true,原因字段清空;PAUSED→enabled=false;ERROR→enabled=false,且必须带status_reason。
status_reason的取值枚举(EvaluationStatusReason)对排障很有价值,例如provider_key_required(未配置提供商 API key)、provider_key_quota_exceeded(配额超限)、provider_key_rate_limited(限流)、model_not_found、hog_error(Hog 评测代码执行失败)等。查询“哪些评测处于异常状态”时,status = 'error'配合status_reason即可定位根因。
评测类型、输出类型与目标单元
由 evaluation_configs.py 定义:
evaluation_type:llm_judge(LLM 作为裁判,唯一使用model_configuration的类型)、hog(自定义 Hog 代码)、sentiment(情感分析);output_type:boolean(Pass/Fail)或sentiment;- 合法组合受
EVALUATION_CONFIG_MODELS白名单约束:llm_judge + boolean、hog + boolean、sentiment + sentiment,其他组合在保存时直接报Unsupported combination; target:评测运行的单元,取值为generation(单个$ai_generation事件)、trace(整条 trace,按聚合窗口从 ClickHouse 拉取)或session(整个会话)。
聚合型目标(trace/session)携带target_config,内含“settle 策略”:fixed_window(首个匹配 generation 后等待固定窗口再评测)或inactivity(无活动超过静默期即评测,max_age_seconds为总等待上限)。其默认值与边界定义在 evaluation_configs.py,例如 trace 的默认窗口 30 分钟、上限 2 小时;session 的静默期默认 1 小时、上限 24 小时,且max_age_seconds ≥ quiet_period_seconds由模型校验器强制。查询这类评测的target_config时,可对照这些常量判断配置是否合理。
配置与条件字段的运行时处理
save()中还做了几件影响“数据长什么样”的事:evaluation_type = hog时会将evaluation_config.source编译为字节码写回evaluation_config.bytecode;conditions中的每条属性过滤也会经compile_filters_bytecode预编译并附上bytecode/bytecode_error。也就是说仓库里的conditions不只是“过滤条件列表”,还内嵌了编译产物——查询展示时通常只需取原始properties部分。
四、三条必须遵守的查询约定
参考文档在 “Important notes” 中给出的三条约定,全部可以从模型实现中得到解释:
- 过滤
deleted = false:Evaluation使用软删除(deleted布尔字段,默认false),默认在线评测列表只展示未删除项; - 顶层评测用
directory_id IS NULL:directory外键可空,未归入任何目录的评测就是 NULL; - 删除目录不删除评测:
on_delete=SET_NULL保证删除目录后其评测保留并回到顶层(directory_id置 NULL)。这与模型上activity_logging_on_delete = True(目录删除会记录操作日志)共同构成“目录可安全删除”的产品语义——查询时不应假设评测会随目录消失。
五、可直接复用的查询模式
1. 列出各目录及其活跃评测数量
SELECT d.id, d.name, count(e.id) AS evaluation_count FROM system.evaluation_directories AS d LEFT JOIN system.evaluations AS e ON e.directory_id = d.id AND e.deleted = false GROUP BY d.id, d.name ORDER BY d.name ASC要点:LEFT JOIN保证空目录也会出现(计数为 0);e.deleted = false放在JOIN 条件而非 WHERE 中,这是保留空目录行的正确写法。结果按目录名排序,与模型默认排序一致。
2. 列出顶层活跃评测
SELECT id, name, evaluation_type, status, updated_at FROM system.evaluations WHERE deleted = false AND directory_id IS NULL ORDER BY updated_at DESC LIMIT 100这条查询恰好对应“默认在线评测列表中位于顶层的部分”:软删除过滤 +directory_id IS NULL+ 最近更新的 100 条。status列直接给出三态生命周期,若出现error可继续按status_reason下钻。
3. 进一步下钻:查评测结果
配置表只回答“评什么、怎么评”;“评得怎样”要去查评测结果事件。如参考文档所述,结果以$ai_evaluation事件存储而非挂在配置表上,因此统计通过率、得分分布时应基于事件侧数据(可配合system.evaluations按评测名/type 做映射),而不是期望从配置表中读出分数。
六、小结与延伸阅读
| 关注点 | 表/位置 | 关键约定 |
|---|---|---|
| 目录组织 | system.evaluation_directories | 扁平结构;team 内名称大小写不敏感唯一 |
| 评测配置 | system.evaluations | deleted = false;顶层为directory_id IS NULL;目录删除后评测保留 |
| 生命周期 | status/status_reason | active/paused/error三态,error 必带原因码 |
| 评测结果 | $ai_evaluation事件 | 不在配置表中 |
相关源码与文档路径:
- 参考文档(本文主体):models-ai-observability-evaluations.md.j2
- 评测模型:products/ai_observability/backend/models/evaluations.py
- 类型/输出/结算配置常量:products/ai_observability/backend/models/evaluation_configs.py
- 目录模型:products/ai_observability/backend/models/evaluation_directories.py
- 目录 API 测试(端点形态参考):products/ai_observability/backend/api/test/test_evaluation_directories.py
需要提醒的是:system.*两张表面向数据仓库查询场景,字段清单以技能渲染后的schema_columns输出为准;本文字段说明来自仓库中的 Django 模型定义,二者应保持一致。若在 SQL 中遇到个别列名差异,优先以渲染后的列清单为准。
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考