auto_instrument() creates duplicate LLM spans for Google ADK Gemini calls
I maintainer di solito rispondono entro 1 giorno
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
With braintrust.auto_instrument(), a Google ADK Gemini request produces two nested llm spans with identical token usage: ADK's llm_call [direct_response] and Google GenAI's generate_content.
Reproduction
Install:
pip install braintrust==0.45.0 google-adk==2.11.0 google-genai==2.28.0
Configure BRAINTRUST_API_KEY, BRAINTRUST_PROJECT, and GOOGLE_API_KEY through environment variables. Use a test project: this example makes a Gemini request and uploads its trace to Braintrust.
import asyncio
import os
import braintrust
from google.adk.agents import LlmAgent
from google.adk.runners import InMemoryRunner
from google.genai import types
logger = braintrust.init_logger(project=os.environ["BRAINTRUST_PROJECT"])
braintrust.auto_instrument()
async def main():
agent = LlmAgent(
name="hello",
model="gemini-2.5-flash",
instruction="Reply with one word.",
)
runner = InMemoryRunner(agent=agent, app_name="repro")
session = await runner.session_service.create_session(
app_name="repro", user_id="u"
)
msg = types.Content(
role="user", parts=[types.Part(text="Say hello.")]
)
with braintrust.start_span(name="adk_duplicate_span_repro"):
async for _ in runner.run_async(
user_id="u", session_id=session.id, new_message=msg
):
pass
asyncio.run(main())
logger.flush()
Observations and validation
Originally observed with Braintrust 0.41.0, Google ADK 1.14.1, and Google GenAI 1.75.0.
Also reproduced on October 7, 2026 using the latest stable versions available that day: Braintrust 0.45.0, Google ADK 2.11.0, and Google GenAI 2.28.0, on Python 3.13.12/macOS.
The latest-version test used the real ADK runner, Gemini adapter, GenAI SDK, and Braintrust instrumentation, with only the provider network response mocked. Spans were captured in memory without uploading. It did not verify live Gemini calls or Braintrust dashboard aggregation on these newer versions.
A synthetic response containing 23 prompt tokens and 62 completion tokens produced:
| Instrumentation | Provider requests | LLM spans | Summed prompt tokens | Summed completion tokens |
|---|---|---|---|---|
| Both enabled | 1 | 2 | 46 | 124 |
| ADK only | 1 | 1 | 23 | 62 |
| GenAI only | 1 | 1 | 23 | 62 |
Each configuration ran in a fresh process. Assertions confirmed that both spans carried identical usage and that generate_content was a direct child of llm_call [direct_response]. Dependency validation with pip check passed.
In the original live traces, trace summaries counted both spans and reported duplicated LLM-call and token totals. Exact token values can vary between live runs.
Expected behavior
Each underlying Gemini request should contribute usage and LLM-call count once, while retaining ADK agent/tool tracing and instrumentation of Gemini calls made outside ADK.
Suspected cause
_flow_call_llm_async_wrapper in py/src/braintrust/integrations/adk/tracing.py opens an llm span around BaseLlmFlow._call_llm_async and logs response usage.
The nested Google GenAI generate_content call is separately instrumented as an llm span and logs usage for the same request.
Impact and possible approach
Duplicated usage inflates token totals and can affect cost reporting based on those totals. Disabling ADK instrumentation loses its agent/tool tracing; disabling Google GenAI instrumentation loses automatic tracing of direct Gemini calls outside ADK in the same process.
One possible approach is to suppress the redundant provider span within an ADK model call, or retain it as a non-llm span without duplicated usage. Removing usage alone would leave the duplicate LLM-call count.
Related: #878, fixed by PR #880, concerns a different duplication mechanism involving wrap_openai() and auto_instrument().
- Lingua principale
- Python
- Stelle
- 22
- Fork
- 24
- Merge medio
- 16h
- PR unite (30g)
- 101
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di braintrustdata/braintrust-sdk-python
-
feature python
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
braintrustdata/braintrust-sdk-python#868 ·
I maintainer di solito rispondono entro 1 giorno
-
new-integration python
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
braintrustdata/braintrust-sdk-python#854 ·
I maintainer di solito rispondono entro 1 giorno
-
new-integration python
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
braintrustdata/braintrust-sdk-python#853 ·
I maintainer di solito rispondono entro 1 giorno
-
new-integration python
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
braintrustdata/braintrust-sdk-python#852 ·
I maintainer di solito rispondono entro 1 giorno
-
Migrate legacy HTTPConnection callers to the policy-aware Transport incrementallyForse già presa @AbhiPrasad l’ha presa 11 giorni fa. Apertapython
braintrustdata/braintrust-sdk-python#839 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di braintrustdata/braintrust-sdk-python
Issue simili
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
openwisp/openwisp-utils#777 ·
-
Boolean statistics (Covered, Confident, JaccardDistant) aggregate to 1.0 without float weightsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 63/100
google-research/weatherbenchX#310 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
huggingface/peft#3955 ·
I maintainer di solito rispondono entro 1 giorno
-
author-page correction
Difficoltà 2/5 1-3 ore Idoneità per principianti 60/100
acl-org/acl-anthology#10313 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
AOSSIE-Org/Gitcord-GithubDiscordBot#147 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno