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
| Topic | What it covers | |
|---|---|---|
| The agent loop | A chatbot maps one message to one reply. An agent is given a goal and runs a loop: decide the next action, take it | lesson |
| Tools and function calling | The model does not run your code. It emits a request naming a tool and arguments; your code executes it. Everything the | lesson |
| Memory and retrieval | A model sees only the tokens in the request. As a conversation grows, cost and latency rise while attention to early | lesson |
| Planning and task decomposition | Decomposition is the decision of when the plan is produced and who produces it. The model is only one option. Choosing | lesson |
| Agent frameworks compared | Every framework offers the same core: run a model, dispatch the tool calls it requests, append the results, decide when | lesson |
| Model Context Protocol in practice | Before a shared protocol, connecting N agent clients to M tool integrations needed N times M adapters, each with its | lesson |
| Multi-agent patterns | Splitting one agent into several is an engineering technique, not an intelligence upgrade. Every additional agent is | lesson |
| Guardrails, budgets and stopping conditions | An agent with no ceiling is an unbounded loop with a credit card. You need four independent limits, because any one of | lesson |
Quick snippets
The agent loop
Chatbot versus agent
goal ──▶ [ think ] ──▶ [ act: tool call ] ──▶ [ observe result ]
▲ │
└────────────── not done yet ◀─────────────┘
│
done / limit → final answer
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 -> answerFull 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, replaceableFull 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 TrueFull lesson: Guardrails, budgets and stopping conditions →
FAQ
Is this AI Agents cheat sheet free to use?
Where do the examples come from?
How do I go deeper than a cheat sheet?
Related cheat sheets
AI Basics Math for AI Machine Learning scikit-learn TensorFlow PyTorch
Last refreshed 2026-09-27.