跳到正文

观测与评测 ​

定位:一条 trace 从产生、消费到门禁的完整路径。

一句话:可观测回答“这次为什么这样”,评测回答“下一版能不能上”,门禁回答“谁批准它上”;三者共用同一条 trace 链和同一批数据(轨迹、事件、版本、成本),拆成三套系统就会三套口径互相打架。

整合说明:本篇合并吸收旧 14 篇(信号体系与 span 语义)、40 篇(Langfuse 选型决策与落地推演)、42 篇(OpenJudge 实跑记录)、43 篇(观测接口 17 端点契约实跑)四篇重写,并以 C:\Users\Administrator\Desktop\02-项目代码\OpenJudge\openjudge\graders\ 本地源码复核为主线修正旧文口径。全文用两类标记区分证据强度:源码坐实=读本地源码确认(附文件行号);实测=本机对真实服务实跑闭环(附日期 2026-10-26)。通用方法论见 可观测与评测 与 BadCase 与质量运营;调优数据链见 26-调优闭环落地设计;审计管道见 08 专栏《10-安全体系与全链路审计》。

版本适用:AgentScope Java 2.x / agentscope-service 2.1.0-BETA1 / Langfuse v4.x(自托管)/ py-openjudge 0.2.4。


§一 为什么需要统一观测视图 ​

平台上线后,证据问题以三类故障形式暴露:

  1. 分不清慢在哪:一次任务跨网关、控制面、队列、内核、工具,指标只报“Turn P95 涨了 3 秒”——是模型变慢、工具超时、审批等待还是排队?没有按语义拆开的 span,四种原因的 owner 和处置动作完全不同,最后只能人工翻日志。
  2. 说不清为什么失败:日志按服务分散,一次任务出问题时只能按时间戳猜顺序;被拒绝的工具调用、被中断的 turn 在可观测里干脆是空白——“没记录”比“有错误”更难归因。
  3. 发布门禁拍脑袋:离线跑分不错,上线仍然退化——评测集和真实流量不是同一分布,也没有人规定“降到多少必须回滚”;门禁没有接在发布流水线上,就只是一份没人看的报告。

根因是把观测、评测、治理当成三个系统。六类信号各有分工,但只有 Trace 能跨组件串起来,其余都挂靠在这条链上:

信号来源关键属性回答什么问题成本
Trace网关、内核、工具、数据面trace_id、span 名、模型、工具、版本这次为什么走这条分支中,需采样
事件流Service 事件日志(43 篇契约)单调 seq/游标、会话、Turn、审批执行到哪一步、谁批准高,需保留策略
指标OTel SDK / 网关模型、Agent、工具、状态码趋势与告警低,但基数敏感
成本账网关计量 + Token 用量 + budget ledger租户、应用、模型、输入/输出/缓存钱花在哪中,需对账
评测分黄金集 + OpenJudge grader用例、版本、评分维度这一版是否更好高,需标注
审计控制面 + 网关主体、动作、对象、结果谁改了什么、谁调用了什么高,需不可改

一条必须分清的边界:Session 是交互容器,Trace 是因果链。session_id 可跨天、跨多次执行,顺序靠事件游标;trace_id 是一次执行,结构靠父子 span。不要把 session_id 当 trace_id;不要从 trace 结束推断任务完成(完成看任务账本与证据);子 Agent 或跨队列执行另起 trace 时必须用 Span Link 指回父执行,不能变成孤岛。

本篇的展开顺序即一条 trace 的生命周期:§二定信号(span 语义、指标、采样)→ §三定归宿(Langfuse 后端)→ §四定接口(观测契约怎么调)→ §五定消费(评测与门禁)→ §六给链路(四条端到端时序)。


§二 信号体系 ​

2.1 十二类 span 语义 ​

Trace 能串起来不等于能读懂。一次 Agent 执行里混着模型调用、检索、记忆、工具、策略检查、压缩、人工审批与中断;如果都记成 chat 或 execute_tool,“慢在哪、钱花在哪、哪一步被拦下”就无从回答。按语义动作建 span,共十二类:

