← Articles
AI Coding Assistants

Building with AI Coding Assistants: A Practical Workflow

This site was built end to end alongside Claude Code, from the Rust backend to the text you're reading right now. Here's how that workflow is actually put together: setup, CLAUDE.md, review, autonomy boundaries, and the failures that taught me most of it.

July 15, 2026·25 min read·

Why this isn't autocomplete

Autocomplete suggests the next line while you're typing. An agent does the entire piece of work for you: it takes a task in natural language, decides on its own which files to read, what to change, which commands to run, and comes back with a finished result or a question if it gets stuck. The difference isn't a matter of degree. It's a change in kind: the developer's role shifts from "I write code" to "I define tasks and check the output," and misunderstanding exactly that shift is usually what's behind the "I tried Copilot, nothing special" disappointment.

This entire site is built in that mode: a Rust backend, a Next.js frontend, a React admin panel, deployment through systemd. All of it written alongside Claude Code, including the text you're reading right now. What follows is a concrete breakdown of how that workflow is actually put together: where to start with setup, how to write instructions for the agent, how to review its code, where to draw the line on autonomy, and what failed for me personally before it started working.

One important caveat before getting into the details: nothing below is universal across every agentic tool in exactly the same way, though the general principles carry over. I use Claude Code specifically, and part of the mechanics (the structure of CLAUDE.md, permission modes) is specific to it. But the principles that actually make this piece worth reading if you use a different tool transfer almost unchanged: being specific in how you frame a task, expanding autonomy gradually, mandatory review. These work the same regardless of which agent brand you're using.


Setting up Claude Code for your project

The minimum setup takes five minutes, but those five minutes determine whether the agent turns into a useful partner or a source of constant small annoyances.

Three things worth starting with. A file with project instructions (covered separately below). Permissions: by default the agent asks for confirmation on every potentially dangerous action, and that's the right call at the start, even if it feels excessive. And integration with the team's existing tools: the linter, the formatter, the test runner need to be set up before the agent starts writing code, because an agent, like any developer, writes to the project's existing conventions rather than inventing its own if none are given.

A common mistake among people new to agentic coding: granting the agent broad permissions right away "to avoid being interrupted by confirmations." It sounds like it speeds things up, but in practice it removes exactly the mechanism that saves you from an accidental rm -rf or a commit straight to the main branch with no review. Permissions should expand gradually, as trust builds up for specific types of actions on a specific project, not get handed out all at once up front.

A practical sign that expanding autonomy is already justified for a given type of action: several successful runs in a row of exactly that type of task, with zero incidents. Not a general feeling that "the agent seems to be doing fine," but a specific, trackable track record: the agent correctly updated dependencies five times in a row without breaking the build, which is grounds to expand autonomy specifically for dependency updates, not for every task at once by association.

It's also worth configuring permission modes for specific phases of work. For exploring the codebase and reading files, a maximally open mode makes sense: the agent can't break anything just by reading code. For active development, a mode that asks for confirmation on changes but not on every read command is useful, otherwise the conversation turns into an endless series of "yes, go ahead" clicks. For routine operations already proven on this project, like running tests, the linter, or a local build, you can pre-approve a specific list of commands instead of asking every time. This is a case where narrowly scoped autonomy is justified, because the risk is known and acceptable.

Another practical setup consideration: integrations through MCP (Model Context Protocol) and similar mechanisms that give an agent access to external systems like a bug tracker, a knowledge base, or company-specific internal tools. The same rule applies here as with filesystem permissions. Connect them as the actual need arises, not the entire available set of integrations at once, because every extra integration widens the surface for unpredictable behavior.


CLAUDE.md: how to write instructions for an AI agent

CLAUDE.md is a file at the root of the repo that the agent reads at the start of every session. It's not documentation for humans (though it partly overlaps with that), it's context specifically for the agent: what the project is, how it's structured, what commands to use for builds and tests, which patterns to follow.

