cd /news/ai-agents/stop-ai-from-writing-sloppy-laravel-… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-139650] src=dev.to β†— pub= topic=ai-agents verified=true sentiment=Β· neutral

Stop AI From Writing Sloppy Laravel Code: My Kilo Code + AGENTS.md Workflow

A developer has published a workflow for constraining AI coding assistants to an existing Laravel project's architecture using an AGENTS.md rules file, a skills.md knowledge file, and the Kilo Code agent, rather than prompting the AI to "write better code." The approach requires the agent to inspect the existing project first β€” checking composer.json and current framework choices such as Livewire, Inertia, Tailwind or existing components β€” so it extends rather than redesigns the codebase, and the author notes the same pattern maps to OpenCode, Codex and Claude Code via their respective instruction files.

by read14 min views1 publishedSep 25, 2026

AI coding assistants are getting very good at generating Laravel code.

Give an AI a feature request and it can probably create:

The problem is not whether the code works.

The problem is whether the code belongs in the project.

AI can easily generate Laravel code that works today but becomes a maintenance problem tomorrow:

$request->all()``<style> blocks<script> blocks For me, the solution is not to tell the AI to "write better code".

The better approach is to define the engineering rules and make the AI work inside the existing project architecture.

My current workflow is built around:

Laravel Project
      β”‚
      β”œβ”€β”€ AGENTS.md
      β”‚      └── Engineering rules
      β”‚
      β”œβ”€β”€ skills.md
      β”‚      └── Knowledge / examples / procedures
      β”‚
      └── Kilo Code
             └── Implement within those rules

And for longer-running projects, there is another layer that can work alongside them:

DSOM Brain
└── Project state, decisions, continuity and context

I'll come back to that near the end.

Before asking an AI coding agent to implement anything, I want it to understand the project that already exists.

This is probably the most important rule in my workflow.

Don't start with:

"Build a user management system."

Start with:

"Inspect the existing project first."

The AI should inspect things such as:

composer.json The reason is simple.

The existing project is already an architecture.

If the application already uses Livewire, don't suddenly introduce Inertia and React just because the AI knows how to generate them.

If the application already uses React + Inertia, don't create a random Blade-based application UI.

If the application uses Tailwind, don't introduce Bootstrap.

If the project already has reusable components, don't create another component that does the same thing.

AI should extend the project, not accidentally redesign it.

AI optimizes heavily for producing a plausible solution.

That doesn't necessarily mean it optimizes for:

For example, imagine this request:

Add an endpoint to update a user's profile.

A simplistic AI implementation might put everything inside the controller:

public function update(Request $request, User $user)
{
    $user->update($request->all());

    // validation
    // authorization
    // business logic
    // logging
    // notifications
    // other operations...

    return redirect()->back();
}

It might work.

But the better Laravel implementation should consider:

The goal isn't to make the code more complicated.

The goal is to put each responsibility where it belongs.

Although this workflow was developed and tested with Kilo Code, the underlying idea is not tied to Kilo Code.

The important part is not the tool name. The important part is giving an AI coding agent a clear set of engineering rules, project knowledge, and working context before asking it to write code.

If you use other coding agents such as OpenCode, Codex, or Claude Code, you can apply the same concept.

The exact mechanism may be different:

the instruction file may have a different name,

the location may be different,

the way instructions are loaded may be different,

and each tool may have its own instruction hierarchy or configuration.

But the architecture can remain the same:

                AI Coding Agent
                       β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β–Ό            β–Ό            β–Ό
    Engineering     Project      Working
       Rules       Knowledge      Context
          β”‚            β”‚            β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β–Ό
                Laravel Project

For example, the same principles can be adapted to:

Kilo Code β†’ AGENTS.md + skills

OpenCode β†’ project instructions / AGENTS.md

Codex β†’ project instructions / AGENTS.md

Claude Code β†’ project instructions / CLAUDE.md

The exact filenames and supported features should be checked against the documentation for the coding agent you are using.

The key idea

Don't think:

"I need to use Kilo Code because this workflow uses AGENTS.md."

Think instead:

"I need to give my coding agent an engineering contract."

That contract should tell the agent things such as:

how the project is structured,

which Laravel conventions to follow,

how authorization should be handled,

where validation belongs,

how database access should be designed,

what security practices are required,

how tests should be written,

what the agent must inspect before changing code,

and what it should not change unnecessarily.