Span 类型何时产生必带属性常见错误
ENTRY请求进入平台入口类型、认证结果、租户、路由与网关 HTTP span 混成一个
AGENT一次 Agent 调用agent_key、release_id、会话缺发布单元,无法复现
WORKFLOW工作流整体执行workflow_revision、触发方式把每次节点执行都记成 workflow
STEP工作流节点node_id、join_type、分支节点与工具调用混层
LLM一次模型请求模型、参数、输入/输出/缓存 Token、finish_reason只记总 Token,不记缓存
RETRIEVAL知识检索索引版本、top_k、命中 ID、分数只记耗时,无法解释召回变化
MEMORY记忆读或写作用域、操作、文档版本把记忆写当成普通工具调用
TOOL一次工具执行工具名、版本、side_effect、action_id、结果缺 action_id,接不上审批与审计
GUARDRAIL策略/内容检查策略 ID、决定、原因码只记放行,拒绝的检查完全消失
COMPACTION上下文压缩压缩前后 Token、丢弃的引用不记丢了什么,事后无法解释
HITL等待人工等待类型、审批 ID、决定、等待时长把等待时间算进模型时延
INTERRUPT取消、超时、中断原因、未完成项数量、补偿状态非正常退出没有 span

四条落地规则:同一次动作只产生一个语义 span;拒绝也要留 span(否则越权尝试在可观测里是空白);等待与执行分开计时(HITL 与 task.wait 的时长不能混进模型延迟);重试开新 Trace 并用 Span Link 指回上一次,不复用 trace_id 造两个根 span。

每个 span 至少带四类属性:版本(Agent、提示词、模型、工具)、用量(输入/输出/缓存 Token)、结果(状态码、错误类型)、归属(租户、应用、会话)。缺版本无法回放,缺归属无法计费,缺结果无法聚合。

2.2 采集管道:OTel SDK → Collector → OTLP ​

AgentScope Java 的 OtelTracingMiddleware 默认覆盖 invoke_agent、chat、execute_tool 三类 span,并通过 Reactor 上下文传播 traceparent。整条链的采集管道分三段:

三处 traceparent 续接是硬要求(网关、调度/队列、Runtime Host),否则链路断成截;RAGFlow 走官方 connector 直投 Langfuse(06 专栏实测端点 POST /api/v1/langfuse/api-key 可用)。非官方框架只要产出 OTel GenAI 语义 span(llm/tool/retrieval/embedding/pipeline)即可经 Collector 汇入,无第二套 SDK。

2.3 指标表(Instrument 类型标注) ​

指标Instrument维度用途告警思路
Turn 时延 P95Histogram(agent.turn.duration_ms)Agent、模型体验连续 5 分钟超过基线 1.5 倍
Token 用量Counter(gen_ai.client.token.usage,按 input/output/cache 分)租户、模型成本单租户日环比突增 50%
Token 成本Counter(金额累加)应用、模型分摊预算消耗达 80% / 100%
工具错误率Counter(调用数,按状态码/错误类型分桶),率值告警端派生工具、错误类型稳定性5xx 与超时分开统计
任务成功率 / 重试率Counter(终态计数)任务类型可靠性重试率连续上升
队列等待Histogram(queue.wait_ms)+ Gauge(“最后消息时间”滞后)LiteTopic 通道容量自建滞后指标
审批等待Histogram(hitl.wait_ms)审批类型流程瓶颈超 SLA 未处理
任务等待(按类型)Histogram(task.wait.duration_ms,wait_type 维度)wait_type、任务类型区分审批/工具/输入/外部/排队按类型设 SLA,不混成“处理中”
上下文压缩次数CounterAgent质量风险单会话频繁压缩
决策一致率Gauge(周期重算写入)用例Jev 校准影子建议与实际结果偏差扩大

两条纪律:指标标签只放低基数字段(模型、Agent、工具、状态码),会话 ID、用户 ID、任务 ID 放 Trace 与事件;成本以网关计量与 budget ledger 为准,内核自报 Token 只用于排障。等待必须按 wait_reason.type 拆开——审批慢、工具慢、模型限流、排队、等外部回调的处置 owner 完全不同;等待分类约定见 22-架构评审与任务闭环 §三、§十四。

2.4 采样策略 ​