The working structure used in this exact project rests on four blocks. An architecture overview: what parts the project consists of and what each one is responsible for, laid out literally as a table with columns for directory, description, port. Development commands: how to bring up each part locally, with no need to guess or dig through command history. Backend structure: where the handlers live, where the models live, where the migrations live, so the agent doesn't burn calls re-exploring the structure in every single session. And key patterns: things that aren't self-evident from the code itself, for example that the public API accepts an optional locale parameter, or that migrations run idempotently on every startup instead of living in separate migration files.

The main mistake when writing CLAUDE.md: turning it into a general description of the project instead of concrete, actionable instructions. The sentence "this project uses Rust and Axum" is useless, the agent will see that from Cargo.toml anyway. But a note like "migrations are written with INSERT OR IGNORE because the schema gets rebuilt on every startup, not through separate migration files" genuinely saves time: without that line, the agent will most likely try to create a separate migration file following the pattern common to most projects, and that would be wrong specifically for this one.

A second important point: CLAUDE.md has to get updated as often as the code does. A stale instruction is worse than a missing one. It confidently steers the agent in the wrong direction as if it were still accurate.


Working with an AI agent in a monorepo

A project with several sub-projects in a single repo (backend, frontend, admin panel) creates a specific difficulty for an agent: the context from one part can be irrelevant to a task in another, and a wrongly guessed context wastes both time and token budget.

Practices that remove this difficulty:

  1. A separate CLAUDE.md section for each sub-project, rather than one general section covering everything at once. A backend task shouldn't drag along instructions about the frontend stack.
  2. Explicitly stating task boundaries in the request. "Change the endpoint in backend/src/handlers/blog.rs" works faster and more precisely than "change the blog endpoint," because it removes the guessing step of figuring out which of three parts of the project to look in.
  3. Separate, explicitly documented build and test commands for each part. The agent doesn't need to guess how the frontend specifically gets built if that's a separate command from building the backend.

In practice, a monorepo with a well-documented structure works with an agent just as well as a set of separate repos. The only difference is that the structure needs to be spelled out explicitly, rather than trusting the agent to figure it out from file layout alone.

An additional practice that pays off specifically in a monorepo with multiple languages or frameworks: explicitly state in the task which conventions are specific to a given sub-project and which apply repo-wide. Variable naming conventions on the backend and the frontend can deliberately differ because of different language conventions, and an agent that isn't warned about this explicitly sometimes carries the style from one part of the project into another simply because it saw it most recently in the current context.


How to review code written by an AI agent

Reviewing an agent's code isn't the same as reviewing a coworker's code. Treating it as a formality, "the agent is smart, it's probably fine," is the fastest way to get an unpleasant surprise in production.

Three things worth checking first:

  • The boundaries of the change. An agent sometimes decides to "also" fix something nearby that's outside the scope of the task. That can be useful, or it can quietly widen the blast radius. It's worth explicitly checking the diff for changes you didn't ask for.
  • Error handling. Models tend to write for the happy path and only add try/catch blocks or checks where explicitly asked. If the task didn't spell out edge-case handling, chances are the result won't include it either.
  • Consistency with existing patterns. Even with a good CLAUDE.md, an agent sometimes writes code that technically works but doesn't look like the rest of the project: different naming style, a different error structure. This is a cumulative problem, invisible in any single instance: over a few months, the codebase's style drifts apart.

A practical rule: review an agent's diff with the same level of attention you'd give a pull request from a new hire who doesn't yet know all the team's unwritten agreements, because that's essentially the exact same situation.

A useful habit that saves time on regular agent-code review: keep a short mental list of two or three error types specific to this particular project, and explicitly check the diff for those first, before reading through everything line by line. For one project that might be incorrect time zone handling. For another, forgotten cache invalidation. For a third, inconsistent field naming across layers of the system. A focused but recurring checklist like this catches project-specific regressions noticeably more reliably than trying to read the entire diff with the same level of attention every single time.


