The article details the implementation of cost and token observability for LangChain applications using Arize Phoenix and OpenTelemetry, focusing on distinguishing between LLM tool calls, tool execution, and final responses to avoid collapsing metrics.
I’m implementing cost and token observability for a Python/LangChain application using Arize Phoenix + OpenTelemetry. The main goal is to clearly distinguish between these four things: - LLM tool-call generation → input/output tokens + cost - Tool execution → tool name, arguments, latency, output, output size/tokens, provider cost (if available) - Tool output consumption → tokens added to the next LLM request + corresponding input cost - Final LLM response → output tokens + cost For example: LLM #1 ├─ input: 156 tokens ├─ output/tool-call: 17 tokens └─ cost: $0.0000896 ↓ Tool ├─ output: 850 tokens (estimated) ├─ latency: 3.49s └─ provider cost: if available ↓ LLM #2 ├─ input: 1478 tokens ├─ output: 101 tokens └─ cost: $0.0007528 The 850 tool-output tokens must NOT be treated as LLM output tokens. They should be measured separately, while the actual 1478 tokens sent to LLM #2 should come from the provider's usage data. Implementation requirements I’m planning to use a custom LangChain "BaseCallbackHandler" with: on_llm_start / on_llm_end on_chat_model_start / on_chat_model_end on_tool_start / on_tool_end Each tool should have a unique "tool.call.id" so the trace can correlate: LLM → Tool → Tool Output → Next LLM Phoenix should expose attributes such as: llm.model llm.token_count.prompt llm.token_count.completion llm.cost.input llm.cost.output llm.cost.total tool.name tool.call.id tool.arguments tool.output tool.output.token_count tool.output.size_bytes tool.execution.duration_ms tool.cost I also need: - Centralized, configurable model pricing - Exact vs estimated tool-output token counts - "unavailable" status when token usage/pricing isn't provided - Configurable masking of sensitive tool arguments/outputs - Tracing failures must never break the actual agent/tool execution - Parent/child span correlation in Phoenix The key requirement: never collapse tool-call tokens, tool-output tokens, LLM input tokens, and tool-provider costs into a single metric. Has anyone implemented something similar with LangChain + Arize Phoenix? I’d especially appreciate examples or recommendations for the best way to correlate the tool span with both the LLM that generated the call and the subsequent LLM that consumed the tool output.
TraceSage is a new MIT-licensed, local-first observability tool for LangChain and LangGraph that runs entirely on your machine, providing live topology graphs, step-by-step replay, token tracking, and OpenTelemetry export without sending data to the cloud.
LangChain released a tracing plugin for Codex sessions in LangSmith, enabling detailed traces of every turn including tool calls and token usage, configurable with just two blocks and a flag.
A study by LangChain and Harvey explores methods to reduce the cost of verifying legal agent outputs by batching criteria evaluations and using open models, achieving order-of-magnitude cost savings while maintaining near-frontier performance.