采样在 Collector 的 tail-based 处理器完成(按 trace 尾部决策,不做头部采样,保证错误 trace 完整):

  • 错误与高风险全采:含错误状态码的 trace、GUARDRAIL 拒绝、预算超限、审批拒绝——一条不丢;
  • 正常请求按比例采:初始 10%,按存储容量与排障需求调整;采样率变更要记录版本,否则跨版本错误率对比失真;
  • 决策窗口:tail-sampling 按 trace 完成后 30s 窗口决策,需为长任务放宽 policy 生命周期;
  • 审计不走采样:审计记录与 Trace 分开存储、写后不可改、保留期按合规单独设定(衔接 08 专栏管道:网关+控制面+实例审计 → OTel → MinIO 归档 180 天)。有事件不等于有审计——事件是运行记录,审计要求完整性、不可改与保留期。

§三 后端选型(Langfuse) ​

3.1 为什么是 Langfuse ​

选型面对六条硬约束:数据不出域、MIT/Apache 开源许可、企业 SSO、按 user_id/实例隔离审计、RAGFlow 端点已就绪、AgentScope 官方接入证据。候选九家(Langfuse、Arize Phoenix、Comet Opik、W&B Weave、LangSmith、Helicone、OpenLIT、Traceloop OpenLLMetry、AgentOps)逐一对照后的否决链:

候选否决点
LangSmith平台闭源 SaaS,自托管锁 Enterprise 许可——许可与成本双杀
W&B Weave服务端不开源,自托管需付费 license,非 OTel 原生
Comet Opik评估指标库最强(30+ LLM-judge),但自托管 OSS 无认证/无用户管理,违反隔离审计
Arize Phoenix技术能力强、OSS 自带 OIDC+LDAP,但 ELv2 非 OSI 开源、RAGFlow 无官方集成——备选观察位
OpenLITApache-2.0 全栈最接近的挑战者,但双生态集成与 SSO 证据弱——第二备选
Helicone / AgentOps无企业 SSO 文档、评估体系弱
OpenLLMetry只是埋点 SDK 不是后端,主仓库已放缓

Langfuse 胜出的结构:核心 MIT、可完全自托管;trace/span/generation 三层数据模型 + usage/cost + userId/sessionId/tags/prompt 版本为一等属性;社区版自带 OIDC SSO 与告警;评估器(scores/datasets/experiments/LLM-as-judge)内置,judge 经 LiteLLM 可接本地开源模型;RAGFlow 官方内置 connector(≥0.18.0,端点已实测)+ AgentScope Python/Java 官方接入文档——双官方集成全场仅一家。

复合形态是一主多辅,不引第二套 trace:

Langfuse(观测主干,唯一 trace 归宿)
   ├── 评估模块:Langfuse 原生 evaluator + OpenJudge/Judge 服务(域内模型打分,见 §五)
   ├── 告警模块:Langfuse Alerts(v4+ 社区版可用)+ Grafana 兜底(邮件渠道)
   ├── 回流模块:datasets 导出管道(RAGFlow 回灌 / 微调数据 SFT/DPO/CPT)
   └── 门户皮:HiMarket 统一入口 + 观测面 API 聚合

3.2 十二类 span → Langfuse 数据模型映射 ​

agentscope-service 观测面(§四 17 端点实证)与 OTel GenAI 语义的汇入映射。generation 是 Langfuse 的模型调用专用对象(带 model/prompt/output/token/cost),span 是通用观察对象,metadata tag 承载非树状语义:

#span/观测对象来源契约Langfuse 汇入对象说明
1sessionGET .../snapshottrace(会话 root)一次会话一条 trace,user_id/session_id 属性打标
2turnevents type=turn(单调 seq)observation(子 span)turn 级,agent_version 属性
3runevents type=runobservation(子 span)run 级,含 execution_attempts 重试语义
4itemevents type=item / GET .../itemsobservation消息/工具 item,type=message 属性
5toolevents type=tool / GET .../toolsobservation(name=tool_call)工具调用(arguments/input/model_call_id)
6usageGET .../usageLangfuse 内置 usage/costmodel_calls/tokens 汇入 generation 计量
7llm/generationOTel GenAI gen_ai.* spangeneration 对象模型调用(qwen3.8-max 等),prompt/output/token
8retrievalOTel GenAI retrieval span(RAGFlow 链路)observation(type=retrieval)RAGFlow connector 已就绪(实测)
9embeddingOTel GenAI embedding spangeneration(type=embedding)向量化调用
10pipeline网关/调度/编排链路span(父上下文)端到端链路对标百炼“大模型/MCP/向量检索”
11budgetGET | PUT .../budget平台侧(Langfuse 无原生 budget)ledger 与 cost 双源对照,见 §4.4
12hands/workerGET /api/hands/status平台侧 metadata/Gauge(不入 trace)执行体健康走 Grafana