How to constrain an AI agent so it doesn't break production

An agent's autonomy isn't a binary on/off switch. It's a spectrum, and the right setting depends on exactly what's at stake in a given project.

A practical hierarchy of constraints, from soft to hard:

  1. Confirmation before potentially dangerous commands. Deleting files, changing configuration, database operations. The baseline level, worth keeping on almost always.
  2. No direct access to production. The agent works against a local environment or a test branch, and deploying to production stays a separate, deliberate step taken by a human, even if the deploy process itself is automated.
  3. An explicit list of forbidden actions in the project instructions. Don't rely only on generic confirmation mechanisms, spell it out directly: no pushing straight to the main branch, no editing environment files with secrets, no destructive operations without explicit permission granted in that specific conversation.
  4. Splitting by task type. A refactor with full test coverage can afford more autonomy. Changes to billing or authorization need a human keeping control over even small steps, no matter how trivial the change looks.

Constraints don't signal distrust of the tool. It's the same engineering common sense applied to access permissions for any new team member: trust builds up gradually, alongside a track record of successful tasks, rather than getting granted up front.

It's worth writing this hierarchy down rather than keeping it only as a general feeling about how much to trust the agent. Explicit, written autonomy levels tied to specific task types are easier to hand off to a new team member and easier to deliberately revisit than an unwritten rule everyone interprets slightly differently.


Working with secrets and environment variables

A separate, easily overlooked risk category: an agent with broad filesystem access can technically read a secrets file if it sits inside the project's working directory, and in some scenarios accidentally include its contents in output, a log, or even a commit.

