-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Description
Title: Feature Request: Support for Nested Multi-Turn Agent Conversations
Description:
Thank you for the excellent work on Pydantic AI! It's proving very useful.
I'm building an application with a primary "orchestrator" agent (like a general assistant) that needs to delegate complex sub-tasks to more specialized agents (e.g., a web search agent, a code generation agent, etc.).
Currently, the @tool mechanism works well for single request/response interactions. However, my use case requires richer delegation where the primary agent might need to have a multi-turn conversation with the delegate agent to refine the request, clarify details, or process intermediate results before returning a final consolidated response to the end-user.
Proposed Functionality:
I envision a mechanism where a primary agent can initiate a "nested" or "sub" agent run with a delegate agent. This would function conceptually like this:
- Initiation: The primary agent, within its
agent.iter()loop, identifies the need for delegation and calls a special function/tool that initiates a nested run with a specified delegate agent (e.g.,ask_agent). It passes the initial query/context. - Nested Conversation: A separate, temporary conversational context is established between the primary agent (or a proxy representing its objective for this sub-task) and the delegate agent. They can exchange multiple messages (
ModelRequest/ModelResponse) within this nested context. - Termination: The nested conversation concludes based on defined criteria (e.g., the delegate provides a final answer, a maximum turn limit is reached, or the primary agent proxy determines the goal is met).
- Result (Transcript): The key outcome is that the entire message history (list of
ModelMessageobjects) from this nested conversation is captured. - Return to Primary: This captured transcript is returned as the result of the initial delegation call back to the primary agent's main
agent.iter()loop. - Primary Context Update: The primary agent receives this transcript. Its prompt would guide it on how to process this transcript (e.g., summarize it, extract key information) and incorporate it into its main conversation history with the end-user. The primary agent then continues its interaction with the user, now informed by the detailed sub-conversation.
Use Case Example:
- User asks Primary Agent: "Research the pros and cons of using Pydantic V2 vs V1 for a new project, and summarize the key migration steps."
- Primary Agent -> Initiates Nested Run with
research_agent. research_agent-> "Okay, searching for Pydantic V2 vs V1 comparisons..."research_agent-> "Found sources A, B, C. Source A focuses on performance, B on validation changes, C on tooling. Which area is most critical?"- Primary Agent (Proxy) -> "Focus on validation changes and performance first."
research_agent-> "Okay, V2 offers significant performance improvements via Rust core... Validation requires X, Y, Z changes..." (continues until info gathered)research_agent-> "Here is the full comparison and migration summary..."- Nested Run Ends -> Transcript returned to Primary Agent.
- Primary Agent -> Processes transcript -> "Okay, I researched Pydantic V1 vs V2. The key benefits of V2 are performance... The main migration steps involve..." (summarizes for the user).
Benefits:
- Allows for more complex and robust delegation patterns.
- Provides better context preservation for the primary agent.
- Enables UI possibilities where the nested conversation transcript could be optionally displayed to the user (e.g., in an expandable section).
- Keeps the logic for the sub-task contained within the interaction between the relevant agents.
Possible Implementation Approach (Suggestion):
This seems non-trivial with the current primitives. Some ideas:
- Could
agent.iter()support being called recursively or in a nested fashion? - Perhaps a new type of node within the agent graph (
NestedAgentRunNode?) could manage the lifecycle of the sub-run. - How would the message history and
RunContextbe managed and isolated between the outer and inner runs? The inner run needs context from the outer, but the outer run should only receive the final transcript as a result. - The result mechanism would need to support returning a
List[ModelMessage](the transcript) from the tool/node execution.
Questions:
- Does this concept align with the vision for Pydantic AI's multi-agent capabilities?
- Is there any existing or planned functionality that addresses this type of nested, multi-turn agent interaction?
- If this is a desirable feature and not currently on the roadmap, I would be interested in discussing it further and potentially attempting an implementation in a separate branch.
Thank you for considering this feature request!
References
No response