Show HN: Recreated Claude Code's behavior in 280 lines of Python

4 ljw1004 1 9/4/2025, 4:01:39 PM github.com ↗
The magic in AI coding assistants isn't the code -- it's the prompts.

I studied the externally observable behavior of Claude Code and recreated it from scratch in Python with the exact same behaviors. It works with any model -- OpenAI, Gemini, Claude. What's surprising:

1. You can keep the core agent really simple, just 280 lines of Python. As long as it supports hooks, custom sub-agents and Model Context Protocol (MCP), then all the rest of the coding-assistant-specific behavior and tools can be factored out into a separate MCP server.

2. The magic is in the prompts (1200 lines of system-prompt, tool-descriptions, system-reminders), not the tool implementations (400 lines of code) nor the core agent itself. I created my own crummy prompts, and so get much worse results from this assistant than from Claude.

3. The magic is also in the UX. This mini-agent has none of Claude's polished UX, none of its permissions system, none of its file-based configurability. It's not fun to use. It's really just an educational toy.

4. Coding assistants are "transparent" in the sense that there aren't hidden depths, and you can see what's going on. "Hey agent, please list for me all your built-in tools. Please study their input schemas and create a suite of test-cases to exercise all edge cases. Please study this suite of test-cases written by a junior developer and fill in the gaps. Please implement a function which satisfies all the test-cases." (Those four sentences are a glib summary of what really took me four hours per tool.)

Modern AI coding assistants took huge effort to create and get right. It's striking that the end result has such a straightforward architecture. And what is that architecture? I'll let it speak for itself...

    $ python3 -m venv venv
    $ source venv/bin/activate
    $ pip install -r requirements.txt

    $ export GEMINI_API_KEY=redacted
    $ ./mini_agent.py --model gemini/gemini-2.5-pro

    [MODEL: gemini/gemini-2.5-pro + gemini/gemini-2.5-flash]
    [IMPLICIT --mcp builtin]
    [TRANSCRIPT: /Users/ljw1004/.claude/projects/default/2025-09-01.jsonl]

    > Please analyze the files in my current directory and tell me what they do.

      >> <system-reminder># CLAUDE.md (project instructions) ...</system-reminder>
      >> <system-reminder>Your TODO list is empty. Remember that the TodoWrite tool is a great
         way to stay on top of complex tasks.</system-reminder>
     [7193 input tokens, 202 response tokens]
      >> LS(...) -> "- /Users/ljw1004/code/mini_agent/\n  - CLAUDE.md\n  - LICENSE
     [4042 cached input tokens, 3912 further input tokens, 204 response tokens]
      >> Read(...) -> "    1→# Mini-agent\n    2→\n    3→
      >> Read(...) -> "    1→#!/usr/bin/env python3\n    2→\n    3→from __future__
      >> Read(...) -> "    1→from __future__ import annotations\n    2→from path
      >> Read(...) -> "    1→from __future__ import annotations\n    2→from typi
      [55145 input tokens, 5650 further input tokens, 194 response tokens]

    < This project is a minimal coding assistant. Here's a breakdown of the key files:
    *   `mini_agent.py`: The main script that runs the interactive agent loop.
        It takes user input, communicates with an LLM, and uses tools to perform tasks.
    *   `core_tools.py`: Implements the core functionalities (tools) that the agent
        can use, such as reading/writing files (`Read`, `Write`, `Edit`), searching
        (`Grep`, `Glob`), and running commands (`Bash`).
    *   `typedefs.py`: Defines the data structures and types used for messages, tools,
        and conversation history (transcripts).
    *   `adapter.py`: A module that connects to different Language Models (like GPT,
         Claude, Gemini) through the `litellm` library, allowing the agent to be
         model-agnostic.
    *   `test/`: Contains unit tests for the project.

Comments (1)

zahlman · 1d ago
Now this is what an AI-related Show HN should be. You demonstrate something about how the technology works; you provide something usable; and you aren't trying to sell anything. Kudos.

I don't think the "straightforward architecture" is all that surprising, though. Once you've identified an entire LLM as a single "moving part", and have the idea of allowing its output to be interpreted as commands (and have wrappers available to connect to the LLM's API), the rest pretty much writes itself.