Pydantic AI, LangGraph and the OpenAI Agents SDK compared for Python teams shipping agents to production, plus how Encore adds the database, queues and cloud resources an agent backend needs.
Agent frameworks in Python handle the model loop, tool calls and structured output, and the choice between them is mostly about how much control you want over each step. Running an agent in production needs more than the loop, since conversations have to be stored, long tasks have to survive a restart, and the model API keys have to live somewhere other than the repository.
Developers are also cautious about the output, with 46 percent of respondents to the 2025 Stack Overflow Developer Survey saying they distrust the accuracy of AI tools against 33 percent who trust it, which is one reason agent backends tend to keep a full record of each run.
What to weigh when choosing:
Pydantic AIPydantic AI comes from the Pydantic team and treats an agent as a typed object with tools declared as Python functions and outputs validated as Pydantic models.
Pydantic AI keeps orchestration light, so complex branching flows are written as ordinary Python or with its graph module, and state between requests is yours to store.
LangGraphLangGraph models an agent as a graph of nodes with shared state, and checkpointers persist that state so a run can pause for human input and resume.
The graph model adds concepts to learn, and the checkpoint store is another database you run in each environment.
OpenAI Agents SDKThe OpenAI Agents SDK provides agents, tools, handoffs between agents and guardrails, with tracing of each run.
The SDK is designed around OpenAI's APIs first, and its default tracing goes to OpenAI's dashboard, which matters if your data must stay in your own systems.
Encore combines the FastAPI or Django app that serves the agent with its infrastructure through an infrastructure SDK you install into the app, so the agent framework keeps the model loop while the service declares a Postgres database for runs and a Pub/Sub topic for work that takes longer than a request. encore run starts Postgres locally along with the topic, and a deploy provisions both in your own AWS or GCP account. Whichever option above you pick, Encore can add the database, topics and secrets to the same app.
The endpoint records a run and hands it to a background subscription that calls a Pydantic AI agent:
from contextlib import asynccontextmanager
import encore
from encore import pubsub
from encore.storage import postgres
from fastapi import FastAPI
from pydantic import BaseModel
from pydantic_ai import Agent
db = postgres.Database("agent", migrations="./migrations")
class RunRequested(BaseModel):
run_id: int
prompt: str
runs = pubsub.Topic[RunRequested]("agent-runs")
agent = Agent("openai:gpt-4o", instructions="Answer support questions briefly.")
async def execute(message: pubsub.Message) -> None:
result = await agent.run(message.data.prompt)
await db.exec(
"UPDATE runs SET output = $1, done = true WHERE id = $2",
result.output,
message.data.run_id,
)
worker = pubsub.Subscription[RunRequested](
runs, "execute-run", handler=execute, max_retries=3
)
@asynccontextmanager
async def lifespan(app: FastAPI):
await encore.start()
yield
app = FastAPI(lifespan=lifespan)
@app.post("/runs", status_code=202)
async def create_run(prompt: str) -> dict:
row = await db.query(
"INSERT INTO runs (prompt) VALUES ($1) RETURNING id", prompt
).one()
await runs.publish(RunRequested(run_id=row["id"], prompt=prompt))
return {"run_id": row["id"]}
@app.get("/runs/{run_id}")
async def get_run(run_id: int) -> dict:
row = await db.query("SELECT output, done FROM runs WHERE id = $1", run_id).one()
return {"output": row["output"], "done": row["done"]}
Encore does not call models or define tools, so the framework comparison below still decides how the agent itself is written. Agent output still needs review, and OpenTelemetry now defines semantic conventions for generative AI so model calls can be recorded in a standard shape, which makes the stored record of each run worth keeping. Cloud resources are created by Encore at deploy time, and the cloud access sits with Encore's IAM role, not the agent. Python support is in beta, and you can sign up for access.
Anthropic's guide to building effective agents reports that the most successful implementations used "simple, composable patterns" rather than complex frameworks, which favors starting small.
For more on giving agents access to tools safely, see Encore's AI integration docs. Python support in Encore is in beta, and you can sign up for access.
Pydantic AI suits teams that want typed tool calls and structured output with little abstraction, LangGraph suits agents modeled as stateful graphs with checkpoints and human approval steps, and the OpenAI Agents SDK suits teams that want handoffs between agents with tracing built in. Encore is not an agent framework but an infrastructure SDK you add to the web framework that serves the agent, such as FastAPI, for its database, queues and secrets.
Not always. Many production agents are a loop around a model API with a few tools. A framework helps once you need typed tool schemas, retries, persistence between steps or several cooperating agents.
Publish a message to an Encore Pub/Sub topic from the endpoint that receives the request, and run the agent in the subscription handler. The handler stores the result in the Postgres database the service declares, and the client polls or receives the result when it is ready.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.