Skip to content

M19 notes: Build agents in many frameworks (the one idea)

The one idea: every agent framework, LangGraph, CrewAI, AutoGen, smolagents, LlamaIndex, the OpenAI Agents SDK, the Claude Agent SDK, even no-code n8n, wraps the same loop you wrote by hand in M9. Learn the loop once and every framework is just a new set of names for it.


1. The loop under all of them

ask the model  ──▶  does it want a tool?
                       │ yes → run the tool, give the model the result ──┐
                       │ no  → return the final answer                   │
                       └──────────────◀──────────────────────────────────┘

That's it. That's an agent (M9). 01_from_scratch.py is this loop in ~20 lines of plain Python with the Anthropic SDK. A framework's job is to write this loop for you: and add conveniences: memory, retries, streaming, multi-agent coordination, tracing, a visual canvas. None of them change the idea.

Analogy. Every car has an engine, wheels, and a steering wheel. A pickup, a sports car, and a minivan feel completely different to drive, but you already know how to drive, so you can get in any of them. Frameworks are the body styles; the loop is the engine.

2. The same agent, nine ways

We build one agent everywhere: a tool multiply(a, b), asked "What is 23 times 17?". Here's how each framework spells the three steps, define a tool, make the agent, run it:

Framework Define tool Make agent Run
From scratch a tools=[{json schema}] + a Python fn the while loop call run()
LangGraph @tool on a fn create_react_agent(model, [tool]) agent.invoke({...})
CrewAI @tool("name") Agent(role, goal, tools, llm) + Task + Crew crew.kickoff()
AutoGen a plain Python fn AssistantAgent(model_client, tools=[...]) await agent.run(...)
Claude Agent SDK @tool(...) + create_sdk_mcp_server ClaudeAgentOptions(mcp_servers=...) query(prompt, options)
smolagents @tool (docstring schema!) ToolCallingAgent(tools, model) agent.run(...)
LlamaIndex FunctionTool.from_defaults(fn) FunctionAgent(tools, llm) await agent.run(...)
OpenAI Agents SDK @function_tool Agent(model, tools) Runner.run_sync(...)
n8n (no-code) a "Code Tool" node an "AI Agent" node + chat-model node click Execute

Read the table top-to-bottom: the columns are identical in meaning. That's the lesson.

3. Two things that bite beginners

The model string isn't the same everywhere. Frameworks that talk to Claude through LiteLLM (CrewAI, smolagents, OpenAI Agents SDK) need the provider prefix: anthropic/claude-opus-4-8. The ones with a native Anthropic integration (from-scratch, LangGraph, AutoGen, Claude Agent SDK, LlamaIndex) take the bare claude-opus-4-8. Same model, different label.

Python version + install drift. Several frameworks don't ship wheels for the newest Python yet, use Python 3.10-3.12. And these libraries move fast: an import path can change between versions. If something breaks, the pattern (model + tools + run) still holds; just check the current docs for the new name. (This is exactly why M9 says "build the loop by hand first.")

4. How to choose (the actually-useful part)

  • Just need one agent with tools? Any of them. LangGraph if you want explicit graph control; LlamaIndex if you're already doing RAG there; the Claude Agent SDK if you want to reuse the MCP tools you built in M16; smolagents if you want minimal.
  • Need a team, agents talking to / handing off to each other? CrewAI (role-based crews) and AutoGen (conversational multi-agent) are built for that. They map straight onto the orchestration shapes from M18 (pipeline / router / fan-out / hierarchical).
  • Want non-developers to build or edit the agent? n8n (visual canvas, connects to hundreds of apps), great for ops and automation.
  • Production? Whatever your team can operate and debug. Add tracing/observability and the M10 guardrails + M18 oversight (human-in-the-loop) regardless of framework.

Don't collect frameworks. Pick one or two, go deep, and keep 01_from_scratch.py in your head so you always know what the framework is doing on your behalf.

5. Why "from scratch" still matters

When an agent misbehaves, loops forever, ignores a tool, burns tokens, the framework's abstraction is exactly what's in your way. Knowing the raw loop lets you reason about where it went wrong (bad tool schema? model never emitted tool_use? result fed back wrong?) no matter which framework wraps it.


Words you'll hear

Framework vs. from-scratch, ReAct loop, tool / function calling, LiteLLM (a router that gives many providers one interface), single-agent vs. multi-agent / crew, no-code / low-code (n8n), provider prefix (anthropic/…). Full definitions in the glossary.