TypedDict for a conversation
Welcome! I'm Param. In this workshop we are going to model a multi-turn conversation as a LangGraph state machine. The demo is a booking assistant, but the pattern is the real thing you are here to learn. Every slot-filling chat (intake forms, travel booking, support triage) follows the same recipe once you see it.
A single-turn LLM call is easy. Multi-turn is where things fall apart. The conversation needs to remember what was said, know what slots are still missing, and decide where to go next. A state machine makes every one of those things explicit. No more prompt stuffing, no more guessing what the bot remembers.
# Clone the workshop repository
git clone https://github.com/learnwithparam/healthcare-booking-langgraph.git
cd healthcare-booking-langgraph
# One command to set up everything
make devThis clones the repo, creates a virtual environment with uv, installs LangGraph and FastAPI, and starts the server.
from typing import TypedDict, Optional, List, Dict, Any
class BookingState(TypedDict, total=False):
"""Shared state passed between every node in the graph."""
# Conversation
user_message: str
thread_id: str
patient_id: Optional[str]
history: List[Dict[str, str]]
# Derived fields, filled by nodes as the turn progresses
intent: Optional[str] # book | list | cancel | smalltalk | unknown
symptom: Optional[str]
specialty: Optional[str]
doctor: Optional[Dict[str, Any]]
slot_options: List[str]
slot: Optional[str]
status: str # gathering | ready_to_confirm | confirmed | ended
# Output
assistant_reply: str
events: List[Dict[str, Any]]TypedDict with total=False means every field is optional. Nodes fill in what they can, leave the rest alone. The state is the single source of truth for the turn.
State shape across one turn
How slots and status fields evolve as the turn moves from intent routing to confirmation.
LangGraph passes state between nodes as a plain dict. TypedDict gives you static type checking with zero runtime overhead and zero conversion. Pydantic would re-validate on every hop between nodes, which is wasted work here because the state fields change frequently. Dataclasses would force every node to construct a new instance. TypedDict fits the "mutable shared dict" semantics of a graph run exactly.
Quiz: Quiz
Loading practice…