The problem it solves

In the LangChain course, an agent's output is fundamentally a string. If you wanted structured data back, you parsed the string yourself, or reached for with_structured_output and hoped the model cooperated. Pydantic AI starts from the opposite direction: you declare the shape of the output you want as a Pydantic BaseModel, and the framework guarantees you either get a validated instance of that model back, or an error you can handle, never a string you have to hope is JSON.

This isn't a competing "better LangChain." It's a narrower, more opinionated framework built by the Pydantic team, the validation library nearly every Python AI framework, including LangChain, already depends on, specifically for the case where an agent's inputs and outputs need to be type-safe: validated, IDE-autocompletable, and caught by your type checker before they ever reach the model.

The core idea: types in, types out

An Agent in Pydantic AI is generic over two things. deps_type is the type of runtime context or dependencies the agent and its tools can read: a database connection, a user ID, an API client. This is dependency injection, not a global. output_type is the type the agent's final answer must validate against. The default is str, but it can be any Pydantic model, dataclass, TypedDict, or union of those.

Everything else in this course, tools, streaming, multi-agent delegation, MCP, sits on top of that one idea: an agent is a function from validated input to validated output, where the LLM fills in the reasoning in between.

How this maps onto LangChain concepts

Nothing here is a brand-new idea, just a stricter shape for ideas you already know from the langchain course. @tool and bind_tools become @agent.tool (Lessons 6-7). with_structured_output becomes output_type= (Lesson 3). Closures for shared state become RunContext[Deps].deps (Lesson 5). LangGraph multi-agent graphs become agent-as-tool delegation (Lesson 12). LangSmith datasets and evaluators become pydantic_evals (Lesson 15). LangSmith tracing becomes OpenTelemetry via Logfire (Lesson 18). And langchain-mcp-adapters becomes MCPToolset (Lesson 21).

There's no agent yet in this lesson, just the vocabulary fixed in your head before Lesson 2 runs a real one:

CORE_IDEA = (
"An Agent is generic over deps_type (what it can read at runtime) "
"and output_type (what its final answer must validate against)."
)
LANGCHAIN_MAPPING = {
"@tool / bind_tools": "@agent.tool (Lessons 6-7)",
"with_structured_output": "output_type= (Lesson 3)",
"closures for shared state": "RunContext[Deps].deps (Lesson 5)",
"LangGraph multi-agent graphs": "agent-as-tool delegation (Lesson 12)",
"LangSmith datasets/evaluators": "pydantic_evals (Lesson 15)",
"LangSmith tracing": "OpenTelemetry / Logfire (Lesson 18)",
"langchain-mcp-adapters": "MCPToolset (Lesson 21)",
}

Checkpoint

  • Pydantic AI agents are generic over deps_type (what they can read) and output_type (what they must return).
  • The default output_type is str; anything else is validated before you ever see it.
  • Every concept in this course has a direct LangChain, LangGraph, LangSmith, or MCP counterpart, just enforced by types instead of convention.

If anything here still feels unclear, ask before moving to Lesson 2, where we run a real agent.