汇入规则:1–10 走 OTLP(traceparent 三处续接照常生效);11–12 为平台侧指标面,不混入 Langfuse trace 语义。首 Token 耗时需埋点补 span attribute(小项缺口)。

3.3 最小部署足迹 ​

六件套(官方最小足迹合计约 9C/21.5GiB,需 K8s 承载;Docker Compose 单机快速起步建议 ≥4C/16GiB/100GiB):

组件资源职责
langfuse-web2C/4GiUI + Ingestion/Public API
langfuse-worker2C/4Gi异步评估任务、回填
PostgreSQL2C/4Gi元数据(项目/用户/dataset/prompt 定义)
ClickHouse2C/8Gitrace/observation/score 事实数据,单分片可到 TB 级
Redis1C/1.5Giingestion 队列与缓存
S3 / MinIO按量附件与 blob 存储

版本现状:v4.70.0(2026-10-24),月均约 23 个 release;v4 于 2026-08-17 GA,v3 安全补丁维持到 2027-01。所有投递为异步——观测面故障不阻塞业务主链路(RAGFlow connector 与 SDK 侧均为失败不影响响应的语义)。

3.4 社区版 RBAC 限制与缓解 ​

企业 license key 才解锁的能力:项目级 RBAC、审计日志、服务端脱敏、数据保留策略、SCIM。平台侧缓解:

  • API 隔离成立:每租户/每实例独立 Langfuse project + 独立 pk/sk,API key 按项目鉴权(数据隔离由项目模型原生支撑);trace 强制携带 userId/sessionId 一等属性,Observations API、告警过滤器均支持按 user 过滤——“按 user_id/实例隔离审计”在 API 层闭环。
  • UI 隔离不成立:社区版登录用户可访问所加入组织下的项目,无项目级角色细分。收敛路径:门户观测面只读、按角色(平台 admin / 租户 owner / 普通用户)在 HiMarket 聚合页收敛数据范围(走 Public API 而非直放 UI);写操作(evaluator/dataset 管理)走平台后台。iframe 直嵌官方无证据(X-Frame-Options 未文档化),按“网关反代 + 观测面 API”落地。
  • 其余自建:脱敏用 SDK 侧 client-side masking;数据保留用 ClickHouse TTL + 归档任务(对齐 08 专栏 180 天审计保留);SSO 社区版 OIDC 覆盖 Keycloak/AzureAD/Okta 等,纯 SAML 场景由前置 IdP 做 SAML→OIDC 桥接;告警渠道 Slack/Webhook/GitHub Actions,邮件由 Grafana 或自有通知中心兜底。

§四 观测接口契约 ​

agentscope-service 观测面 17 端点全部实跑(2026-10-26,主链会话 d57377bc-...,454 事件;以下均为实测)。接入点 gateway :18080;鉴权三件套:Authorization: Bearer <jwt> + X-AgentScope-Tenant + X-AgentScope-Namespace。

4.1 端点清单 ​

#端点(前缀 /api/v1/agent-sessions/{id})实测用途
1GET /events?after=&limit=200事件游标分页 {data,next_cursor,has_more}
2GET /events/stream?after=200(SSE)15s keepalive 实时流,支持 Last-Event-ID
3GET /snapshot200views+session+usage 一致快照(as_of 水位)
4GET /tools200工具调用记录(arguments/input/model_call_id)
5GET /items?limit=200消息/工具 item 分页(消息正文载体)
6GET /inputs200输入应用记录(input_id→run_id→turn_id)
7GET /subagents200子代理列表
8GET /artifacts200产物列表
9GET /required-actions200HITL 待办(Inbox 聚合数据源)
10GET /usage?include_children=200用量聚合(model_calls/tokens/估算成本)
11GET | PUT /budget200预算读写(GET 先 reconcile 自愈,revision 递增)
12GET /checkpoints200checkpoint 清单(cp_ id+turn_id+reason)
13POST /checkpoints/restore—回滚(body checkpoint_id+reason,需 Idempotency-Key)
14POST /fork—派生新会话
15GET /export200 NDJSON全量导出(Content-Disposition: session-events.jsonl)
16GET /trace(+subagents/recovery/POST reconcile)404敏感对账面默认关,需 trace-enabled=true
17GET /api/hands/status200worker/租约健康(心跳+认领度量)

4.2 关键端点语义 ​

events 游标分页:cursor 是 SessionEventCursor 的 base64 编码,不透明、不外泄内部 seq;limit 上限 1000(实测 454 事件一页取全);data[] 按事件时间升序。坑:游标超前当前水位返回 409,需重拉最新页;GET /events/{eventId} 按事件自身 id(evt_*/id 字段)查询——传 item id 实测 404,不是消息 id。

SSE 事件流:Accept: text/event-stream,每 15s 输出 :keepalive 注释行防代理超时;public 过滤——只推公共事件(turn/run/item/tool/usage),不推内部 journal 事件;durable subscribe:断线带 Last-Event-ID 重连不丢事件(链路见 §六.3)。

snapshot:as_of 为快照一致水位(events 游标语义),inputs/artifacts/action_commands 等分视图各带独立 item cursor——一次读取即得一致视图,报表侧不用拼多次分页。

export:NDJSON 每行一个事件(含 session_id/schema_version/type/cursor),适合归档与评测集回放(§五数据源);原子导出走 Lua 脚本。

trace 敏感面:builder.agent-api.trace-enabled=false(默认)时 trace/trace-subagents/trace-recovery 全部 404 且响应体 {"error":"not found"}——是“默认关”而非接口不存在;开启需配置项翻转 + ROLE_ADMIN 或 ROLE_SESSION_TRACE。内部 journal 级对账接口,生产默认不暴露是正确姿势。

4.3 usage 与 budget:两个“看起来缺数据”的实测结论 ​

usage 面不承担单价换算(实测):

json
{"data":{"cost_complete":false,"currency":null,"estimated_cost":0,"model_calls":4,
  "models":[{"model":"qwen3.8-max","scope":"session_only",
    "usage":{"inputTokens":6698,"outputTokens":233,"reasoningTokens":151,"totalTokens":6931}}]}}

currency=null、estimated_cost=0 不是缺陷——Service 记录的是原始 token 用量,单价化换算在 Langfuse 侧配置(见 4.4)。含子代理走 include_children=true。

budget 默认不限(实测):

json
{"enforcement":"before_model_call","limits":{},"revision":8,"scope":"session_tree",
 "usage":{"total_tokens":29293,"unpriced_calls":4,"unreported_calls":0}}

limits:{} 即默认无上限——预算不 PUT 就等于没有;revision 每次 reconcile/写入递增(实测 8 = 4 次模型调用 × 2 类事件对账);GET 先 reconcile 自愈的语义意味着读操作也可作对账触发器。

4.4 配置方法:让成本与预算数字真实 ​

  1. 成本单价表(Langfuse 侧):在 Langfuse model definition 按模型名(如 qwen3.8-max)登记 input/output 单价,trace 汇入 generation 后自动推算美元成本。注意 unpriced_calls>0 时任何成本门禁都失真——先配价,再谈预算。
  2. 预算限制(Service 侧):PUT .../budget 设置 limits。生产推荐初值:max_tokens = 单会话稳态用量 2–3 倍(实测会话树 P50≈6.9k tokens、四调用合计 29,293 total_tokens,起步建议 100k);max_cost 必须等第 1 步定价就绪后再设;enforcement=before_model_call 保持默认——拦在调用前,防超额产生费用。
  3. 对账口径:usage+budget → 成本看板,与 Langfuse cost 双源对照;不一致时以 budget ledger(实测态)为准排查,网关计量为账单权威(14 篇纪律:Trace 不是账单,采样、重试、缓存都会让 Token 统计偏离真实计费)。

4.5 调用注意事项汇总(踩过/实测确认) ​

