Session 12 · Deep Agents · play the map

Session 12

You already know this.
It is a food delivery.

Uber Eats. Swiggy. Zomato. Talabat. You order. A rider brings it. Watch the little bike on the map. That picture is enough to explain LLM, agent, and harness — and why Deep Agents exists when you already have LangChain and LangGraph.

Say this first

Three different jobs. Not three models.

If you mix them, students will ask “why do I need a harness if the agent already delivers?” Keep the names separate. Then the next slides prove why.

LLM
The rider’s city knowledge
Every street, every shortcut. Ask “how do I reach the restaurant?” and he can tell you. Knowledge sitting in the head delivers nothing.
Agent
The rider doing the job
“Pick this up. Take it there.” He decides the route. A road closes — he picks another. He is the doer.
Harness
The bike + the delivery app
The bike moves him. The app gives the order, shows the map, marks pickup, tells you it arrived. Decisions become real action.

LLM = knows the way  ·  Agent = does the delivery  ·  Harness = bike + app that make the movement real.

Proof 1 — LLM alone

He knows the city. Your food never moves.

TALABAT · order #4412
Rider can describe every street. Bike is parked.

This is LangChain at its simplest: a model that answers in chat.

“How do I get to Gulf Mart?” — perfect directions. No bag. No door. No file. Close the notebook and the answer is gone.

Food: still at the shop

Proof 2 — Agent + harness

Road closed. He still delivers.

TALABAT · live
CLOSED
Waiting for the order…

Agent decides: go to the shop, then your door. Street closed? Take the other street. You did not write a new Python node named add_detour.

Harness is what actually moves the icon and marks delivered. That is Deep Agents: the same LangGraph engine, with file tools, rules, how-tos, and helpers already attached.

Idle

The third thing

The rider is not the bike. The bike is not the app.

Harness = equipment + system. Two pieces. Both sit outside the rider’s head.

The bike
Turns “go left” into movement
In code: tools that do work
write_file · edit_file · your get_store_hours
Without tools, the agent only talks.
The delivery app
Order, map, pickup, live update
In code: the loop + memory + skills
create_deep_agent() · AGENTS.md · SKILL.md
Without the app, nobody even gets the order.

He decides. The bike-and-app carry it out. Two jobs. That is why we use two names.

The sharp question

“The agent cannot deliver without the bike. So why split them?”

You are right: in operation they must work together. A rider with no bike delivers nothing. A bike with no rider goes nowhere. We still name them separately because you can swap one without swapping the other.

Today
Same rider. Swiggy app. Company bike.
Same brain. That company’s harness.
Tomorrow
Same rider. Zomato app. Different bike.
Brain unchanged. Only the harness changed.

If they were one inseparable thing, you would rebuild the brain every time the app changed.

Play this in class

Same rider. Different app. Instantly a different worker.

SWIGGY · same rider
Harness: Swiggy. Brain: still Omar.
The rider (unchanged)Omar — city knowledge + decisions
GPT / Claude / Gemini — you did not train this.

Same LLM. Food-delivery tools. He is a delivery agent.

Why engineers care

When the delivery fails, which part do you fix?

SymptomFix this
Bad route choicesHe keeps turning into the closed streetThe brain — better model or prompt
App crash / no mapHe decided correctly; nothing movedThe harness — tools, loop, files
Forgot “always Gulf Mart”Rule was not in today’s promptMemory file — AGENTS.md
Invoice format wrongHow-to was stuffed in every chat, or missingSkill file — SKILL.md

If you called it all “one thing,” you would never know where the problem is.

Memory · loads every run

AGENTS.md — standing rules on every shift

Official docs name it AGENTS.md. This course also uses AGENT.md. Same idea: a markdown file the harness injects every time. You do not paste it into the user message.

/AGENTS.md · always on
Standing rules:
- Every shopping list starts with
  Store: Gulf Mart
- Never invent items the user
  did not name.
- Confirm the bag is sealed
  before you leave the shop.
User says only:
“Create shopping.md. Items: rice, oil.”

No “Gulf Mart” in that sentence.
File the agent writes:
Store: Gulf Mart
rice
oil

Delivery version: the rider does not re-learn “always confirm the seal” each order. The app loads it at the start of the shift. Change the file, not the Python.

Skill · loads only if the job matches

SKILL.md — the how-to he opens when he needs it

At start he only sees the name and description. He reads the full page when the task matches. A 200-line invoice how-to does not sit in every “hello.”

/skills/invoice/SKILL.md · on demand
---
name: invoice
description: Write a store invoice.
---
1. Line 1: Invoice #: INV-001
2. Line 2: Store: Gulf Mart
3. Then one line per item
4. Save as invoice.md
User: “Deliver chicken biryani to Al Barsha.”
Skill stays closed. He does not load invoice rules to deliver food.

Do not mix these up

Memory is who we are. A skill is how to do one job.

Memory · AGENTS.mdSkill · SKILL.md
When loadedEvery run. Always in the prompt.Only if the task matches the description.
Delivery“Always seal the bag. Always Gulf Mart.”“How to process a refund” — opened only on refunds.
In the notebookmemory=["/AGENT.md"] + seed in files=skills=["/skills/"] + /skills/invoice/SKILL.md
If you put it in the wrong placeInvoice how-to in memory = wasted tokens on every chatStanding rules only in a skill = forgotten on a normal list

LangChain: paste the rule into every prompt. Forget once, gone. LangGraph: paste it into every node you write. Harness: one file.

The rest of the bike and app

Tools, files, helper — still the harness

Your tools
GPS · hours · mark delivered
Same idea as LangChain tools=. Deep Agents keeps them and already has write_file. LangChain can call get_store_hours and only talk. Here it lands in hours.md.
File tools
The bag is a document
Work lives in shopping.md, not in a chat bubble. “Add eggs” is edit_file. You do not add_node('add_eggs').
Helper (subagent)
A second rider, empty chat
He only extracts prices from a messy WhatsApp dump and returns bullets. The main rider never carries those 10 pages forever.

Screenshot this

LangChain talks. LangGraph is steps you wrote. Deep Agents is the bike and the app.

QuestionLangChainLangGraphDeep Agents
Where does the work live?ChatState keys you namedFiles the model writes
“Also add eggs”Another chatNew add_nodeedit_file
Always Gulf MartPaste every promptPaste every nodeAGENTS.md
How to write an invoiceGiant system promptA node with that promptSKILL.md on demand
Call my hours toolYes — in chatYes — a nodeYes, and save hours.md
Don’t flood the main chatYou hopeYou split nodesHelper with empty chat

create_deep_agent() still returns a LangGraph graph. You did not replace LangGraph. You stopped writing a new node for every “also…”

Notebook: 12_deepagents/notebooks/01_langchain_langgraph_deepagents.ipynb · Docs: overview · memory · skills · subagents