Skip to content

Usage Recording

Per-model token-usage recording for the adapter wrappers.

The three adapter wrappers (DeepEvalLLMWrapper, RagasLLMWrapper, LangChainLLMWrapper) are the only frames that hold both the invoker that served a call and the LMOutput it produced. Recording usage there keeps each response's tokens attributed to the model that actually billed them, without a proxy layer reconstructing that association after the fact.

UsageRecordingMixin

Accumulates per-model token usage across an adapter's invoker chain.

Mix into an LMComponent subclass only -- _record_usage uses self._logger, which LMComponent provides and this mixin does not.

take_usage drains: it returns the accumulated usage and clears it, so a second read in the same row sees None. Read-once by design -- the metric drains exactly once per row, at the point it builds the row's result.

Every method below reads/writes through _bucket() rather than _usages directly, so a caller running inside row_scope() -- currently only RAGAS's concurrent batch path -- transparently gets a row-local accumulator instead of the wrapper's shared one, with no change to _record_usage/take_usage/ reset_usage call sites.

reset_usage()

Discard anything accumulated in the active bucket and start a fresh row.

Public counterpart to take_usage(): both are part of the contract a metric drives from the outside, unlike _record_usage/_init_usage which only the wrapper itself calls.

row_scope() staticmethod

Open a context-local usage bucket for the duration of one row.

Isolates concurrent asyncio.gather() siblings that share one wrapper instance -- RAGAS's batch path is the only current caller. Every _record_usage/take_usage/reset_usage call made by this row while inside the with block goes to a fresh, task-local dict instead of the wrapper's shared _usages, so a sibling row draining concurrently cannot observe or clear it.

Yields:

Type Description
None

None

take_usage()

Drain and return usage keyed by model_id, or None if nothing was recorded.

Warns once, at drain time, when calls were attempted this row but none of them produced usage -- the only point that can tell that apart from a row that made no LLM calls at all, which is also None here.