An Agent in 100 Lines of Lisp
A post on The Beach shows a complete agent written in 100 lines of Common Lisp: recursive loop, model call, tool execution. No dependencies beyond HTTP and JSON. The entire loop fits in 8 lines: base case (model responds), recursive case (wants tools, executes them, calls itself). The agent’s state is just the argument flowing through recursion.
Why it matters to you: if you’ve followed the course lessons on your first useful agent or downloaded the minimal scaffolding, this implementation is the bare skeleton of what’s underneath. There’s only one tool: eval. The model writes Lisp code as a string, the agent executes it and returns the result. No tool catalog, no framework: the language itself becomes the interface. For Fibonacci(30), the model wrote the recursive function, executed it with eval, and returned 832040. Two calls, zero prefab prompts.
It’s a sandbox experiment (open eval is a clear security risk), but the idea is instructive: Lisp is homoiconic (code is made from the same data structure as the program), so a program can build and modify other code like it’s a shopping list. It’s the property that 25 years ago made Lisp “the language of symbolic AI”. Today that promise materializes differently: the model generates the code, Lisp executes it, and the recursive loop holds it all together. 114 points on Hacker News say the idea hit home.
In detail
Context
Around 2000, Lisp was considered the language of symbolic artificial intelligence: expert systems, theorem provers, programs that manipulated symbols and rules. Then statistical methods won, deep learning buried them, and Lisp became a historical curiosity for most developers. The post’s author learned Lisp in an AI course at the University of Guelph and never saw it used after.
Today building an AI agent platform, he asks: could Lisp still be useful for an agent loop? The answer is yes, but for different reasons than in 2000.
Agent anatomy
The complete implementation (available on The Beach) uses SBCL (Steel Bank Common Lisp), two libraries (dexador for HTTP, shasht for JSON), and nothing else. The recursive loop:
lisp (defun agent-loop (messages) (let* ((message (ref (call-model messages) choices 0 message)) (tool-calls (gethash tool_calls message))) (if (and tool-calls (plusp (length tool-calls))) (agent-loop (append messages (list message) (map list # execute tool-calls))) (append messages (list message)))))
Eight lines. If the model responds, it returns the history. If it requests tools, it executes them, appends the results, and calls itself again. The state is just the message list flowing through recursion. No state machine, no global variables.
The trick: eval as the only tool
Most agents have a tool catalog (web search, file read, python exec). This agent has one tool: eval. The model writes a Lisp form as a string, the agent reads it (read-from-string), executes it (eval), and returns the printed result.
lisp (defun lisp-eval (form-string) (handler-case (format nil “~s” (eval (read-from-string form-string))) (error (e) (format nil “ERROR: ~a” e))))
This is possible because Lisp is homoiconic: code is written in the same data structure (lists) that the language manipulates. A Lisp program can build and modify other Lisp code as easily as it builds a shopping list. In the post’s transcript, the agent calculated Fibonacci(30) in two steps: first it defined the function in the runtime, then called it.
Declared limits
The author is clear about it: open eval is a security risk. The model executes arbitrary code on the machine. This is a sandbox experiment, not a production recipe. The author ran it only in a local Docker container.
But the idea holds as a teaching tool: it shows what’s underneath an agent without framework, without abstractions, without dependencies. It’s like writing an HTTP server in 50 lines to understand what Express or Flask do behind the scenes.
Why now
Lisp’s original promise was “programs that manipulate programs”. In 2000 that meant hand-written symbolic rules. In 2026 it means: the model writes the code, Lisp provides the substrate where that code runs, and the recursive loop holds it all together. Symbolic work has been outsourced to the model, but Lisp’s homoiconic property makes execution immediate.
If you’re building agents or following the builder path of the course, this post is worth reading: it’s clean anatomy, no frills, of how a loop works. And if you’ve ever thought “I want to understand what’s really under the hood before using a framework”, this is the kind of code that shows you.