Agent 系统健康度:延迟、降级率与 Token 成本的正确口径

输出质量回答“结果好不好”,系统健康度回答“服务是否稳定、及时且成本可控”。这两类评估应一起运行:正确但经常超时的服务难以使用,响应很快却频繁降级的服务也不能仅凭延迟达标就判定健康。

先定义请求成功,再计算延迟

普通 HTTP 请求不能只看状态码;流式响应还需要检查协议是否正常结束、是否返回错误事件、最终结果是否符合约定。列表查询成功也不代表生成、检索和工具调用链路正常。

一条请求记录至少应包含请求 ID、任务类型、开始与结束时间、成功状态、错误类型、降级原因和模型版本。失败与取消请求应分别统计,不能因为只分析成功样本而从报告中消失。

TTFT 与完整响应耗时分别反映什么

TTFT 是从约定的请求起点到第一个有效生成内容到达的时间;完整响应耗时则从同一起点计到任务正常结束。连接建立、心跳和空事件不应被当作首 Token。对流式应用,两项指标共同决定用户感受。

测量耗时宜使用单调时钟,例如 Python 的 time.perf_counter()。同时明确测量位置:浏览器端、网关端和模型调用端的耗时范围不同,不能直接互相替换。

import time

start = time.perf_counter()
first_content_at = None

# 以下为事件处理示意,event 由实际协议解析器提供。
# 收到第一个非空内容事件时:
# first_content_at = time.perf_counter()
# 收到合法完成事件时:
# completed_at = time.perf_counter()

# ttft_ms = (first_content_at - start) * 1000
# total_ms = (completed_at - start) * 1000

服务端发送的事件名即使叫 token,一个事件也可能携带多个 Token 或只包含一段字符。事件数量不能用作模型 Token 消耗,更不能直接参与计费。

分位数必须说明算法与样本范围

P50 是中位位置的延迟,P95 描述尾部体验。平均值不是 P50。不同分位数算法可能在小样本上得到不同结果,因此报告需要固定算法、样本量和观察窗口。

from math import ceil, isfinite

def nearest_rank(values, p):
    if not values or not 0 < p <= 1:
        raise ValueError("invalid sample or percentile")
    ordered = sorted(float(v) for v in values)
    if not all(isfinite(v) and v >= 0 for v in ordered):
        raise ValueError("invalid latency")
    return ordered[ceil(p * len(ordered)) - 1]

samples = [4231, 3812, 5120, 3677, 4389]
print(nearest_rank(samples, 0.50))  # 4231
print(nearest_rank(samples, 0.95))  # 5120

这 5 个数只是计算示例。此时 P95 接近最大值,不能代表稳定的线上尾延迟。少量顺序请求适合冒烟检查;性能评估还应覆盖并发、冷启动、缓存命中与未命中、输入长度及任务类型,并报告足够长的观察窗口。

成功请求延迟应与失败率并排展示,另列超时和取消情况。否则某些最慢请求超时后被排除,P95 反而可能看起来更好。

降级率要有明确分母与原因

请求级降级率可以定义为:观察窗口内至少触发一次降级的合格请求数,除以该窗口全部合格请求数。一条请求多次降级,在请求级口径中只计一次;如果统计调用级口径,需要另列分母。

Fallback 率 = 触发过降级的请求数 / 纳入统计的请求数

事件记录应区分模型超时、检索失败、重排不可用、限流和主动策略切换。正常业务路由不应与故障降级混为一谈。降级成功也可能牺牲回答质量,最好单独抽查降级样本。

如果系统尚未记录 fallback_used 与原因,就只能说明缺少数据,不能报告降级率为零。

Token 与费用来自真实调用记录

优先使用模型服务返回的 usage 信息,并区分输入、输出、缓存等计费类别。一条 Agent 请求可能包含改写、生成、裁判和重试等多次模型调用;请求成本应汇总所有相关调用,同时防止重复采集造成重复计数。

Langfuse 支持使用调用的用量与成本信息进行追踪;各 usage_details 类别应避免重叠计数。具体接入方式以所用 SDK 版本为准,参见 Langfuse Token 与成本追踪文档。

单次请求模型成本
  = Σ 各调用、各计费类别的(用量 × 对应单价)

总任务成本
  = 模型成本 + 检索/搜索等外部服务成本

不要在监控脚本里长期写死旧价格。价格配置应包含供应商、模型版本、币种、生效日期和计价单位。缺失 usage 应单列缺失比例;如使用估算值,也要与供应商实际用量区分。

历史查询需要真正覆盖观察窗口

“最近 50 条 Trace”与“最近 24 小时”不是同一口径。统计指定时间范围时,要显式过滤开始、结束时间并完整分页,记录总请求量和缺失字段数量。日志中没有报错,也不等于所有请求都已被完整采集。

按任务建立告警与排查路径

异常 优先排查
TTFT 上升 排队、检索、预处理与模型首响应
总耗时上升,TTFT 稳定 输出长度、生成速度与后处理
降级率上升 供应商错误、限流及依赖服务状态
Token 激增 历史上下文、检索片段、重试与调用次数
列表接口正常,生成失败 真实业务链路、工具调用与完成事件

阈值应根据任务复杂度、用户等待容忍度和历史基线制定。问答、简历分析与单轮面试不宜共用同一个延迟目标。Token 增加也不能直接证明提示词泄露,应先检查上下文和调用结构。

一份有用的健康报告应同时展示成功率、延迟分布、降级率、成本与数据完整性,并明确观察窗口和样本量。指标不足时标记“待确认”,比用一个“系统健康”标签掩盖未知更有价值。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