qwen-code 的 `/stats` 生成时序指标(TTFT / Generation Time / TPS):从实现到验证
发布时间:2026/9/11 1:13:51 锦皓数字建站
:从实现到验证`)
qwen-code 的/stats生成时序指标TTFT / Generation Time / TPS从实现到验证【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文聚焦 qwen-codeAn open-source AI coding agent that lives in your terminal终端 CLI 中/stats命令新增的Generation Metrics生成时序指标模块讲解 TTFT首 token 延迟、Generation Time生成耗时、Output Tokens、TPS每秒输出 token 数以及 Session 级平均 TTFT 与 Session TPS 的数据模型、计算口径与采样过滤规则并完整还原该功能的自动化验证、手动验证场景与回归检查清单。读者读完可以掌握该指标体系的设计意图、源码位置与可复现的验证方法为在自己环境中核查或二次开发该功能提供依据。一、功能背景/stats里的生成时序指标/stats是 qwen-code 的内置斜杠命令提供使用统计仪表盘。它既可以在交互式 TUI 中弹出统计对话框也可以在非交互式命令面上输出纯文本。在新增 Generation Metrics 之前/stats的会话统计只有 token 用量、模型用量、工具调用、文件变更等维度缺少对“生成过程本身有多快”的量化而 TTFT 等时序数据此前仅存在于 tracing链路追踪中。本文依据的验证文档.qwen/e2e-tests/2026-07-24-generation-stats.md正是为这一功能制定的自动化与手动验证基线核心目标是回答/stats的 Session 标签页能否展示最新一次请求的生成时序模型、TTFT、生成耗时、输出 token 数、TPS多次请求后会话级请求计数、平均 TTFT、Session TPS是否正确累计在非交互式命令面上同样的指标能否以文本形式输出在各种边界情况下无流式响应、非流式响应、零耗时、内部 prompt、无用户可见内容指标不会出现空节、编造数值或 Infinity。本文所引用的指标实现、测试与验证步骤均可在当前仓库.qwen/e2e-tests/2026-07-24-generation-stats.md、packages/core/src/telemetry/uiTelemetry.ts、packages/cli/src/ui/commands/statsCommand.ts、packages/cli/src/ui/components/StatsSessionTab.tsx及对应测试文件中找到原始依据。二、数据模型GenerationMetrics 与 GenerationTimingSample生成时序指标定义在 packages/core/src/telemetry/uiTelemetry.ts 中由两个核心接口承载export interface GenerationTimingSample { model: string; ttftMs: number; generationDurationMs: number; outputTokens: number; } export interface GenerationMetrics { timedRequests: number; totalTtftMs: number; totalGenerationDurationMs: number; totalThroughputOutputTokens: number; last?: GenerationTimingSample; }GenerationTimingSamplelast字段最新一次被采样的请求快照包含模型名、TTFT、生成耗时与输出 token 数用于“Latest Request”展示GenerationMetrics的四个累计字段timedRequests被采样的请求数、totalTtftMsTTFT 累加和、totalGenerationDurationMs生成耗时累加和、totalThroughputOutputTokens用于计算吞吐的输出 token 累加和。它们挂在SessionMetrics的可选字段generation?: GenerationMetrics上随会话指标一起被统计、查询和重置。默认空值由createInitialGenerationMetrics()生成timedRequests: 0确保任何会话初始时都能安全访问。从源码结构看GenerationMetrics是一个增量累加模型每次事件到来时更新累计值并覆盖last快照因此“Session 级平均值”可由累加值在展示层计算而无需保存每个请求的历史明细。三、指标口径TTFT、Generation Time、TPS 的计算方式3.1 采样逻辑core 侧在 packages/core/src/telemetry/uiTelemetry.ts 中#accumulateApiMetrics对每次 API 事件做如下处理if ( event.ttft_ms undefined || !Number.isFinite(event.ttft_ms) || event.ttft_ms 0 || isInternalPromptId(event.prompt_id) ) { return; } const generation metrics.generation ?? (metrics.generation createInitialGenerationMetrics()); const generationDurationMs Math.max(0, event.duration_ms - event.ttft_ms); generation.timedRequests; generation.totalTtftMs event.ttft_ms; if (generationDurationMs 0) { generation.totalGenerationDurationMs generationDurationMs; generation.totalThroughputOutputTokens event.output_token_count; } generation.last { model: event.model, ttftMs: event.ttft_ms, generationDurationMs, outputTokens: event.output_token_count, };关键规则可归纳为TTFT 有效性ttft_ms必须存在undefined不算、是有限数值Number.isFinite、且不小于 0duration_ms - ttft_ms可能为负例如数据上报抖动因此生成耗时用Math.max(0, ...)夹取到 0内部 prompt 排除isInternalPromptId(event.prompt_id)为真时直接返回不产生采样保证内部 prompt 不会覆盖最新用户可见的生成样本零生成耗时不计入吞吐当generationDurationMs 0时请求仍然计入timedRequests与totalTtftMs但不累加totalGenerationDurationMs与totalThroughputOutputTokens从根上避免除零导致的 Infinity。TTFT 的原始测量点位于 packages/core/src/core/loggingContentGenerator/loggingContentGenerator.ts当响应流出现首个用户可见内容时记录ttftMs Date.now() - startTime如果流直到结束都没有用户可见内容则ttftMs保持undefined进而不会被采样——这与回归检查“A stream with no user-visible content does not create a timing sample”完全对应。3.2 展示与计算CLI 侧在 packages/cli/src/ui/components/StatsSessionTab.tsx 中Generation Metrics 区域按以下公式渲染指标公式边界处理最新请求 TPSlast.outputTokens / (last.generationDurationMs / 1000)仅当generationDurationMs 0时计算否则不显示避免 InfinityAverage TTFTgeneration.totalTtftMs / generation.timedRequests仅当timedRequests 0时计算否则不显示Session TPSgeneration.totalThroughputOutputTokens / (generation.totalGenerationDurationMs / 1000)仅当totalGenerationDurationMs 0时计算否则不显示同样的公式以纯文本形式存在于 packages/cli/src/ui/commands/statsCommand.ts 的formatGenerationMetrics()中见下文非交互式输出。三个平均值都遵循“分母为零则不显示”的口径保证任何极端情况下不会输出 Infinity。StatsSessionTab.tsx的展示结构为Latest Request 区Model最新模型名、TTFT、Generation Time、Output Tokens、TPSSession 区RequeststimedRequests、Average TTFT、Session TPS。会话级指标由 packages/cli/src/ui/contexts/SessionContext.tsx 提供上下文数据/stats打开时读取的是同一个SessionMetrics因此 TUI 展示与文本输出口径天然一致。四、自动化验证聚焦测试与仓库级校验验证文档给出了可复现的自动化验证路径分为两个层次。4.1 聚焦的 Core 测试在仓库根目录或packages/core下执行cd packages/core npx vitest run src/telemetry/uiTelemetry.test.ts npx vitest run src/core/loggingContentGenerator/loggingContentGenerator.test.tspackages/core/src/telemetry/uiTelemetry.test.ts 覆盖采样逻辑构造带ttft_ms的事件后断言generation数据正确累计同时覆盖“缺少 TTFT 或内部 prompt 不产生采样”“duration_ms ttft_ms时生成耗时夹取为 0”“按会话隔离”“service 重置时清空 generation 指标”等场景packages/core/src/core/loggingContentGenerator/loggingContentGenerator.test.ts 覆盖 TTFT 测量点即“首个用户可见内容才记录 TTFT”。4.2 聚焦的 CLI 测试cd packages/cli npx vitest run src/ui/commands/statsCommand.test.ts npx vitest run src/ui/components/StatsSessionTab.test.tsx npx vitest run src/ui/contexts/SessionContext.test.tsx npx vitest run src/i18n/mustTranslateKeys.test.tsstatsCommand.test.ts验证/stats命令及其子命令model、tools、skills、daily、monthly、export的文本输出与参数解析StatsSessionTab.test.tsx验证 Session 标签页对 Generation Metrics 的渲染包括各指标的存在性与格式SessionContext.test.tsx验证会话统计上下文的组装与下发mustTranslateKeys.test.ts国际化的强制校验确保Generation Metrics、Latest Request、TTFT、Generation Time、Output Tokens、TPS、Average TTFT、Session TPS等新增文案都有对应的翻译键避免遗漏。4.3 仓库级校验聚焦测试通过后再执行仓库级校验npm run format npm run lint npm run build npm run typecheck这四步分别对应格式化、静态检查、构建与类型检查确保新指标代码不影响仓库整体的可维护性与可发布性。五、手动验证场景一步一步核对指标验证文档同时给出了端到端手动验证步骤可作为功能验收的标准流程启动开发版 CLI使用流式模型streaming model保证响应可产生多 token 输出提交一个 prompt让其产生多 token 的流式响应打开/stats交互式 TUI在Session 标签页确认Generation Metrics显示最新模型latest modelTTFTGeneration Time生成耗时Output Tokens输出 token 数TPS每秒输出 token 数。提交第二个 prompt再次打开/stats确认Latest Request 字段已更新为第二个请求的数据Session 请求计数Requests变为 2Average TTFT与Session TPS同时包含两次被计时的请求在非交互式命令面运行/stats确认同样的指标以纯文本形式出现见下一节。注意/stats daily、/stats monthly、/stats export属于 token 用量统计不包含生成时序验证时不应期待它们出现 TTFT/TPS。六、非交互式输出文本形式的 Generation Metrics/stats命令在 packages/cli/src/ui/commands/statsCommand.ts 中根据context.executionMode区分行为交互式模式下弹出stats对话框非交互式non_interactive与acp模式下返回文本消息。formatGenerationMetrics()生成的文本格式为Generation Metrics (Latest Request) Model: model TTFT: formatted duration Generation Time: formatted duration Output Tokens: count TPS: x.x tok/s Requests: count Average TTFT: formatted duration Session TPS: x.x tok/s其中若尚无任何计时样本metrics或last为空整段返回空不会渲染空壳标题当最新请求的generationDurationMs为 0 时TPS 显示为—formatDuration之外的另一处防除零处理当timedRequests为 0 时Average TTFT 显示为—当累计生成耗时为 0 时Session TPS 显示为—数字使用Intl.NumberFormat按当前语言本地化格式化。这与回归检查“Opening/statsbefore any streamed response does not show an empty Generation Metrics section”以及“A zero generation duration displays TPS as unavailable instead of Infinity”直接对应。此外/stats export输出的文本末尾带有明确提示Note: generation timing (TTFT/TPS) belongs to generation metrics.用于避免与 token 用量统计混淆。七、回归检查清单六条不可回归的边界验证文档将以下场景列为回归红线每条都有对应的实现或测试佐证#回归检查项实现保证源码/测试依据1打开/stats但尚无任何流式响应时不显示空的 Generation Metrics 节formatGenerationMetrics对空 metrics 返回空数组StatsSessionTab仅在有lastGeneration时渲染该区域2非流式响应不编造 TTFT 或 TPSTTFT 仅在流式响应出现用户可见内容时记录loggingContentGenerator无ttft_ms的事件直接跳过采样3无用户可见内容的流不产生计时样本hasUserVisibleContent(response)为假时ttftMs保持undefined事件被采样过滤4零生成耗时显示 TPS 为不可用而非 InfinitygenerationDurationMs 0才参与 TPS/吞吐累计展示层分母为零时输出—5内部 prompt 不覆盖最新用户可见生成样本isInternalPromptId(event.prompt_id)直接 return不更新generation.last6/stats daily、/stats monthly、/stats export行为不变子命令走独立的queryTokenUsage路径Generation Metrics 不介入 token 用量聚合对应测试集中在 packages/core/src/telemetry/uiTelemetry.test.ts例如it(does not create samples for missing TTFT or internal prompts)同时覆盖检查 2、3、5对duration_ms: 100, ttft_ms: 150的事件断言generationDurationMs: 0对应检查 4按 session 隔离与 service reset 的用例保证会话切换不会串数据。八、基线状态变更前的可验证前提验证文档记录了一个重要的环境约束当前验证环境中没有发布版全局qwen可执行文件因此无法运行“变更前”的手动场景对比。其基线结论为TTFT 已通过 tracing链路追踪输出——即时序数据此前就存在于观测侧/stats在变更前没有生成时序区块——即该功能属于对/stats的增量扩展而非重构。这意味着本功能的行为验证完全依赖源码与新增测试来确立基线uiTelemetry.test.ts与loggingContentGenerator.test.ts中的断言即代表了“变更后”的期望行为手动场景仅作为 TUI 层面的最终验收补充。九、相关文件速查围绕本功能仓库中的关键文件与角色如下文件角色.qwen/e2e-tests/2026-07-24-generation-stats.md本功能的验证与回归检查规范本文依据packages/core/src/telemetry/uiTelemetry.tsGenerationMetrics/GenerationTimingSample定义与采样累加逻辑packages/core/src/telemetry/uiTelemetry.test.tscore 侧采样与边界场景测试packages/core/src/core/loggingContentGenerator/loggingContentGenerator.tsTTFT 测量点首个用户可见内容packages/cli/src/ui/components/StatsSessionTab.tsxTUI Session 标签页的 Generation Metrics 渲染packages/cli/src/ui/commands/statsCommand.ts/stats命令、文本输出与daily/monthly/export子命令packages/cli/src/ui/contexts/SessionContext.tsx会话统计上下文数据源.qwen/specs/2025-06-03-stats-dashboard-redesign.md/stats仪表盘整体设计Session 标签页保持不变的背景结语Generation Metrics 为 qwen-code 的/stats补齐了“生成过程性能”这一观测维度其设计有三个显著特点增量累加模型用last快照 四个累计值同时支撑单请求与会话级指标、防御式采样对缺失 TTFT、内部 prompt、零耗时、无可见内容等边界一律显式处理、双出口一致性TUI 渲染与非交互文本输出共享同一数据源与计算口径。配合.qwen/e2e-tests/2026-07-24-generation-stats.md中给出的自动化与手动验证流程任何开发者都可以在几分钟内独立验证该功能的正确性。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。