-
Notifications
You must be signed in to change notification settings - Fork 876
Notes on structured output strategies #1615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
First of all, thanks for this effort! Few comments partially related to the above @dmontagu , I have serious concerns about the If Currently all our code is making one final (accumulatively-expensive) call to wrap-up and duplicate. [https://github.com//issues/127]
I assume the behavior of the line above should be different, and it should allow matching tool result type against output_type. Maybe not for Alternatively, exposing the agent graph and allowing to manually iterate nodes would be very useful. This is currently not possible and makes building custom solutions around the pydantic_ai Agent very hard. In the following example, the class Response(BaseModel):
response: str
my_agent = Agent(
model="openai:gpt-4o",
instrument=True,
output_type=Response,
system_prompt="Make the operation the user wants",
model_settings={"temperature": 0.0},
)
@my_agent.tool_plain
async def sum_numbers(args: Foo) -> Response:
result = args.num1 + args.num2
# Already provides the result in the final output type
return Response(response="The sum is: " + str(result)) |
@nzlzcat Have you seen https://ai.pydantic.dev/agents/#iterating-over-an-agents-graph?
With the callable |
Hadn't seen that particular option, thanks!
Waiting for changes at #1628 . What is the reasoning behind solving it via
Do these 2 "types" have, or will have different decorators? Or that is supposed to be handled via StructuredOutput? Will |
@nzlzcat Behind the scenes, we currently use the model's tool call functionality to enable it to return JSON matching some type (or to be more precise, the type's JSON schema) by calling a special output tool named Which output mode is used is not tied to whether your output type is a model or a function, in both cases the model will just generate JSON that's pared out by PydanticAI and passed to the model constructor or the custom function. So in your scenario, There will be no new way of defining tools, as this is more about a new type of output (call a function) rather than a new thing the model can do during its run. |
@DouweM is looking into this and asked me to write up some notes on the requirements our approach to supporting different output strategies will need to satisfy:
output_type
accept unions directly (i.e., something likeAgent(..., output_type=A | B)
.output_type=Annotated[A, ...]
.TypeValue
and dooutput_type=TypeValue[A | Annotated[B, ...]]
or similar. But this is kind of ugly and becomes unnecessary if/when PEP-747 is supported by type-checkers, so 🤷♂ probably not worth it.ToolOutput
needs to support callables. (I already have an open draft PR for this, but it needs to be finished.)ToolOutput
(forX
=Tool
, etc.) as a way to more explicitly control precisely what outputs the model can produce. In particular, this gives a way to useToolOutput(type_=str)
alongside other tool outputs, and a way to set the tool name for each. It also gives a way to use ananyOf
JSON schema as the parameters schema for a tool call. (Some/most models may not support this today, but there's nothing wrong with it in principle.)ResponseFormatOutput
orContentOutput
strategies (or whatever we choose to call them) since there isn't a good mechanism to specify which one is being used. But I'd be open to it if we did come up with such a mechanism. (At least for content output, it's more obvious how this could be done, but I'm not sure it's necessary.)Eventually, I think we need a better native agent handoff, which is in many ways like a callable ToolOutput where the call is the relevant
agent.run
method. Maybe allowing an agent as an output strategy is enough, I'm not sure. (Maybe it requires some care to get multi-agent streaming to work nicely across handoffs.) But I wouldn't get too caught up on this now unless it's obvious how it could/should work.The text was updated successfully, but these errors were encountered: