Description
I've been trying to understand the control flow for agent runs, which I think others are also trying to learn about. Here are some of the related issues for context:
It would be very helpful for someone with deep knowledge of the library to create a documentation section for control flow within agents. These are some examples of what I want to understand:
- inside
agent.run()
what is executed sequential v.s. concurrently (post to LLM provider, tool calls, result validation, etc.)? - are there points where coroutines within
agent.run()
can be cancelled? - at what points will control be given back to the caller of
agent.run()
? - which of these points are considered "success" cases and which ones "error" cases?
I'm trying to write a user application, where the agent might be sending data back to the user while it's running (see example below), so it's really helpful to be crystal clear on what's happening inside the agent.
import dataclasses
from fastapi import WebSocket
from pydantic_ai import Agent, RunContext
@dataclasses.dataclass
class AgentDeps:
websocket: WebSocket
agent = Agent(
"openai:gpt-4o",
)
@agent.tool
async def do_something(ctx: RunContext[AgentDeps], message: str) -> None:
"""Do the thing.
Args:
ctx: The call context.
message: The info from my llm.
"""
await ctx.deps.websocket.send(f"The llm sent me this: {message}")
print("Agent did the thing.")
async def run_context(websocket: WebSocket, user_message: str):
# Doing something before running the agent
print("Doing something before...")
# Blocks while agent is running
await agent.run(user_prompt=user_message, deps=AgentDeps(websocket=websocket))
# Doing something after running the agent
print("Doing something after...")
I've also seen some examples thrown around where agent-runs are initiated in tools. The documentation would also help us reason about how that pattern would be executed under the hood.