InfoWok
⌘K
Beginner

Python Type Hints: A Primer for Reading AI Agent Code (2026)

A Python type hints primer for reading AI agent code: function hints, Optional, Union, TypedDict for message lists, and how frameworks use them.

SK
Sukhveer Kaur
Published June 22, 2026
4 min read
On this page +

The first time agent code confuses a Python developer, it’s rarely the logic — it’s the labels. def get_weather(city: str) -> dict: has two of them before the body even starts, and a tool’s arguments often arrive as a TypedDict or a Pydantic model you’ve never declared. This Python type hints primer names those labels once, so the rest of the code reads cleanly.

Here’s the reassuring part: type hints don’t change what your code does. They’re notes for humans and tools. But agent frameworks read them to figure out how the model should call your functions, so recognising the syntax is the difference between following a tutorial and squinting at it. Let’s clear it up.

🟢 Beginner⏱️ 12 min readStack: Python 3.10+ (reading level — no agent code needed)
Before you start
  • You can read a basic Python function and a dictionary — new to that? The Python for AI agents primer covers both
  • That’s it — this primer assumes no prior typing knowledge
🎯 Key takeaways
  • A type hint is a label, not a rule: city: str documents intent, but Python doesn’t enforce it at runtime.
  • Function hints annotate each argument and the return value (-> dict) — the most common form you’ll read.
  • TypedDict types a dictionary’s shape — exactly the {"role": ..., "content": ...} structure agent messages use.
  • Frameworks turn your hints into a schema the model reads, which is why tool functions are always carefully typed.

What a type hint is — and what it isn’t

A type hint is an annotation that says what kind of value something holds. You add it with a colon for variables and arguments, and an arrow for return values.

python
name: str = "Asha"
def add(a: int, b: int) -> int:
return a + b

The crucial thing to internalise early: Python does not enforce hints at runtime. The function above will happily run add("a", "b") and return "ab" — the hint is documentation, not a guard. Hints exist for people reading the code and for tools that check it. That’s not a weakness; it’s the design (see PEP 484). Enforcement is opt-in, and we’ll get to who opts in.

Function hints: arguments and return values

This is the form you’ll meet most, because every agent tool is a typed function. Read it left to right: each parameter gets name: type, and -> type after the parentheses is what the function gives back.

python
def get_weather(city: str) -> dict:
"""Return the current weather for a city."""
return {"city": city, "temp_c": 31}

city: str says the input is a string; -> dict says you get a dictionary back. When an agent framework sees this, it builds a description of the tool from exactly these hints — the model learns the function takes a string called city. That’s why untyped tools misbehave: with no hints, the model is guessing the arguments.

The handful of types you’ll actually see

Beyond str, int, float, and bool, a few container and “maybe” types cover most agent code.

  • list[str], dict[str, int] — a list of strings, a dict mapping strings to ints. The shape inside the brackets tells you what’s stored.
  • str | None — “a string or nothing.” The | None part marks a value that might be absent (older code writes this as Optional[str]).
  • int | str — a union: either an int or a string. You read | as “or”.
python
def find_user(user_id: int) -> dict | None:
"""Return the user record, or None if not found."""
...

That return hint, dict | None, is a tiny but useful signal: it warns you the function can hand back nothing, so your code should check before using the result.

📌 Two ways to write the same thing`str | None` (Python 3.10+) and `Optional[str]` (any version, needs `from typing import Optional`) mean the identical thing. You'll see both in the wild — the `|` form is the modern style.

TypedDict: typing the shape of a dictionary

Here’s the one that unlocks agent code. A conversation is a list of dictionaries, each with a role and content. A TypedDict declares that exact shape — which keys exist and what type each value is.

python
from typing import TypedDict
class Message(TypedDict):
role: str
content: str
messages: list[Message] = [
{"role": "system", "content": "You are a helpful agent."},
{"role": "user", "content": "What's the weather in Delhi?"},
]

Now messages isn’t just “a list of dicts” — it’s a list of Message, and a tool can see at a glance that every entry needs a role and a content (PEP 589). LangGraph uses this exact pattern for an agent’s State, so once you recognise TypedDict, that part of framework code stops being mysterious.

Where hints get teeth: Pydantic

