Strona główna / Artykuły / Wskazówki praktyczne: Buduj → Testuj → Naprawiaj → Powtarzaj: Automatyzacja rozwoju w Laravelze

Wskazówki praktyczne: Buduj → Testuj → Naprawiaj → Powtarzaj: Automatyzacja rozwoju w Laravelze

Krok po kroku praktyczne wskazówki: Buduj → Testuj → Naprawiaj → Powtarzaj: Automatyzacja rozwoju w Laravel – kontrakty, sprawdzania oraz gotowe miejsca na kod dla zespołów stosujących ten wzorzec.

3634 słów

To przewodnik pokazuje, jak przejść od surowców do gotowego systemu w ramach procesu: Buduj → Testuj → Naprawiaj → Powtarzaj: Automatyzacja rozwoju aplikacji Laravel za pomocą agentów AI. Kluczowe są konkretne kroki, jasne sprawdzenia oraz kod, który można bez problemu umieścić w repozytorium, bez konieczności domyślania się intencji. Na etapie przeglądu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.

Kilka pojęć, zanim przejdziemy dalej

Gdy przechodzisz przez etap „Kilka pojęć przed rozpoczęciem”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie wykonać późniejszy element.

Dlaczego „Czy sztuczna inteligencja potrafi pisać kod?” nie jest już interesującym pytaniem

Gdy przechodzisz przez etap „Dlaczego AI może pisać”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki cichego, częściowego ukończenia zadania. Ustaw punkty kontrolne po kosztownych krokach. Program powinien unikać ponownego pobierania opłat za tę samą operację LLM, gdy operator próbuje ponownie wykonać późniejszy element procesu.

Developer → AI → Developer → Test → Developer → AI → Developer → Test → ...
Developer → Orchestrator → Build → Test → (failed? → Fix → Test again) → Review → Done

Poznaj dwa główne narzędzia

Gdy pracujesz nad etapem „Meet the Two Main”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokena lub zapytania obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Zapisz nazwę narzędzia, hash argumentów, opóźnienie oraz wynik każdego wywołania. Bez takich informacji debugowanie pętli agenta marnuje godziny.

Laravel Boost — tłumacz między sztuczną inteligencją a naszą aplikacją

Gdy przechodzisz przez etap tłumaczenia w Laravel Boost, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny sekretów oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Ustaw punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za ten sam wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

composer require laravel/boost --dev

php artisan boost:install

OpenCode — tam, gdzie agent faktycznie wykonywa pracę

Gdy pracujesz nad etapem agenta w OpenCode, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez człowieka oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

Praktyka: Integracja Boost z OpenCode

Gdy pracujesz nad projektem Hands-On Wiring Boost, najpierw zapisz specyfikację: wymagane wejścia, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie uruchomić późniejszy element.

1. Połącz OpenCode z Boost

Gdy pracujesz nad krokiem 1 „Połącz OpenCode z etapem realizacji”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki cichego, częściowego ukończenia zadania. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą próbę wywołania LLM, gdy operator ponawia działanie w późniejszym etapie.

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "laravel-boost": {
      "type": "local",
      "command": ["php", "artisan", "boost:mcp"],
      "enabled": true
    }
  }
}
opencode mcp list

2. Stwórz agenty o określonych obowiązkach

Gdy pracujesz nad zadaniem „Create agents with stage”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czas wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy pracujesz nad zadaniem „Create agents with stage”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

---
description: Build Agent for new features
mode: primary
tools:
  write: true
  edit: true
---
You are the Build Agent.
Use Laravel Boost tools to understand the application structure
before writing any code. Never assume the database structure -
always check the schema first. Write tests for every new behavior.
At the end of your work, return ONLY JSON in this format:
{"status": "success", "files_changed": [...], "summary": "..."}
opencode agent list

3. Spróbuj najpierw uruchomić to ręcznie

Etap 3 „Spróbuj uruchomić” działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden udany wynik, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i utrudniają kontynuację pracy po przerwach.

opencode run --agent builder "Add a task assignment feature to TaskFlow according to the requirements in TASK.md"

Prawdziwy przypadek: funkcja przydzielania zadań w „TaskFlow”

Faza „The Real Case A” funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis postępowania, jeden przypadek niepowodzenia oraz notatkę o cofnięciu działań, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć milczące, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po przerwach.

1. A task has an assignee column (belongs to a User).
2. A user can only assign tasks within a project they're a member of.
3. A user must not assign or access tasks from other projects.
4. All of the above must be covered by automated tests.

Dlaczego potrzebujemy „dziennika” (bazy danych) do tego procesu

The Why We Need a stage funkcjonuje najlepiej, gdy jest traktowany jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwę w kontynuacji działania po zakłóceniach. The Why We Need a stage funkcjonuje najlepiej, gdy jest traktowany jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Dokumentuj zarówno pomyślny przebieg działania, jak i ścieżkę odzyskiwania. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

Schema::create('ai_tasks', function (Blueprint $table) {
    $table->id();
    $table->string('type');
    $table->string('status')->default('pending');
    $table->text('prompt');
    $table->json('result')->nullable();
    $table->unsignedTinyInteger('iteration')->default(0);
    $table->timestamps();
});
class AiTask extends Model
{
    protected $fillable = [
        'type', 'status', 'prompt', 'result', 'iteration',
    ];

