bot/docs/vikingbot-real-user-metrics-cases.md
这份文档给出一组可以直接拿来执行的真实用户问答案例,用来逐项验证本次补充的 feedback / outcome 指标是否正常。
本文只覆盖当前代码里已经落地的指标口径:
openviking_feedback_responses_totalopenviking_feedback_responses_with_feedback_totalopenviking_feedback_events_totalopenviking_feedback_thumb_up_totalopenviking_feedback_thumb_down_totalopenviking_feedback_positive_outcomes_totalopenviking_feedback_negative_outcomes_totalopenviking_feedback_reasked_outcomes_totalopenviking_feedback_resolved_outcomes_totalopenviking_feedback_follow_up_without_feedback_outcomes_totalopenviking_feedback_coverageopenviking_feedback_thumbs_up_rateopenviking_feedback_thumbs_down_rateopenviking_feedback_positive_feedback_rateopenviking_feedback_negative_feedback_rateopenviking_feedback_reask_rateopenviking_feedback_one_turn_resolution_rateopenviking_feedback_channel_*当前指标不是在线自增 counter 语义,而是 scrape /metrics 时基于 bot/sessions/*.jsonl 聚合出来的快照值。
因此验证时建议遵循两个原则:
建议所有查询都先带上 valid="1"。
当前分母口径说明:
responses_total 统计的是 session JSONL 中所有带 response_id 的 assistant 最终回答,不要求这些回答已经进入 response_outcomes。feedback_coverage、positive_feedback_rate、negative_feedback_rate、reask_rate、one_turn_resolution_rate 都是基于 responses_total 重新聚合出来的快照比例。thumbs_up_rate、thumbs_down_rate 仍然只在显式 feedback 样本内部计算,因此它们的分母是 feedback_total,不是 responses_total。需要先确认:
http://127.0.0.1:30300/bot/v1/health 返回 200。http://127.0.0.1:30300/metrics 能正常返回 Prometheus 文本。建议先记一份基线值:
openviking_feedback_responses_total{valid="1"}
openviking_feedback_responses_with_feedback_total{valid="1"}
openviking_feedback_events_total{valid="1"}
openviking_feedback_thumb_up_total{valid="1"}
openviking_feedback_thumb_down_total{valid="1"}
openviking_feedback_positive_outcomes_total{valid="1"}
openviking_feedback_negative_outcomes_total{valid="1"}
openviking_feedback_reasked_outcomes_total{valid="1"}
openviking_feedback_resolved_outcomes_total{valid="1"}
openviking_feedback_follow_up_without_feedback_outcomes_total{valid="1"}
目的:验证一次普通问答至少会进入 responses_total。
真实用户问题:
请用一句话介绍 OpenViking,控制在 20 个字以内。
预期 Vikingbot 回答特征:
response_id请求示例:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-01",
"user_id": "metrics-user",
"message": "请用一句话介绍 OpenViking,控制在 20 个字以内。"
}'
重点核对指标:
openviking_feedback_responses_total{valid="1"}
预期结果:
openviking_feedback_responses_total{valid="1"} 通常增加 1;如果这是一个全新的 session 文件,openviking_feedback_sessions_scanned_total{valid="1"} 也可能增加 1。events_total、thumb_up_total、thumb_down_total、responses_with_feedback_total 以及各类 outcome total 在这一步通常不应直接增加,因为这里只发生了一次普通 /bot/v1/chat,没有显式 feedback,也没有 follow-up。目的:验证 thumb_up、positive_feedback、one_turn_resolution_rate 相关口径。
真实用户问题:
帮我总结一下 OpenViking 的主要作用。
预期 Vikingbot 回答特征:
response_id真实用户后续行为:
这次回答有帮助,我给一个赞。
执行步骤:
/bot/v1/chat。response_id。thumb_up。聊天请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-02",
"user_id": "metrics-user",
"message": "帮我总结一下 OpenViking 的主要作用。"
}'
反馈请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/feedback" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-02",
"response_id": "<response_id>",
"feedback_type": "thumb_up",
"feedback_text": "helpful"
}'
重点核对指标:
openviking_feedback_events_total{valid="1"}
openviking_feedback_thumb_up_total{valid="1"}
openviking_feedback_responses_with_feedback_total{valid="1"}
openviking_feedback_positive_outcomes_total{valid="1"}
openviking_feedback_coverage{valid="1"}
openviking_feedback_thumbs_up_rate{valid="1"}
openviking_feedback_one_turn_resolution_rate{valid="1"}
预期结果:
events_total、thumb_up_total、responses_with_feedback_total、positive_outcomes_total 通常各增加 1;如果你先看过基线,再在一次 scrape 之后复查,这几个 total 最容易确认。thumb_down_total、negative_outcomes_total、reasked_outcomes_total、follow_up_without_feedback_outcomes_total 在这个场景通常不应直接增加,因为当前动作是对同一条 response 提交显式正向反馈,而不是差评或追问。coverage、thumbs_up_rate、one_turn_resolution_rate 通常会上升或保持不变,但如果历史 response 和历史 feedback 已经很多,显示上也可能接近不变;其中 thumbs_up_rate 的分母是 feedback_total,one_turn_resolution_rate 的分母是 responses_total,并且当前实现会把 resolved + positive_feedback 都算入 one-turn resolution。目的:验证 thumb_down、negative_feedback 相关口径。
真实用户问题:
请告诉我 OpenViking 的部署步骤,越短越好。
预期 Vikingbot 回答特征:
response_id真实用户后续行为:
这次回答不够有帮助,我给一个踩。
聊天请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-03",
"user_id": "metrics-user",
"message": "请告诉我 OpenViking 的部署步骤,越短越好。"
}'
反馈请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/feedback" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-03",
"response_id": "<response_id>",
"feedback_type": "thumb_down",
"feedback_text": "not helpful"
}'
重点核对指标:
openviking_feedback_events_total{valid="1"}
openviking_feedback_thumb_down_total{valid="1"}
openviking_feedback_negative_outcomes_total{valid="1"}
openviking_feedback_thumbs_down_rate{valid="1"}
openviking_feedback_negative_feedback_rate{valid="1"}
预期结果:
events_total、thumb_down_total、negative_outcomes_total 通常各增加 1;如果基线样本不多,这几个 total 的跳变会比较直观。thumb_up_total、positive_outcomes_total、reasked_outcomes_total、resolved_outcomes_total、follow_up_without_feedback_outcomes_total 在这个场景通常不应直接增加,因为这里只提交了显式负向反馈,没有发生追问或静默结束。thumbs_down_rate、negative_feedback_rate 通常会上升或保持不变,但如果历史样本很多,比例变化可能很小;其中 thumbs_down_rate 的分母是 feedback_total,negative_feedback_rate 的分母是 responses_total,因此仍然优先看 total 是否按预期跳变。reasked目的:验证“无显式反馈,但 10 分钟内追问”会被判定为 reasked。
真实用户第一问:
请解释 OpenViking 的 metrics 是做什么的。
预期 Vikingbot 第一轮回答特征:
真实用户第二问:
我还是没明白,请再具体一点。
执行要求:
/bot/v1/chat 必须使用同一个 session_id。/bot/v1/feedback。第一轮请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-04",
"user_id": "metrics-user",
"message": "请解释 OpenViking 的 metrics 是做什么的。"
}'
第二轮请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-04",
"user_id": "metrics-user",
"message": "我还是没明白,请再具体一点。"
}'
重点核对指标:
openviking_feedback_reasked_outcomes_total{valid="1"}
openviking_feedback_reask_rate{valid="1"}
预期结果:
reasked_outcomes_total 增加 1。reask_rate 不下降,通常会上升或保持不变;它的分母是全量历史 responses_total,不是已经写入 outcome 的回答子集。responses_total 通常还会因为第二次 /bot/v1/chat 再增加 1,但真正被打上 reasked 的是第一轮 assistant response,而不是第二轮新生成的 response。events_total、thumb_up_total、thumb_down_total、responses_with_feedback_total 通常不变,因为这个场景没有显式调用 /bot/v1/feedback。positive_outcomes_total、negative_outcomes_total、resolved_outcomes_total、follow_up_without_feedback_outcomes_total 通常不应因为这一步直接增加;如果你看到增长,通常说明混入了其他验证样本,或第二次提问已经越过 10 分钟窗口而被判成了别的 outcome。补充说明:
reask_rate 之所以写成“通常上升或保持不变”,而不是“必然上升”,是因为这是一个基于全量历史 response 重新聚合的比例;如果历史样本很多,分母同步变化后也可能在显示上保持不变。reasked。reasked 和 follow_up_without_feedback 的边界是 follow-up 是否发生在上一条 assistant response 之后 10 分钟内:10 分钟内优先归类为 reasked,超过该窗口且又没有显式反馈时,才更可能落入 follow_up_without_feedback。follow_up_without_feedback目的:验证“没有点赞/点踩,也不是 10 分钟内追问”的 follow-up 会被归为 follow_up_without_feedback。
真实用户第一问:
OpenViking 和普通向量数据库有什么关系?
真实用户第二问:
那你能再举一个更具体的例子吗?
执行要求:
session_id。/bot/v1/feedback。第一轮请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-05",
"user_id": "metrics-user",
"message": "OpenViking 和普通向量数据库有什么关系?"
}'
第二轮请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-05",
"user_id": "metrics-user",
"message": "那你能再举一个更具体的例子吗?"
}'
重点核对指标:
openviking_feedback_follow_up_without_feedback_outcomes_total{valid="1"}
预期结果:
follow_up_without_feedback_outcomes_total 通常增加 1;同时第二次 /bot/v1/chat 也会让 responses_total 再增加 1,但真正被补判为 follow_up_without_feedback 的仍然是第一轮 assistant response。events_total、thumb_up_total、thumb_down_total、responses_with_feedback_total 通常不变,因为整个场景没有显式调用 /bot/v1/feedback;positive_outcomes_total、negative_outcomes_total、reasked_outcomes_total 也通常不应在这一步直接增长。reasked_outcomes_total,优先检查第二次提问是不是仍在 10 分钟窗口内;rate 类指标同样可能因为历史样本较多而变化不明显,所以这个场景优先看 total 跳变。resolved目的:补充验证“没有追问、没有负向反馈”的响应会被统计为 resolved。
真实用户问题:
请用一句话解释什么是 OpenViking 的 readiness 指标。
预期 Vikingbot 回答特征:
请求示例:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-06",
"user_id": "metrics-user",
"message": "请用一句话解释什么是 OpenViking 的 readiness 指标。"
}'
重点核对指标:
openviking_feedback_resolved_outcomes_total{valid="1"}
openviking_feedback_one_turn_resolution_rate{valid="1"}
预期结果:
resolved_outcomes_total 有机会增加 1,one_turn_resolution_rate 也可能上升或保持不变;当前该 rate 的分母是全量 responses_total。events_total、thumb_up_total、thumb_down_total、responses_with_feedback_total 在这个场景通常不变,因为既没有显式 feedback,也没有后续追问;negative_outcomes_total、reasked_outcomes_total、follow_up_without_feedback_outcomes_total 也通常不应直接增加。resolved 相比 thumb_up、thumb_down、reasked 更适合作为补充验证项,因为它依赖后续 outcome 评估时机,出现时间和幅度都不如显式反馈稳定;因此看到短时间内没有立刻跳变,不一定表示链路异常。说明:resolved 相比 thumb_up、thumb_down、reasked 更适合作为补充验证项,不建议当成唯一验收依据。
openviking_feedback_channel_*目的:验证 channel 维度聚合是否正常。
前提:环境里已经配置了 bot_api 的某个 channel,例如 demo,对应聚合维度应为 bot_api__demo。
真实用户问题:
请简单介绍一下 OpenViking。
真实用户后续行为:
这次回答没帮助,我给一个踩。
聊天请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/chat/channel" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-07",
"user_id": "metrics-user",
"channel_id": "demo",
"message": "请简单介绍一下 OpenViking。"
}'
反馈请求:
curl -sS -X POST "http://127.0.0.1:30300/bot/v1/feedback" \
-H "Content-Type: application/json" \
-d '{
"session_id": "real-metrics-case-07",
"channel_id": "demo",
"response_id": "<response_id>",
"feedback_type": "thumb_down",
"feedback_text": "not helpful"
}'
重点核对指标:
openviking_feedback_channel_events_total{channel="bot_api__demo",valid="1"}
openviking_feedback_channel_thumbs_down_rate{channel="bot_api__demo",valid="1"}
openviking_feedback_channel_negative_outcomes_total{channel="bot_api__demo",valid="1"}
openviking_feedback_channel_one_turn_resolution_rate{channel="bot_api__demo",valid="1"}
预期结果:
channel_events_total{channel="bot_api__demo"}、channel_negative_outcomes_total{channel="bot_api__demo"} 通常增加;如果你同时看 channel 维度和全局维度,两边都应体现这次负向反馈。/bot/v1/chat 而不是 /bot/v1/chat/channel,通常也不会得到目标 channel="bot_api__demo" 的聚合样本。channel_thumbs_down_rate{channel="bot_api__demo"}、channel_one_turn_resolution_rate{channel="bot_api__demo"} 这类比例在历史 channel 样本较多时可能变化不明显,所以 channel 验收优先看该 channel 的 total 是否跳变,再看 rate 方向是否合理。如果只想用最少案例覆盖这次新增指标,建议按下面顺序执行:
responses_total 正常。thumb_up、positive_outcomes_total、coverage、one_turn_resolution_rate 正常。thumb_down、negative_outcomes_total 正常。reasked_outcomes_total、reask_rate 正常。follow_up_without_feedback_outcomes_total 正常。resolved 作为补充验证。满足下面条件,可以认为本次补充的主要指标链路正常:
openviking_feedback_responses_total{valid="1"} 增加。openviking_feedback_events_total、openviking_feedback_thumb_up_total、openviking_feedback_positive_outcomes_total 增加。openviking_feedback_thumb_down_total、openviking_feedback_negative_outcomes_total 增加。openviking_feedback_reasked_outcomes_total 增加。openviking_feedback_follow_up_without_feedback_outcomes_total 增加。openviking_feedback_channel_* 会按目标 channel 出现并跳变。补充判定原则:如果 rate 没有明显跳变,但对应 total 已按预期变化,通常仍可视为链路正常,因为这些 rate 都是对全量历史回答重新聚合的快照值。
bot/docs/vikingbot-feedback-observability-design.mdbot/docs/vikingbot-phase3-outcome-validation-with-openviking-server.mddocs/zh/guides/12-vikingbot-metrics-validation.md