So if you move from Kilo Code to OpenCode, Codex, or Claude Code, you don't have to throw away the workflow.

You adapt the instruction layer, while keeping the underlying engineering principles.

This makes the workflow tool-agnostic, even though my current implementation and examples are based on Kilo Code.

AGENTS.md as the Project Engineering Contract This is where AGENTS.md becomes useful.

Instead of repeating the same instructions every time I ask the AI to implement something, I keep the important engineering rules inside the repository.

For example:

my-laravel-app/
β”œβ”€β”€ AGENTS.md
β”œβ”€β”€ skills.md
β”œβ”€β”€ composer.json
β”œβ”€β”€ artisan
β”œβ”€β”€ app/
β”œβ”€β”€ bootstrap/
β”œβ”€β”€ config/
β”œβ”€β”€ database/
β”œβ”€β”€ public/
β”œβ”€β”€ resources/
β”œβ”€β”€ routes/
β”œβ”€β”€ storage/
└── tests/

The important idea is that AGENTS.md is not documentation for humans only.

It becomes a working contract between the project and the AI coding agent.


- Follow the existing project architecture.
- Inspect existing code before implementation.
- Keep controllers thin.
- Use Form Requests for validation.
- Use policies for authorization.
- Prefer Eloquent over unnecessary repository abstractions.
- Do not put business logic in Blade.
- Avoid N+1 queries.
- Use migrations for database changes.
- Write tests for application behaviour.
- Do not introduce another frontend framework without a clear requirement.
- Reuse existing components.
- Do not add unnecessary abstractions.
- Do not refactor unrelated code.

Now the AI has something concrete to follow.

Laravel applications don't all have the same frontend architecture.

A project may use:

Laravel's current starter kits also provide different application stacks, so the starter kit already present in a project should be treated as part of that project's architecture.

My rule is:

Inspect the starter kit before creating new UI.

If the project already has a component system, use it.

If the project already has layouts, use them.

If the project already has navigation components, don't create another navigation implementation.

The starter kit is a starting architecture, not something the AI should casually replace.

This is one of the easiest ways for AI-generated code to become messy.

Imagine an existing Laravel project using:

Blade + Alpine + Tailwind

Then an AI decides to add:

React + Vite + another component library

Now the project has two frontend architectures.

That might be justified in some applications.

But it should never happen simply because the AI generated a React solution faster.

The rule should be:

Follow the frontend architecture already used by the project unless there is an explicit reason to change it.

Before creating a new component, look for an existing one.

resources/views/components/

might already contain:

button.blade.php
input.blade.php
modal.blade.php
alert.blade.php
table.blade.php

If the application already has a button component, don't generate another button implementation.

The AI should inspect first.

This simple rule prevents a lot of duplication.

Another common AI-generated pattern is:

<style>
    .some-big-component {
        ...
    }

    .another-component {
        ...
    }

    /* 200 more lines */
</style>

This may work, but it can quickly become difficult to maintain.

If the project uses Tailwind, use Tailwind.

If the project uses Bootstrap, use Bootstrap.

If custom CSS is genuinely required, put it into the project's existing CSS structure.

resources/
└── css/
    β”œβ”€β”€ app.css
    └── components/
        └── editor.css

The exact structure depends on the project.

The important rule is:

Follow the project's existing CSS architecture instead of dumping large amounts of CSS into Blade.

The same principle applies to JavaScript.

Don't create a huge:

<script>
    // 300 lines of application logic
</script>

inside a Blade view if the project already has a proper JavaScript/TypeScript structure.

These are the rules I want an AI coding agent to understand before it starts changing my Laravel application.

Controllers should coordinate the request.

They shouldn't become the entire application.

Bad:

public function store(Request $request)
{
    // validation

    // authorization

    // database queries

    // business rules

    // notifications

    // logging

    // calculations

    // 100 more lines
}

Better:

public function store(StoreOrderRequest $request)
{
    $this->authorize('create', Order::class);

    $order = $this->orderService->create(
        $request->validated()
    );

    return redirect()->route('orders.show', $order);
}

The exact architecture depends on the project.

The important part is keeping responsibilities separated.

I don't want AI-generated Laravel code to casually do this:

$data = $request->all();

Especially when the data is going into a model.

Use a Form Request when validation and authorization belong there:

$data = $request->validated();

Or:

$data = $request->safe()->only([
    'name',
    'email',
]);

This makes the input boundary explicit.