    protected function casts(): array
    {
        return ['result' => 'array'];
    }
}
pending → building → testing → (fixing → testing)* → reviewing → completed / failed

Łączenie OpenCode z naszym kodem PHP

Aby wdrożyć OpenCode na naszą platformę, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Ludzka akceptacja powinna być wymagana w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności biznesowej.

interface AgentRunner
{
    public function run(string $agent, string $prompt): array;
}
class OpenCodeAgentRunner implements AgentRunner
{
    public function run(string $agent, string $prompt): array
    {
        $result = Process::timeout(600)->run([
            'opencode', 'run',
            '--agent', $agent,
            '--format', 'json',
            $prompt,
        ]);

        if (! $result->successful()) {
            return [
                'status' => 'error',
                'error' => $result->errorOutput(),
            ];
        }

        return json_decode($result->output(), true) ?? [
            'status' => 'error',
            'error' => 'Agent output was not valid JSON',
        ];
    }
}
$this->app->bind(AgentRunner::class, OpenCodeAgentRunner::class);

Zadanie dla każdego etapu

Dla zasady „praca dla każdego etapu” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Wymagaj ludzkiej aprobaty w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego.

Zadanie budowy

W fazie Build Job należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Obok wyników funkcjonalnych należy zapisywać czas trwania oraz koszt tokena lub zapytania. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Konieczne jest ludzkie zatwierdzenie w przypadkach, gdy dochodzi do wydatków lub zmian w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie gwarantują pełnej kompletności rozwiązania biznesowego.

class BuildFeature implements ShouldQueue
{
    public function __construct(protected AiTask $task) {}

    public function handle(AgentRunner $agent): void
    {
        $result = $agent->run(
            agent: 'builder',
            prompt: $this->task->prompt,
        );

        $this->task->update([
            'status' => 'testing',
            'result' => $result,
        ]);

        RunTests::dispatch($this->task);
    }
}

W fazie Build Job należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy jednocześnie udokumentować ścieżkę prawidłowego działania oraz ścieżkę naprawczą. Próby ponownego wykonania, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

Test Job

Podczas pracy na etapie Test Job najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie wykonać późniejszy element.

class RunTests implements ShouldQueue
{
    public function __construct(protected AiTask $task) {}

    public function handle(): void
    {
        $result = Process::timeout(300)->run('php artisan test --compact');

        if ($result->successful()) {
            $this->task->update(['status' => 'reviewing']);
            ReviewFeature::dispatch($this->task);
            return;
        }

        $this->task->update(['status' => 'failed']);
        AnalyzeFailure::dispatch($this->task, $result->output());
    }
}
Test
 ├── passed → move to Review
 └── failed → move to Analyze

Nie przekazuj surowych błędów agentowi

Gdy przechodzisz przez etap „Don’t Hand Raw”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co się dzieje w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki cichego, częściowego ukończenia zadania. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie zrealizować późniejszy element.

{
  "status": "failed",
  "failed_tests": [
    {
      "name": "user_cannot_assign_task_from_other_project",
      "error": "Expected response status code [403] but received 200."
    }
  ]
}
You are the Debug Agent.

Analyze the failed tests below. DO NOT modify any files.
Inspect: relevant models, policies, migrations, and tests.
Return JSON with:
- root_cause
- affected_files
- recommended_fix
- risk_of_regression
{
  "status": "analyzed",
  "root_cause": "TaskPolicy does not verify project membership before allowing assignment",
  "affected_files": ["app/Policies/TaskPolicy.php"],
  "recommended_fix": "Add a project membership check inside the assign() method",
  "next_action": "fix"
}

Napraw, a potem sprawdź ponownie — nie napraw i koniec

Gdy przechodzisz przez etap „Popraw i ponownie przetestuj”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

class FixFeature implements ShouldQueue
{
    public function __construct(protected AiTask $task, protected array $analysis) {}

    public function handle(AgentRunner $agent): void
    {
        $result = $agent->run(
            agent: 'fixer',
            prompt: json_encode($this->analysis),
        );

        $this->task->increment('iteration');
        $this->task->update([
            'status' => 'testing',
            'result' => $result,
        ]);

        RunTests::dispatch($this->task);
    }
}

Gdy przechodzisz przez etap „Popraw i ponownie przetestuj”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

Orkiestrator: „Kontroler ruchu”, który decyduje, co dalej

Faza Orkiestratora i Kontrolera ruchu funkcjonuje najlepiej, gdy traktowana jest jako mierzalna struktura. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję działań. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury danych ukrywają informację o tym, który węzeł zapisał dane w danym polu, co utrudnia kontynuację pracy po przerwach.

Bus::chain([
    new BuildFeature($task),
    new RunTests($task),
    new ReviewFeature($task),
])->dispatch();
class AgentOrchestrator
{
    public function next(AiTask $task): void
    {
        match ($task->status) {
            'pending'   => BuildFeature::dispatch($task),
            'testing'   => RunTests::dispatch($task),
            'failed'    => AnalyzeFailure::dispatch($task),
            'fixing'    => RunTests::dispatch($task),
            'reviewing' => ReviewFeature::dispatch($task),
            'completed', 'stopped' => null,
            default => throw new LogicException("Unknown status: {$task->status}"),
        };
    }
}

