跳到正文

TECH NOTE

1975 字 10 分钟 系列 15 / 22

15 附录:重复请求占比怎么统计(一次调用耗时、平均 token 好量,这个得先定义)

ON THIS PAGE / 目录10 节

一句话讲透:它不是一个能从数据库里直接取出来的字段,而是一个”要先定义清楚”的派生指标。它唯一要服务的决策是——有状态模式(Handoffs / Skills)到底能替你省掉多少次”决策调用”。所以定义必须对着这个目的来:别拿”用户消息文本一样”当判据(追问、换说法、补充信息全都会漏判)。

关联:03 场景二与结尾的”量三件事” | 05 Handoffs | 06 Skills | 抓包方法见 13 附录


一、先定义:什么叫”一次重复请求”#

对着决策来定义:同一会话里,这一轮能不能沿用上一轮已经”进入”的那个域/步骤——能,就是一次重复。

thread A: 轮1 [咖啡域] 轮2 [咖啡域] 轮3 [咖啡域] 轮4 [机票域]
└─ 粘住 ─┘ └─ 粘住 ─┘ └─ 切换 ─┘
相邻轮次对 3 个,其中粘住 2 个 → sticky_rate = 2 / 3 ≈ 66.7%

公式:

sticky_rate = Σ(i≥2) [ d(i) == d(i-1) 且 gap(i) ≤ 空闲阈值 ] / Σ(i≥2) 1
d(i) = 第 i 轮**真正被使用**的域/步骤标签(落到了哪个子智能体 / 技能 / 路由分支)
gap(i) = 与同会话上一轮的时间间隔(超过阈值就算"重新开始",不算粘住)

为什么是这个量:有状态模式省掉的那一次调用,正是”重新进入这个域”的开销——Handoffs 省的是交接,Skills 省的是加载技能,Router 若做成有状态省的是分诊。所以”能沿用上一轮”的比例,就是它们省钱比例的上界。


二、口径先选一个(三种 d(i) 取法,别混着比)#

口径d(i) 取什么优点代价
业务主键(推荐优先)这一轮操作的业务对象:订单号 / 工单号 / 设备号 / SKU最客观、SQL 一句 join 就能算、不用模型通用闲聊类请求没有主键,算不出来
域 / 专家标签本轮落到哪个子智能体、哪个技能、哪条路由分支直接对应省下来的那次调用需要标签(要从 trace/checkpoint 里取或补埋点)
意图分类离线用分类提示词打出的意图通用、无业务假设要花一次离线模型调用;分类口径本身会漂

🧭 建议:先试业务主键——多数 ToB 场景(客服工单、订单、设备)天然有主键,“同一工单连续追问”就是最典型的重复请求。没有主键的通用助手,再退到域标签或离线分类。


三、三条取数路线#

路线 A:从 trace / checkpoint / 日志派生(推荐,半天能出第一个数)#

每轮只需要四个字段:thread_id、turn_no、ts、domain_label。

标签从哪来:

  • LangGraph checkpoint:状态里就有历史 messages。每轮的 AIMessage.tool_calls 告诉你调了哪个工具/子智能体;按 tool → 域 的映射表就能得到 domain_label。
  • Deep Agents:更省事——它会给子智能体运行打上 lc_agent_name 元数据(见 deepagents/01 的”同一个工具在多个智能体间共用”),在工具里 runtime.config["metadata"]["lc_agent_name"] 就能读到”这轮是谁在干活”。
  • 纯日志:按 request_id / thread_id 聚合,取日志里”本轮调用了哪个工具/子智能体”的字段。

如果现在什么都没有:加一行埋点,就四个字段,成本远低于事后靠猜。

路线 B:业务主键 join(SQL 模板)#

-- 模板:表名/列名换成你自己的;核心是 LAG 取上一轮,再比主键与时间间隔
WITH t AS (
SELECT thread_id,
turn_no,
biz_key, -- 订单号/工单号/设备号…
created_at,
LAG(biz_key) OVER (PARTITION BY thread_id ORDER BY turn_no) AS prev_key,
LAG(created_at) OVER (PARTITION BY thread_id ORDER BY turn_no) AS prev_ts
FROM agent_turn_log
WHERE created_at >= NOW() - INTERVAL 14 DAY
AND thread_id IS NOT NULL
)
SELECT
COUNT(*) AS pairs, -- 分母:相邻轮次对
SUM(prev_key IS NOT NULL AND biz_key = prev_key
AND TIMESTAMPDIFF(MINUTE, prev_ts, created_at) <= 30) AS sticky_pairs, -- 分子
ROUND(100 * SUM(prev_key IS NOT NULL AND biz_key = prev_key
AND TIMESTAMPDIFF(MINUTE, prev_ts, created_at) <= 30) / COUNT(*), 1) AS sticky_rate_pct
FROM t
WHERE prev_key IS NOT NULL;

