-
Notifications
You must be signed in to change notification settings - Fork 324
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
Add result_type
to run
methods
#565
base: main
Are you sure you want to change the base?
Conversation
a7976b2
to
e9bdb04
Compare
bedb980
to
733750b
Compare
Examplefrom pydantic import BaseModel
from pydantic_ai import Agent
class City(BaseModel):
name: str
class Country(BaseModel):
name: str
class Community(BaseModel):
name: str
agent = Agent(
model='openai:gpt-4o',
system_prompt='You are a tour guide assistant.',
result_type=list[City | Country | Community],
)
result = agent.run_sync(
user_prompt='Provide me the best communities to hang out.',
result_type=list[Community],
)
result = agent.run_sync(
user_prompt='Provide me the best countries to visit.',
result_type=list[Country],
)
result = agent.run_sync(
user_prompt='I have no idea about what should I visit this winter, give me some ideas.. countries, cities, communities',
# It will use the `result_type` defined in the agent
) |
result_type
to run
methods
_default_result_schema: _result.ResultSchema[ResultData] | None = field(repr=False) | ||
_current_result_schema: _result.ResultSchema[ResultData] | None = field(repr=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ha, this would break a lot of cases since agents can be run concurrently, they need to be static.
You'll need to pass the result_schema
around everywhere you need to use it.
I suspect a better approach would be to move all the run logic from Agent
into a new AgentRun
(data)class, to avoid argument overload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a good idea structurally to implement sooner rather than later
Actually, the correct way to do this is to add the |
system_prompt: str | Sequence[str] = (), | ||
deps_type: type[AgentDeps] = NoneType, | ||
name: str | None = None, | ||
model_settings: ModelSettings | None = None, | ||
retries: int = 1, | ||
result_type: type[ResultData] = str, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs a different TypeVar (+overloads)? Its not the same type as Agent´s generic TResult, its basically a type override.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #564 (comment)
733750b
to
874d4ba
Compare
After having played around with it for while, I would strongly suggest to drop the generic return type for the Agent itself completely. I think having the typing for return type stricly "call-based" is the favourable approach, mixed approaches lead to weird ambiguities. |
Quality Gate failedFailed conditions See analysis details on SonarQube Cloud Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE |
In case you have chance, take over this feature. ;) |
No, sorry, I didnt mean to intervene, but Just tryin to provide some input since I ran into the same initial issues you had. I now solved it by getting rid of TResult for the "main" Agent and then introducing a second StructuredAgent. class StructuredAgent[TDeps, TResult]:
"""Wrapper for Agent that enforces a specific result type.
"""
def __init__(
self,
agent: Agent[TDeps],
result_type: type[TResult],
final_tool_name: str = "final_result",
final_tool_description: str | None = None,
): That allows to have a "flexible" Agent as well as a fixed "structured" agent. |
Fix: #564