feat(token-tracking): accumulate token usage across session_async calls
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -193,6 +193,7 @@ class SessionScoreJobManager:
|
||||
|
||||
# Lazy imports — keep web server bootable if ragas is not installed.
|
||||
from rag_eval.advisor import run_advisor
|
||||
from rag_eval.metrics.token_tracker import track_token_usage
|
||||
from rag_eval.metrics.weights import compute_weighted_score
|
||||
from rag_eval.reporting.writers import write_run_artifacts
|
||||
from rag_eval.settings import EvaluationSettings
|
||||
@@ -215,20 +216,21 @@ class SessionScoreJobManager:
|
||||
|
||||
try:
|
||||
# --- Scoring (can run concurrently for the same session) ----------
|
||||
if effective:
|
||||
raw_scores = inline_scorer.score(
|
||||
question=request.question,
|
||||
answer=request.answer,
|
||||
contexts=request.contexts_as_list(),
|
||||
ground_truth=request.ground_truth,
|
||||
metrics=effective,
|
||||
judge_model=judge_model,
|
||||
embedding_model=embedding_model,
|
||||
settings=settings,
|
||||
judge_language=judge_language,
|
||||
)
|
||||
else:
|
||||
raw_scores = {}
|
||||
with track_token_usage() as usage_tracker:
|
||||
if effective:
|
||||
raw_scores = inline_scorer.score(
|
||||
question=request.question,
|
||||
answer=request.answer,
|
||||
contexts=request.contexts_as_list(),
|
||||
ground_truth=request.ground_truth,
|
||||
metrics=effective,
|
||||
judge_model=judge_model,
|
||||
embedding_model=embedding_model,
|
||||
settings=settings,
|
||||
judge_language=judge_language,
|
||||
)
|
||||
else:
|
||||
raw_scores = {}
|
||||
|
||||
latency_ms = int((time.monotonic() - t0) * 1000)
|
||||
finished_at = utc_now_iso()
|
||||
@@ -250,6 +252,14 @@ class SessionScoreJobManager:
|
||||
run_dir = self._output_dir / run_id
|
||||
run_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Merge this call's token usage into the session's running total, so
|
||||
# repeated calls accumulate instead of overwriting (mirrors the
|
||||
# scores.csv append-only accumulation below).
|
||||
existing_metadata = self._read_metadata(run_dir)
|
||||
merged_token_usage = usage_tracker.merge_into(
|
||||
existing_metadata.get("token_usage", {})
|
||||
)
|
||||
|
||||
# Read all existing rows, then append the new one
|
||||
existing_rows = self._read_score_rows(run_dir)
|
||||
call_number = len(existing_rows) + 1
|
||||
@@ -312,6 +322,7 @@ class SessionScoreJobManager:
|
||||
valid_samples=valid_samples,
|
||||
invalid_samples=[],
|
||||
score_rows=all_rows,
|
||||
token_usage=merged_token_usage,
|
||||
)
|
||||
|
||||
write_run_artifacts(result)
|
||||
@@ -376,6 +387,16 @@ class SessionScoreJobManager:
|
||||
except (OSError, ValueError):
|
||||
return []
|
||||
|
||||
def _read_metadata(self, run_dir: Path) -> dict[str, Any]:
|
||||
"""Read this session's existing metadata.json, returning {} if absent/unreadable."""
|
||||
metadata_path = run_dir / "metadata.json"
|
||||
if not metadata_path.is_file():
|
||||
return {}
|
||||
try:
|
||||
return json.loads(metadata_path.read_text(encoding="utf-8"))
|
||||
except (OSError, ValueError):
|
||||
return {}
|
||||
|
||||
def _read_metric_means(self, run_dir: Path) -> dict[str, float | None]:
|
||||
"""Compute per-metric means from the session's scores.csv."""
|
||||
scores_path = run_dir / "scores.csv"
|
||||
|
||||
Reference in New Issue
Block a user