注意点说明
409events 游标超前水位,重拉最新页
Idempotency-Key写操作(turns/restore/fork)必带且唯一,否则 400/重复执行
中文 body必须显式 UTF-8 bytes(坑位 K16:PowerShell 默认 GBK 编码丢汉字)
events/按事件 id 查,不是 item/message id
trace 404默认关而非不存在,开面走 admin 角色
limit 上限events ≤1000,超限按 1000 截断

§五 评测与门禁 ​

5.1 评测框架选型:OpenJudge ​

  • 官方生态:AgentScope 官方评测框架(agentscope-ai/OpenJudge,Apache-2.0)——与 agentscope-service 同源,随官方演进,不是第三方拼装;
  • grader 覆盖面:本地源码复核计得 58 个 grader 类(源码坐实,清单见 5.2),Agent 族按 action/memory/observation/plan/reasoning/reflection/response/tool/trajectory 九个子域组织;
  • judge 模型复用:grader 用 OpenAI 兼容模型当 judge,直接复用 token-plan 网关(qwen3.8-max)——零新增模型成本;
  • 评测即训练奖励:输出同时适配训练 reward,评估结果可回流强化。

两条口径修正(相对旧 42 篇,均以本地源码为准):

  1. TrajectoryComprehensiveGrader 不是误称——类真实存在(源码坐实:graders/agent/trajectory/trajectory_comprehensive.py:276,LLMGrader,逐 step 评 contribution/relevance/accuracy/efficiency 四维 1–5 分再平均归一)。42 篇实跑 0.0 分、“No steps to evaluate”的根因是输入 schema 适配:该 grader 期望 agent 级 step 轨迹,drill 级合并出的 messages 没被提取出可评步骤。落地结论不变但依据改写:门禁主力用 ToolSelectionGrader(源码坐实:agent/tool/tool_selection.py:158,aevaluate(query, tool_definitions, tool_calls) 输入契约极简,与 §四 tools 端点的 arguments/input/model_call_id 直接吻合,无需轨迹重排)+ ToolCallSuccessGrader(agent/tool/tool_call_success.py:170,执行成功判定)作补充;TrajectoryComprehensiveGrader 保留给已完成 step 级 schema 对齐的深度评估。
  2. RelevanceGrader 的真实来源是 graders/common/relevance.py:196(源码坐实:通用相关性 grader,1–5 分制、threshold 默认 3、支持 ZH 评估模板,输入 query+response(+对话历史))——42 篇实跑用的即此。skills/relevance.py:275 定义的是 SkillRelevanceGrader,评的是 Skill 定义与用途的相关性,属技能供给面评估,两者不可混用。

5.2 可用 grader 矩阵(源码坐实) ​

按目录全量清点;类型区分 LLM(judge 模型驱动)与规则(确定性计算,零模型成本,适合 L0/L1 快检):

族grader类型
agent/actionActionAlignmentGrader · ActionLoopDetectionGraderLLM · 规则
agent/memoryMemoryAccuracyGrader · MemoryDetailPreservationGrader · MemoryRetrievalEffectivenessGraderLLM
agent/observationObservationInformationGainGrader规则
agent/planPlanDecompositionGrader · PlanFeasibilityGraderLLM
agent/reasoningReasoningCoherenceGrader · ReasoningGroundednessGraderLLM
agent/reflectionReflectionAccuracyGrader · ReflectionOutcomeUnderstandingGrader · ReflectionProgressAwarenessGraderLLM
agent/responseResponseCompletenessGrader · ResponseHelpfulnessGraderLLM
agent/toolToolCallAccuracyGrader · ToolCallSuccessGrader · ToolParameterCheckGrader · ToolSelectionGrader(LLM);ToolCallPrecisionRecallMatchGrader · ToolCallStepSequenceMatchGrader · ToolUsageEfficiencyGrader(规则)LLM+规则
agent/trajectoryTrajectoryAccuracyGrader · TrajectoryComprehensiveGrader · TrajectoryErrorRecoveryGrader(LLM);TrajectoryStepEfficiencyGrader(规则)LLM+规则
skillsSkillCompletenessGrader · SkillDeclarationAlignmentGrader · SkillDesignGrader · SkillRelevanceGrader · SkillThreatAnalysisGraderLLM
textNumberAccuracyGrader · SimilarityGrader · StringMatchGrader规则
codeCodeBugDetectionGrader · CodeComplexityGrader · CodeSecurityGrader(LLM);CodeExecutionGrader · CodeStyleGrader · PatchSimilarityGrader · SyntaxCheckGrader(规则)LLM+规则
formatJsonMatchGrader · JsonValidatorGrader · LengthPenaltyGrader · NgramRepetitionPenaltyGrader · ReasoningFormatGrader · ReasoningToolCallFormatGrader规则
mathMathExpressionVerifyGrader规则
multi_turnAnaphoraResolutionGrader · ContextMemoryGrader · InstructionClarificationGrader · ProactiveInteractionGrader · ResponseRepetitionGrader · SelfCorrectionGrader · TopicSwitchGraderLLM
multimodalImageCoherenceGrader · ImageHelpfulnessGrader(LLM);TextToImageGrader(规则)LLM+规则