It also reduces the chance of accidentally passing unexpected fields into application logic.

Another common mistake is confusing:

Who are you?

with:

Are you allowed to do this?

Authentication identifies the user.

Authorization determines whether that user can perform the operation.

Laravel provides policies and gates for this.

$this->authorize('update', $post);

The AI should not assume that:

auth()->check()

means the user is allowed to modify the resource.

Laravel already provides a powerful ORM.

I don't want an AI to create:

Repository
    ↓
Interface
    ↓
Repository Implementation
    ↓
Manager
    ↓
Service
    ↓
Model

for a simple CRUD operation.

If Eloquent is enough:

$user = User::findOrFail($id);

use Eloquent.

Repositories can be useful in the right context.

But abstraction should solve a problem, not create one.

AI-generated Laravel code can easily create N+1 queries.

$posts = Post::all();

foreach ($posts as $post) {
    echo $post->author->name;
}

The correct implementation may need:

$posts = Post::with('author')->get();

The AI should inspect relationships and query behaviour rather than assuming that syntactically valid Eloquent code is automatically efficient.

Blade should primarily handle presentation.

I don't want this:

@php
    $orders = Order::where('user_id', auth()->id())->get();

    // business logic
    // calculations
    // database operations
@endphp

The view should receive the data it needs.

$orders = $user->orders()->latest()->get();

return view('orders.index', compact('orders'));

Then Blade renders it.

I'm not against service classes.

I'm against creating them automatically.

A service or action can make sense when there is:

But this:

CreateUserService

for a three-line CRUD operation may simply add another layer.

The rule is:

Introduce abstractions because the problem requires them, not because AI likes generating classes.

Don't manually modify production database structures.

Use migrations.

php artisan make:migration add_status_to_orders_table

Then define the change.

Database design should also consider:

AI should inspect the existing schema before creating another migration.

If an operation modifies several related records and they must succeed or fail together, consider a transaction.

DB::transaction(function () {
    // create order

    // create order items

    // update inventory
});

But again, don't wrap every single database query inside a transaction just because the AI knows the API exists.

Use transactions when atomicity matters.

Security shouldn't be an afterthought.

For Laravel development, I want the AI to consider:

Log::info('User updated profile', [
    'user_id' => $user->id,
]);

is useful.

But:

Log::info($request->all());

could expose sensitive information.

The AI should understand that logging itself can become a security problem.

I don't want AI to say:

Tests should be added later.

If a feature changes application behaviour, testing should be part of the implementation.

Feature
β”œβ”€β”€ implementation
β”œβ”€β”€ validation
β”œβ”€β”€ authorization
└── tests

Feature tests are useful for application behaviour.

Unit tests are useful for isolated logic.

And one important rule:

Never claim that tests passed unless they were actually executed.

An AI saying:

All tests pass.

without running them is not useful.

Before accepting AI-generated code, I can ask:

- Did you inspect the existing architecture first?
- Did you follow the existing starter kit?
- Did you reuse existing components?
- Did you follow the existing CSS/JS structure?
- Are controllers still thin?
- Is validation handled properly?
- Is authorization handled separately?
- Did you use Eloquent before introducing abstractions?
- Did you check for N+1 queries?
- Is business logic outside Blade?
- Are services/actions actually justified?
- Are database changes done through migrations?
- Are transactions used only where needed?
- Did you consider security?
- Did you add appropriate tests?
- Did you avoid unrelated refactoring?
- Did you remove debug code?

This checklist is often more valuable than telling an AI:

"Write clean code."

Because "clean" is subjective.

Rules are more explicit.

skills.md Is Different From I also like separating rules from knowledge.

AGENTS.md answers:

How should the AI work on this project?

While skills.md can contain:

AGENTS.md
└── Rules

skills.md
└── Knowledge / procedures / examples

This keeps the main engineering contract focused.

The AI doesn't need every piece of project knowledge to become a hard rule.

My current workflow uses Kilo Code as the coding agent.

I don't need to run four different coding agents for every Laravel project.

The important part isn't how many AI tools are involved.

The important part is whether the AI is working inside a clear engineering environment.

My basic setup is:

Kilo Code
    β”‚
    β”œβ”€β”€ Inspect project
    β”‚
    β”œβ”€β”€ Read AGENTS.md
    β”‚
    β”œβ”€β”€ Load relevant skills
    β”‚
    β”œβ”€β”€ Plan
    β”‚
    β”œβ”€β”€ Implement
    β”‚
    β”œβ”€β”€ Test
    β”‚
    └── Review changes

