Pi Coding Agent instrumentation double-counts tokens and estimated cost in trace rollups (AgentSession.prompt carries summed LLM usage)

Fermée Adaptée aux débutants
#2,659 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@AbhiPrasad y travaille déjà.

Depuis le 26/10/2026.

  • #2660 par @sharonadhitya — fermée sans fusion
  • #2672 par @AbhiPrasad — fusionnée

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
72/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
typescript
Domaine
observability

Piste de recherche

Commencez par lire js/src/instrumentation/plugins/pi-coding-agent-plugin.ts, en particulier finishPiLlmSpan et finishPiPromptRun, pour voir comment l’usage des spans enfants est ajouté au span du prompt et journalisé. Suivez un prompt avec un appel LLM et comparez son cumul aux métriques du LLM feuille. Le travail est terminé lorsque le cumul de la trace comptabilise une seule fois l’usage et le coût estimé.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Summary

With wrapPiCodingAgentSDK (braintrust 3.39.0, @earendil-works/pi-coding-agent 1.4.0), each AgentSession.prompt task span gets the summed token usage of its child llm spans, and it also carries metadata.model. Braintrust's trace rollups add the parent's metrics to the children's. As a result, the trace summary, the logs table and the trace header report exactly 2× the prompt, completion and cached tokens and 2× estimated_cost for every Pi run.

The instrumentation spec says parent task spans "MAY include aggregate token metrics for display, but SDKs SHOULD avoid making parent rollups look like independent billable LLM calls" (braintrust-spec/skills/instrumentation-spec/references/features/token-and-cost-metrics.md). Here the parent is priced and summed like an LLM call.

Where

js/src/instrumentation/plugins/pi-coding-agent-plugin.ts at [email protected]:

  • finishPiLlmSpan logs the usage on the LLM span and also calls addMetrics(promptState.metrics, usageMetrics) (L703-L707).
  • finishPiPromptRun logs cleanMetrics(state.metrics) on the AgentSession.prompt span, together with extractModelMetadata(...) (L655-L667).

Minimal reproduction

  1. Call braintrust.wrapPiCodingAgentSDK(pi), create an AgentSession with any model, and run one session.prompt(...) that takes at least one LLM turn under initLogger(...).
  2. Run these two project-log queries on that trace:
-- trace rollup
SELECT id, metrics.prompt_tokens, metrics.estimated_cost
FROM project_logs('<project_id>', shape => 'summary') WHERE root_span_id = '<root>'

-- per span, grouped
SELECT span_attributes.name, span_attributes.type, sum(metrics.prompt_tokens) AS pt, sum(metrics.estimated_cost) AS cost
FROM project_logs('<project_id>') WHERE root_span_id = '<root>' AND metrics.prompt_tokens IS NOT NULL
GROUP BY 1, 2

Observed on one trace (gpt-6.1-sol via openai.responses.create, 11 LLM calls):

span type prompt_tokens estimated_cost
openai.responses.create (×11) llm 443,901 0.1708972
AgentSession.prompt task 443,901 0.1708972
summary rollup 887,802 0.3417944

Across 19 consecutive traces, the ratio of summary to leaf-llm sums was 2.000 for both tokens and cost in every trace.

Expected

A trace's rollup equals the sum of its leaf llm spans. Either the prompt span should not carry summed usage (or should carry it under a non-rolled-up name), or it should not be priced or summed as a billable call.

Workaround we use

We sum span_attributes.type = 'llm' AND span_attributes.purpose IS NULL spans and ignore the summary's token and cost metrics.

Langage dominant
TypeScript
Étoiles
29
Forks
22
Merge moyen
1 j 6 h
PR mergées (30 j)
69

Préparer son environnement

  • Fournit un Dockerfile ou un fichier Docker Compose
  • Aucun modèle de pull request
  • Aucun guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de braintrustdata/braintrust-sdk-javascript

Toutes les issues de braintrustdata/braintrust-sdk-javascript

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.