Create an Agent Class from Scratch in Python
Strip away LangChain, LangGraph, and CrewAI. In this lesson, we build a complete autonomous Agent class in vanilla Python to master the raw mechanics of message state, regex action parsing, function dispatching, and loop control.
1. Core Architecture of a Vanilla Python Agent
Select a component to inspectPython Implementation Inspector
# 1. SYSTEM PROMPT: Enforcing the strict ReAct grammar
REACT_SYSTEM_PROMPT = """
You run in a loop of Thought, Action, PAUSE, Observation.
At the end of the loop you output an Answer.
Use Thought to describe your thoughts about the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Observation will be the result of running those actions.
Your available actions are:
calculate:
e.g. calculate: 4 * 7 / 3
Runs a calculation and returns the number
get_planet_mass:
e.g. get_planet_mass: Jupiter
Returns the mass of a celestial body
Example session:
Question: What is the mass of Earth times 2?
Thought: I need to find the mass of Earth first.
Action: get_planet_mass: Earth
PAUSE
""".strip()2. Interactive Scratch Agent Debugger
Step-by-Step Message MemoryPure Python Agent Class Execution DebuggerZero Frameworks
Step line-by-line through the raw Python mechanics of self.messages, regex dispatch, and tool execution
Initialize Agent with system prompt and dictionary of callable actions.
agent = Agent(
system="You run in a loop of Thought, Action, PAUSE, Observation.",
actions={"calculate": calculate, "get_time": get_time}
)Common Engineering Traps
If an agent enters a state where the LLM repeats the same failing tool call indefinitely, an unbounded while True: loop will rapidly drain your API quota and spike latency. Always enforce a strict max_turns parameter (typically 5 to 10 iterations max).
Allowing an agent to pass arbitrary string arguments into Python's native eval() or exec() introduces catastrophic Remote Code Execution (RCE) vulnerabilities. Always sanitize expressions using AST parsing or dedicated math parsers like numexpr.
Key Architectural Takeaways
- 1.Three Core State Elements: A stateful agent only needs three things: a system prompt contract, a mutable message history list, and a dictionary of callable Python functions.
- 2.The ReAct Loop Cycle: The cycle consists of Model Invocation -> Action Parsing -> Local Function Dispatch -> Observation Injection. This repeats until the model emits an Answer.
- 3.Framework Decoupling: Understanding this architecture allows you to easily debug LangGraph or CrewAI traces, because you know what every node and edge translates to under the hood.
Building Tools with Schema Validation (Pydantic)
Upgrade from fragile text parsing to industry-standard Pydantic schemas. Learn how modern LLMs use function calling with type-enforced JSON validation.