
bug: session/trace cost mis-aggregates for multi-agent runs traced via the OpenInference Claude Agent SDK instrumentor
快速结论:使用 OpenInference ClaudeAgentSDKInstrumentor 将多 Agent Claude Agent SDK 调用链路导入 Langfuse 时,Session 和 Trace 级别的费用/Token 聚合结果不可靠。优先排查 Session 总费用是否为 $0.00 或与 Trace 总费用不一致,检查父 Agent Span 上的 llm.cost.total 属性是否被 Langfuse 正确解析。
问题场景
用户在 Langfuse 4.x 版本中,通过 OpenInference Claude Agent SDK 探针(openinference-instrumentation-claude-agent-sdk)将多 Agent 工作流的追踪数据通过 OTel 协议导入 Langfuse。典型场景为:query() 方法调度了至少一个子 Agent(通过 Task 工具),导致顶层 ClaudeAgentSDK.query Span 成为整棵调用树的父 Span。
报错原文
Session totalCost = $0.00, while trace.totalCost reports the correct ~$2.42.
For a small one-subagent run, the partial parent-span cost was counted in the session total.
原因分析
存在三个叠加问题:
- 属性未被识别:Langfuse 的
extractCostDetails()函数仅检查langfuse.observation.cost_details和gen_ai.usage.cost属性,但 OpenInference 约定的llm.cost.total属性未被纳入解析逻辑。尽管 Claude Agent SDK 探针将真实费用写入了顶层 AGENT Span 的llm.cost.total中,Langfuse 仍会丢弃该值,回退至根据不完整的 Token 计数 × 定价表推算费用。 - 费用仅绑定了 GENERATION/EMBEDDING 观察类型:Langfuse 目前只对
GENERATION和EMBEDDING类型的观察对象填充费用字段。顶层ClaudeAgentSDK.querySpan 映射的是AGENT类型,即使llm.cost.total被识别,其费用仍会被忽略,除非 Span 类型被重新分类。 - Session 层面独立求和:Session 的 totalCost 是通过对每个观察对象的
cost_details['total']字段做sumMap计算得来的,而不是从预先计算好的 Trace 总费用汇总。因此,如果 AGENT 观察对象的cost_details为空(由于问题1和2),Session 汇总结果会变为 $0.00,导致 Session 视图与 Trace 视图之间出现差异。
环境排查
- Langfuse 版本(验证是否 >= 4.x,尤其是 4.5.1)
openinference-instrumentation-claude-agent-sdk版本(如 0.1.6)claude-agent-sdk版本(如 0.2.93)opentelemetry-sdk版本(如 1.41.1)- Python 版本(如 3.13)
- 使用的 Langfuse 部署环境(Cloud 或自托管)
解决步骤
- 临时规避方案(可优先尝试):在自定义的 SpanProcessor 中,读取 AGENT Span 上的
llm.cost.total属性,并将其映射为gen_ai.usage.cost(OTel GenAI 语义约定)写入一个类型为 GENERATION 的 Span,或者写入langfuse.observation.cost_details属性(如{"total": 0.52})。Langfuse 会优先采纳后者。 - 等待官方修复:该问题已被确认,最直接的修复方式是修改 Langfuse 核心代码中的
extractCostDetails()函数(位于packages/shared/src/server/otel/OtelIngestionProcessor.ts),增加对llm.cost.total属性的识别作为第三个回退选项。 - 关注 Langfuse 官方路线图:支持在非 GENERATION 类型的观察对象上记录费用是一个更大的架构决策,需要 Langfuse 团队后续处理。
验证方法
重新执行多 Agent 工作流,在 Langfuse 会话列表中检查 Session 级别的 totalCost 是否与 Trace 级别的 totalCost 一致,且均能正确反映调用链路的真实总费用(应与 SDK 报告的 ResultMessage.total_cost_usd 匹配)。



