From Vibe Coding to Engineering: How I Work With AI Coding Agents in Kiro
AI coding agents get more reliable with a clear written plan, the right background and tools, automatic checks, and reviewed lessons carried between sessions. Longer and longer prompts don’t get you there.
The big shift: from asking for code to building the loop
Coding agents are AI tools that can read the code in a project, write and edit code, and run commands. Vibe coding means asking one for code and taking whatever seems to work without reading it closely. My examples use Kiro, an AI coding tool from Amazon Web Services. The biggest change in how I think about coding agents is this: the prompt, the request I type, isn’t the product. The product is the loop around the model. What background information (context) does it get? What goal is it working toward? Which tools can it use? How do we check that it worked? What record is kept after the session? And when should a person step in?
AI expert Andrew Ng’s 2026 writing goes well beyond how to word a prompt. His AI Engineering Skills Map has four separate parts: building and launching AI apps, software-engineering basics, using coding agents, and shaping what gets built. His essays on loops put the agent’s fast coding loop inside slower ones: the developer’s own loop, and a loop of feedback from outside. What I take from this: when code gets faster to write, the other parts matter more, not less. Those are the overall design, a clear written plan, checking the work and good product judgment.
Ng also describes agentic loop coding. You let the agent keep working until it meets a condition, like matching a product spec, a written description of what to build. That shifts the focus away from one impressive answer. Instead, you define a clear, measurable point where the work counts as done. A good model can keep trying again and again. But without a test that says when it’s done, that’s just guessing over and over.
1. Start with a spec, not a giant prompt
DeepLearning.AI has a course called Spec-Driven Development with Coding Agents. Paul Everitt teaches it, in partnership with JetBrains. It lays out a useful set of layers. At the top, a project “constitution” sets the mission, the technical limits and the roadmap. Next, each feature gets its own requirements and a way to check them. Then the code follows the spec. The agent doesn’t have to guess what you meant from an old chat.
In Kiro, I can do this directly with a feature called Specs. For a serious engineering app, I want the requirements to say where the system starts and stops. They should list the inputs, the outputs and the assumptions. They should say what happens when something fails, and which tests prove it’s done. For data analysis, I also want the units, where the data came from, and what’s left out on purpose. I want the grain too, meaning what one row stands for, like one row per order. The agent can help write all this. But the spec is valuable because I can read it and fix it before the code turns a small misunderstanding into a big one.
2. Plan what the agent reads
Context is everything the agent reads before it works, like notes about the project and its rules. The part it reads every single time should stay small. In Kiro, steering files hold notes for the agent. They’re a good fit for project habits and limits that rarely change, like how things are named or which folders are off limits. Guidance for specialized areas works better when it loads only for matching files, or gets pulled in automatically when it’s relevant. Kiro’s Skills are better for step-by-step procedures you reuse, which should load only when needed. This idea is called progressive disclosure: show the basics first, and the details only when they’re needed.
My own Kiro notes back up a practical rule: link to detailed material instead of stuffing it into every session. A short project contract, a page of ground rules, can point to longer pages. Those might cover how to launch the app, rules for SQL (the language for asking databases questions), data definitions or a list of saved queries. That keeps clutter out of the agent’s context, and the agent can still find the details. The same idea works for AGENTS.md files, which hold instructions for coding agents, and for other project docs. Keep the front door short, and let the agent go get the details on purpose.
3. Let code check what code can check
Don’t ask a model to “remember” facts that software can check. Code does a better job with formatting, the expected shape of the data, duplicate IDs and required columns. The same goes for whether a query returns one row per item as it should, test results, and files the agent must not touch. Kiro hooks help here. A hook automatically runs a command or a prompt when something happens, like a file being saved. Some hooks run before the agent acts, and they can stop it when a check fails.
The difference matters. Steering is advice. A test is evidence. A check that blocks the agent is a rule it can’t break. Say a query the agent writes must return exactly one row per task. A careless join, which combines two tables, can copy rows and inflate the result. So write a test with sample data that fails when that happens. Say a schedule can’t book more work than there’s room for. Then have code check for overlaps. A prompt can explain the rule, but a check should prove it holds.
4. Add more agents only when the jobs really split
It’s tempting to turn every job into a team of agents: a planner, a coder, a reviewer, a tester and a critic. Anthropic’s guide to building effective agents says to start with the simplest setup that works, built from small pieces. Add complexity only when the benefit is worth the extra waiting time and cost. My own notes on graph workflows reach the same conclusion for Kiro.
Handing work to a second agent helps when each one truly needs different background, different tools or a different kind of output. One example is an agent that writes code and a separate one that checks it. A workflow graph is a map of steps and what each one waits on. It helps when you really need steps that depend on each other, retries, sign-offs or a way to recover from failure. But if one Kiro session plus a test command does the job reliably, a fancy multi-agent setup is just for show.
5. Use a graph when the work really is a graph
Some engineering tasks really do have steps that depend on each other. You can draw them as a graph: boxes for the steps and arrows for what has to come first. A change to a database query may depend on first checking how the database is laid out. Checking a change depends on having the new version. Launching should depend on the tests passing. And a review might mean later work has to be redone. Mapping those links lets you retry just the part that failed. You rerun the failed step and the steps after it, instead of starting over.
The graph-workflow prompt in my notes adds two habits I find really useful. First, limit how many times the agent can try to fix something. After that, repeated failure becomes a report for a person instead of an endless loop. Second, compare the graph against a simple setup. A workflow should earn its extra complexity by being more reliable, easier to recover or easier to review.
6. Keep the work and the lessons separate
A really useful idea comes from Lamis Mukta’s talk at AI Native DevCon. Keep the live work loop separate from a later learning loop. While the work is happening, the agent builds, checks and fixes. Later, a separate process looks back over finished sessions. It spots problems that keep coming up. Then it suggests changes to the project’s saved notes (its memory) or to its procedures.
Keeping them apart stops one bad session from quietly rewriting the rules for every session after it. Each suggested lesson should come with its evidence, where it applies, how sure we are, version info and a way to test it. Turning a suggestion into a real rule should be something a person can review and undo. This is closer to careful version tracking for settings than to a magic model that teaches itself. The model’s weights, the numbers it learned in training, aren’t changing. What changes is what it reads next time.
7. Give the agent trusted definitions to look up
Coding agents get much more useful for engineering data work when they can look up trusted definitions. Otherwise they have to guess what a number means from old database queries. Say the agent needs to count “late jobs”. It should be able to look up exactly what “late” means. One way to do this is a shared list of definitions, each with a version number so changes are tracked. It covers what one row stands for, how tables connect, and how dates and times work. It also covers how each measure is calculated, the rules for building estimates, and where the data came from.
That splits the work cleanly. Looking things up tells the agent what a measure means and how the tables must connect. A fixed check can then return PASS, FAIL or REVIEW_REQUIRED (a person needs to look). The model can explain what it found and suggest a fix. But it shouldn’t make an old query the official definition just because that query shows up a lot.
8. MCP connects tools. It doesn’t make the agent smarter
MCP (Model Context Protocol) is a standard way to plug outside tools and data into an AI agent. Kiro supports it. That helps when an agent needs approved access to documentation, databases, the status of a deployment (putting new code live) or other services. But hooking up an MCP server doesn’t make a process reliable by itself. Clear tool descriptions, permissions and checks on each tool’s inputs still matter. So does a clear line between what you trust and what you don’t.
For work at a big company, I start with narrow tools that mostly just read. Look up how a database is laid out. Search approved documents. Run a pre-written query where you only fill in the blanks. Check the status of a deployment. Passwords and access keys stay out of prompts and out of the code. A tool the model can use should do the smallest useful job, not run anything it’s asked to.
9. A practical Kiro routine I can actually use
For a new feature: First, ask Kiro to look through the project’s code and write or improve the feature spec. Second, confirm the assumptions and what counts as done. Third, build it in small, limited steps. Fourth, run the automatic tests and check it in the browser. Fifth, have a review compare the changes against the spec, not against a fuzzy idea of what I wanted. Sixth, write down open problems and useful evidence.
For work that repeats, sort things into the right places. Project habits that rarely change go into steering. Procedures you reuse become Skills. Cheap automatic checks become Hooks. Outside services go behind approved MCP tools. If the same failure keeps showing up across sessions, suggest a change to the agent’s memory or procedures, and test that change on its own. The result isn’t software that builds itself. It’s a partnership between a person, the agent and its setup, and regular automated tools. Bit by bit, you engineer that partnership to work better.
What I’d avoid
Here’s what I’d avoid. One giant instruction file the agent has to read every time. Agents that exist only to act out job titles. Hooks that kick off expensive loops after every edit. Memory that turns every failure into a permanent rule. And claims that a process is reliable because the model said its own work looked right.
The most important lesson for a beginner: Kiro’s features aren’t interchangeable. Specs say what to build. Steering gives lasting background. Skills package up procedures. Hooks react when something happens. Custom agents set up a focused workspace for one kind of job. Subagents take on smaller, clearly limited pieces of work. MCP connects tools and data. Tests and checkers provide the proof. Use them together, picking what each job needs, and you get a real system for building software, not just a bigger prompt.