If hints aren’t enforced, how do agents avoid “the model returned garbage”? They bring in a library that chooses to enforce them. Pydantic takes a class of hints and validates real data against it, raising a clear error when the shape is wrong.

python
from pydantic import BaseModel
class WeatherReport(BaseModel):
city: str
temp_c: int
report = WeatherReport(city="Pune", temp_c="hot") # raises a validation error

This is the backbone of type-safe agents: you declare the shape you expect, and Pydantic guarantees you either get it or a loud failure — never silent nonsense three functions later. The Pydantic AI tutorial shows this inside a full agent.

💡 Want runtime checks without Pydantic?A type checker like [mypy](https://mypy.readthedocs.io/en/stable/) reads your hints and flags mismatches *before* you run the code — `mypy agent.py` catches a `str` passed where an `int` was promised. It's the cheapest way to make hints earn their keep.

Why Python type hints matter so much to agents

Pulling it together: in ordinary scripts, hints are a nicety. In agent code, Python type hints are load-bearing. A tool’s hints become the schema the model reads to call it; a TypedDict defines the state that flows through the graph; a Pydantic model guarantees the output is shaped the way the rest of your app expects. Strip the hints and an agent framework is flying blind. That’s why every well-written tool you’ll copy is carefully typed — and why reading hints fluently makes all of it legible.

Quick recap

The whole primer, in five lines:

  • A type hint is a label (city: str, -> dict), not a runtime rule.
  • Function hints annotate each argument and the return — the form you read most.
  • str | None and unions flag “maybe absent” and “either/or” values.
  • TypedDict types a dict’s keys and values — the agent messages/State shape.
  • Pydantic and mypy are how hints get enforced, on purpose.

Frequently Asked Questions

What are type hints? Optional labels for the type of a value (city: str, -> dict). They document intent and feed tools; Python ignores them at runtime.

Do hints change how code runs? No. By default they’re not enforced — a function hinted -> int can still return a string. Enforcement comes from mypy or Pydantic.

What is a TypedDict? A declaration of the exact keys and value types a dictionary should have — the structure agent message lists use.

Do I need hints before building agents? Read them first; tool schemas, LangGraph state, and Pydantic all rely on them. Writing thorough hints is a habit you grow into.

Conclusion

Python type hints look like extra ceremony until you see what they’re for: they’re how agent frameworks learn the shape of your functions and data. Read city: str as “this argument is a string,” -> dict | None as “returns a dict or nothing,” and TypedDict as “a dictionary with these exact keys,” and the typed parts of any agent tutorial turn from noise into signal.

Which typed pattern trips you up most — Optional, unions, or TypedDict? Tell me in the comments and I’ll expand on it.

🧭 Where to go from here

Frequently asked questions

What are type hints in Python? +
Type hints are optional labels that say what type a value is — for example `city: str` or `-> dict`. They don't change how your code runs; Python ignores them at runtime. Their job is to document intent and let tools (and AI agent frameworks) understand the shape of your data.
Do type hints make Python code run slower or differently? +
No. By default Python treats hints as annotations and does not enforce them — a function hinted `-> int` can still return a string and Python won't complain. Enforcement comes from separate tools like mypy, or from libraries like Pydantic that validate against the hints on purpose.
What is a TypedDict and why do agents use it? +
A TypedDict declares the exact keys and value types a dictionary should have. Agent code uses it because a conversation is a list of dicts like `{'role': str, 'content': str}`, and a TypedDict makes that shape explicit and checkable instead of a guess.
Do I need to learn type hints before building AI agents? +
Learn to read them first. Tool definitions, LangGraph state, and Pydantic models all lean on hints, so recognising the syntax lets you follow agent code. Writing thorough hints of your own is a habit you build gradually, not a prerequisite to start.
Advertisement

References

  1. typing — Support for type hints (Python documentation)
  2. PEP 484 — Type Hints
  3. PEP 589 — TypedDict
  4. mypy — Optional static typing for Python

Tags

#PythonForAI#TypeHints#PythonTyping#TypedDict#AIAgents#AIForDevelopers

Share

Previous Article
Python Virtual Environments: venv, pip & uv Primer (2026)

One email when something good ships

New guides the day they publish. No digest spam.

InfoWokCode-first AI engineering, in Python.
AboutEditorial standardsContactRSS