← Back to courses
Course
Agentic AI
75 lessons across 8 modules
Build an agent by hand, then learn the frameworks. Runs entirely on your own machine with Ollama - no paid API key needed.
Module 01Agents From Scratch- 13 lessons · Pure Python, no framework - see exactly what an agent is made of before anything hides it from you
Talking to a Local Modelbasics
Send a prompt to a model running on your own machine and read the reply.
ollama.chat(model, messages)
reply lives in ["message"]["content"]
runs on your machine, not a server
1.1 lesson
Prompting Basicsbasics
Set the model’s behaviour with a system message, and control randomness with temperature.
system = the job description
user = the question
temperature: low = steady, high = varied
1.2 lesson
Structured Outputbasics
Get the answer back as JSON your program can use - then parse it, validate it, and retry only when retrying can help.
ask for an exact JSON shape
json.loads() -> dict, then validate
bad JSON: retry with feedback
wrong data: reject, do not retry
1.3 lesson
What Makes It an "Agent"concept
The difference between a chatbot and an agent: tools, and a loop to use them in.
chatbot: prompt -> text, done
agent: decide -> act -> observe -> repeat
Agent = LLM + tools + loop
1.4 lesson
Manual Tool Callingtools
Teach the model to ask for a tool in a fixed format - then parse that request and run the function yourself.
describe the tools in the prompt
fixed format: TOOL: name(arg="x")
the model asks, your code parses and runs it
1.5 lesson
The ReAct Loop by Handcore
Thought, Action, Observation, repeat - the whole agent loop as a plain Python for loop.
ReAct = Reason + Act
Thought / Action / Observation / Final Answer
your loop runs the tools; max_steps stops runaways
1.6 lesson
Real Toolstools
Swap the pretend tools for ones that do real work - and think about what that lets the agent reach.
the loop stays exactly the same
TOOLS["read_file"] = read_file
real tools need real limits - in the tool, not the prompt
1.7 lesson
Conversation Memorymemory
Memory is just a list of past messages you keep sending back - and trim before it gets too big.
no memory = blank slate each call
memory = the whole message list, resent
trim it - and know that trimming forgets
1.8 lesson
Multi-Step Planningplanning
Have the model break a goal into ordered steps before it starts acting on any of them.
plan first, then execute
numbered steps = checkable
carry results forward, re-check as you go
1.9 lesson
Error Handling & Retriesrobustness
Catch bad output, unknown tools, and tools that blow up - and keep the agent running.
unreadable output -> nudge and retry
unknown tool -> list the real ones
tool raises -> catch, report, continue
1.10 lesson
Two Agents Talkingmulti-agent
The simplest multi-agent setup: one agent’s output becomes the next agent’s input.
two agents, two jobs
output of one -> input of the next
no loop, no shared memory - and no fact-checking
1.11 lesson
Module 1 Projectsbuild
Three small projects that put the whole module together - built, run, and debugged.
calculator agent in the terminal
notes agent that survives restarts
research-and-summarize agent
1.12 projects
Module 1 Final Quizreview
Seven core questions covering every lesson in the module, then six on what the real runs showed.
agent = LLM + tools + loop
ReAct, memory, planning, errors
why build it by hand first
1.13 final quiz
Module 02Building Agents with LangChain- 15 lessons · The same agent, rebuilt with a framework - plus embeddings, vector stores, and RAG
Why a Frameworkframework
What LangChain gives you that Module 1’s hand-rolled loop did not - and what it still leaves to you.
same loop: model -> tools -> model
LangChain writes the plumbing
you still own limits, errors, and the model
2.1 lesson
LangChain + Ollama Setupsetup
Connect LangChain to the same local Ollama model with ChatOllama, and run a hello-world chain.
llm = ChatOllama(model="llama3.1")
llm.invoke("Hello").content
prompt | llm is a chain
2.2 lesson
Prompt Templatesprompts
Reusable prompts with variables, system and human messages, and few-shot examples.
"Explain {topic} to a {level} developer"
chain.invoke({"topic": ..., "level": ...})
examples show the pattern
2.3 lesson
Chains (LCEL)chains
Pipe a prompt into a model into a parser with |, and run the whole thing as one.
chain = prompt | llm | parser
chain.invoke({"topic": "Docker"}) -> a string
each step’s output is the next step’s input
2.4 lesson
Output Parsersparsers
Turn the model’s text into a Recipe object your code can use - with PydanticOutputParser at the end of an LCEL chain.
class Recipe(BaseModel): name, ingredients
parser = PydanticOutputParser(pydantic_object=Recipe)
chain = prompt | llm | parser
2.5 lesson
Tools in LangChaintools
Rebuild the weather tool with @tool: LangChain reads the name, docstring and type hints and writes the tool schema for you.
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
The model chooses the tool; your code runs it.
2.6 lesson
Agents & AgentExecutoragents
Give the tools from Lesson 2.6 to an agent and let LangChain run the ReAct loop - with create_agent today, AgentExecutor in older code.
agent = create_agent(llm, tools=[get_weather, calculate])
model -> tools -> model ... until no tool is called
The model decides; the runtime executes.
2.7 lesson
Memorymemory
The chat agent with memory, next to Module 1’s version: ConversationBufferMemory and its relatives, and the checkpointer that replaced them.
memory = the message list, sent back every call
Module 1: self.messages
LangChain 1.x: checkpointer + thread_id
2.8 lesson
Ollama Embeddingsembeddings
Turn text into vectors with OllamaEmbeddings and compare them with cosine similarity: which of three sentences is closest in meaning?
LLM: text -> text
Embedding model: text -> vector
close vectors = close meaning (cosine similarity)
2.9 lesson
Vector Storesvector stores
Index five short notes into Chroma, inspect exactly what got stored, and search them by meaning.
vector store = id + text + metadata + vector, with a nearest-neighbour index
add_texts() embeds and stores
similarity_search() embeds the question and returns the closest documents
2.10 lesson
Retrieversretrievers
Turn the vector store into a retriever, ask for the top k, and see why MMR can return better context than plain similarity.
retriever = vector_store.as_retriever(search_kwargs={"k": 2})
retriever.invoke(question) -> list of Documents
similarity = closest; MMR = relevant and different
2.11 lesson
Putting It Together: RAGrag
Combine embeddings, a vector store and a retriever into one chain that answers questions about a PDF - and see where it fails.
Retrieve: question -> retriever -> chunks
Augment: chunks + question -> prompt
Generate: prompt -> LLM -> answer
2.12 lesson
Custom Tools & Multi-Tool Agentsmulti-tool
Give one agent a calculator, a search tool and RAG as a tool - and let the model choose, per question, which ones to use.
tools = [calculate, search, search_documents]
agent = create_agent(llm, tools)
RAG chain: always retrieves. RAG tool: retrieves when the model decides to.
2.13 lesson
Agent Types Comparedagent types
Zero-shot ReAct, structured chat and tool calling, swapped in on the same tool and questions - and what each did with llama3.
ReAct: the action is text you parse
Structured chat: the action is a JSON blob you parse
Tool calling: the action is a structured call the API returns
In every one, your code runs the tool
2.14 lesson
Vector Stores Deep Divevector stores
Go past the basics of Lesson 2.10: cut documents into good chunks, give them ids you can rebuild, update a file without leaving old pieces behind, and filter with every Chroma operator. Every result comes from a real run.
chunk small enough for ONE topic
id = "file#position" -> re-index without duplicates
changed file: delete(where={"source": file}), then add
filter on metadata: $eq $ne $gt $in $and $or
2.15 lesson
Projects: Document Q&A agent - RAG over a folder of notes · Multi-tool personal assistant - calculator, notes and search · Customer-support style agent with memory
Final quiz covers: LCEL chains, parsers, tools, AgentExecutor, memory, embeddings, vector stores, retrievers, RAG
Module 03Building with LangGraph- 9 lessons · When a straight line is not enough - branching, loops, saved state, and human approval
Why Graphs, Not Chainslanggraph
A chain runs its steps in a fixed order. A graph can choose the next step and go back to an earlier one. Learn the difference with everyday examples, real code, and your first LangGraph program.
Chain: step 1 -> step 2 -> step 3, always the same order
Graph: nodes (work) + edges (what runs next)
A graph can go back: check -> check -> check -> escalate
3.1 lesson
State, Nodes, and Edgeslanggraph
The three building blocks of every LangGraph program - state, nodes and edges - explained slowly, with an everyday picture, step-by-step code, an LLM node, and a practice task.
State = what do I know? (the shared data)
Node = what do I do? (a function that returns changes)
Edge = where do I go next?
StateGraph -> add_node -> add_edge -> compile -> invoke
3.2 lesson
Conditional Edgeslanggraph
Let the graph choose the next step. A small router function reads the state and names the next node. Build a support desk that sends billing, technical and account questions to the right team - then let llama3 do the understanding.
add_edge("A", "B") -> after A, ALWAYS go to B
add_conditional_edges("A", router, [...]) -> after A, router(state) CHOOSES
router = reads the state, returns a node name, changes nothing
always pass the list of possible nodes (the path map)
3.3 lesson
Cycles and Loopslanggraph
Rebuild Module 1’s ReAct loop as a LangGraph cycle - agent -> tools -> agent - with llama3 deciding and a step limit that actually stops it.
add_edge("tools", "agent") makes the cycle
should_continue(state): answer -> END, too many steps -> give_up, else -> tools
Cycle + exit + limit = a loop you can trust
3.4 lesson
Tool Nodelanggraph
Replace the hand-written tools node with LangGraph’s prebuilt ToolNode - and see exactly what it does with good calls, bad calls and crashing tools.
agent -> tools_condition -> ToolNode(tools) -> agent
The model requests, ToolNode executes, ToolMessages carry the results
MessagesState appends - the conversation is the state
3.5 lesson
Persistence & Checkpointinglanggraph
Give a graph a checkpointer and a thread_id, and its state survives between calls, across a crash, and - with a database - across a restart.
builder.compile(checkpointer=saver)
invoke(input, {"configurable": {"thread_id": "t-1"}})
A checkpoint after every step - invoke(None, config) resumes
3.6 lesson
Human-in-the-Looplanggraph
Pause a graph with interrupt(), show a person the proposed action, and resume with their decision - approve, edit or reject - even from another process.
answer = interrupt(proposal) -> the run pauses, the checkpoint keeps it
graph.invoke(Command(resume=answer), config) -> it continues
The paused node runs again from its first line
3.7 lesson
Multi-Agent Graphslanggraph
Split one job between small agents - a researcher, a writer and a reviewer - and let a supervisor decide who works next. Real runs, two real bugs, and when one agent is the better choice.
worker = a node with ONE job
supervisor = a node that only decides who goes next
Command(goto="writer") + every worker reports back to the supervisor
3.8 lesson
Streaminglanggraph
Show the user what is happening while the graph runs: progress messages, finished steps, and the answer word by word - in the console and in a browser. Measured with real runs.
invoke(): wait, then get everything
stream(): get pieces while it runs
stream_mode = "updates" | "values" | "messages" | "custom"
3.9 lesson
Projects: Stateful multi-turn agent with checkpointing, resumable after a restart · Supervisor and worker graph - research, draft, review · Human-in-the-loop approval workflow
Final quiz covers: state, nodes and edges, conditional routing, cycles, checkpointing, human-in-the-loop, multi-agent graphs
Module 04Model Context Protocol (MCP)- 7 lessons · One standard way for any agent to connect to any tool, instead of a custom integration each time
What is MCP and Why It Mattersmcp
You have wrapped the same tool three times - for your own agent, for LangChain, for LangGraph. MCP is one standard plug: write a tool once as a server, and any MCP app can use it. We prove it with one Python server and three very different clients.
Without MCP: every app x every tool = its own glue code
With MCP: tool -> MCP server, app -> MCP client, they just plug in
One Python server worked with a Python client, curl, and a TypeScript app
4.1 lesson
MCP Architecturemcp
Look inside MCP: the host, its clients and servers; the three things a server offers (tools, resources, prompts); the JSON messages on the wire - recorded from real runs; the two transports, stdio and HTTP; and the two kinds of error.
server offers: tools (model uses) · resources (app reads) · prompts (user picks)
messages: JSON-RPC 2.0 - request, response, notification
transports: stdio (a child process) or Streamable HTTP (POST /mcp)
4.2 lesson
Building a Simple MCP Servermcp
Build the "current time" MCP server step by step with the Python SDK 2.x: one function, two decorators. Then test it three ways, send clear errors the model can use, and learn the one rule that breaks stdio servers.
server = MCPServer("time-server")
@server.tool() on a normal function -> an MCP tool
docstring -> description, type hints -> input schema
raise ToolError("clear message") · log to stderr, never print to stdout
4.3 lesson
Connecting an Agent to an MCP Servermcp
Give the LangGraph agent from Lesson 3.5 tools that live on an MCP server. Write a 20-line adapter, watch llama3 fail four different ways, and fix each one - then compare with LangChain’s official adapter.
async with Client(server) as client: # keep the connection open
tools = await load_mcp_tools(client) # MCP tools -> LangChain tools
ToolNode(tools) # the 3.5 graph, unchanged
4.4 lesson
Multiple Tools and Resourcesmcp
Build a notes server with three tools and two resources - and keep it locked inside one folder. We break an unsafe version first (it reads a secret file), add tool hints like "read-only" and "destructive", and watch an agent invent a delete that never happened.
tools: list_notes · read_note · write_note (destructive!)
resources: notes://index and the template notes://{name}
every path: check the name, resolve, must stay inside NOTES
4.5 lesson
Using Community Serversmcp
Find ready-made MCP servers in the official registry, install the official time, fetch and filesystem servers, and use them from your own agent with no new code. Then read what they really do - one tool description talks directly to your model.
find: registry.modelcontextprotocol.io (a catalogue, not a safety check)
run: pip / uvx (Python) or npx (Node) - the client starts it
check: tools, descriptions, folders, network - before you connect
4.6 lesson
Full MCP-Powered Agentmcp
One agent, two MCP servers: our notes server and the official web fetch server. Prefix tool names so they cannot clash, ask a human before anything not marked read-only, and watch a web page hijack the agent - stopped by the approval step, and not stopped without it.
open every server in one AsyncExitStack
name tools "<server>__<tool>" - duplicates are dropped silently otherwise
read-only -> run; anything else -> interrupt() and ask a human
text from the web can give your agent orders
4.7 lesson
Projects: MCP-powered file assistant - read, write and organise local files · Multi-server agent - filesystem and search servers used by one agent
Final quiz covers: MCP architecture, building a server, connecting as a client, multi-server agents
Module 05LangSmith & Tooling- 7 lessons · Seeing inside an agent: tracing, evaluation, guardrails, and getting it deployed
Why Observability Mattersobservability
An agent gave a wrong answer that looked right - and two right answers that were right only by luck. From the answers alone you cannot tell. Build a tiny tracer in 60 lines, see the bug in one line of the trace, and learn what every trace should record.
final answer = what the user sees; trace = every step that made it
trace = a tree of runs: name, input, output, time
the bug was between two steps: model said "Europe/Paris", tool got {}
5.1 lesson
Evaluation Basicsevaluation
Write a test set of 14 questions for a RAG bot, score every answer with code checks and an LLM judge, and compare two versions. Along the way: a test that passed by luck, a keyword check fooled 5 times out of 5, and a judge that was wrong too.
dataset = questions + what a good answer must be
evaluator = a function: (case, answer) -> pass / fail
change one thing -> run the same set -> compare -> read the failures yourself
5.4 lesson
Guardrails & Validationguardrails
Put checks around a model: Pydantic rules on what it extracts, business rules before a tool runs, and output rules before a reply reaches a customer. Measured with real refund requests - and a retry loop that cannot fix bad data.
input -> Pydantic model with validators (format, ranges)
before a tool runs -> rules only YOUR data can check
before the user sees it -> output rules (length, placeholders, promises)
retry with the error - but it cannot fix wrong data
5.5 lesson
Cost and Latency Awarenessperformance
Measure what every model call costs in tokens and seconds: reading the prompt, writing the answer, loading the model. Then benchmark llama3 against gemma3 - and see a benchmark lie by 5 times because of how it was run.
time = load + read prompt + write answer
writing is slow (~18 tokens/s), reading is fast, a repeated prompt start is almost free
cost = input tokens x price + output tokens x price
measure several times, one model at a time, with a stopwatch beside the numbers
5.6 lesson
○LangSmith setup & tracing5.2
Environment variables and automatic tracing of a run
example Trace the Module 3 supervisor graph
○Reading a trace5.3
Steps, latency and token counts in the interface
example Walkthrough of a real trace
○Packaging & deployment5.7
Wrapping an agent as a command-line tool or a small API
example Turn the Module 3 agent into a FastAPI endpoint
Projects: Fully traced multi-agent system · Evaluated RAG pipeline with a dataset and automatic scoring · Agent deployed behind a small FastAPI service
Final quiz covers: tracing, evaluation, guardrails, cost, deployment basics
Module 06CrewAI- 9 lessons · Role-based agents: give each one a job title, a goal and a task, then let the crew work
Roadmap — lesson pages for this module are not written yet.
○What is CrewAI6.1
Role-based agents versus graph-based agents
example Diagram: a crew of employees versus a graph
○CrewAI + Ollama setup6.2
Pointing every agent in a crew at a local model
example Hello-world single-agent crew
○Defining an Agent6.3
role, goal and backstory - why the persona changes output quality
example A researcher persona
○Defining a Task6.4
description, expected_output, and assigning a task to an agent
example One task for the researcher
○Sequential process6.5
A crew of two or three agents where each task feeds the next
example Researcher into writer
○Hierarchical process6.6
A manager agent that hands out work as it goes
example Manager assigns work to two workers
○Tools in CrewAI6.7
Attaching tools to individual agents
example Give the researcher a search tool
○Memory in CrewAI6.8
Short-term, long-term and entity memory
example A crew that remembers facts across runs
○Full crew build6.9
Everything together - researcher, writer and editor
example End-to-end content pipeline
Projects: Content-creation crew - research, draft, edit · Trip-planning crew - destination researcher, budget planner, itinerary writer
Final quiz covers: roles, goals and backstory, tasks, sequential versus hierarchical process, tools, memory
Module 07AutoGen- 8 lessons · Agents that hold a conversation with each other, rather than calling tools one at a time
Roadmap — lesson pages for this module are not written yet.
○What is AutoGen7.1
The conversable agent idea - agents that talk to each other
example Diagram: agent-to-agent chat versus a single-agent loop
○AutoGen + Ollama setup7.2
Configuring a local model as an OpenAI-compatible endpoint
example Hello-world two-agent chat
○Two-agent conversation7.3
AssistantAgent and UserProxyAgent, and taking turns
example Assistant solves a task, proxy relays the results
○Tool and function calling7.4
Registering a Python function that both agents can call
example A calculator shared between two agents
○GroupChat7.5
Several agents in one conversation
example Three agents brainstorming together
○GroupChatManager7.6
Deciding who speaks next and when to stop
example A manager orchestrating turn order
○Human-in-the-loop7.7
UserProxyAgent pausing for real human input mid-conversation
example Approve a step before the agents continue
○Full multi-agent build7.8
A complete review team, end to end
example Code-review team
Projects: Code-review team - coder, reviewer and tester agents · Debate agents - two argue opposite sides, a judge scores them
Final quiz covers: conversable agents, tool calling, GroupChat, orchestration, human-in-the-loop
Module 08OpenClaw- 7 lessons · An always-on personal agent that acts on a schedule and messages you first
Roadmap — lesson pages for this module are not written yet.
○What is OpenClaw8.1
An always-on personal agent, versus the request-and-response frameworks so far
example Diagram: request/response agent versus always-running agent
○Install & configure with Ollama8.2
Running it locally against a local model so no data leaves the machine
example First run, first chat message
○The Skills system8.3
Packaging a routine as a skill and installing it
example Write a "greet the user by name" skill
○Heartbeat & proactive tasks8.4
The scheduled cycle that lets the agent act without being asked
example A skill that checks a folder every hour
○Messaging integrations8.5
Connecting the agent to Telegram, Slack or WhatsApp
example Get a message from your agent in Telegram
○Security considerations8.6
Why an always-on agent that can run tools needs extra hardening
example Checklist before giving it shell or file access
○Full proactive assistant8.7
A working proactive skill, end to end
example Daily-digest assistant
Projects: Daily-digest skill - summarise a folder each morning and send it to you · Monitoring skill - check a condition on a schedule and message you when it changes
Final quiz covers: architecture, skills, heartbeat, messaging integrations, security basics
Worth covering later
The modules above cover most of what people actually build with. These five come up often enough to each deserve a module of their own one day.
- LlamaIndex Agents
- A data-indexing-first framework, strong for agents that lean heavily on retrieval.
- Semantic Kernel
- Microsoft's plugin and planner based orchestration, common in .NET and enterprise shops.
- smolagents
- Minimal code-writing agents from Hugging Face - the agent writes and runs Python instead of calling separate tools.
- OpenAI Agents SDK
- A lightweight agent-to-agent hand-off pattern, worth learning even if you never use the SDK itself.
- Browser and computer-use agents
- Agents that drive a real browser or desktop interface instead of calling APIs.
Start at 1.1 and work straight through Module 1 - every lesson builds on the code from the one before it, and by the end you have written an agent from nothing.