feat(langchain): add CAUSED_BY_GENERATION span links for tool call attribution#4352
Open
grvnmttl wants to merge 1 commit into
Open
feat(langchain): add CAUSED_BY_GENERATION span links for tool call attribution#4352grvnmttl wants to merge 1 commit into
grvnmttl wants to merge 1 commit into
Conversation
Extend TraceloopCallbackHandler to record which LLM generation triggered
each tool invocation using OTel span links with a structured link_type
attribute. On on_llm_end the handler saves the generation SpanContext and
maps each structured tool_call_id to the LLM run id; on on_tool_start it
looks up the saved context by tool_call_id (or parent run id fallback) and
attaches a Link(gen_ctx, attributes={gen_ai.attribution.link_type:
CAUSED_BY_GENERATION}) to the tool span.
Changes:
- Import Link from opentelemetry.trace
- Add _generation_contexts and _tool_call_id_to_generation state dicts
- Thread optional links: List through _create_span and _create_task_span
- Capture SpanContext + map tool_call_ids in on_llm_end before ending span
- Build attribution link in on_tool_start and pass to _create_task_span
- Add test_attribution_links.py with two unit tests (2 passed)
|
|
|
Caution Review failedAn error occurred during the review process. Please try again later. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The parent-child span hierarchy records when a tool was called but not which LLM generation requested it. In a multi-turn ReAct loop, an
invoke_agentspan can contain many interleaved LLM calls and tool executions; the parent-child tree alone cannot distinguish whether a tool was triggered by the first or third generation.This PR extends
TraceloopCallbackHandlerto attach a typed OTel span link from eachexecute_toolspan back to thechatspan whose completion contained the tool-call invocation.Changes
callback_handler.pyLinkfromopentelemetry.trace_generation_contexts: dict[str, SpanContext]and_tool_call_id_to_generation: dict[str, str]to__init__links: List[Link]parameter through_create_spanand_create_task_spaninto all threetracer.start_span()call siteson_llm_end: save the generationSpanContextand map each structuredtool_call_idto the LLM run ID before ending the spanon_tool_start: look up the generation context bytool_call_id(withparent_run_idfallback), then create:tests/test_attribution_links.py(new file)Two unit tests exercising the handler directly (no VCR / real API calls):
test_caused_by_generation_link_structured_tool_call— verifies the link is created and points to the correct LLM spantest_no_attribution_link_without_tool_call_id— verifies no spurious links appear when no LLM predecessor existsResulting trace structure
The link makes provenance explicit and queryable in backends (Jaeger, Tempo) without requiring parent-child restructuring.
Relation to OTel GenAI SIG
The
gen_ai.attribution.link_typeattribute is proposed to the OTel GenAI SIG in a companion PR to open-telemetry/semantic-conventions-genai, addressing the open question in issue #311.Test plan
pytest tests/test_attribution_links.py -v— 2 passedlinks=Nonedefault preserves existing behavior)links=[]which is a no-op totracer.start_span