Przejdź do głównej zawartości

Konwersja projektu to procedura, która sprawia, że istniejące repozytorium nadaje się do pracy z agentami kodującymi: jeden plik AGENTS.md wygenerowany z prawdziwego kodu i poprawiony przez człowieka, cienkie adaptery dla Claude Code i Cursora, kontrola w CI, która pilnuje, by opisane polecenia działały, oraz pilotaż przed/po na prawdziwych zgłoszeniach, który dowodzi, że agenci trzymają się konwencji projektu.

Wskazujesz agentowi trzyletnie repozytorium Next.js i prosisz o nową funkcję. Agent dodaje bibliotekę stanu, którą usunęliście kwartał temu, umieszcza handler trasy (route handler) w złym katalogu i uruchamia npm test w repozytorium, które rok temu przeszło na pnpm. Kod nie jest zły. Agent po prostu nie wie, jak działa twój projekt, i lepszy prompt tego nie naprawi. Ten playbook jest dla tech leada, który odpowiada za repozytorium i musi sprawić, by działało dla ośmiu osób i trzech narzędzi.

  • Kanoniczny AGENTS.md wygenerowany z repozytorium, z każdym poleceniem sprawdzonym w praktyce
  • Cienkie adaptery, dzięki którym Claude Code, Codex i Cursor ładują ten sam rdzeń zamiast trzech rozjeżdżających się kopii
  • Cztery prompty do skopiowania: szkic AGENTS.md z repozytorium, sprawdzenie, co załadowała sesja, audyt kodu legacy i przełożenie audytu na plan konwersji w fazach
  • Deterministyczną kontrolę w CI, która zawodzi, gdy AGENTS.md wymienia polecenie, którego już nie ma
  • Kartę wyników pilotażu, która na trzech zamkniętych zgłoszeniach pokazuje, czy konwersja zmieniła zachowanie agentów

Gdzie konwersja projektu mieści się we wdrożeniu zespołowym

Dział zatytułowany „Gdzie konwersja projektu mieści się we wdrożeniu zespołowym”

Konwersja to krok wykonywany dla pojedynczego repozytorium w ramach mapy drogi adopcji. Następuje po zmierzeniu punktu odniesienia, a przed przebudową delegowania i code review. Dwie sąsiednie strony omawiają jej części dokładniej:

  • Jak przygotować repozytorium do pracy agentów ocenia cechy repozytorium (kontrola jednym poleceniem, deterministyczne testy, wymuszone granice modułów), dzięki którym kontrole zastępują czytanie diffów. Ten audyt uruchamiasz w kroku 1 poniżej.
  • Wspólne reguły agentów to pełne omówienie tego, jak każde narzędzie odnajduje pliki instrukcji i jak sprawdzić, że każdy agent je załadował. Ta strona korzysta z opisanego tam wzorca adapterów, ale go nie powtarza.