对百炼 8 类预置轨迹评估器的映射(旧 40 篇把这块全列为“自建”,OpenJudge 到位后大部分降级为“配置即用”):

百炼预置轨迹评估器OpenJudge 对应(源码坐实)判定
轨迹准确性TrajectoryAccuracyGrader直接覆盖
动作循环检测(ATIF)ActionLoopDetectionGrader(规则)直接覆盖
回答忠实度ReasoningGroundednessGrader直接覆盖
执行成功性与错误定位ToolCallSuccessGrader + TrajectoryErrorRecoveryGrader组合覆盖
观察信息增益ObservationInformationGainGrader(规则)直接覆盖
工具调用成功率ToolCallSuccessGrader + ToolUsageEfficiencyGrader组合覆盖
最终回答有害性无对应类仍需自建安全 judge
检索有效性MemoryRetrievalEffectivenessGrader 只覆盖记忆检索;RAG 检索命中率仍需规则自建部分覆盖

5.3 实跑结论 ​

链路实测(2026-10-26,全链路闭环):events 游标分页取 454 真实事件 → 轨迹构造(item.completed message → OpenAI messages;tool.requested+tool.completed → tool_calls)→ OpenJudge grader → token-plan 网关 qwen3.8-max 作 judge → score+reason 产出。结果:

Grader输入得分judge 理由(节选)
RelevanceGrader(common)query=USER 首条 / response=assistant 末条5.0judge 自主识别出链路的中文编码事故(汉字变 ?,非 UTF-8 转换丢字),并给出可操作步骤
RelevanceGrader(common)中文验证回合3.0违反“请简短回复”显式指令——多余细节、泄露 sess_* 内部 ID 与环境信息,均被 reason 点名
TrajectoryComprehensiveGrader12 条 messages(drill 级合并)0.0“No steps to evaluate”——schema 适配问题(见 5.1 修正 1),非类不存在

关键结论:judge 评分质量足以精准诊断真实缺陷并当质量门禁——5.0 例识别编码事故、3.0 例抓指令违背与信息泄露;缺陷→修链路→重跑回归的迭代闭环已完成一轮(编码修复后重跑中文回合,ENCODING_OK + Relevance 出分)。

5.4 评测集管理 ​

评测不是“跑一遍 benchmark”,而是维护三样东西:

  1. 黄金集:按业务域与任务类型分层,覆盖正常、边界、对抗与历史 BadCase;每条用例带输入、期望、评分标准与版本;数据源即 §四 契约——export NDJSON 归档、events 游标回放历史会话轨迹批量评分;
  2. 评分器组合:规则断言(text/string_match、format/json_validator、agent/tool 规则系——工具是否调用、参数是否正确、是否越权)+ LLM judge(Relevance/ToolSelection/Response 系)+ 人工复核(高风险样本);新 grader 上线前要先在自己样本上验证与人工判断的一致性;
  3. 采样与回流:线上按成功率、成本、时延分层抽样、脱敏后入集;只抽失败样本会让评测集越来越偏。

对照必须按维度看,不只看总分:总分持平但成本翻倍,同样不能上。评测集、grader 配置、阈值随发布冻结——改评测集要像改代码一样评审(LLM-as-Judge 本身会漂移,高风险结论必须人工复核或规则兜底)。