Practical measures that actually remove this risk, not just reduce it by eye:

  • Secrets shouldn't live in files the agent reads by default. A gitignored .env is the bare minimum, but it's worth going further and keeping real production secrets entirely outside the repo, in a dedicated store (a secrets manager, the server's own environment variables), not in a file sitting next to the code, even a gitignored one.
  • An explicit ban in the project instructions on reading and printing the contents of secrets files, even where technical access exists. This adds a second layer on top of the technical protection rather than replacing it.
  • Rotate keys after any incident, even a suspected one. If there's the slightest doubt a secret might have shown up in an agent conversation log or in commit history, it's cheaper to reissue the key than to spend time later figuring out whether it actually leaked.

This is one of the rare cases in working with AI agents where it's better to lean toward over-caution than to underestimate the risk. The cost of extra caution is a couple of minutes. The cost of a leaked production secret can turn into a serious incident.


AI agents and git: commit and PR practices

Git is where an agent's mistakes become especially visible if you don't set the right discipline up front.

Practices that work:

  • Small, atomic commits, not one giant commit for an entire task. Easier to review, easier to roll back a specific change if something goes wrong without touching the rest.
  • Meaningful commit messages that describe "why," not just "what." An agent is capable of writing good messages if explicitly asked, but defaults toward a generic "update file.rs" otherwise.
  • Never push directly to a protected branch without explicit permission granted in that specific session, even if the technical permissions to do so exist.
  • Explicitly review the diff before committing, rather than blindly trusting that the agent did exactly what was asked. A few seconds spent on git diff saves hours spent later figuring out what actually happened if something goes wrong a week down the line.

Co-authorship deserves a separate note: if the agent genuinely wrote a substantial part of a commit, say so honestly in the commit message. That's useful information for future-you or a colleague digging through the change history later, not a formality for its own sake.


Teaching an AI agent your codebase's style

Every project and developer has unwritten conventions that live nowhere except habit: how to name variables, when to use an early return instead of nested conditionals, how detailed comments should be.

An agent learns this through explicit training on concrete examples, not through magic:

Here's a code example from this project that reflects our style well:
[code snippet].

Notice: early returns instead of nested ifs, no comments where the code
is self-explanatory, imports grouped by origin (external libraries
first, then internal modules). Follow this style for further code in
this project.

A prompt like this works better than an abstract "write clean code," because it gives a concrete reference instead of a judgment call everyone interprets differently. If the agent keeps breaking the same pattern after several sessions, it's usually simpler to write the rule explicitly into CLAUDE.md than to repeat the instruction in every new conversation.

There's a subtler layer of style that's harder to formalize in a prompt: the intuitive sense of when an abstraction is actually needed and when it's still too early. Agents default toward one of two extremes depending on the model and its settings. One extreme: over-abstracting the code, pulling things that are only used once out into separate functions and modules. The other: writing everything as flat, unstructured code even where repetition is already obvious. No instruction in CLAUDE.md replaces personal review during the first few weeks of working on a specific project here. A rule like "the fifth repetition is grounds for an abstraction, but three identical lines aren't yet" gets absorbed by the agent through concrete examples of edits in conversation, not through a single abstract statement.


Multi-agent workflows: when they're actually worth it

Running several agents in parallel on different parts of a task sounds like an obvious speedup, but in practice it's justified far less often than it seems, and knowing when it works versus when it just adds chaos saves real time.

Works well: independent tasks with no overlapping files. One agent edits a frontend component, another writes tests for a separate backend module. No conflicts arise, because they physically don't touch the same files. Or exploratory work running alongside the main task: while one agent implements a feature, a second can simultaneously dig into an unfamiliar part of the codebase for the next task.

Works poorly: overlapping changes in the same files, which guarantee merge conflicts that are usually more expensive in time than whatever was saved by running in parallel. Or tasks where one agent's decision needs to shape another's approach: if an architectural choice in one part of the task needs to determine how another part gets done, running in parallel loses that dependency, and the result has to be redone.

A practical rule of thumb: if you can cleanly split a task into independent chunks with no shared files ahead of time, a multi-agent approach delivers a real win. If the boundaries of the task are fuzzy, sequential work with a single agent that holds the whole picture in context is more reliable.


Multi-agent workflows: practical constraints

Beyond the substantive limits covered above, running agents in parallel has a purely technical side worth understanding up front, before trying it on a serious task.

Shared context between agents doesn't sync automatically. If the first agent made an architectural decision partway through its task, the second agent won't know about it until you tell it yourself. In practice, this means running in parallel requires more upfront work framing the tasks, not less, contrary to the intuitive feeling that several agents at once means less manual work for the human.

A second constraint: cost. Every parallel agent spends its own token budget rebuilding project context, unless it's reusing context that's already loaded. For small, independent tasks this doesn't matter much, but for a large refactor split into five parallel streams, the cost difference can be noticeable compared to running those same five tasks sequentially with one agent that keeps its context.

The practical takeaway: start with sequential work and move to parallel only once you've built up real experience splitting tasks into genuinely independent pieces. A premature attempt to parallelize the workflow usually creates more synchronization overhead than it saves.


Autonomous development: how much can you actually hand off unsupervised

The question isn't whether an agent can work fully autonomously. Technically, yes, on plenty of tasks. The question is where the cost of a mistake is low enough that it's actually reasonable.

A rough grading by task type. High autonomy is justified for generating tests for already-written code, refactors with full test coverage, dependency updates with a full test run, documentation. Medium autonomy with mandatory review fits new features with a clear spec, data migrations on non-critical tables, performance optimization. Minimal autonomy with step-by-step oversight is needed for changes to authorization and billing, working with production data, and generally anything hard to roll back with a single action.

This grading isn't fixed. It shifts as you build up experience working with a specific agent on a specific project. In the first month of working with Claude Code on this site, I kept almost everything in the medium or minimal category. Now I trust it with a lot less oversight on routine things, like adding a new CRUD endpoint modeled on existing ones, because months of work have built up a track record: the agent reliably handles this class of task, and I've learned to frame these tasks in a way that leaves no room for ambiguous interpretation.


Tests as insurance for agentic development

Test coverage plays a specific role in agentic development: it's a concrete, measurable way to check that the agent didn't break something in another part of the system while fixing the current task, not just a general good practice.

A working pattern worth keeping as a default: before asking an agent to change existing code, confirm that the tests covering that code already exist and pass. If there are no tests, the first ask for the agent is to write them for the current behavior before changing the behavior itself. This gives an objective "nothing broke" criterion instead of a subjective "seems to work," which gets checked with a quick manual pass and can miss a regression in a non-obvious spot.

The flip side: an agent that isn't explicitly told to write tests often doesn't write any at all, even when adding new functionality from scratch. That's not the model being lazy, it's literally following the boundaries of the task: if tests weren't part of the request, they don't count as part of the expected result. Either explicitly include a test requirement in every substantial task, or write it into CLAUDE.md as a standing rule so it doesn't need repeating every time.

A separately useful practice for agentic workflows: ask the agent to first write a failing test that describes the desired behavior, and only then write the code that makes it pass. The classic TDD cycle works even better with an agent than it does with a person working alone, because it explicitly separates two different modes of work, stating the requirement as a test versus implementing against an already-fixed requirement, instead of blending them into one continuous stream of edits.


Debugging with an AI agent: how to describe bugs effectively

The quality of the bug report you give an agent directly determines how fast and how accurate the fix is. The same principle applies here as with a human colleague: a vague description gets vague help.

A working bug report template:

Bug: [exactly what's happening, specific and without interpretation].
Expected behavior: [what should happen instead].
Steps to reproduce: [1, 2, 3].
Context: [what changed before the bug appeared, if known].
Already checked and ruled out: [if you've tried something yourself].

The last line gets skipped often, and shouldn't be: if you've already checked and ruled out the obvious causes, saying so explicitly saves the agent, and you, the time of re-checking the same hypothesis. Without that line, the agent often starts with exactly the most obvious cause you already ruled out and burns the first round of the conversation on it.

A separately useful practice: ask the agent to first explain its hypothesis about the cause before changing any code, rather than jumping straight to fixing the bug. This catches cases where the assumed cause is wrong: it's better to spend a minute checking a hypothesis in words than ten minutes editing code that doesn't fix the original problem because the diagnosis was wrong from the start.


Claude Code, Cursor, Windsurf: a comparison for real work

The three tools solve a closely related problem, but with different emphases, and the choice between them should come down to your actual working style, not the hype around a particular name.

ToolStrong pointWeaker at
Claude CodeA terminal-based, agentic workflow with strong autonomy on multi-step tasks, deep engagement with the whole project's contextLess of a visual IDE experience than its competitors, takes some adjustment if you've only worked in a GUI editor before
CursorA full VS Code fork with AI built into a familiar editor interface, low barrier to entryThe agentic mode is less autonomous by default, more geared toward line-by-line edits with confirmation
WindsurfA UX similar to Cursor, with some standout features for multi-file editsA smaller plugin ecosystem and community than Cursor or the VS Code-based options

Practical takeaway: if your working style is a terminal and framing an entire task explicitly upfront, rather than line-by-line editing with frequent confirmations, Claude Code wins out on deeper autonomy. If a classic IDE experience with AI as an enhancement rather than a replacement for hands-on editing feels more natural, Cursor or Windsurf will feel right from day one. Nothing stops you from trying several tools on different tasks. They're not mutually exclusive, and plenty of developers keep two tools around for different kinds of work.

Worth keeping in mind: this market moves faster than most other categories of dev tools, and the relative strengths in the table above could easily flip within a few major releases of any of the three products. It makes more sense to pick a tool that fits your current working style than to chase whichever one is considered the leader at any given moment, because that lead has a habit of shifting between competitors fairly quickly.


What this actually costs

A separate practical question that rarely gets discussed honestly: agentic coding isn't free, and the cost is worth understanding before building this approach into your daily work, not after the first unexpectedly large bill.

Cost comes down to the volume of context the agent reads and processes on every iteration. A small, targeted task with a narrow context is cheap. A task that requires reading through half the codebase just to understand what's going on gets noticeably more expensive, and the cost sometimes jumps rather than scaling linearly once the context balloons to several dozen files at once.

Practical ways to keep spending under control without sacrificing quality:

  • A good CLAUDE.md saves money on its own, not just time: the agent doesn't need to re-explore the project's structure in every session if it's already documented.
  • Narrowly framed tasks are cheaper than broad ones. "Fix the bug in file X" costs less than "figure out why something's not working right," because in the second case the agent spends context just finding the problem first, and that can be a significant share of the whole task's cost.
  • Not every task needs the most powerful model. Routine, well-specified tasks are often handled just fine by a faster, cheaper model, and it's worth saving the heavy artillery for genuinely hard cases.

My own experience: in the first month I spent noticeably more than I expected, simply because I was giving the agent tasks that were too broad and imprecise, and it burned tokens guessing at context I could've just handed over myself. Once I started framing tasks more specifically (see the section below on phrasing), the cost dropped by roughly half for the same amount of actual work done. The difference was entirely in how I framed the tasks, not in the model or the plan.

Is it worth it compared to writing the code yourself? For me, unambiguously yes, but not because it's "free" or "replaces thinking for yourself." It's because it shifts time away from the routine parts of a task and toward the architectural decisions and review, where my own experience is actually needed. An hour spent framing a good task and reviewing the result usually produces more finished, verified code than an hour of typing it out by hand, even accounting for the cost of tokens.

A useful way to check this math for yourself instead of trusting someone else's numbers: over the course of a week, honestly log how much time actually goes into framing tasks and reviewing results, against how much time writing the same volume of code by hand would've taken. The subjective sense of time saved often diverges from the objective measurement, and without concrete numbers it's easy to over- or underestimate the real effect based purely on the overall impression left by a week of work.


A case study: automating deployment with an AI agent

Deploying this site used to be manual: build the backend, copy the binary, restart the systemd service, then repeat all of that separately for the frontend and the admin panel. The same sequence of commands every time, and every time a risk of forgetting a step, especially when deploying tired in the evening after the day job.

I gave the agent a specific task, not just "write me a Makefile": I described the current manual sequence step by step, showed it the project structure, and asked it to assemble that into unified commands with a check at each step. For example, the backend deploy should fail with a clear error if a required variable is missing from .env, instead of silently taking down an already-running service. The result: a Makefile with explicit targets for each part of the system and a separate environment check before touching anything already running in production.

The most useful part turned out not to be the time saved on the deploy itself, though that was noticeable too, but the fact that the process became reproducible and stopped depending on remembering the exact sequence of steps. The old risk was making a mistake out of forgetfulness. The new risk shifted to whether the logic in the Makefile itself was correctly described in the first place, and that's far easier to carefully verify once and lock in than to hold in your head every single time.

An interesting side effect: writing a Makefile alongside an agent forces you to explicitly spell out every step of a manual process that used to happen on autopilot, without a second thought. In the process of spelling it out, I noticed a couple of steps I was doing out of habit that were actually redundant or even potentially risky: for example, I'd never checked the state of the .env file before a backend deploy, just trusting that it was always there. Formalizing the process surfaced that risk before it had a chance to turn into a real incident.


AI agent failures: what they taught me

Not everything worked on the first try, and some of these lessons cost more time than an honest account of someone else's experience would have saved upfront.

Blind trust with no review. In the first few weeks I sometimes accepted the agent's output after a quick skim of the diff, especially when a task looked routine. Once that led to part of the backend's routing getting implemented in a way that technically worked but was structurally wrong. The site ran fine, but the code was painful to build on further. I had to roll it back and rewrite it by hand, spending more time than the speed of the first pass had saved.

Tasks framed too broadly. "Improve the project structure" with no specifics is a guaranteed way to get a result that technically improves something, just not the thing that was actually needed. An agent doesn't read minds. It interprets exactly what's written, and the more general the phrasing, the further the final result drifted from what I actually had in mind.

Ignoring accumulated technical debt from AI-written code. A few times I noticed a similar pattern repeating across several spots in the codebase with small variations, because the agent solved the task fresh each time instead of reusing an existing solution. The issue was that I hadn't mentioned similar code already existed elsewhere in the task, not that the agent was incapable of finding it on its own. This is a case where explicitly pointing to an existing example saves both time and the quality of the final code.

Trusting a confident tone instead of checking the result. An agent that's wrong rarely sounds unsure. It states the wrong solution with the same conviction as the right one. I caught myself more than once judging the quality of a result by how smooth and professional the agent's explanation sounded, rather than by how accurate it actually was. That's exactly the same trap I wrote about in the piece on learning with AI: how smooth an explanation sounds and how correct it is are two different things, and one easily gets mistaken for the other unless you specifically check.

The overall lesson from all four: the more specific and context-rich the task, the fewer surprises in the result. That's not specific to Claude Code. It's a general principle of working with any agentic tool, one I honestly underrated at first, assuming "the smart model will figure it out on its own."


How to frame tasks for predictable results

Most of the problems described in the failures section above boil down to one root cause: a task that wasn't specific enough. It's worth breaking down exactly what makes a request specific, rather than just long.

A good task for an agent usually includes four elements: exactly what needs to get done, why (what problem it solves), what constraints apply (don't touch certain files, keep backward compatibility, follow a specific pattern), and how to verify the result is correct (which tests should pass, what behavior is expected). Whatever's missing from these four elements, the agent fills in with its own assumptions, and those assumptions are usually exactly what diverges from what was actually meant.

A telling example of the difference. Weak phrasing: "add validation to the contact form." Working phrasing: "add validation to the contact form in the ContactForm component: the email needs to match a valid email format, the message field can't be empty, errors should show under the relevant field as soon as it loses focus, without waiting for form submission. Use the existing validation pattern from the LoginForm component as a reference." The second version is longer, but it saves the "not quite what I meant" iteration that would almost certainly have followed the first one.


Where to go from here

Everything covered here is practice specifically for writing code with an AI agent. If you're curious about the bigger picture of how AI-driven development changes the architecture and structure of projects themselves, AI for Developers: How AI Is Changing Software Engineering covers that broadly, and Architecture for AI-Driven Development continues the topic at the technical level: repo structure, documentation as code, autonomy boundaries at the whole-system level rather than for a single task.

Reviewing an agent's code is only half of quality control. AI Code Review: How to Automate Reviewing Code covers automating code review with AI separately and in detail, including tools and metrics.

If you're curious how this same approach applies not just to building one site but to launching entire products, the piece on how I build AI products solo covers how I build Cruxly and Planio on my own, including where Claude Code fits into that process at the product level, not just the engineering one.


Takeaways

  • Agentic coding is a shift from "I write code" to "I define tasks and check the output," not a fancier autocomplete. Underrating that difference is the main reason people try it and come away unimpressed.
  • CLAUDE.md needs concrete, actionable instructions, not a general project description, and it needs updating just as regularly as the code itself.
  • Autonomy is a spectrum, not a switch. Expand the agent's permissions gradually as trust builds up for specific types of tasks, and keep autonomy minimal wherever the cost of a mistake is high.
  • Failures almost always trace back to the same cause: a task framed too broadly or without enough specificity. The more context given upfront, the fewer surprises in the result.
  • The cost of agentic development comes down to how specifically tasks are framed, not the model's pricing tier: a narrow, precise request is almost always cheaper and more reliable than a broad, vague one, both in dollars and in the quality of the result.

Comments

No comments yet. Be the first.