How I start a new project with AI coding agents¶
This page is not really documentation. It is me writing down how I actually start a project with SpeedPy and AI coding agents, because people keep asking, and because the process is not obvious if you have never done it.
The code is not the hard part anymore. The hard part is saying what you want clearly enough that the agent cannot get it wrong. If you have never written a spec, or never worked with an agent on something bigger than one file, that is where things fall apart. So most of this page is about the spec, and only a small part is about the building.
Everything here is what I do, not a demo I made up for the docs. Your setup may differ, and that is fine, but I would follow the order.
You do not need to know Django
You do not need to have written a spec before either. You do need to know what you want to build, and you need to be willing to answer questions about it in writing.
The short version¶
I write a rough spec in my own words. I let an agent tear it apart with questions until there are no holes left. Then I let a second agent, from a different company, tear it apart again, because it fails in different places. Then I turn that into an implementation spec, deploy the untouched boilerplate so I know deployment works, and only then let the agents build. One phase at a time, each phase reviewed by the other agent and deployed before the next one starts.
What you need¶
| SpeedPy, installed and running | See Installation, and the mode comparison below |
| Two coding agents from two different companies | I use Claude Code as my main agent and Codex CLI for reviews. Any two work, as long as they are not the same model |
| An Appliku account | Optional, but one of the steps below is much easier with it |
I will write Claude Code and Codex everywhere on this page, because that is my setup. Swap them around if you like. What matters is that two different companies are involved, not which one leads.
Step 1. Install the boilerplate and pick a mode¶
Start with the one-liner:
Or clone it yourself:
Now you pick how the project runs on your machine. There are two init scripts and they are not the same thing.
So which one?¶
Docker mode (init-docker.sh) |
Local mode (init-local.sh) |
|
|---|---|---|
| You need installed | Docker, or Docker Desktop | uv, plus Node and npm on your machine |
| Database | PostgreSQL in a container | SQLite, a file called db.sqlite3 |
| Redis | Yes, in a container | None |
| Background tasks | A real Celery worker and Celery Beat | Celery runs tasks inline, in the same process |
| Running commands | docker compose run --rm web python manage.py ... |
uv run python manage.py ... |
| How close to production | Same services as production | Different database, different task setup |
| Startup time and machine load | Higher | Lower |
If you are not sure, pick Docker mode. It looks like production, so problems show up on your laptop instead of on your server. Pick local mode if you want the lightest possible loop, you do not have Docker, or you are building something that never touches background tasks.
Either script writes an AGENTS-local.md file for you. That is the file that tells your agent whether to put docker compose run --rm web or uv run in front of commands. AGENTS.md tells the agent to read it before running anything, so it never has to guess. It is git-ignored, because it describes your machine, not the project.
Actually run it and click around
Open the app in the browser, log in with the superuser from local_password.txt, and use it a bit before you write any spec. You need to know what is already there. Teams, billing, login, two factor, the API, all of it is built. Otherwise you will write a spec asking an agent to build something you already have.
Step 2. Write the first draft of the spec yourself¶
There is an empty specs/ folder in the boilerplate. That is where this lives.
Write this one yourself. Do not ask an agent to generate it. This draft is the one part of the whole process where what is in your head is the input, and nobody else can do it for you.
Write about the product, not about the technology. No database tables, no library names, no API design. If you notice yourself writing models.py, delete the sentence.
Here is the shape I use every time:
# Project name
## What it is
One or two paragraphs. What it does, and what problem it takes
away. Normal language, like you are telling a friend.
## Target audience
Who uses it. Be specific. "Freelance designers who invoice 5 to
20 clients a month" tells you something. "Small businesses" does
not.
## Jobs to be done
### JTBD 1: <the job, in the user's words>
1. Step the user takes
2. Step the user takes
3. What the system does about it
4. What the user sees at the end
### JTBD 2: <next job>
1. ...
## Other notes
Everything else. Requirements, constraints, things you want,
things you definitely do not want, integrations, pricing ideas,
rules that must always hold. Any order. This part is allowed to
be a mess.
The Jobs To Be Done part is what does the work. Each job is one thing a person is trying to get done, split into the steps they take, or the steps that happen on their own. Those steps are what stop an agent from inventing a flow you never asked for.
A short example¶
# LateNudge
## What it is
LateNudge chases unpaid invoices so freelancers do not have to.
You add an invoice with a due date and a client email. Once the
due date passes, LateNudge sends polite reminders on a schedule
you choose, and stops the moment you mark the invoice as paid.
## Target audience
Freelance designers, developers and consultants who send 5 to 20
invoices a month, work alone or in a team of two or three, and
hate writing "just following up" emails.
## Jobs to be done
### JTBD 1: Add an invoice to be chased
1. The user opens the dashboard and clicks "Add invoice".
2. The user enters client name, client email, amount, currency,
invoice number and due date.
3. The user picks a reminder schedule, or keeps the default.
4. The system saves the invoice as "awaiting payment" and shows
when the first reminder would go out.
### JTBD 2: Reminders go out on their own
1. Once a day the system looks for invoices that are past due
and not paid.
2. For each one it decides if a reminder is due today, based on
that invoice's schedule and the last reminder sent.
3. It emails the reminder to the client, with invoice number,
amount and due date.
4. It records the sent reminder on the invoice, so the user can
see the whole history.
### JTBD 3: Stop chasing a paid invoice
1. The user clicks "Mark as paid" on the invoice.
2. The system sets the invoice to "paid" and cancels every
future reminder for it.
3. No more email is ever sent for that invoice.
## Other notes
- Default reminder schedule: 1 day after due, then 7, 14, 30.
- The user must be able to edit the email text for each step.
- Teams: everyone in a team sees the same invoices.
- Never email a client on a weekend.
- Not in v1: taking payments, PDF invoices, accounting
integrations.
Look at how much is missing there. Time zones. What happens when the email bounces. Whether you can undo "paid". That is on purpose. Finding those holes is the next step's job, not yours.
Step 3. Let an agent pick it apart¶
Open your main agent in the project folder, start a new chat, and ask it to find what is wrong with your document:
Read specs/spec.md. Help me improve it. Ask me questions about gaps
in the spec, missing information, contradictions, and anything that
needs clarifying. Do not write any code and do not edit the spec.
You will get questions. Some you will read and think "obviously". Others will point at decisions you did not know you were making.
Answer in the file, not in the chat
This is the most important habit on this page. When you answer a question, go and edit specs/spec.md so the answer lives in the document. Then tell the agent to read the file again.
Answers typed into a chat are gone the second that chat ends. Answers written into the spec are still there for the next agent, the next chat, and for you in six months when you have forgotten all of it.
Then go around again:
Re-read specs/spec.md. I answered your previous questions in the
document. Another round please. What gaps, contradictions or unclear
parts are left?
Keep doing that. Each round should give you fewer and smaller questions. Carry on until the questions start to feel like nitpicking. That is the moment to change the prompt and raise the bar:
Re-read specs/spec.md. Raise only critical concerns. Things that would
block the implementation or seriously damage it if left unresolved.
When that comes back with nothing, this chat is done.
Then open a fresh chat and ask again¶
Read specs/spec.md. Help me improve it by asking about gaps, missing
information and contradictions. Raise only critical concerns.
Same file, same question, new chat. This matters more than it sounds. An agent that has been talking to you about your spec for an hour has picked up all your explanations and assumptions along the way. It stops reading the document and starts remembering the conversation. A fresh chat only has the file, which is exactly what the implementing agent will have too.
If the fresh chat finds real problems, your spec was leaning on the conversation. Fix the file and do it again.
Step 4. Ask the other company's agent¶
When my main agent has nothing critical left, I take the same final question to an agent from a different company. If I have been talking to Claude Code, now I ask Codex.
codex exec "$(cat <<'EOF'
Read specs/spec.md in this repository. Help me improve it by asking
questions about gaps in the spec, missing information, contradictions,
and anything that needs clarifying. Raise only critical concerns.
Do not write code and do not edit the spec.
EOF
)"
They are different models, from different companies, trained on different data. They think differently. They are good in different places and blind in different places. Asking the second one is not a formality. It is asking another person what they think, and it keeps finding things the first one missed.
Answer these the same way, in the file. When both of them are quiet, specs/spec.md is finished.
Step 5. Turn it into an implementation spec¶
Your spec now describes the product well. It still says nothing about how to build it. That is a different document, and this is the point where two agents stop being a nice idea and become the only way I do it.
New chat in the main agent:
Given this initial spec in specs/spec.md, look at it and write me the
final spec suitable for implementation of the project. Use codex exec
for review and act on the feedback. Write the final spec in
specs/final-spec.md.
This part is dense technical detail. Data models, phases, order of work, edge cases, what to test. One agent has never once gotten all of it right for me. When Codex reviews a spec Claude wrote, it always finds mistakes, wrong assumptions and things that were skipped. The other way around is just as true. I have tried both directions many times and the result is the same.
Before you accept specs/final-spec.md, read it yourself and check it has:
- phases in order, each one small enough to finish and check on its own
- a data model, so you know what gets stored and how the pieces connect
- a way to verify each phase, either tests or a manual check
- clear use of what SpeedPy already gives you, instead of rebuilding login, teams, billing or the API
- whatever is out of scope, written down as out of scope
If a phase reads vague to you, say so and have it rewritten. A vague phase turns into a guess inside your codebase.
Step 6. Deploy before you build anything¶
Please do not skip this one. It takes a few minutes and it saves you an afternoon.
Right now your repo is a clean boilerplate that nobody has touched, and a clean boilerplate deploys correctly. SpeedPy ships an appliku.yml, so the platform reads your web process, worker, beat and databases straight out of the repository.
Deploy it now, while nothing is your fault yet. After that, any deployment failure was caused by a change you can point at.
appliku apps create github <your-github-user>/<your-repo> \
--team <team-path> --name myproject --branch master --server <server-id>
Open the URL and log in. If that works, deployment is a solved problem for this project. There is more detail on the Deployment page, and the bundled appliku skill lets your agent drive the CLI for you.
Why I insist on this
If your first deploy happens after 4,000 lines of agent-written code, you cannot tell a broken migration from a missing environment variable from a build image problem. Everything is a suspect at once. Deploy the clean boilerplate first and all of that ambiguity disappears.
Step 7. Build it, phase by phase, with both agents¶
New chat in the main agent:
Start implementation of the project according to the spec in
specs/final-spec.md. On every stage ask codex exec for review and act
on the feedback.
I would add one more thing to that prompt, and I recommend it strongly:
Start implementation of the project according to the spec in
specs/final-spec.md. On every stage ask codex exec for review and act
on the feedback. Commit and push phases to get the application deployed
with Appliku, and monitor deployment success or failure with the
Appliku CLI.
That last sentence changes the whole build. Every phase gets committed, pushed, deployed and checked before the next one starts. When something breaks, the cause is inside one small phase that was just written, not somewhere in a week of work. The agent finds it and fixes it right away.
What you do while this runs¶
You are not done. You are reviewing.
- Read what each phase changed. Not every line. The summary, the new models, the new pages.
- Use the app after each phase. Walk through the job that phase was supposed to build. Agents pass their own tests and still build the wrong thing.
- Answer questions in the spec. If the agent asks something the spec did not cover, put the answer in
specs/final-spec.mdand then carry on. The spec stays the source of truth. - Stop it early when a phase is wrong. Fixing phase 2 costs minutes. Fixing phase 2 after phases 3 to 7 were built on top of it does not.
Step 8. Before you go live¶
Two things are left.
Strip the demo content. SpeedPy ships demo and placeholder content. It is useful while you learn the patterns and embarrassing on a live site. Ask your agent to use the bundled strip-demo skill. It audits first, shows you a removal plan, and changes nothing until you say yes.
Walk the production checklist. See Production Readiness and the checklist on the Deployment page. DEBUG=False, a real SECRET_KEY, a real email provider, a changed admin URL, and the rest of it.
Mistakes I see people make¶
| What they do | What happens | What to do instead |
|---|---|---|
| One line prompt instead of a spec | The agent invents a product, and it is not yours | Write specs/spec.md first, by hand |
| Let the agent write the first draft | You end up reviewing its idea instead of describing yours | Write the draft, then let it attack the draft |
| Answer questions in the chat | The answers disappear with the chat and the next agent asks again | Edit the spec file, then say "read it again" |
| Skip the fresh chat | The spec only makes sense to an agent that heard you explain it | New chat, same question, before you call it done |
| Use one agent for everything | Its blind spots go straight into your codebase with nobody checking | Second company's agent, for the spec and for every phase |
| Deploy at the very end | The first deploy fails and everything is a suspect | Deploy the clean boilerplate before phase 1 |
| One giant implementation prompt | A huge broken diff with no clean place to go back to | Phases, each one reviewed and deployed |
| Put technology in the product spec | You lock in decisions before anyone understands the problem | Describe the product, let the final spec pick the technology |
All the prompts, in order¶
Copy this into a scratch file and work down it.
1. (main agent, new chat)
Read specs/spec.md. Help me improve it. Ask me questions about gaps
in the spec, missing information, contradictions, and anything that
needs clarifying. Do not write any code and do not edit the spec.
2. (same chat, after each round of edits, repeat until the questions
turn into nitpicks)
Re-read specs/spec.md. I answered your previous questions in the
document. Another round please. What gaps, contradictions or
unclear parts are left?
3. (same chat)
Re-read specs/spec.md. Raise only critical concerns. Things that
would block the implementation or seriously damage it if left
unresolved.
4. (main agent, FRESH chat)
Read specs/spec.md. Help me improve it by asking about gaps,
missing information and contradictions. Raise only critical
concerns.
5. (the other company's agent)
Read specs/spec.md. Help me improve it by asking about gaps,
missing information and contradictions. Raise only critical
concerns.
6. (main agent, new chat)
Given this initial spec in specs/spec.md, look at it and write me
the final spec suitable for implementation of the project. Use
codex exec for review and act on the feedback. Write the final
spec in specs/final-spec.md.
7. --- deploy the clean boilerplate to Appliku now ---
8. (main agent, new chat)
Start implementation of the project according to the spec in
specs/final-spec.md. On every stage ask codex exec for review and
act on the feedback. Commit and push phases to get the application
deployed with Appliku, and monitor deployment success or failure
with the Appliku CLI.
9. (main agent)
Use the strip-demo skill to remove demo content before production.
Swap codex exec for whatever runs your second agent without an interactive session.
Where to go next¶
- Using SpeedPy with AI coding agents, what the boilerplate already ships for agents:
AGENTS.md, the bundled skills, the CLI and MCP examples - Project Layout, where things live, so you can read what your agent wrote
- Production Readiness, the full pass before launch
- Deployment, Appliku and self-hosting
Stuck somewhere? Come and ask in the Discord. SpeedPy is free and questions about it are very welcome.