5.5 门禁分级与发布流水线集成 ​

级别检查执行者通过条件失败动作
L0 静态配置 schema、链接、许可、禁用词 + format/text 规则 graderCI 构建阶段全部通过阻止合并
L1 离线黄金集回归(RelevanceGrader + ToolSelectionGrader + ToolCallSuccessGrader + 规则断言)CI/发布前批跑,score+reason 入库(Postgres/Redis)关键维度不退化;阈值门禁(如 Relevance < 3 阻断);成本增幅在阈值内阻止发布
L2 影子真实流量旁路Langfuse 指标面决策一致率、错误率无异常只观察,不切流
L3 灰度1% → 10% → 50%Langfuse Alerts + Grafana成功率、时延、成本、投诉率达标自动回滚上一 revision
L4 全量持续监控告警规则(错误率 2%/延迟 p95 15s/成本日环比 50%/faithfulness 均值 <0.7 持续 30min)稳定窗口内无回归手动或自动回滚

门禁是递进关系而非并列清单:每级只解决“上一级看不见的风险”,任一级不过就退回,且退回路径必须比前进路径短。

三级递进的依据:L0/L1 拦“已知会错的东西”(规则断言 + 黄金集,跑在 CI 里,成本可控);L2 拦“评测集分布外的问题”,只观察不切流,产出的是决策一致率而不是分数;L3/L4 拦“真实流量才暴露的问题”,判据换成成功率、时延、成本与投诉率。B2/RB 两条退回边都指向 L1,而不是指向 L0——改完必须重新跑离线回归,静态检查通过不代表质量没退化。

与发布流水线的三个集成点:

  1. 触发点:Agent 定义的发布工单绑定 release_id,CI 在 promote 到 staging 前调 §六.2 的门禁链路(历史会话轨迹回放 + 黄金集评分),评测产物不可变归档;
  2. 判定与留证:score+reason 入库并回写 Langfuse(numeric score 挂 trace),按 agent/skill/模型版本出对比看板——门禁结论必须可回放,不接受“报告说过了”;
  3. 回滚能力是门禁成立的前提:Agent 定义用版本切换、Endpoint 用 release 切换、Workflow 用 revision 固定,回滚十分钟内一键完成(checkpoint/restore 契约在 §四 #13);如果回滚需要改代码,门禁就只是形式。

评测还差接入层补齐的部分(控制台范围):数据集/任务/报告 UI 归 HiMarket 门户皮;这与百炼“评测任务状态机/综合得分仪表盘/5 模型对比”对齐,结构上 Langfuse experiments + 自建报告聚合已覆盖。


§六 已支持场景链路 ​

6.1 一次对话的 trace 上报全链路(内核 → OTel Collector → Langfuse) ​

6.2 评测门禁触发(CI → 黄金集 → 评分 → 放行/阻断) ​

6.3 SSE 事件流续传(断线 → Last-Event-ID → 不丢不重) ​

6.4 预算观测(usage → 成本计算 → 阈值告警) ​


边界与验收 ​

六条边界:Trace 不是账单(采样/重试/缓存使 Token 统计偏离计费,账单以网关与供应商为准);指标不是根因(指标只说“哪里变了”,定位靠 trace 与事件);评测集不是真实分布(黄金集永远滞后线上,必须持续回流);LLM-as-Judge 不是裁判(评分器会漂移,高风险结论人工复核或规则兜底);有事件不等于有审计(审计要完整性、不可改、保留期,单独管道);Span 不是越细越好(按语义动作建,工具内部重试与分页是属性不是几十个同级 span)。

五条验收判据(判断证据体系是否成立):任取一条线上回答能还原完整 span 树,且被拒绝的工具调用也有 GUARDRAIL 或 TOOL span;等待审批的时长不计入模型时延;指标能按租户与 Agent 聚合;黄金集能复现至少一个历史 BadCase;回滚在十分钟内完成、审计与 Trace 分开且不可改。

整合自旧 14/40/42/43 篇 | OpenTelemetry GenAI 语义约定 / Langfuse v4.x / py-openjudge 0.2.4 / agentscope-service 2.1.0-BETA1 | 2026-10

把 AI 工程讲到既懂也会用