This repository contains the hands-on exercises for the O’Reilly Live Event:
.
├── hands_on/ # Hands-on exercises
├── helper_functions/ # Helper functions for some notebooks
└── README.md
Concepts
- State machines and typed state
- Tool integration in LangGraph
- Deterministic control flow
Exercise
Build a minimal stateful agent with one tool.
Concepts
- Chain of Thought and ReAct
- Planner–executor vs unified agents
- Test-time compute tradeoffs
- Error propagation and validation
Exercise
Compare a simple agent with a planner–judge setup.
Concepts
- Autonomy vs oversight
- Checkpointing and state inspection
- Interrupt and resume patterns
Exercise
Insert a human approval gate into your workflow.
Concepts
- Supervisor-based architectures
- Role separation
- Delegation and task routing
Exercise
Transform a single-agent workflow into a two-agent system.
Concepts
- Message passing vs shared memory
- Event-driven coordination
- Handoff reliability
Exercise
Swap a communication strategy and observe system behavior changes.
Concepts
- Schema-based prompting
- Pydantic validation
- Model Context Protocol (MCP)
Exercise
Turn free-form input into validated structured tool calls.
Concepts
- Episodic vs procedural memory
- Checkpointing
- Context engineering
Exercise
Add simple episodic and procedural memory to your agent.
Concepts
- Planner vs unified agents
- Thinking vs non-thinking modes
- Dense vs MoE models
- KV cache considerations
Exercise
Switch planning modes and compare latency and decision quality.
Concepts
- Logging state transitions
- Monitoring workflows
- Task-specific evaluation
Exercise
Add logging hooks and compare two workflow runs.
Concepts
- Tool misuse and memory poisoning
- Schema enforcement
- Secure execution patterns
Exercise
Add policy checks and validation to an existing workflow.
All notebooks are designed to run in Google Colab.
- Open a notebook using its Colab link.
- Install the required dependencies when prompted.
- Configure the API key for the model provider used in the notebook.
- Run the notebook cells in order.
The notebooks can use OpenRouter through LangChain’s ChatOpenAI integration by specifying the OpenRouter API endpoint:
from langchain_openai import ChatOpenAI
LLM = ChatOpenAI(
model=OPENROUTER_MODEL,
base_url="https://openrouter.ai/api/v1",
api_key=OPENROUTER_API_KEY,
temperature=0,
)Use the OpenRouter model identifier shown on the model’s OpenRouter page, for example:
openai/gpt-5.4-nano
Never commit API keys to the repository.
The notebooks support loading configuration from a .env file:
from dotenv import load_dotenv
import os
load_dotenv()
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
OPENROUTER_MODEL = os.getenv(
"OPENROUTER_MODEL",
"openai/gpt-5.4-nano",
)In Colab environments that provide terminal access, such as some paid Colab plans, create a .env file in the notebook’s working directory:
cat <<'EOF' > .env
LLM_PROVIDER=openrouter
OPENROUTER_API_KEY=your_openrouter_key_here
OPENROUTER_MODEL=openai/gpt-5.4-nano
EOFReplace your_openrouter_key_here with your actual API key.
To use OpenAI directly instead, the file could contain:
cat <<'EOF' > .env
LLM_PROVIDER=openai
OPENAI_API_KEY=your_openai_key_here
OPENAI_MODEL=gpt-5.4-nano-2026-03-17
EOFWhen terminal access is unavailable, create the file from a Colab code cell:
from pathlib import Path
Path(".env").write_text(
"""
LLM_PROVIDER=openrouter
OPENROUTER_API_KEY=your_openrouter_key_here
OPENROUTER_MODEL=openai/gpt-5.4-nano
""".strip()
)Then load it:
from dotenv import load_dotenv
load_dotenv(override=True)For a temporary Colab session, environment variables can also be set directly in a notebook cell:
%env LLM_PROVIDER=openrouter
%env OPENROUTER_API_KEY=your_openrouter_key_here
%env OPENROUTER_MODEL=openai/gpt-5.4-nanoThese values exist only for the current Colab runtime and must be entered again after the runtime is restarted.
Design deliberately.
Deploy responsibly.
