Structuring Your Coding Agents: Stop Picking Frameworks, Pick Control Flow
Stop asking which framework is the best.
You open 15 browser tabs looking at LangChain, CrewAI, and AutoGen, trying to figure out which one to learn. Every tool promises that their autonomous agents will write your whole codebase for you while you sleep. But when you sit down on Monday morning to fix a real bug, the agent gets stuck in a loop and burns your money.
Frameworks are just libraries. What actually matters is how you control the agent.
The Golden Rule: Don't ask which framework is trending. Ask how much freedom, how many retries, and what safety gates your code actually needs.
1. What Actually Happens When an Agent Writes Code
Chatting with AI is completely passive.
You send some code, the model sends back text, and nothing else happens. But a real coding agent is an active loop running directly on your machine or inside a container. It doesn't just talk, it touches your project, runs commands, and watches what happens.
Look at the loop it runs every time:
The agent execution loop
Checks files and imports before it plans.
Decides which lines to change.
Writes files and runs shell commands.
Reads compiler errors and test output. On failure, loops back to planning and fixes it again.
Every good coding setup handles four basic jobs:
- Breaking down the task into small edits, then checking if the latest edit broke your build.
- Keeping track of files it already touched without filling up the prompt with useless junk.
- Running tools safely, like editing files and running shell commands without deleting your disk.
- Passing the errors cleanly from the compiler back to the model so it knows what went wrong.
More agents won't fix a messy prompt.
If you just copy-paste the whole chat history back and forth between five different agents, they won't get smarter. They will just get confused, lose the point, and eat your API budget.
2. The 5 Ways to Wire Your Agents
These are not rivals. You don't have to pick just one.
Think of them like Lego bricks you stack together. In a real app, you can use a State Machine to control the steps, put two specialized agents inside it, and use a plain script to run your tests.
Note: Frameworks can do more than one of these. Don't worry about the brand name, look at how the code moves.
Setup 1: The Step-by-Step Script (Linear Pipeline)
Your code makes decisions, not the model.
Step 1 reads a file. Step 2 asks the AI to write TypeScript types. Step 3 runs your linter with a normal script. The AI only fills in the blanks when you tell it to.
-
Read database schema→AI writes TypeScript types→Run linter & tsc→AI writes API boilerplate. -
Why it's great: It's super fast, dead cheap, and predictable. It never gets confused.
-
The catch: Zero flexibility. The second an unexpected error pops up that your script didn't plan for, it breaks.
-
Tools people use: Simple Python scripts,
LangChainsequential chains.
Setup 2: The Open Room (Agents Talking to Agents)
You put multiple agents in a room together.
One agent acts as a planner, one writes code, and one reviews it. They talk back and forth, argue about the best approach, and decide on their own when the job is done.
-
Planner suggests an idea→Coder writes it and runs tests→Reviewer spots a bug→Coder rewrites it. -
Why it's great: Great when you don't know the answer yet, like exploring three different ways to redesign a database.
-
The catch: They love to talk. Without strict limits, they argue in circles, make tiny edits forever, and drain your wallet.
-
Tools people use:
Microsoft AutoGen,CrewAI.
Setup 3: Strict Job Roles (No Stepping Over the Line)
Give each agent one single job with hard boundaries.
Your Architect Agent only designs the interface, and it is physically blocked from writing code. Your Coder Agent writes the code, but has no access to the internet. Your Security Agent only looks for leaks and can only answer yes or no.
-
Architect outputs interface→Coder writes implementation→Security agent approves or rejects. -
Why it's great: Clean context. The coder never has to read 50 pages of security rules, so it makes fewer mistakes.
-
The catch: Very rigid. If the architect writes an impossible interface, the coder gets stuck until you step in.
-
Tools people use:
CrewAI(role mode),ChatDev.
Setup 4: The State Machine (Rules with Loops)
Think of a train track with safety switches.
You define exact boxes and rules: Box A writes the patch. Box B runs the test. If the test fails, a rule sends the error back to Box A to try again, but only up to 3 times. If tests pass, it freezes and waits for you.
-
Edit code→Run test→Test fails? Retry (max 3)→Test passes? Pause for human. -
Why it's great: Total control. You get the power of retries without letting the model run wild and loop forever.
-
The catch: You have to write more code upfront to set up the rules and handle edge cases.
-
Tools people use:
LangGraph,Microsoft Semantic Kernel.
Setup 5: Drag-and-Drop Canvases
Build your workflow visually on a screen.
You drag a box for the model, connect a line to your database, and inject a prompt to test your idea. It's like whiteboard sketching that actually runs.
-
Drag model box→Connect database tool→Hit run→See result on screen. -
Why it's great: Zero boilerplate. You can test if a prompt works in 10 minutes on a Friday afternoon.
-
The catch: You can't use it for production. It's almost impossible to track with Git, run automated tests on, or deploy at scale.
-
Tools people use:
Langflow,Flowise.
3. Look at What Happens to Your Wallet
Sending full chat history destroys your budget.
When developers build multi-agent setups, they usually make one big mistake: on every single turn, they send the whole conversation history to the next agent. Look at what happens to the token count:
Proposes an idea. Context is still small, so this is the cheapest turn of the whole run.
Gets the whole history so far and writes code. The context has already doubled.
Gets the whole history and critiques the code. Every new turn re-reads all previous turns.
Gets the whole history and rewrites. The bill compounds on every single hand-off.
Every turn costs more than the last one.
By turn 4, your model is paying money to re-read mistakes, failed code, and arguments from 10 minutes ago. Features like prompt caching help, but the real fix is simple: stop forwarding whole chat logs. Send only the small code diff and the compiler error.
The Golden Rule: Always use plain code for things you already know. Only spend AI tokens on things you are actually uncertain about.
4. How to Stop Agents from Breaking Your Repo
Database backups don't save your local files.
People think that saving agent state to SQLite or Redis makes their app safe. It doesn't. If an agent crashes halfway through editing a file, you still have broken code sitting on your hard drive. A database record can't fix that.
Protect your real files:
- Use separate
git worktreefolders: Run the agent on a temporary copy of your code. If it goes crazy or crashes, you just delete the folder. Your main branch stays completely clean. - Remember the limits: A worktree only protects files. It does not isolate your database, open ports, or remote API calls.
- Make your tools safe to re-run: If a tool tries to edit a file twice after a crash, make sure it doesn't paste the same code twice.
The Commit Gate: Never Let It Push Unsupervised
Never give an agent permission to push directly to your main branch.
Instead, build a pause gate right into the system:
The Commit Gate: Safe Autonomous Execution
Inspects project AST, dependencies, and interfaces before touching code.
Produces minimal targeted edits inside an isolated git worktree.
Typecheck and test runners exit with code 0. No automated failures found.
THE PAUSE GATE
Agent execution loop completely suspends. Zero API tokens spent while waiting for human.
Full color-coded diff output rendered to terminal for manual inspection.
SHA-256 fingerprint seals the exact staged files. Any secret drift invalidates approval.
[ Wipe Diff & Reset ]
Triggered if the operator rejects the change, or if background file modification causes a hash mismatch.
- Discards uncommitted changes with
git reset --hard - Keeps main branch pristine and untouched
- Halts autonomous action without token drain
[ Commit the Code ]
Triggered only when the human clicks approve AND the current worktree SHA-256 matches the verified diff signature.
- Verifies cryptographic hash before commit
- Executes standard atomic
git commit - Appends verified author/audit metadata
$ agent-runner execute --task "harden billing webhook"
✔ Agent finished edits: 2 files modified
✔ Vitest: 18 passed in 1.4s (exit code 0)
✔ Calculating diff fingerprint: sha256:7f9b8c2d4a1e9380
[PAUSE GATE ACTIVE] Execution frozen. Waiting for human approval... (0 tokens/sec)
Press [Enter] to approve, [R] to reject, or test above simulator buttons.
Agent finishes edits → Tests pass → System calculates diff hash (SHA-256).
Execution freezes → Terminal shows diff → Zero API tokens spent while waiting.
You hit approve → System checks hash matches → Runs git commit.
If files change secretly → Approval is cancelled → Forces a clean re-check.
5. Which Setup Should You Pick?
Answer these four questions before writing any orchestration code:
- Question 1: Are the steps completely predictable? (Generating boilerplate, running linters, updating packages) Write a simple script. Don't use agents or dynamic loops. Keep it dead simple.
- Question 2: Does it just need to try again if tests fail?
(Fixing a bug with a unit test, fixing TypeScript compiler errors)
Use a retry loop or State Machine. For a simple script, a
whileloop with a max of 3 retries is plenty. If you need it to pause for a human, use a state graph. - Question 3: Does it need strict separation of duties? (Big refactors, separating architecture from code, security reviews) Use strict roles. Lock down what each agent can touch. If it's a small task, just use separate prompt steps instead of whole new agents.
- Question 4: Do you actually need to test different ideas at the same time? (Comparing three totally different caching strategies to see which is faster) Use an exploratory multi-agent loop. Give them hard token limits and run them in separate folders.
6. Two Real Tests to Run in Your Repo
Don't trust framework marketing. Test it on your own machine:
Test 1: Single Agent vs. 3-Agent Team
- What to do: Pick three real bugs backed by automated tests. Run Setup A (one agent in a retry loop) against Setup B (three agents: planner, coder, reviewer).
- What to look at: Which one actually solved more bugs? How many tokens did each use? How much clock time did they take? Did the 3-agent team touch files it wasn't supposed to touch?
Test 2: Pull the Plug Mid-Run
- What to do: Give the agent a multi-file task. While it's in the middle of writing files, kill the terminal with
SIGKILL, or unplug your internet right after a remote tool call. - What to check:
- Did it leave broken, half-written files on your disk?
- When you restart it, does it waste money re-reading files it already checked?
- Did it accidentally run the same API command twice?
The Takeaway
- Control flow comes first: Figure out how your code needs to run before you pick a framework.
- Only use AI where you need it: Write plain code for the steps you already know. Save tokens for the real thinking.
- Databases don't save broken files: Use
git worktreeso an agent crash never ruins your working directory. - Lock your approvals: Never let an agent commit without a human checking the exact diff hash.
Even the best setup will fail if your instructions leave room for guessing.
In the next part: We look at Spec-Driven Development—how to write files like mission.md and techstack.md so your agent never hallucinates the wrong libraries in the first place.