Another developer may prefer another coding agent.

That's fine.

The principles remain the same.

My development environment is not necessarily a traditional Linux workstation.

I work across:

Windows
   β”‚
   └── WSL2
          β”‚
          β”œβ”€β”€ Linux
          β”œβ”€β”€ Laravel
          β”œβ”€β”€ Git
          └── Kilo Code

This is another reason why project-local instructions are useful.

The AI shouldn't assume a generic environment.

If the project has specific commands, paths, services or development procedures, document them.

AGENTS.md belongs in the project.

That means it may eventually be committed to Git.

Therefore:

Don't put secrets inside it.

Never store:

API keys
passwords
tokens
private credentials
production secrets

Instead document the expected configuration:

MAIL_USERNAME=<configured through environment>
MAIL_PASSWORD=<configured through environment>

The actual secret belongs in the appropriate secret/configuration mechanism.

A simple Laravel project can look like:

my-laravel-app/
β”œβ”€β”€ AGENTS.md
β”œβ”€β”€ skills.md
β”œβ”€β”€ composer.json
β”œβ”€β”€ artisan
β”œβ”€β”€ app/
β”œβ”€β”€ bootstrap/
β”œβ”€β”€ config/
β”œβ”€β”€ database/
β”œβ”€β”€ public/
β”œβ”€β”€ resources/
β”œβ”€β”€ routes/
β”œβ”€β”€ storage/
└── tests/

The important part isn't the number of files.

It is that the project contains a small, visible place where the AI can learn:

Rules
Knowledge
Code
Tests

This is where another interesting layer comes in.

AGENTS.md is useful for defining how the AI should work.

skills.md is useful for giving the AI knowledge, procedures and examples.

But long-running projects can have another problem:

What does the AI need to remember about the project over time?

Architecture decisions.

Previous work.

Current project state.

Session handovers.

Decisions that were already made.

Things that should not be repeated.

This is a different problem from coding rules.

One project I came across is Deep State of Mind (DSOM), which approaches this problem as a persistent AI context and governance layer. Its DSOM architecture includes persistent project state, decision/context artifacts, session continuity and a Git-oriented workflow.

Conceptually, I see the layers like this:

                    AI Coding Workflow
                           β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                β”‚                β”‚
          β–Ό                β–Ό                β–Ό
     AGENTS.md         skills.md        DSOM Brain
          β”‚                β”‚                β”‚
       Rules          Knowledge       Project State
     & standards       & examples     & continuity
          β”‚                β”‚                β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
                       Kilo Code
                           β”‚
                           β–Ό
                    Laravel Project

The distinction is important:

AGENTS.md
"What rules should the AI follow?"

skills.md
"What knowledge/procedures can help the AI?"

DSOM Brain
"What does the AI need to remember about this project?"

I don't see DSOM Brain as something that replaces AGENTS.md or skills.md.

Instead, it can run alongside them.

For a small Laravel project, AGENTS.md and a small set of skills may already be enough.

For a long-running project, however, persistent project state and context can become useful.

That's where DSOM Brain becomes interesting.

I'm keeping the DSOM Brain implementation out of this article because it deserves its own discussion.

I'll cover that separately in another article.

For reference:

Deep State of Mind (DSOM) For My AI

The goal isn't to make AI write more code.

The goal is to make AI work inside an engineering system.

My current thinking is:

AGENTS.md
    β”‚
    └── Engineering rules

skills.md
    β”‚
    └── Knowledge and procedures

DSOM Brain
    β”‚
    └── Persistent project context

Kilo Code
    β”‚
    └── Implementation

Git
    β”‚
    └── History and audit trail

Laravel
    β”‚
    └── The actual application

This changes the relationship with an AI coding agent.

Instead of:

"AI, build this feature."

The workflow becomes:

"Here is the project. Inspect it first. Here are the engineering rules. Here are the relevant skills. Here is the project context. Now implement the feature within the existing architecture."

That is a much more useful way for me to think about AI-assisted Laravel development.

Don't try to teach the AI everything. Define the rules that matter, inspect the existing project first, keep those rules close to the project, and make the AI work within the architecture that already exists.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @laravel 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/stop-ai-from-writing…] indexed:0 read:14min 2026-09-25 Β· β€”