Skip to content

Publish usage, run id and model name from LLMOperator's subclasses - #75208

Merged
pierrejeambrun merged 7 commits into
apache:mainfrom
astronomer:llm-subclasses-run-telemetry
Oct 29, 2026
Merged

pierrejeambrun merged 7 commits into
apache:mainfrom
astronomer:llm-subclasses-run-telemetry

Conversation

@pierrejeambrun

@pierrejeambrun pierrejeambrun commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

#74272 and #74355 made LLMOperator publish its model name, usage and run_id on XCom and stamp the task-instance identity on its GenAI spans. #74334 added the AI Model tab that reads those XComs. LLMBranchOperator, LLMSQLQueryOperator, LLMSchemaCompareOperator and LLMFileAnalysisOperator got none of this, because they override execute() without calling super().execute(). You couldn't see what a branch or SQL-generation task cost, or which model answered, without reading its logs. This was left as follow-up work in those PRs.

Calling super().execute() from the subclasses would not work. LLMOperator.execute() also writes the generic decision record and applies the confidence gate, the on_uncertain policy and its own review body. LLMBranchOperator replaces all of that with its own decision record. The SQL, schema-compare and file-analysis operators don't use any of it. Copying the reporting block into four overrides would mean four copies of the failure path and its guards to keep in sync.

So the reporting now happens in _run_llm, which every one of these execute() methods already calls to run the agent. The four subclasses report the same metadata as LLMOperator without changing their own code, and so would any future subclass. The AI Model tab is now scoped to the four operators and their @task.llm_* decorators too. LLMBatchOperator is not an LLMOperator subclass and is unchanged.

The changes to existing subclass tests are mechanical. The agent mocks now allow instrument, since identity stamping runs. The run_sync call assertions now include the usage (and, where a task instance is present, run_id) the run is called with.

I ran each operator and its @task.llm_* decorator against a real model in a local Airflow. Every task pushed usage, run_id and the model name, and its AI Model tab shows them:

Operator Decorator
LLMBranchOperator (covered by the decorator run)
LLMSQLQueryOperator
LLMSchemaCompareOperator
LLMFileAnalysisOperator

related: #74272, #74334, #74355


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5.5)

Generated-by: Claude Code (Opus 5.5) following the guidelines

@pierrejeambrun
pierrejeambrun marked this pull request as ready for review October 20, 2026 14:21
pierrejeambrun added a commit to astronomer/airflow that referenced this pull request Oct 20, 2026
pierrejeambrun added a commit to astronomer/airflow that referenced this pull request Oct 20, 2026
@pierrejeambrun
pierrejeambrun force-pushed the llm-subclasses-run-telemetry branch from 43ab8a6 to 8579d01 Compare October 28, 2026 11:37
LLMBranchOperator, LLMSQLQueryOperator, LLMSchemaCompareOperator and
LLMFileAnalysisOperator override execute() without calling
super().execute(), so they never pushed the usage, run_id and model name
XComs, never stamped the task-instance identity on their GenAI spans,
and had no AI Model tab. Calling super() is not an option: it would also
apply LLMOperator's decision record, confidence gate and review body,
which these operators replace or don't have. The reporting now lives in
_run_llm, the one place every execute() runs the agent, so the
subclasses, and any future one, report the same metadata as LLMOperator.
The Scope bullet read as if agents traced through agent_framework_tracing
were excluded from everything, when they still get the airflow.* identity
attributes and only miss the XComs.
Both methods were named after running, which hid that _run_llm is the
entry point every execute() calls and the other one only runs the agent
under the usage budget.
The subclass tests passed even when _run_llm forwarded no run id or skipped the
identity stamp, and the AI Model tab's operator list could miss a new LLMOperator
subclass unnoticed. The tests now fail in each of those cases.
The SQL, branch, file-analysis and schema-compare pages stopped at the log
summary, so a reader of those pages could not tell the operators also push
usage, run_id and the model name. The XCom tests used an unspecced task
instance, so any attribute the identity stamping read would silently pass.
@pierrejeambrun
pierrejeambrun force-pushed the llm-subclasses-run-telemetry branch from 8579d01 to 37e7402 Compare October 28, 2026 12:06
The anchor sits inside a bullet rather than before a section, so Sphinx has no title to use for a bare reference to it.
… anchor

Every other operator page, llm.rst included, points at the observability page as a whole; an anchor inside a bullet was a one-off pattern.
@pierrejeambrun
pierrejeambrun merged commit 226de8a into apache:main Oct 29, 2026
75 of 76 checks passed
@pierrejeambrun
pierrejeambrun deleted the llm-subclasses-run-telemetry branch October 29, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants