by zoogeny | 2025-04-29 20:51:35+00:00
That is exactly what I am working on actually. I am trying to build a web app where the LLM writes 80%+ of the code. The end goal is to present the learnings as encountered on a realistic project. I am currently streaming it on Twitch but the goal is to make it into YouTube videos that document the process.

I should clarify the "perfect 0-iteration" since that would be an exaggeration. Like I said, that is the goal, but not always the outcome. For example, the latest versions of Cursor have an agentic flow that does things like notice when there are linter errors and it automatically fixes them. So a single prompt can end up with the agent itself making iterative changes, without my input. I also make exceptions to my "single prompt" aim when it is reasonable. It is a goal, not a restriction.

I more mean it is a change in intent when I am starting a new task. I do not expect to take a stab at the prompt and then iterate my way to a result. I expect to got 99% of the task done in a single prompt.

As an example from yesterday, I was integrating Prisma (an ORM for Typescript) into my project. Here is the task breakdown (which I had Gemini help to create):

* Install Prisma: Install Prisma: npm install prisma --save-dev, npm install @prisma/client.

* Create schema.prisma: Define models for User, Conversation, Message (reflecting Phase 1 structure initially + Phase 2 additions like User). Configure the datasource db block to use postgresql and read the connection URL from an environment variable (DATABASE_URL provided by Docker Compose).

* Run Migration Run Initial Migration: npx prisma migrate dev --name initial_schema. This will generate the SQL for Postgres and apply it to your local Dockerized DB. Generate Prisma client Generate Prisma Client: npx prisma generate

* Refactor DB code to use Prisma: Refactor existing Phase 1 database interaction logic (currently using sqlite3 driver?) to use the generated Prisma Client.

* Create the users table: Create a SQLite migration (or update DB init). Define a table named users with columns: <snipped SQL column description> Create a UNIQUE index on (provider, provider_id). Update type definitions in src/types/database.types.ts to include DatabaseUser."

* Update existing tables (conversations, artifacts) to use user_id:Ensure the user_id column in conversations and artifacts tables is NOT NULL and is intended to be a foreign key referencing users.id (though SQLite doesn't enforce FKs by default, design it that way). Remove any 'local' default value if previously set. Update database repository functions (conversationRepository, artifactRepository) to require userId for all creation and query operations (e.g., listArtifactsByUser(userId), getConversationById(conversationId, userId)).

Each of those bullets roughly corresponds to a single prompt. Before I start each task I create a brand new Cursor agent context. I don't use the prompt recommendations directly, instead I craft each one using Cursor @file references to give the necessary context. After each task is accomplished I check in the result.

As I mentioned, getting the LLM to write out the broken down tasks is super helpful. I can give a high level description of what I want to do (e.g. replace my hand written SQL with Prisma) and then tell the LLM "break this goal down into small tasks that an LLM should be able to complete".

I'm not an expert on this stuff (no one is yet, field is too new) so I'm just sharing what I'm doing and saying what has worked for me based on my limited experience.