Building a Coding Agent with LLM: A Deep Dive into Simon Willison's llm-coding-agent Experiment
Building a Coding Agent with LLM: A De…
Simon Willison bootstrapped a Claude Code-style coding agent using two prompts and TDD via his LLM library.
Simon Willison's llm-coding-agent 0.1a0 demonstrates how far coding agent democratization has come: built almost entirely by AI using just two prompts and a strict TDD workflow, the project implements a complete toolset for file operations, command execution, and search — closely mirroring tools like Claude Code — while highlighting the emerging "AI building AI" recursive development pattern.
When an LLM Library Evolves into an Agent Framework
Well-known developer and Datasette creator Simon Willison recently released an experimental project — llm-coding-agent 0.1a0. This is his latest venture following a series of AI experiments he calls "Fable" experiments. The motivation is straightforward: his open-source LLM library has gradually evolved from a simple model-calling utility into a framework with genuine Agent capabilities — so what would it look like to build a Claude Code-style coding agent on top of it?
Simon's LLM library was originally designed as a command-line tool and Python API for unified access to model providers like OpenAI, Anthropic, and Google. The pivotal moment in its evolution into an Agent framework was the maturation of Function Calling / Tool Use capabilities in large language models — OpenAI introduced Function Calling in June 2023, and Anthropic followed with Tool Use. These features transformed models from mere "question-answering machines" into systems capable of actively invoking external functions and continuing to reason based on the results, forming a closed "perceive-decide-act" loop. The widespread adoption of this underlying capability is what allowed a personally maintained LLM abstraction library to support a complete Agent workflow.
This question is itself quite representative. As tool-calling capabilities in large models mature, "coding agents" are no longer the exclusive domain of large tech companies. A solid LLM abstraction layer, combined with a carefully designed set of tool functions, is sufficient to build a functional automated coding assistant. Simon's experiment is a firsthand validation of exactly this trend.
Building AI with AI: TDD-Driven Bootstrapped Development
The most noteworthy aspect is that this coding agent was itself almost entirely written by AI.
Simon created a new project from his python-lib-template-repository template and completed the entire development process with just two prompts.
The first prompt generated the spec document:
Write a spec.md for this project - it will depend on the latest "llm" alpha from PyPI and implement a Claude code style coding agent complete with tools for reading and editing files and executing commands
The second prompt instructed the AI to build the project using strict Red/Green TDD in a series of sensible commits:
Commit the spec, then build it using red/green TDD in a series of sensible commits (each with passing tests and updated docs) - occasionally manually test it using the OpenAI API key in your environment
Red/Green TDD is the core rhythm of test-driven development: first write a test that must fail (red), then write the minimum code to make it pass (green), then refactor. This methodology was systematized by Kent Beck in Test-Driven Development: By Example and is a cornerstone of Extreme Programming (XP). Embedding it into an AI-assisted workflow means every piece of AI-generated code must satisfy verifiable test constraints, effectively reducing the risk of hidden errors caused by AI hallucination — every commit comes with passing tests, acting as a mechanical safeguard against the AI's autonomous creativity.
This process emphasizes three engineering best practices: spec before implementation, every commit accompanied by passing tests and updated documentation, and manual verification with a real API key. This isn't simply "letting AI write some code" — it's embedding mature software engineering methodology into an AI-collaborative workflow. The entire development process was completed via Claude Code for web, and the spec, README, and commit sequence are all publicly available.
It's worth noting that this recursive bootstrapping pattern of "using AI to build AI tools" is not new. GitHub Copilot's team used Codex to help optimize Codex prompts in its early days, and Anthropic's Constitutional AI includes self-iteration mechanisms where the model evaluates its own outputs. The philosophical significance of this recursive pattern is that it blurs the boundary between "tool creator" and "tool user," while also placing higher demands on the developer as a reviewer — as AI gains the ability to autonomously extend designs, the human engineer's role gradually shifts from "code writer" to "intent definer and quality gatekeeper."
The Agent Toolset: The "Hands" and "Eyes" of a Coding Assistant
At the heart of any coding agent is what tools it can operate. llm-coding-agent automatically implements a fairly complete toolset, viewable via uvx ... llm tools.
The design of a coding agent's toolset is fundamentally a balance between the principle of least privilege and auditability. Mature products like Claude Code, Devin, and Cursor all use a similar combination of file read/write + command execution + search tools. This combination covers the four core operations of code comprehension (read), modification (write/edit), validation (execute), and navigation (search/list) — a minimum viable toolset proven by industry practice.
File Reading and Writing
- read_file: Reads a text file and returns its content with line numbers (similar to
cat -n), withoffsetandlimitsupport for paginating through large files; - write_file: Creates or overwrites a file, automatically creating parent directories as needed;
- edit_file: Precisely replaces a string within a file —
old_stringmust exactly match the file content (including whitespace) and be uniquely locatable, and returns a diff for verification.
The requirement for edit_file to use exact, unique matching and return a diff draws from version control system design — git's patch format is based on the same "contextually unique location" precise replacement logic, effectively preventing the agent from accidentally modifying non-target code segments in large files. This is the standard approach in mature tools like Claude Code.
Command Execution and File Search
- execute_command: Runs a shell command in the session's root directory, returning combined stdout/stderr and exit code, with timeout protection (max 600 seconds; timeout terminates the entire process tree);
- list_files: Lists files matching a glob pattern, automatically skipping hidden directories,
node_modules,__pycache__, and content covered by.gitignore, returning at most 200 paths; - search_files: Searches file contents with a regular expression, returning matches in
path:line:contentformat.
This toolset covers five core operations — read, write, edit, run, and find — with thoughtful design around security (timeout protection, ignore rules, path restriction), effectively replicating the capability boundaries of mainstream coding agents.
A Pleasant Surprise: A Python API Nobody Asked For
Beyond the CLI, the AI proactively implemented a class-based Python API that was never requested in Simon's prompts:
CodingAgent(model="gpt-5.5", root="/path", approve=True).run("Fix the failing test in tests/test_parser.py")
Simon described this as a "surprise." This detail illustrates a notable characteristic of current AI-assisted programming: models don't just complete assigned tasks — they proactively supplement reasonable interface designs based on their understanding of the project's intent. This kind of "over-delivery" is both a demonstration of capability and a reminder that developers need to review the AI's autonomous additions — not all "bonus features" are desired. From a software engineering perspective, this also reveals an interesting trait of current large models: having been trained on vast amounts of well-designed open-source libraries, they naturally "reproduce" these best practices when generating projects, even without being explicitly asked.
The generated README also lists useful invocation recipes, such as llm code --yolo (disabling approval) and llm code --allow "pytest*" --allow "git diff*" (whitelisting commands by pattern). This kind of fine-grained permission control — analogous to Linux's sudo whitelist mechanism — is a critical design feature for making coding agents practically usable, providing an adjustable trade-off between "automation efficiency" and "human oversight."
In Practice: Getting GPT-5.5 to Draw an ASCII Clock in SwiftUI
Simon tested the agent with a slightly mischievous task. After running llm code --yolo, he requested that the agent create a CLI application in /tmp/demo using SwiftUI to display the current time in ASCII art.
Interestingly, GPT-5.5 directly noted during its reasoning that "SwiftUI isn't really suited for a true CLI" — a technically accurate assessment: SwiftUI is Apple's declarative framework designed for GUI applications, with a rendering pipeline that depends on AppKit/UIKit and is not suited for writing to standard streams (stdout). The model nonetheless went on to build a working application, likely using a hybrid approach (e.g., using the Foundation framework for output logic while referencing SwiftUI concepts structurally). After running swift run AsciiTime, the program successfully printed the current time in ASCII art. This case demonstrates both an Agent's real-world ability to complete tasks end-to-end, and a model's ability to make judgment calls when a request contains technical contradictions and find workarounds — precisely the capability that distinguishes a "code completion tool" from a true "Agent."
Quick Start
The project has been published to PyPI as a pre-release (which Simon humorously calls a "slop-alpha") and can be run directly:
uvx --prerelease=allow --with llm-coding-agent llm code
The uvx command here is part of the uv toolchain developed by Astral, allowing PyPI packages to be executed directly in an isolated environment without manual installation — similar to npx in the Node.js ecosystem. uv is written in Rust and is 10–100x faster than traditional pip, rapidly becoming the new standard in Python's modern toolchain. The --prerelease=allow flag corresponds to the "slop-alpha" pre-release status Simon mentioned, reflecting the open-source culture of rapid iteration and public experimentation.
Closing Thoughts: A Clear Signal of Coding Agent "Democratization"
Simon Willison's experiment, though only an early 0.1a0 release, sends a clear signal: the barrier to building a functional coding agent is dropping rapidly. When an underlying LLM library provides mature tool-calling abstractions, combined with disciplined TDD workflows and a thoughtfully designed toolset, an individual developer can bootstrap a Claude Code-style coding assistant in two prompts and a few hours.
Equally thought-provoking is the recursive pattern of "AI building AI tools" — it both showcases the current boundaries of large models' engineering capabilities and provides a vivid example for thinking about the future shape of software development. From a broader perspective, this trend of "individual developers using AI to replicate core features of big-tech products" closely parallels the historical trajectory of the open-source movement replicating commercial software: technological democratization is happening, and this time the accelerant is the large model itself. For developers who want to deeply understand the inner workings of coding agents, this open-source project's spec, commit history, and tool implementations are all excellent learning material.
Key Takeaways
Related articles

Grok 4.5 Feels Weaker in Cursor? A Deep Dive into AI Coding Tool Integration Differences
Users report Grok 4.5 underperforms in Cursor vs. the official terminal. We analyze how system prompts, context management, parameters, and tool calling create AI coding tool integration gaps.

Carta: Pandoc Rewritten in Rust — 45x Faster, 20x Smaller
Carta is a Rust reimplementation of Pandoc with a 9MB binary (1/20th of Pandoc) and up to 45x faster conversion. Supports Markdown, DOCX, LaTeX, and Pandoc JSON filters.

A Beginner's Guide to AI Agents: Core Principles and Learning Paths Explained
Learn AI Agent core principles from scratch: understand how Agents differ from LLMs, their execution mechanisms, why rule design matters, and find the right learning path for your goals.