AI Agents cheat sheet

A scannable AI Agents reference: 13 short snippets across 8 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
The agent loopA chatbot maps one message to one reply. An agent is given a goal and runs a loop: decide the next action, take itlesson
Tools and function callingThe model does not run your code. It emits a request naming a tool and arguments; your code executes it. Everything thelesson
Memory and retrievalA model sees only the tokens in the request. As a conversation grows, cost and latency rise while attention to earlylesson
Planning and task decompositionDecomposition is the decision of when the plan is produced and who produces it. The model is only one option. Choosinglesson
Agent frameworks comparedEvery framework offers the same core: run a model, dispatch the tool calls it requests, append the results, decide whenlesson
Model Context Protocol in practiceBefore a shared protocol, connecting N agent clients to M tool integrations needed N times M adapters, each with itslesson
Multi-agent patternsSplitting one agent into several is an engineering technique, not an intelligence upgrade. Every additional agent islesson
Guardrails, budgets and stopping conditionsAn agent with no ceiling is an unbounded loop with a credit card. You need four independent limits, because any one oflesson

Quick snippets

The agent loop

Chatbot versus agent

goal ──▶ [ think ] ──▶ [ act: tool call ] ──▶ [ observe result ]
            ▲                                          │
            └────────────── not done yet ◀─────────────┘
                             │
                        done / limit → final answer

Full lesson: The agent loop →

Tools and function calling

A tool is a described function

{
  "name": "lookup_order",
  "description": "Find one order by its id. Use this before answering anything about order status.",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": { "type": "string", "description": "Order id, e.g. 'A-1042'" }
    },
    "required": ["order_id"]
  }
}

Read tools and write tools

def send_email(to, subject, body):
    if not re.fullmatch(r"[^@\s]+@[^@\s]+", to or ""):
        return {"error": "invalid recipient"}
    if len(body) > 5000:
        return {"error": "body too long"}
    # irreversible actions go through approval, never straight through
    return {"status": "queued_for_approval", "to": to}

Full lesson: Tools and function calling →

Memory and retrieval

Retrieval-augmented generation

documents ─▶ split into chunks ─▶ embed ─▶ vector store
                                              │
question ─▶ embed ─▶ similarity search ─▶ top-k chunks
                                              │
                        prompt = question + chunks ─▶ answer

Retrieval-augmented generation

hits = index.search(embed(question), k=5)
context = "\n\n".join(h["text"] for h in hits if h["score"] > 0.75)

answer = model(f"""Answer using ONLY the context below.
If the answer is not there, reply "Not found in the provided documents".

Context:
{context}

Question: {question}""")

Full lesson: Memory and retrieval →

Planning and task decomposition

Four ways to structure the same task

plan-then-execute
  goal -> [ plan: s1, s2, s3 ] -> run s1 -> run s2 -> run s3 -> answer

interleaved (ReAct)
  goal -> think -> act -> observe -> think -> act -> observe -> answer

Full lesson: Planning and task decomposition →

Agent frameworks compared

The same agent in two shapes

# A plain loop: the same behaviour, no dependency
def run(goal, tools, max_steps=8):
    messages = [{"role": "user", "content": goal}]
    for _ in range(max_steps):
        reply = model(messages, tools=[t.schema for t in tools])
        messages.append(reply)
        if not reply.tool_calls:
            return reply.content
        for call in reply.tool_calls:
            messages.append(execute(call, tools))
    return None

Keeping the exit open

# Keep the run state in a shape you own, whatever the framework thinks
@dataclass
class RunState:
    run_id: str
    goal: str
    steps: list[dict]        # {tool, args, result, error, ms}
    tokens: int
    cost_usd: float

def to_framework(state: RunState) -> list:
    return [dict(s) for s in state.steps]      # thin, lossy, replaceable

Full lesson: Agent frameworks compared →

Model Context Protocol in practice

Running a server

# stdio: the client spawns the server as a child process
python -m orders_server

# streamable HTTP: the server runs independently, possibly remotely
python -m orders_server --transport streamable-http --port 8931

curl -s http://localhost:8931/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Running a server

{
  "mcpServers": {
    "orders": { "command": "python", "args": ["-m", "orders_server"] },
    "docs":   { "url": "https://mcp.internal.example.com/docs" }
  }
}

Operating MCP safely

ALLOWED = {"orders": {"lookup_order"}, "docs": {"search_docs"}}
WRITE_TOOLS = {"cancel_order", "refund_order"}

def dispatch(server: str, tool: str, args: dict):
    if tool not in ALLOWED.get(server, set()):
        return {"error": "tool not permitted in this environment"}
    if tool in WRITE_TOOLS and not current_run().approval_token:
        return {"error": "approval required"}
    return clients[server].call_tool(tool, args)

Full lesson: Model Context Protocol in practice →

Multi-agent patterns

Orchestrator and workers

def orchestrator_with_writes(goal):
    reads = [t for t in plan_subtasks(goal) if t["kind"] == "read"]
    reads_done = parallel_map(run_worker, reads[:4])

    writes = plan_writes(goal, reads_done)         # planned with real results
    for w in writes:                               # serialised, never parallel
        run_worker(w)
    return synthesise(goal, reads_done)

Full lesson: Multi-agent patterns →

Guardrails, budgets and stopping conditions

Implementing them

# cycle detection: the same call with the same arguments, twice
seen = collections.Counter()

def signature(call):
    return hashlib.sha256(f"{call.name}:{json.dumps(call.args, sort_keys=True)}".encode()).hexdigest()

def before_tool(call, seen, limit=2):
    sig = signature(call)
    seen[sig] += 1
    if seen[sig] > limit:
        raise LoopDetected(f"{call.name} requested {seen[sig]} times with identical arguments")
    return True

Full lesson: Guardrails, budgets and stopping conditions →

FAQ

Is this AI Agents cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 8 lessons of the AI Agents course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full AI Agents course — it carries the worked explanations, the edge cases and the exercises behind every line here.

AI Basics Math for AI Machine Learning scikit-learn TensorFlow PyTorch

Last refreshed 2026-09-27.