Limita prób — aby nie działo się to w nieskończoność

Etap „A Cap on Retries” funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej strukturze typów. Wложone elementy utrudniają identyfikację tego, który węzeł zapisał dane w danym polu, co powoduje przerwanie kontynuacji pracy po zakłóceniach.

Fix → Test fails → Fix → Test fails → Fix → Test fails → ...
class RunTests implements ShouldQueue
{
    protected const MAX_ITERATIONS = 5;

    public function handle(): void
    {
        if ($this->task->iteration >= self::MAX_ITERATIONS) {
            $this->task->update(['status' => 'needs_human_review']);
            return;
        }
        // ... run tests as usual
    }
}

Testy zielone ≠ funkcja ukończona

Faza „Feature Done” w narzędziu Green Tests funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres testowania. Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co może powodować przerwy w kontynuacji procesu. Faza „Feature Done” w narzędziu Green Tests funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres testowania. Dokumentuj zarówno optymalną ścieżkę działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

public function assign(User $user, Task $task): bool
{
    return $user->isAdmin();
}
Build → Tests pass → Deploy immediately
Build → Test → (if failed: Debug → Fix → Test again) → Human review → Deploy

Jeśli kilka agentów pracuje równolegle, uważaj na konflikty plików

W etapie „Jeśli kilka agentów pracuje” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Lepiej używać małych, testowalnych jednostek niż rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Wprowadź ludzką aprobatę w tych przypadkach, gdy dochodzi do wydawania pieniędzy lub zmian w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności biznesowej.

Agent A → writes Task.php
Agent B → reads Task.php (nearly at the same time)
Agent A → writes Task.php again
Research Agent   → read-only
Review Agent     → read-only
Security Agent   → read-only
Build Agent      → write access
Fix Agent        → write access

Nie zmuszaj jednego agenta do wykonywania wszystkiego

Dla etapu „Nie twórz jednego” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Wymagaj ludzkiej aprobaty w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełności biznesowej rozwiązania.

Planner   → designs the approach
Builder   → writes the new feature's code
Tester    → runs the test suite
Debugger  → diagnoses failures (read-only)
Fixer     → executes the fix
Reviewer  → final quality check (read-only)

Minimalna lista kontrolna przed faktycznym użyciem

W fazie A Minimal Checklist Before należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisuj czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Konieczne jest ludzkie zatwierdzenie w przypadkach, gdy dochodzi do wydatków lub zmian w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie gwarantują pełnej kompletności rozwiązania biznesowego. W fazie A Minimal Checklist Before należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

Podczas przechodzenia przez etap „So What’s Laravel”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolimy małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.

Developer (us)
    │
    ▼
Orchestrator (traffic controller, running on Laravel Queue)
    │
    ├── Build Agent
    ├── Test Agent
    ├── Debug Agent
    └── Fix Agent
          │
          ▼
      OpenCode (where the agent does its work)
          │
          ▼
    Laravel Boost (context translator, via MCP)
          │
          ▼
    Our Laravel application

Wniosek: Pytanie się zmieniło

Gdy przechodzisz przez etap „Wniosek: Pytanie pozostaje”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć możliwość cichego, częściowego ukończenia zadania. Ustaw punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

Lista kontrolna operacyjna

Etap listy kontrolnej operacyjnej działa najlepiej, gdy jest traktowany jako mierzalna powierzchnia do analizy. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy.

Zachowaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności przeglądania całej struktury.

Zachowuj prostą i typowaną strukturę stanu grafu. Wkładki nawarstwione ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji działania po przerwach.

Gdy budżet na to pozwala, dodaj test sprawdzający kluczową ścieżkę w procesie CI przy użyciu fixitów, a nie rzeczywistych, płatnych API.

Dokumentuj zarówno prawidłową ścieżkę działania, jak i ścieżkę przywracania. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie element późniejszej optymalizacji.

Zachowuj prostą i typowaną strukturę stanu grafu. Wkładki nawarstwione ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji działania po przerwach.

Zanim zastosujesz nową architekturę, zamroź wersje produktu, utwórz dokładny zapis działań na kluczowej ścieżce i potwierdź kroki konieczne do cofnięcia zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji uprawnień oraz wyraźnego odpowiedzialnego za rotację haseł. Wolisz nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwagi dotyczące partii 815696fa9b90: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików testowych, aby późniejsze zmiany modeli pozostały porównywalne.

Literatura pokrewna

  • Praktyczne notatki: Rozwój wykonyany na podstawie specyfikacji z użyciem agentów programistycznych AI: The Definitive — Szczegółowy przewodnik po Praktycznych notatkach: Rozwoju wykonywanym na podstawie specyfikacji z użyciem agentów programistycznych AI: The Definitive, w tym informacje o kontraktach, sprawdzaniach oraz miejscach na kod do wstawienia dla zespołów stosujących ten model.