GenAI Trace 与耗时语义
理解 interaction、LLM、工具执行和审批等待,以及标准字段迁移。
一次逻辑 prompt 可包含多个模型请求、审批、工具执行和续跑。Qwen Code 的 trace 分层帮助区分这些耗时,不应将单个 API 请求时间当作整个任务耗时。
Span 分层
| Span | 范围 |
|---|---|
| qwen-code.interaction | 主 agent 一次逻辑 prompt,包含模型、工具、审批和 continuation |
| qwen-code.llm_request | 一次 LLM API 调用 |
| qwen-code.tool | 工具完整生命周期,包括审批等待 |
| qwen-code.tool.execution | 审批后的实际执行,仅为尝试过的执行创建 |
| qwen-code.tool.blocked_on_user | 等待审批的时段,含 decision 和 source |
| qwen-code.hook | PreToolUse、PostToolUse、PostToolUseFailure、PostToolBatch 的调用 |
| qwen-code.subagent | 单次子智能体调用,可区分 foreground、fork、background |
| qwen-code.daemon.request / bridge | daemon HTTP 请求与 bridge 操作 |
CLI 每次 interaction 有自己的 traceId;ACP/daemon 可以继承入站 parent。跨 prompt 使用 session.id 关联,不应要求所有对话轮次共享一个 trace。
用户查询、重试、cron、通知、队友消息和 Goal turn 可创建 invocation;工具结果、Hooks 和 steering 复用当前 prompt ID。
会话生命周期
OTel logs 启用时,session.start/end 携带 session.id。恢复持久对话且新 session ID 与当前不同的特定切换可带 session.previous_id;冷启动 --resume、--continue、--fork-session 不带它。
/clear 等丢弃原对话的替换流程不会声称 continuation。qwen-code.session.count 则按 CLI 启动计数,与 session.start 的切换事件数量不是同一指标。
GenAI 字段来自哪里
interaction 的 operation 是 invoke_agent,agent.name 为 qwen-code;它不写 gen_ai.request.model,因为一次调用可能动态切换、覆盖或回退模型。其敏感输入是原始用户文本投影,输出是最后可见回答,区别于实际 LLM 请求的展开历史。
llm_request 的标准 request 字段取自适配器处理默认值、覆盖、移除不支持字段及输出窗口限制之后的第一个 provider-final SDK 请求对象,不猜测 SDK 或服务端未声明默认值。
标准 response 字段取自提供商响应;token 只接受提供商报告的非负安全整数。仅有 total token 时不估算 input/output。
流式延迟与 token
流式调用写 gen_ai.request.stream=true;gen_ai.response.time_to_first_chunk 以秒度量从提供商调用到适配器首次产出规范化响应,不一定等于第一帧网络数据。
兼容 ttft_ms 则用于首次用户可见输出,继续影响 /stats、sampling_ms 和输出 token 吞吐。两者单位和观察点不同,不可直接互换。非流式请求省略标准 stream 和 first-chunk 字段。
缓存读取使用 gen_ai.usage.cache_read.input_tokens;旧 gen_ai.usage.cached_tokens、gen_ai.server.time_to_first_token、gen_ai.usage.reasoning_tokens 已不再发出。
成功、取消和失败
成功和取消的 GenAI spans 将 SpanStatus 保留为 UNSET;失败才使用 ERROR,并附有界说明和低基数 error.type。不能把所有 UNSET 都解释为缺失结果,也不能仅因用户取消就算系统错误。
工具 GenAI span 使用 gen_ai.tool.name;blocked_on_user 和 hook 并非同类 GenAI Tool span,仍保留 tool.name。迁移仪表盘时按 span 类型调整字段,不做全局字符串替换。