Kolejność ma znaczenie. Pliki kontekstu napisane, zanim powstaną kontrole, każą agentowi uruchamiać polecenia, które nie działają, a pilotaż przed wdrożeniem plików kontekstu niczego nie mierzy.

  1. Zmierz punkt odniesienia, zanim cokolwiek zmienisz. Wybierz trzy zamknięte zgłoszenia, które dotykały różnych części kodu. Dla każdego zapisz, co dziś robi nowa sesja agenta z oryginalną treścią zgłoszenia: jakim poleceniem sprawdza swoją pracę, które katalogi edytuje i ile poprawek musiałeś jej przekazać. Uruchom też audyt gotowości repozytorium i zanotuj polecenie kontrolne albo jego brak.

  2. Zadbaj o jedno polecenie kontrolne. Jeśli pnpm check (albo make check, albo ./gradlew check) nie uruchamia jeszcze w jednym kroku lintera, sprawdzania typów i testów, dodaj je najpierw. Każda kolejna instrukcja mówi „gotowe oznacza, że to polecenie przechodzi”, więc musi ono istnieć i przechodzić na gałęzi głównej.

  3. Wygeneruj AGENTS.md z repozytorium, a potem go popraw. Użyj poniższego promptu w narzędziu, które masz otwarte. Porównaj szkic z rzeczywistością, rozstrzygnij lub usuń każdą linię TODO: confirm i zatwierdź plik w osobnym pull requeście, aby recenzenci mogli sprawdzić konwencje, które opisuje.

  4. Dodaj adaptery i reguły o ograniczonym zasięgu. Podłącz każde narzędzie do tego samego rdzenia (następna sekcja). Wskazówki dotyczące konkretnych ścieżek, na przykład „handlery API walidują dane schematami Zod z lib/schemas/”, umieść w regułach ładowanych tylko dla tych ścieżek, a nie w pliku głównym.

  5. Powtórz zgłoszenia z punktu odniesienia i zatwierdź konwersję. Uruchom te same trzy zgłoszenia w nowych sesjach i wypełnij kartę wyników pilotażu (zobacz jak udowodnić, że konwersja zadziałała). Tech lead zatwierdza konwersję, gdy karta wyników się poprawia, a nie wtedy, gdy pliki istnieją.

Najważniejsza jest ostatnia instrukcja. Szkic, który w repozytorium opartym na pnpm wymienia npm test, czyta się dobrze i zawodzi przy pierwszym użyciu, więc każ agentowi sprawdzić każde polecenie, zanim zaczniesz recenzować tekst.

Tak wygląda dobry wynik dla aplikacji Next.js: konkretny, krótki i sprawdzalny.

# Acme Storefront
Next.js App Router application. React Server Components by default. pnpm only.
## Commands
- Check (lint + types + tests): `pnpm check`. A task is done only when this passes.
- Dev server: `pnpm dev` · Unit tests: `pnpm test` · Migrations: `pnpm db:migrate`
## Conventions
- Server Components by default; add `'use client'` only for interactivity.
- Route handlers live in `app/api/<resource>/route.ts`, one folder per resource.
- Data access goes through `lib/db/`; never import the Prisma client in a component.
- Money is integer cents everywhere. See `lib/money.ts`.
## Boundaries (ask first)
- `prisma/migrations/`, `infra/`, anything under `generated/`
## Traps
- `pages/checkout/` is being migrated to the App Router. Do not extend it.

Jak każde narzędzie ładuje przekonwertowany kontekst?

Dział zatytułowany „Jak każde narzędzie ładuje przekonwertowany kontekst?”

Rdzeń jest taki sam dla wszystkich trzech narzędzi. Adaptery się różnią, bo każde narzędzie inaczej odnajduje pliki instrukcji. Pełne zasady wykrywania i testy sprawdzające są na stronie wspólnych reguł agentów; tu jest minimum na dzień konwersji.

Obok każdego AGENTS.md dodaj CLAUDE.md, którego pierwsza linia go importuje. Linie specyficzne dla Claude Code umieść pod importem.

@AGENTS.md
## Claude Code only
- Use plan mode for changes under `services/billing/`.

Import @AGENTS.md działa w każdym kanale wydań i u każdego dostawcy. Claude Code czyta też AGENTS.md (lub .claude/AGENTS.md) bezpośrednio, gdy nie ma CLAUDE.md, ale dopiero od v2.1.277 (v2.1.281 na Bedrocku, Google Cloud, Microsoft Foundry, bramkach LLM i w sesjach z wyłączoną telemetrią). Obie wersje są na kanałach latest i stable, odkąd stable doszedł do v2.1.287 (sprawdzone 2026-10-12). Z reguły wyszukiwania wynikają dwie pułapki:

  • Dowolny CLAUDE.md, .claude/CLAUDE.md lub CLAUDE.local.md w katalogu roboczym albo wyżej wyłącza bezpośrednie czytanie, więc CLAUDE.md bez importu całkowicie ukrywa AGENTS.md. Prywatny CLAUDE.local.md inżyniera robi to samo, tylko u niego. Tak jest domyślnie. Aby zachować prywatny CLAUDE.local.md i nadal ładować AGENTS.md, ustaw Project instructions na claude-md-and-agents-md w /config (v2.1.277+).
  • CLAUDE.md, który jedynie słownie każe „przeczytać AGENTS.md”, nie działa niezawodnie: Claude zobaczy ten plik tylko wtedy, gdy sam zdecyduje się go otworzyć.

Wskazówki dla konkretnych ścieżek umieść w .claude/rules/*.md z listą paths we frontmatterze. Takie reguły ładują się, gdy Claude czyta pasujący plik, a nie przy starcie:

---
paths:
- "app/api/**/*.ts"
---
- Validate request bodies with the Zod schemas in `lib/schemas/`.
- Wrap handlers in `withErrorHandler` from `lib/api/errors.ts`.

Pliki CLAUDE.md w podkatalogach też ładują się na żądanie, gdy Claude czyta pliki w danym katalogu. Sprawdź, co się załadowało, poleceniem /context w nowej sesji: pliki pojawiają się w sekcji Memory files.

Uruchom ten test w nowej sesji każdego narzędzia, z katalogu, w którym inżynierowie zwykle zaczynają pracę. Cztery poprawne odpowiedzi oznaczają, że narzędzie załadowało rdzeń. „No instruction” w którejkolwiek linii oznacza, że brakuje adaptera albo plik nie leży na ścieżce wykrywania danego narzędzia.

Starszy projekt wymaga przed krokiem 3 dwóch dodatkowych przejść: mapy tego, co naprawdę istnieje, i planu, który stawia testy przed refaktoryzacją. Oba przeprowadź z agentem, a wynik porównaj z kodem.

Najpierw wdróż fazę 1, żeby każde kolejne zadanie z niej korzystało. Fazę 2 najłatwiej pominąć: bez testów charakteryzacyjnych refaktoryzacja w fazie 3 nie ma wyroczni i wracasz do czytania każdego diffa. Gdy faza 2 jest gotowa, rozdziel niezależne zadania fazy 3 między zadania w chmurze Codeksa, sesje Claude Code w osobnych worktree lub w wersji webowej (claude.ai/code) albo Cloud Agents w Cursorze. Migrację trwającą kilka kwartałów prowadź jako program: zobacz modernizację legacy z agentami.

Udowodnij, że konwersja zadziałała, bez czytania każdego diffa

Dział zatytułowany „Udowodnij, że konwersja zadziałała, bez czytania każdego diffa”

Przekonwertowane repozytorium to takie, w którym agenci zachowują się inaczej, a nie takie, w którym istnieją pliki. Weryfikuj na dwóch poziomach.

Deterministyczne kontrole przy każdym pull requeście. Nie potrzebują modelu i nie da się ich przegadać. Pierwsza zawodzi, gdy AGENTS.md wymienia skrypt, którego package.json nie definiuje. Liczy tylko polecenia w blokach kodu inline, więc proza w rodzaju „pnpm only.” nie może zablokować CI, i pomija flagi takie jak --filter czy -w po nazwie menedżera pakietów. Nazwa skryptu nie mówi jednak nic o menedżerze pakietów: npm test przechodzi kontrolę nazw, o ile istnieje skrypt test. Dlatego ostatnia część osobno zawodzi, gdy istnieje pnpm-lock.yaml, a blok kodu inline zaczyna się od npm lub yarn. Przetestowana w Node.js 22 dnia 2026-09-26 na przykładowym AGENTS.md powyżej, z błędną nazwą skryptu i z npm test w repozytorium opartym na pnpm.

