两件事:钱算得准(找不到主人的消费 = 收入缺口)+ 生成首屏快(灵感前奏三段 Planner → Case 检索 → 首个可见事件)。覆盖核心盘 🟠 组 7 张面板(c27–c33)· 后端核心仪表盘 siliang-backend。
灵感链路像渔夫捕鱼:用户点“生成”后有一段前奏——Planner 先写捕鱼计划,去向量库这片海撒网(Case 检索),捞上来的鱼要挑:烂鱼(invalid)扔掉,好鱼排成一队(candidate)面试,最后只录取少数(selected),然后才正式开工出图。用户感知的“卡不卡”,很大程度就在这段前奏上。
计费则像收银台:本次生成烧掉的每一笔消耗,结算时都要“通过会话找到这笔账的主人”(算哪个画布的)。找不到主人的钱记作 unattributed——等于少收了钱,这是收入完整性问题,不是普通报错。
第一段:前奏。用户点“生成”之后,正式开工前还有三件事:Planner 规划(写今天的捕鱼计划)→ Case 检索(去向量库这片海撒网)→ 首个可见进度事件(让用户先看到点什么,别对着转圈发呆)。这三段各有一张 P95 耗时曲线(c29),用户抱怨“点生成卡”,先看谁冒尖。
第二段:挑鱼。网捞上来(召回命中 hit)不都能吃:投影字段缺失、文档损坏的是烂鱼(invalid_document),搜到了但用不了;好鱼合并排序进入候选(candidate = 进面试的人),最终选中的(selected = 录取的)才真的用于生成。两种病要分清:candidate 持续走低是“网眼变大、捞不到鱼”(召回变窄);candidate 高而 selected 低是“面试官太严、卡太狠”(排序/过滤过严)——修法方向相反。
第三段:收银台。出图烧掉的消耗要记账:结算时通过会话确认这笔账算哪个画布的,记上了就是 ok;找不到主人就记 unattributed——少收/错账,收入在漏。另外“查账单”本身也是个接口(c28):聚合统计类 SQL 会随数据量越滚越慢,小票打不出来,用户一样投诉。
| 类比里的东西 | 系统里对应的东西 |
|---|---|
| 捕鱼计划 | Planner 规划段——灵感三段之一(c29,siliang_inspiration_plan_duration_ms_bucket,单位 ms)。 |
| 撒网的海 | 向量库/案例库。检索 backend 现在只有 vector,留了混合召回扩展位(c32)。 |
| 捞上的鱼 vs 烂鱼 | 召回命中 hit vs invalid_document(c31)——烂鱼 = 投影字段缺失/文档损坏,搜到了但用不了。 |
| 面试候选人 / 最终录取 | candidate(合并排序后的候选数)/ selected(c33),两条分布看检索效果的质量趋势。 |
| 找不到主人的账单 | unattributed(c27)——结算时无法通过会话确认这笔账算哪个画布的。 |
| 打小票的速度 | 消耗统计查询耗时 P95(c28,按 endpoint 拆),聚合统计 SQL 随数据量变慢。 |
# 三段 P95,单位 ms(别当秒看) histogram_quantile(0.95, …siliang_inspiration_plan_duration_ms_bucket… by (le))
rate(siliang_workspace_consumption_unattributed_total[5m]) # 恒 0 才健康;持续增长 = 收入在漏
histogram_quantile(0.95, …siliang_inspiration_vector_hit_count_bucket… by (le)) # hit P95 有数 = 渔网在工作
# invalid_document 持续偏高 = 搜到了但用不了 # 与 hit 对照看:产量高 ≠ 能吃
# candidate 走低 = 召回变窄(网眼变大) # candidate 高 selected 低 = 排序/过滤卡太狠
rate(siliang_inspiration_degraded_total[5m]) by (error_code) # 持续增长 = 查 error_code 指向的那个阶段
# c29 → …_duration_ms_bucket (毫秒) # c28 → …_query_duration_seconds_bucket(秒)
_total 结尾的 Counter,必须配 rate 才是速率;裸画绝对值是永远上扬的直线,毫无信息量。 # 错: 画 empty_total 绝对值 → 永远上扬 # 对: rate(siliang_inspiration_empty_total[5m])
histogram_quantile(0.95, sum(rate(siliang_workspace_consumption_query_duration_seconds_bucket[5m])) by (le, endpoint)) # 持续升高 = 该做索引/预聚合优化了
# 视频结算结局(内存盘 m131) sum by (outcome) (rate(siliang_video_settlement_outcome_total[5m])) # retrying/exhausted 高 = 收入问题,与 c27 互证
它是什么:算账服务的两条线——查询成不成功(按 endpoint × result 拆 ok/failed),以及 unattributed = “找不到主人的消费”(结算时无法通过会话确认这笔账算哪个画布的)。前者是收银台的手速,后者是收银台的漏洞。
回答什么问题:用户的钱算得准不准?有没有正在漏收入?
✅ unattributed 恒为 0;查询 ok 线随业务起伏、failed 贴地。
🚨 unattributed 持续增长 = 计费归因缺口(少收/错账),这是收入完整性问题——非零即查:先冻结相关结算改动,再顺会话链路查这笔消费为什么找不到主人。
# 面板 PromQL(照抄主图谱口径) rate(siliang_workspace_consumption_query_total[5m]) by (endpoint, result) + rate(siliang_workspace_consumption_unattributed_total[5m])
联动:主图谱 c27 ↗ · 视频结算结果 m131(另一条算钱流水线) · 相关课程:视频后台流水线
它是什么:查账单要等多久(P95,按端点 endpoint 拆,单位秒)。查消耗是聚合统计类 SQL——它随数据量增长天然变慢,所以这张图看的是“趋势”而不是“瞬间”。
回答什么问题:收银小票打多快?查账功能会不会慢到让用户以为卡死了?
✅ P95 平稳或缓慢波动;偶发毛刺(后台大查询撞车)可接受。
🚨 持续升高 = 聚合查询需要优化(索引/预聚合)——它慢会连坐“查账单”接口的用户体验,与 c27 的 failed 线互证。
# 面板 PromQL(照抄主图谱口径) histogram_quantile(0.95, sum(rate(siliang_workspace_consumption_query_duration_seconds_bucket[5m])) by (le, endpoint))
联动:主图谱 c28 ↗ · 归因失败 c27 · 相关课程:直方图水桶 / P50/P95/P99
它是什么:点“生成”之后正式开工前的“前奏”三段耗时 P95:Planner 规划 → Case 检索 → 首个可见进度事件(单位 ms)。用户感知的“卡不卡”很大程度在这——这是生成体验的第一印象。
回答什么问题:生成体验的第一印象快不快?如果要优化,先慢在哪一段?
✅ 三条 P95 稳定在各自的量级,无单段突然抬升;首个可见事件越短,用户觉得“越快开动了”。
🚨 检索段抬升 = 向量库变慢/不稳(下钻 c32 向量失败);Planner 段抬升 = 对照 LLM 延迟(c15)看是不是模型变慢连坐——先定位段,再动手。
# 面板 PromQL(照抄主图谱口径,三段并列,单位 ms) histogram_quantile(0.95, …) on siliang_inspiration_plan / _search / _first_visible_duration_ms_bucket
它是什么:灵感链路的三种“不如意”:empty = 检索啥也没搜到;degraded = 某阶段坏了走备用路(按 error_code 区分坏在哪);skipped = 语义上主动跳过(按 reason 区分为什么跳)。三种是三种病,别混在一起看。
回答什么问题:用户拿到的灵感结果是“正常产出的”,还是“兜底凑合的”?
✅ 偶发正常——降级本来就是兜底设计在工作。
🚨 degraded 持续增长 = 向量库/案例库不稳,用户拿到的是降级体验——按 error_code 定位坏掉的阶段,与 c31/c32 互证;empty 持续走高 = 该查语料与召回参数了。
# 面板 PromQL(照抄主图谱口径) rate(siliang_inspiration_empty_total) / …_degraded_total by (error_code) / …_skipped_total by (reason)
联动:主图谱 c30 ↗ · 检索后端失败 c32 · 相关课程:rate()
它是什么:检索“Fishing”收获如何——召回命中数 P95、其中投影完整有效多少(valid)、损坏无效多少(invalid)。相当于渔网捞上多少鱼、多少是烂的。注意它是分布(histogram),看的是 P95 形态。
回答什么问题:网里的鱼够不够、能不能吃?检索质量是在变好还是变坏?
✅ hit P95 稳定、invalid 贴地——产量够、烂鱼少。
🚨 invalid_document 持续偏高 = 向量库文档损坏或投影字段缺失(搜到了但用不了)——产量数字好看但体验照样烂,去修向量库的数据质量而不是调召回参数。
# 面板 PromQL(照抄主图谱口径) histogram_quantile(0.95, …) on siliang_inspiration_vector_hit / _valid_document / _invalid_document_count_bucket
它是什么:两张合一面板:检索量按 backend 拆(现在只有 vector,留了混合召回扩展位),加上向量库失败按原因拆(timeout / error)。前者看“走哪条路检索”,后者看“这条路坏没坏”。
回答什么问题:向量库这片刻稳定吗?失败是超时(过载/网络抖)还是报错(查询/投影出问题)?
✅ retrieval 有稳定速率、vector_failure 贴地。
🚨 失败速率持续 > 0 = 向量库不稳 → 拖慢首屏(c29 抬升)+ 触发降级(c30 增长),三张卡互证;timeout 高查过载与网络,error 高查查询与投影逻辑。
# 面板 PromQL(照抄主图谱口径) rate(siliang_inspiration_retrieval_total[5m]) by (backend) + rate(siliang_inspiration_vector_failure_total[5m]) by (reason)
它是什么:招聘视角看检索效果——candidate = 进入面试的人(合并排序后的候选数),selected = 最终录取数。两者都是数量分布(P95),看的是趋势而不是单次值。
回答什么问题:检索效果的质量趋势如何?该调召回还是该调过滤?
✅ 两条分布稳定:候选有量、录取有质,比例平稳。
🚨 candidate 持续走低 = 召回变窄(网眼变大)→ 查召回参数/语料;candidate 高而 selected 低 = 排序/过滤过严(卡太狠)→ 查过滤逻辑。两种病修法相反,先分清再动手。
# 面板 PromQL(照抄主图谱口径) histogram_quantile(0.95, …) on siliang_inspiration_candidate_count_bucket / _selected_count_bucket
“钱算得准”是这组面板的第一使命。先确认是不是归因在漏,再确认查账接口有没有在报错连坐。
# 1) 归因缺口:找不到主人的消费速率 rate(siliang_workspace_consumption_unattributed_total[5m]) # 持续 > 0 = 收入完整性问题:先冻结相关结算改动再排查 # 2) 用 increase 看问题规模:这段时间总共漏了几笔 sum(increase(siliang_workspace_consumption_unattributed_total[1h])) # 笔数 × 客单价 ≈ 这次漏收的量级,决定处理优先级 # 3) 查询成功率:按 endpoint × result 拆 sum(rate(siliang_workspace_consumption_query_total[5m])) by (endpoint, result) # failed 抬头 = 查账接口在报错;对照 c28 P95 看是不是超时连坐
判读:unattributed 回到恒 0、ok 线恢复正常才算收口;期间产生的缺口要按记录补账。
首屏慢是体验投诉的重灾区。灵感前奏三段各有 P95 曲线,先定位慢在哪一段,再决定往哪查。
# 三段 P95(单位 ms):谁冒尖慢在哪 histogram_quantile(0.95, sum(rate(siliang_inspiration_plan_duration_ms_bucket[5m])) by (le)) histogram_quantile(0.95, sum(rate(siliang_inspiration_search_duration_ms_bucket[5m])) by (le)) histogram_quantile(0.95, sum(rate(siliang_inspiration_first_visible_duration_ms_bucket[5m])) by (le)) # 检索段慢 → 下钻 c32 向量失败按 reason 拆 # Planner 段慢 → 对照 LLM 延迟 c15(模型变慢会连坐) # 首个可见事件慢 → 查进度事件的上报链路
c30 的 degraded 与 c32 的失败互相印证才是实锤。单看任何一张都可能误判,三张连着看。
# 1) 失败原因:timeout / error 分开看 sum(rate(siliang_inspiration_vector_failure_total[5m])) by (reason) # timeout 高 = 向量库过载或网络抖 # error 高 = 查询/投影逻辑出问题 # 2) 降级速率:按 error_code 定位坏掉的阶段 sum(rate(siliang_inspiration_degraded_total[5m])) by (error_code) # degraded 持续增长 = 用户拿到的是降级体验 # 3) 召回质量旁证:烂鱼有没有跟着涨 histogram_quantile(0.95, sum(rate(siliang_inspiration_invalid_document_count_bucket[5m])) by (le)) # invalid 同步上涨 = 不只是慢,数据质量也坏了
每周固定拉一次这组数,检索质量的滑坡能在用户大规模投诉前暴露。
# 召回命中 P95:网里鱼多不多 histogram_quantile(0.95, sum(rate(siliang_inspiration_vector_hit_count_bucket[5m])) by (le)) # 烂鱼率旁证:invalid 持续偏高 = 文档损坏/投影字段缺失 histogram_quantile(0.95, sum(rate(siliang_inspiration_invalid_document_count_bucket[5m])) by (le)) # 面试通过率趋势:候选 vs 选中 histogram_quantile(0.95, sum(rate(siliang_inspiration_candidate_count_bucket[5m])) by (le)) histogram_quantile(0.95, sum(rate(siliang_inspiration_selected_count_bucket[5m])) by (le)) # candidate 走低 → 查召回;高进低出 → 查过滤,方向相反
unattributed 是钱,不该等人看图才发现。用 increase 窗口做告警,出现即处理。
# 归因缺口是收入问题,发现即处理(口径与面板一致) - alert: SiliangConsumptionUnattributed expr: increase(siliang_workspace_consumption_unattributed_total[10m]) > 0 for: 5m labels: severity: warning annotations: summary: "10 分钟内出现找不到主人的消费(计费归因缺口)" description: "unattributed 非零 = 少收/错账,按 c27 → c28 顺序排查,冻结相关结算改动"
empty 和 skipped 不是故障,是“不如意”——但持续走高说明上游变了,先确认是不是预期。
# empty:检索啥也没搜到——召回变窄或语料缺失 sum(rate(siliang_inspiration_empty_total[5m])) # 持续走高 = 查语料覆盖与召回参数(对照 c33 candidate 走低) # skipped:语义上主动跳过,按 reason 拆 sum(rate(siliang_inspiration_skipped_total[5m])) by (reason) # 某个 reason 突增 = 上游策略变更,先确认是不是预期行为
# 错: # “反正没报错,先放着” → 收入在漏没人知道 # 对: increase(siliang_workspace_consumption_unattributed_total[1h]) # → 非零即查
_ms_bucket,c28 是 seconds。正解:看后缀定单位,数量级先对齐再下结论。 # 错: # 把 inspiration_plan_duration_ms 的 500 读成 500 秒 # 对: # _ms_bucket = 毫秒;…query_duration_seconds_bucket = 秒
# 错: # 只汇报 hit P95 涨了 → 产量掩盖质量 # 对: # hit 与 invalid_document 两条分布一起看(c31)
# 错: # candidate 低 → 直接调大召回(可能真正问题是过滤太狠) # 对: # 对照 selected:高进低出 = 查过滤;进得就少 = 查召回
# 错: rate(siliang_inspiration_degraded_total[5m]) # → 只见总量 # 对: rate(siliang_inspiration_degraded_total[5m]) by (error_code) # → 定位阶段
# 错: histogram_quantile(0.95, rate(…query_duration_seconds_bucket[5m])) # 对: histogram_quantile(0.95, sum(rate(…query_duration_seconds_bucket[5m])) by (le, endpoint))
# 错: # 单点 degraded > 0 → 定级事故 # 对: # 持续增长 + c32 失败同步 > 0 → 才是向量库不稳
# 错: # P95 爬升 → 直接申请数据库扩容 # 对: # 按 endpoint 拆定位慢端点 → 索引/预聚合优化
参考答案:unattributed 是“找不到主人的消费”——结算时无法通过会话确认这笔账算哪个画布的。它不报错、不影响功能,但每一条都意味着这笔钱没记到任何画布头上,等于少收/错账。功能坏了用户会喊,收入漏了没人喊,所以必须靠监控非零即报。
参考答案:三段是 Planner 规划 → Case 检索 → 首个可见进度事件(c29,单位 ms)。先看 c29 的三条 P95 谁冒尖:检索段慢下钻 c32(向量失败按 timeout/error 拆),Planner 段慢对照 c15 LLM 延迟,首个可见事件慢查进度上报链路——先定位段,再动手。
参考答案:candidate 持续走低 = 召回变窄(网眼变大),捞都捞不上来,查召回参数与语料;candidate 高而 selected 低 = 面试官太严(排序/过滤卡太狠),捞上来全被毙了,查过滤逻辑。两者修法相反:前者动“进”,后者动“出”,先分清再动手。
参考答案:invalid_document 偏高说明向量库文档损坏或投影字段缺失——搜到了但用不了,是数据质量问题;empty 是检索啥也没搜到,是召回/语料覆盖问题。区别一句话:empty 是“网里没鱼”,invalid 是“捞上来的全是烂鱼”。前者调召回,后者修数据。