Building a Self-Evolving AI Agent in Under One Hundred Lines of Lisp
By leveraging Common Lisp's homoiconic nature, developers can build a recursive agent loop that dynamically writes, compiles, and registers its own tools.

Why it matters
You can design highly minimal agent systems where the LLM writes its own runtime code to expand its active tool catalog.
TL;DR
- 01Replaces bulky orchestrators with a clean 100-line SBCL agent utilizing basic recursion.
- 02Enables self-evolving toolsets where the LLM writes and compiles its own HTTP requests and parsers.
- 03Demonstrates the conceptual power of homoiconicity for model-driven programming loops.
Key facts
- Agent Core Size
- 8 lines of Common Lisp
- Total Codebase Size
- ~100 lines of SBCL
The Minimalist Lisp Agent Loop
An elegant recursive agent loop can be implemented in Common Lisp in just a few lines of code. The model's state is simply folded as arguments through the recursive stack:
(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 (execute-tools tool-calls)))
messages))Self-Evolving Tool Catalogs via Eval
Instead of pre-programming tools like file readers, calculators, or web crawlers, the agent is given a single, powerful tool: the language compiler itself via eval and read-from-string. When asked to complete a task requiring external data, the model writes the necessary Lisp code, compiles it into the live image, and runs it immediately. This permits runtime adaptation without altering the core codebase.
*Caveat: Exposing an arbitrary code execution tool (eval) to an LLM poses massive security risks. This pattern must always run inside an isolated, local Docker sandbox.*
Try it in 2 minutes
(defun agent-loop (messages)
(let* ((msg (call-model messages))
(tool-calls (gethash "tool_calls" msg)))
(if tool-calls
(agent-loop (append messages (execute-tools tool-calls)))
messages)))common-lisp
✓ When to use
- When exploring sandboxed agent concepts that require zero overhead and minimal orchestration dependencies.
- To research dynamic tool creation and self-modifying software loops.
✕ When NOT to use
- In production pipelines or public servers where untrusted model outputs could compromise the host machine.
- If your team lacks familiarity with Lisp-based environments like SBCL.
What to do today
- Run a local SBCL instance inside a sandboxed Docker container to safely test the execution loop
- Experiment with passing the 'eval' tool to Claude inside your Lisp environment