// scripts/check-agents-commands.mjs: run from the repository root in CI
import { existsSync, readFileSync } from 'node:fs';
const scripts = Object.keys(JSON.parse(readFileSync('package.json', 'utf8')).scripts ?? {});
const doc = readFileSync('AGENTS.md', 'utf8');
// Only commands inside `code spans` count, so prose such as "pnpm only." is ignored.
const named = [...doc.matchAll(/`(?:npm|pnpm|yarn|bun) (?:run )?([\w:-]+)[^`]*`/g)].map((m) => m[1]);
const builtins = new Set(['i', 'install', 'ci', 'add', 'remove', 'update', 'exec', 'dlx', 'x', 'create', 'init']);
const unique = [...new Set(named)];
// Skip flags such as `pnpm --filter api build` or `npm run -w web test`.
const missing = unique.filter((s) => !s.startsWith('-') && !builtins.has(s) && !scripts.includes(s));
// Script names say nothing about the package manager, so check the lockfile separately.
const wrongManager = existsSync('pnpm-lock.yaml')
? [...doc.matchAll(/`((?:npm|yarn) [^`]*)`/g)].map((m) => m[1])
: [];
if (missing.length) console.error(`AGENTS.md names scripts that package.json does not define: ${missing.join(', ')}`);
if (wrongManager.length) console.error(`pnpm-lock.yaml exists, but AGENTS.md says: ${wrongManager.join(', ')}`);
if (missing.length || wrongManager.length) process.exit(1);
console.log(`AGENTS.md commands OK (${unique.length} checked)`);

Dodaj go do tego samego zadania (job) CI, które uruchamia polecenie kontrolne, obok kontroli adapterów i rozmiaru ze strony wspólnych reguł agentów. Przy wyzwalaczu pull_request GitHub uruchamia plik workflow i ten skrypt z samego pull requesta, więc pull request może osłabić kontrolę w tym samym diffie, w którym zmienia AGENTS.md; obejmij /.github/, scripts/ i AGENTS.md plikiem CODEOWNERS i wymagaj recenzji właściciela kodu, zanim uznasz ją za bramkę.

Karta wyników pilotażu na zgłoszeniach z punktu odniesienia. Powtórz trzy zgłoszenia z kroku 1 w nowych sesjach i wypełnij jeden wiersz na zgłoszenie i narzędzie. Dwa poniższe wiersze ilustrują format, nie są wynikami pomiarów:

ZgłoszenieNarzędzieSam uruchomił polecenie kontrolneEdytował tylko oczekiwane modułyKontrola zielona przy przekazaniuPoprawki człowieka (przed → po)
SHOP-412Claude Codetaktaktak4 → 1
SHOP-388Codextaknie (pages/checkout/)tak3 → 2

Zalecana przez nas reguła zatwierdzenia dla tech leada: każde narzędzie poprawnie odpowiada na prompt testowy, deterministyczne kontrole są zielone, a liczba poprawek spada w co najmniej dwóch z trzech zgłoszeń. Przebiegi agentów się różnią, więc jedno uruchomienie na zgłoszenie może samo zmienić tę liczbę: uruchom każde zgłoszenie trzy razy w każdym narzędziu i porównuj mediany. Trzy zgłoszenia to test dymny, a nie pomiar. Wiersz bez poprawy wskazuje brakującą konwencję; dopisz ją do AGENTS.md i powtórz tylko to jedno zgłoszenie.

Nieaktualny plik kontekstu każe agentowi z pełnym przekonaniem robić coś złego, na przykład uruchamiać usunięty skrypt. Powyższa deterministyczna kontrola wyłapuje zepsute polecenia przy każdym pull requeście. Na wolniejszy dryf, na przykład zmienione nazwy katalogów albo wymienioną bibliotekę, uruchamiaj cykliczne odświeżanie, które otwiera pull request do zatwierdzenia przez człowieka.

Workflow dzieli pracę na dwa zadania. Zadanie z agentem ma klucz API, ale tylko prawo odczytu repozytorium. Zadanie tworzące pull request ma prawo zapisu, ale nigdy nie uruchamia agenta. Warunek if: w zadaniu z agentem sprawia, że działa ono tylko na gałęzi domyślnej, niezależnie od tego, czy uruchomił je harmonogram, czy człowiek, więc nigdy nie wykonuje kodu, hooków ani konfiguracji MCP kontrybutora, gdy sekret jest w środowisku. --strict-mcp-config dodatkowo pomija serwery MCP zadeklarowane w repozytorium.

.github/workflows/refresh-agent-context.yml
name: Refresh agent context
on:
schedule:
- cron: '0 6 * * 1' # Mondays 06:00 UTC
workflow_dispatch:
permissions: {}
jobs:
draft:
# A manual run from another branch would load that branch's hooks and MCP config with the key set.
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-node@v7
with:
node-version: 22
- name: Let Claude Code correct AGENTS.md in place
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Pinned; bump deliberately after reading the changelog.
npm install -g @anthropic-ai/claude-code@2.1.283
claude -p "Compare AGENTS.md with the current repository. Edit AGENTS.md only where \
a command, version, path or convention no longer matches the code. Change nothing else." \
--permission-mode acceptEdits \
--allowedTools "Read,Glob,Grep,Edit" \
--disallowedTools "Bash" \
--permission-prompts none \
--strict-mcp-config \
--max-budget-usd 2
git diff -- AGENTS.md > context.patch
- uses: actions/upload-artifact@v7
with:
name: context-patch
path: context.patch
open-pr:
needs: draft
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
with:
name: context-patch
- name: Apply the proposed change
run: |
if [ -s context.patch ]; then git apply context.patch; fi
rm context.patch
- uses: peter-evans/create-pull-request@v8
with:
commit-message: 'docs: refresh AGENTS.md from the codebase'
title: 'docs: refresh agent context'
branch: chore/refresh-agent-context

--allowedTools z góry zatwierdza odczyt i edycję, --disallowedTools "Bash" odbiera dostęp do powłoki, --permission-prompts none odrzuca wszystko inne, co wymagałoby zgody, a --max-budget-usd ogranicza koszt jednego uruchomienia. Każda flaga w tym kroku, łącznie z --permission-mode i --strict-mcp-config, jest w claude --help dla v2.1.283. Aby zadanie ze szkicem działało z Codeksem, zastąp krok Claude Code akcją openai/codex-action@v1 z openai-api-key: ${{ secrets.OPENAI_API_KEY }}, permission-profile: ":workspace" i tym samym promptem. :read-only nie pozwala edytować plików, więc :workspace jest konieczny, ale w przeciwieństwie do kroku Claude Code pozwala też Codeksowi uruchamiać polecenia powłoki, więc oba zadania nie mają równych uprawnień. Krok z łatką nadal ogranicza wynik do AGENTS.md, bo do zadania tworzącego pull request trafia tylko git diff -- AGENTS.md. Więcej wzorców uruchamiania bez interfejsu znajdziesz w agentach headless w CI.

Minimum dla projektu gotowego na agentów

  • Istnieje jedno polecenie kontrolne (lint, typy, testy) i przechodzi na gałęzi głównej
  • AGENTS.md wygenerowany z repozytorium, każde polecenie sprawdzone, linie TODO: confirm rozstrzygnięte
  • CLAUDE.md zaczyna się od @AGENTS.md; reguły Cursora wskazują rdzeń zamiast go kopiować
  • Wskazówki dla konkretnych ścieżek są w regułach o ograniczonym zasięgu, nie w pliku głównym
  • Prompt testowy przechodzi w każdym narzędziu, którego używa zespół
  • scripts/check-agents-commands.mjs działa w CI przy każdym pull requeście
  • Ścieżki o najwyższym ryzyku i bez testów mają testy charakteryzacyjne przed jakąkolwiek refaktoryzacją
  • Karta wyników pilotażu pokazuje mniej poprawek w co najmniej dwóch z trzech zgłoszeń
  • Workflow odświeżający otwiera pull request i nigdy nie wypycha zmian na gałąź główną