Skip to content

Conversation

dmontagu
Copy link
Contributor

@dmontagu dmontagu commented Oct 9, 2025

This does the following:

  • Always records (potentially-)dynamic instructions on the agent run span, using the value from the last message
  • In the event that there is another "new" message (i.e., one from the current run of the agent) with different instructions, we set a new attribute on the agent run span pydantic_ai.variable_instructions to True as a way to have a signal in a UI like Logfire that the agent run made use of different instructions in different steps.

Closes #2884

Copy link

github-actions bot commented Oct 9, 2025

Docs Preview

commit: 84361ab
Preview URL: https://8968c6a9-pydantic-ai-previews.pydantic.workers.dev

DouweM
DouweM previously requested changes Oct 10, 2025
def _run_span_end_attributes(
self, state: _agent_graph.GraphAgentState, usage: _usage.RunUsage, settings: InstrumentationSettings
self,
state: _agent_graph.GraphAgentState,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only use state.message_history, lets send in just that, so that the compatibility between that list and new_message_index are clear.


# Store an attribute that indicates that the instructions from this agent run were not always the same
# This can signal to an observability UI that different steps in the agent run had different instructions
# Note: We purposely only look at "new" messages because they are the only ones produced by this agent run.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also store the new_message_index so that the UI can show which messages are from older agent runs? Similar to how I think we should show the ModelResponse.model_name if it's not the same between different messages

Comment on lines 723 to 729
for m in state.message_history[new_message_index:]:
if (
isinstance(m, _messages.ModelRequest)
and m.instructions is not None
and m.instructions != last_instructions
):
attrs['pydantic_ai.variable_instructions'] = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this into an any()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this suggestion

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmontagu attrs['pydantic_ai.variable_instructions'] = any(isinstance(m, _messages.ModelRequest) and m.instructions is not None and m.instructions != last_instructions for m in state.message_history[new_message_index:])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, sure

@dmontagu dmontagu force-pushed the dmontagu/record-instructions-on-agent-run-span branch from bbd4409 to 84361ab Compare October 13, 2025 19:23
@dmontagu dmontagu merged commit 2631d9b into main Oct 13, 2025
30 checks passed
@dmontagu dmontagu deleted the dmontagu/record-instructions-on-agent-run-span branch October 13, 2025 19:36
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.

Show system instructions for pydantic-ai LLM panel

2 participants