ЁЯПл The SchoolтА║ЁЯУЛ AI AgentsтА║ЁЯФм рдзрдбрд╛ 07 тАФ agent рдмрдирд╡рд╛: 130 рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдУрд│реА
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯФм рдзрдбрд╛ 07 тАФ agent рдмрдирд╡рд╛: 130 рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдУрд│реА

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 8 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧреЗ: lesson-06-failures ┬╖ рдкреБрдвреЗ: lesson-08-patterns


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ06, рдЖрдгрд┐ agent/agent.py рдЪреЗ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдд рд╡рд╛рдЪрди тАФ рдпрд╛ course рдордзрд▓реА рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдХрд▓реНрдкрдирд╛, рдПрдХрд╛ рдУрд│ рдХреНрд░рдорд╛рдВрдХрд╛рд╡рд░ рд╕рд╛рдкрдбрдгрд╛рд░реА.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

file рдЙрдШрдбрд╛. рддреАрди рдХреНрд░рдорд╛рдВрдХрд┐рдд рд╡рд┐рднрд╛рдЧ, course рд╢реА рддрдВрддреЛрддрдВрдд рдЬреБрд│рдгрд╛рд░реЗ:

  1. ЁЯз░ THE TOOLS тАФ рдкрдЯреНрдЯрд╛ (L03): SCHOOL_DB (рдЬрдЧ), _safe_eval (рдЕрд╡рдШрдб input рд╡рд┐рд░реБрджреНрдз рдХрдареЛрд░ рдХреЗрд▓реЗрд▓реЗ tool тАФ L05 рдирд┐рдпрдо 3), рддреАрди tool functions, рдЖрдгрд┐ TOOLS registry рдЬрд┐рдереЗ рдкреНрд░рддреНрдпреЗрдХ entry рд╕реЛрдмрдд help (model рд╕рд╛рдареАрдЪреЗ рд▓реЗрдмрд▓) рдЖрдгрд┐ writes (gate рдЪрд╛ flag) рдЕрд╕рддреЛ. рд▓рдХреНрд╖рд╛рдд рдШреНрдпрд╛, done рд╣реА рдлрдХреНрдд рдЖрдгрдЦреА рдПрдХ рд▓реЗрдмрд▓ рдЕрд╕рд▓реЗрд▓реА рдирд┐рд╡рдб рдЖрд╣реЗ.
  2. ЁЯза THE BRAINS тАФ THINK рдареЛрдХрд╛, рдмрджрд▓рддрд╛ рдпреЗрдгрд╛рд░рд╛:
    • ScriptedBrain тАФ рдПрдХ рдЦреЗрд│рдгреНрдпрд╛рддрд▓рд╛ planner (scratchpad рд╡рд░рдЪреА if-рдЪреА рд╢рд┐рдбреА) рдЬреНрдпрд╛рдореБрд│реЗ demo API key рд╢рд┐рд╡рд╛рдп рдЪрд╛рд▓рддреЛ. рддреНрдпрд╛рдЪреА docstring рд╣реЗ course рдЪреЗ рд╕рд░реНрд╡рд╛рдд рдореЛрдареЗ рдЧреБрдкрд┐рдд рдЖрд╣реЗ: рдпрд╛ class рдЪреНрдпрд╛ рдЬрд╛рдЧреА рдПрдХ LLM call рдареЗрд╡рд╛ тАФ "рд╣реЗ goal + pad + tool labels, рдкреБрдвреЗ рдХрд╛рдп?" тАФ рдЖрдгрд┐ рдмрд╛рдХреА рд╕рдЧрд│реЗ рддрд╕реЗрдЪ рд░рд╛рд╣рддреЗ. loop рд╣рд╛рдЪ agent рдЖрд╣реЗ; model рд╣рд╛ рдПрдХ рднрд╛рдЧ рдЖрд╣реЗ.
    • HumanBrain тАФ --drive mode: рддреБрдореНрд╣реА, type рдХрд░рдд. LLM рдЪреНрдпрд╛ рдЬрд╛рдЧреА рдорд╛рдгреВрд╕ рдмрд╕реВ рд╢рдХрддреЛ рдпрд╛рд╡рд░реВрдирдЪ рдХрд│рддреЗ рдХреА LLM рдиреЗрдордХреЗ рдХрд╛рдп рджреЗрддреЗ: рдирд┐рд░реНрдгрдп, рдмрд╛рдХреА рдХрд╛рд╣реАрдЪ рдирд╛рд╣реА.
  3. ЁЯФБ THE LOOP + GUARDRAILS тАФ run(): for step in range(MAX_STEPS) curfew (L05 рдирд┐рдпрдо 1), рдЫрд╛рдкрд▓реЗрд▓реЗ THINK/ACT, done рдордзреВрди рдмрд╛рд╣реЗрд░ рдкрдбрдгреЗ, рдЕрдиреЛрд│рдЦреА tool рдЖрдгрд┐ errors рдирд╛ observations рдореНрд╣рдгреВрди рд╣рд╛рддрд╛рд│рдгреЗ ("errors are data"), write gate if TOOLS[name]["writes"] and not auto_approve (L05 рдирд┐рдпрдо 2 тАФ file рдордзрд▓реЗ рд╕рд░реНрд╡рд╛рдд рдореМрд▓реНрдпрд╡рд╛рди if), рдЖрдгрд┐ scratchpad.append(...) тАФ рдПрдХрд╛ рдУрд│реАрдд memory (L04).

