What Is an Agent?¶
An agent is an LLM that can take actions in a loop — not just generate text, but reason about what to do, use tools, observe results, and decide what to do next.
From LLM to Agent¶
graph LR
A[LLM] -->|+ tools| B[LLM with Tools]
B -->|+ loop| C[Agent]
C -->|+ coordination| D[Multi-Agent System]
| Level | What It Does | Example |
|---|---|---|
| LLM | Generates text from a prompt | "Translate this sentence" |
| LLM + Tools | Generates text OR requests tool calls | "What's the weather?" → calls get_weather() |
| Agent | Loops: reason → act → observe → repeat | Customer support bot that looks up orders, checks FAQs, processes refunds |
| Multi-Agent System | Multiple agents coordinating | Triage → specialist handoff, parallel analysis |
The Agent Loop: Reason → Act → Observe¶
The core of every agent is a simple loop:
graph TD
A[Receive task] --> B[Reason: What should I do?]
B --> C{Need a tool?}
C -->|Yes| D[Act: Call the tool]
D --> E[Observe: Read the result]
E --> B
C -->|No| F[Respond: Deliver the answer]
In code (using the OpenAI SDK), this maps directly to:
- Reason: Call the model with messages + tools → model decides what to do
- Act: If
finish_reason == "tool_calls", execute the requested tools - Observe: Append tool results to messages, loop back to step 1
- Respond: If
finish_reason == "stop", the model has its final answer
This loop is implemented in exercises/commons/agent.py and used throughout the workshop.
What Makes a Good Agent?¶
An effective agent has:
- Clear identity — A focused system prompt defining its role and constraints
- Appropriate tools — Access to the specific functions it needs (and nothing more)
- Bounded behavior — A maximum iteration limit to prevent infinite loops
- Structured reasoning — The model explains its actions through the conversation flow
Agents are not autonomous
In this workshop, "agent" means an LLM + tools + loop. The agent operates within boundaries you define: specific tools, a system prompt, and a maximum number of iterations. It makes decisions about which tool to call, but you control what tools are available.
The Minimal Agent Abstraction¶
This workshop uses a deliberately simple agent abstraction — a Python dataclass:
@dataclass
class Agent:
name: str
system_prompt: str
tools: list # Tool definitions (JSON schemas)
tool_functions: dict # Mapping of name → callable
model: str
max_iterations: int = 10
And a run() function that implements the loop. No inheritance, no metaclasses, no registration — just a data structure and a function. This makes it easy to understand exactly what happens on every iteration.
Agent vs. Framework Agent¶
| This Workshop | Microsoft Agent Framework | Pydantic AI |
|---|---|---|
Agent dataclass |
AssistantAgent |
Agent class |
run() function |
Graph-based orchestration | agent.run() |
messages list |
ChatMessage types |
Message history |
Python dict handoff |
HandoffTermination |
Tool-based delegation |
dataclass context |
AgentContext |
Dependency injection |
By building the agent yourself, you understand what every framework does internally.
Ready to practice?
Continue with the hands-on exercise in the sidebar (✏️) to apply what you've learned.
Key Takeaways¶
- An agent = LLM + tools + loop (Reason → Act → Observe)
- The agent loop runs until the model produces a final text response (
finish_reason="stop") - Agents are bounded — maximum iterations prevent infinite loops
- System prompts define agent identity; tools define agent capability
- Our minimal
Agentdataclass +run()function is everything you need
References¶
- Lilian Weng — "LLM Powered Autonomous Agents"
- Andrew Ng — "What's next for AI agentic workflows" (YouTube)
- Anthropic — "Building Effective Agents"
- MS Learn — AI Agent Design Patterns
- ReAct: Synergizing Reasoning and Acting in Language Models (Yao et al., 2023)
Hands-On Exercise¶
Head to the Single Agent exercise — build a customer support agent with order lookup, FAQ search, and refund processing tools.
You can run it from the terminal or use the Workshop TUI.