PostgreSQL:把 TIMESTAMPDIFF(MINUTE, prev_ts, created_at) 换成 EXTRACT(EPOCH FROM (created_at - prev_ts)) / 60。 顺手再加一列 GROUP BY 维度(业务线 / 域 / 用户类型),分域看——重复率在域之间的差异通常比整体均值有用得多。

路线 C:离线分类(兜底)#

没有主键、也没有埋点标签时:用 07 Router 的分类提示词,抽样 1–2 周会话,给每轮打一个域标签,再按第一节的公式算。 务必只抽样——为了统计而全量跑一遍模型,本身就违反这次优化的初衷。


四、该报告的五个数(一张 measurement card)#

#指标怎么算拿来回答什么
1会话轮数分布单轮会话占比、轮数 P50/P90单轮会话对”重复”没贡献;占比高说明这个指标影响面小
2sticky_rate第一节公式主指标:有状态模式能省的比例上界
3平均连续同域长度(run length)按 thread 切段,统计同域连续段长度均值直接换算”每个会话能省几次调用”≈ 粘性轮数
4域切换频率相邻轮次 d(i) != d(i-1) 的比例切换太频繁 → Handoffs 的交接开销会把省下的吃回去
5空闲阈值敏感性阈值取 5 / 30 / 120 分钟各算一次检验结论稳不稳;差异大说明”会话边界”定得不合理

五、把这个比例换成钱和延迟#

可省调用数/天 ≈ 日轮次 × sticky_rate
省下的 token/天 ≈ 可省调用数/天 × 单次调用平均 token
省下的钱/天 ≈ 省下的 token/天 × 单价
省下的延迟 ≈ 可省调用数/天 × 单次调用耗时 (串行时直接叠加)

反向判据:如果 sticky_rate 只有 10%–15%,有状态模式带来的那点节省,通常撑不起它引入的”粘性复杂度”(要管状态、要兜底切回入口、要解释”为什么这个会话里一直是同一个专家”)——这时候 Subagents 的”恒定成本 + 强隔离”更划算。


六、六个坑(踩了会让数字虚高或虚低)#

  1. 分母口径:按相邻轮次对,不是按会话数——你要省的是调用,不是会话。
  2. **别用”用户消息文本相同”**判重:"再买一杯" 和 "帮我买杯咖啡" 是同一件事;而连着两次 "帮我查下订单" 问的是两个订单,反而是两件事。
  3. 必须设空闲阈值:隔天再来的一句”再买一杯”,状态语义上已经不算”粘住”了;不设阈值,sticky_rate 会明显虚高。
  4. 新 thread 不算粘:状态不跨会话保留(除非你另做长期记忆),跨会话的”同样问题”是新请求,不是重复请求。
  5. 这是上界,不是承诺:上下文压缩可能把粘性打断——比如 Skills 的手册被摘要/裁掉后,下一轮其实得重新加载。真实节省要再打一个折(可用 A/B 或影子流量验证)。
  6. 别跨用户拼会话:一定按 thread_id 分组后再取 LAG,否则会把两个人的对话接成一条”连续追问”。

七、一页速览#

  • 定义:同一会话里”这一轮能沿用上一轮的域/步骤且间隔不超阈值” = 一次重复。
  • 公式:sticky_rate = 粘住的相邻轮次对 / 全部相邻轮次对。
  • 取数:业务主键(首选)→ 域标签(trace/checkpoint/埋点)→ 离线分类(抽样兜底)。
  • 报告:sticky_rate + 平均连续同域长度 + 域切换率 + 会话轮数分布 + 阈值敏感性。
  • 结论用法:sticky_rate 高 → 值得上有状态模式(Handoffs / Skills);很低 → 老实用 Subagents,把精力放在上下文工程上。
15 附录:重复请求占比怎么统计(一次调用耗时、平均 token 好量,这个得先定义)
https://aicooleo.cn/blog/posts/multiagent-15-appendix-dup-rate/
作者
aicooleo
发布于
2026-08-30
许可协议
CC BY-NC-SA 4.0
多 Agent 精讲 · 第 15 / 22 篇 返回合集