~130 рдУрд│реА. framework рдирд╛рд╣реА. рддреБрдореНрд╣рд╛рд▓рд╛ рднреЗрдЯрдгрд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ agent framework рдореНрд╣рдгрдЬреЗ рд╣реАрдЪ file, рдЬрд╛рд╕реНрдд рд╡рд┐рд╢реЗрд╖рдгрд╛рдВрд╕рд╣.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart TB
    subgraph file["agent/agent.py тАФ the map"]
        t["1 ЁЯз░ TOOLS<br/>belt + labels + writes-flags<br/>+ a hardened calc"]
        b["2 ЁЯза BRAINS (swappable!)<br/>ScriptedBrain: toy planner<br/>HumanBrain: --drive<br/>тЖР an LLM call slots HERE"]
        l["3 ЁЯФБ run() loop<br/>MAX_STEPS curfew ┬╖ write gate ЁЯЪз<br/>errors-as-observations ┬╖<br/>scratchpad.append = memory"]
    end
    t --> l
    b --> l
    l --> out["тЬЕ outcome + full printed log ЁЯз╛"]

тЭУ рдХрд╛рдп (рдЙрдЪрд▓рдгреНрдпрд╛рдЬреЛрдЧреЗ рддрдкрд╢реАрд▓)

ЁЯдФ рдХрд╛

Frameworks рдЪрд╛рдВрдЧрд▓реЗ рдЖрд╣реЗрдд тАФ рдкрдг рд╣реЗ mental model рдирд╕рддрд╛рдирд╛ рддреНрдпрд╛рдВрдирд╛ debug рдХрд░рдгреЗ рдореНрд╣рдгрдЬреЗ рдкреБрд░рд╛рддрддреНрддреНрд╡ рд╕рдВрд╢реЛрдзрди. 130 рдУрд│реА рд╡рд╛рдЪрд▓реНрдпрд╛рд╡рд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд│рддреЗ рдХреА LangGraph/CrewAI/рдХрд╛рд╣реАрд╣реА рдпрд╛рдВрдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдерд░ рдХрд╢рд╛рд╕рд╛рдареА рдЖрд╣реЗ, рдХреЛрдгрддрд╛ knob рдХреЛрдгрддреНрдпрд╛ рд╕рдВрдХрд▓реНрдкрдиреЗрд╢реА рдЬреБрд│рддреЛ, рдЖрдгрд┐ тАФ рд╕рд░реНрд╡рд╛рдд рдореМрд▓реНрдпрд╡рд╛рди тАФ рдПрдЦрд╛рджреНрдпрд╛ рдХрд╛рдорд╛рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рд▓рд╛рдЧрдд рдирд╛рд╣реА. рдЪрд╛рдВрдЧрд▓реА tools рдЖрдгрд┐ gates рдЕрд╕рд▓реЗрд▓реЗ рд╕рд╛рдзреЗ loops ship рд╣реЛрддрд╛рдд.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛ тАФ рддреАрди upgrades, рдкреНрд░рддреНрдпреЗрдХреА ~5 рдУрд│реА

# A) new tool: add "list_notes" (READ) that returns note.txt contents.
#    тЖТ belt entry + function. Rerun --drive and call it.
# B) loop detection (L06 #2): in run(), before acting тАФ
#    if scratchpad and f"[{name} {json.dumps(args)}]" in scratchpad[-1]:
#        observation = "you just did exactly that тАФ try something else"
# C) real brain: replace ScriptedBrain.decide with an API call that
#    sends goal + scratchpad + tool helps and parses "name {json}".
#    (~15 lines with any LLM SDK тАФ the harness doesn't change at all.)
python3 agent/agent.py --drive

рдХрд┐рдорд╛рди upgrade A ship рдХрд░рд╛. рдЖрддрд╛ рддреБрдореНрд╣реА "agent framework рд╡рд╛рдкрд░рд▓реЗрд▓реА" рд╡реНрдпрдХреНрддреА рдирд╛рд╣реА тАФ рддреБрдореНрд╣реА рдЕрд╕рд╛ framework рд▓рд┐рд╣реВ рд╢рдХрдгрд╛рд░реА рд╡реНрдпрдХреНрддреА рдЖрд╣рд╛рдд. ЁЯФм

тПня╕П рдкреБрдвреЗ

рд╢реЗрд╡рдЯрдЪрд╛ рднрд╛рдЧ: рдПрдХреЗрдХрдЯреЗ loops рдПрдХрддреНрд░ рдпреЗрдКрди patterns рдХрд╕реЗ рдмрдирддрд╛рдд тАФ planners, critics, teams, human-in-the-loop тАФ рдЖрдгрд┐ agent рдЕрдЬрд┐рдмрд╛рдд рдХрдзреА рд╡рд╛рдкрд░реВ рдирдпреЗ.

git checkout lesson-08-patterns

ЁЯФм Lesson 07 тАФ Build an agent: 130 honest lines

ЁЯУН You are here: Lesson 07 of 8 ┬╖ Previous: lesson-06-failures ┬╖ Next: lesson-08-patterns


ЁЯУж What's in this branch

Lessons 01тАУ06, plus the guided read of agent/agent.py тАФ every concept from this course, findable at a line number.

ЁЯзТ Explain like I'm 5

Open the file. Three numbered sections, exactly matching the course:

  1. ЁЯз░ THE TOOLS тАФ the belt (L03): SCHOOL_DB (the world), _safe_eval (a tool hardened against tricky input тАФ L05 rule 3), three tool functions, and the TOOLS registry where every entry carries help (the label FOR the model) and writes (the gate flag). Notice done is just another labeled choice.
  2. ЁЯза THE BRAINS тАФ the THINK beat, swappable:
    • ScriptedBrain тАФ a toy planner (an if-ladder over the scratchpad) so the demo runs with no API key. Its docstring is the course's biggest secret: replace this class with one LLM call тАФ "here's the goal + pad + tool labels, what next?" тАФ and everything else stays. The loop is the agent; the model is a part.
    • HumanBrain тАФ --drive mode: you, typing. The fact that a human slots in where the LLM goes tells you exactly what an LLM contributes: decisions, nothing else.
  3. ЁЯФБ THE LOOP + GUARDRAILS тАФ run(): the for step in range(MAX_STEPS) curfew (L05 rule 1), THINK/ACT printed, the done exit, unknown-tool and error handling as observations ("errors are data"), the write gate if TOOLS[name]["writes"] and not auto_approve (L05 rule 2 тАФ the most valuable if in the file), and scratchpad.append(...) тАФ the memory (L04) in one line.

~130 lines. No framework. Every agent framework you'll ever meet is this file with more adjectives.

ЁЯЧ║я╕П Diagram

flowchart TB
    subgraph file["agent/agent.py тАФ the map"]
        t["1 ЁЯз░ TOOLS<br/>belt + labels + writes-flags<br/>+ a hardened calc"]
        b["2 ЁЯза BRAINS (swappable!)<br/>ScriptedBrain: toy planner<br/>HumanBrain: --drive<br/>тЖР an LLM call slots HERE"]
        l["3 ЁЯФБ run() loop<br/>MAX_STEPS curfew ┬╖ write gate ЁЯЪз<br/>errors-as-observations ┬╖<br/>scratchpad.append = memory"]
    end
    t --> l
    b --> l
    l --> out["тЬЕ outcome + full printed log ЁЯз╛"]

тЭУ What (details worth stealing)

ЁЯдФ Why

Frameworks are fine тАФ but debugging one without this mental model is archaeology. After reading 130 lines you know what every layer of LangGraph/CrewAI/whatever is FOR, which knob maps to which concept, and тАФ most valuable тАФ what you don't need for a given job. Simple loops with good tools and gates ship.

ЁЯзк Try it тАФ three upgrades, ~5 lines each

# A) new tool: add "list_notes" (READ) that returns note.txt contents.
#    тЖТ belt entry + function. Rerun --drive and call it.
# B) loop detection (L06 #2): in run(), before acting тАФ
#    if scratchpad and f"[{name} {json.dumps(args)}]" in scratchpad[-1]:
#        observation = "you just did exactly that тАФ try something else"
# C) real brain: replace ScriptedBrain.decide with an API call that
#    sends goal + scratchpad + tool helps and parses "name {json}".
#    (~15 lines with any LLM SDK тАФ the harness doesn't change at all.)
python3 agent/agent.py --drive

Ship upgrade A at minimum. You're no longer a person who "used an agent framework" тАФ you're a person who could write one. ЁЯФм

тПня╕П Next

The finale: how single loops combine into patterns тАФ planners, critics, teams, human-in-the-loop тАФ and when NOT to use an agent at all.

git checkout lesson-08-patterns
тЖР PreviousfailuresNext тЖТpatterns

This page is the lesson's README from the lesson-07-build-an-agent branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.