Files
agentic-codemod-pipeline/docs/runbook.md
T
2026-08-29 13:17:59 +02:00

179 lines
8.0 KiB
Markdown

# Runbook
## Uruchomienie lokalne
Zadania uruchamia [go-task](https://taskfile.dev): `brew install go-task` na macOS,
`pip install go-task-bin` gdziekolwiek indziej.
```bash
task doctor # co jest w środowisku, czego brakuje
task install # .venv + zależności (runtime i dev)
task test # 46 testów, bez LLM
task demo # pełny przebieg offline na fixture
task ci # lint + test + demo, czyli to co sprawdza pipeline
```
Wynik przebiegu: `.runs/demo/run.json`, `changes.patch`, `merge_request.md`, `trace.jsonl`.
### macOS - trzy rzeczy, które potrafią zaskoczyć
1. **`externally-managed-environment` (PEP 668).** Homebrew blokuje `pip install` do interpretera
systemowego. Dlatego `task install` zawsze tworzy `.venv` i instaluje tylko do niego.
Nigdy nie uruchamiaj `pip install -e .` na `python3` z systemu.
2. **Systemowy Python to 3.9.** Za stary. `brew install python@3.12`, potem
`PYTHON=python3.12 task install` - `task doctor` powie, jaka wersja jest widoczna.
3. **Weryfikacja repozytorium uruchamia się interpreterem z `.venv`** (`sys.executable`),
a nie `python3` z `PATH`. Repozytorium docelowe z własnym środowiskiem budowania
nadpisuje komendę przez `--verify-command`.
## Model językowy lokalnie
```bash
task llm:list # backendy i ten wykryty dla tej maszyny
task llm:up # uruchomienie + czekanie na gotowość endpointu
task llm:status # czy odpowiada i jakie modele wystawia
task llm:smoke # jedno zapytanie kontrolne
task llm:down
```
### Logi
Jedno wejście niezależnie od tego, czy backend siedzi w kontenerze (`vllm-gpu`),
czy jest procesem z plikiem logu (`vllm-metal`, `ollama`, `mock`):
```bash
task llm:logs # na żywo, ostatnie 100 linii kontekstu
task llm:logs TAIL=500 # więcej historii
task llm:logs FOLLOW=false # jednorazowy zrzut zamiast śledzenia
task llm:logs GREP=throughput # filtr (wyrażenie regularne, bez rozróżniania wielkości liter)
task llm:logs:errors # tylko błędy i ostrzeżenia
task llm:logs:save OUT=/tmp/vllm.log # zrzut do pliku, np. do zgłoszenia
```
Ctrl-C kończy śledzenie normalnie. Pliki logów żyją w `.runs/llm/`.
Czego szukać w logach vLLM:
| Linia | Znaczenie |
|---|---|
| `Downloading ... safetensors` | pobieranie modelu; przy pierwszym starcie to zwykle najdłuższy etap |
| `Application startup complete` | serwer gotowy, endpoint odpowiada |
| `Avg prompt throughput ... Avg generation throughput` | przebieg pracuje; zera przez dłuższą chwilę oznaczają, że nikt nie pyta |
| `GPU KV cache usage` | rosnące do 100% zwiastuje kolejkowanie żądań |
| `CUDA out of memory` | zmniejsz `--max-model-len` albo `VLLM_GPU_UTIL`, albo weź mniejszy model |
| `ValueError: ... tool call parser` | zła wartość `--tool-call-parser` dla tego modelu |
Przy atrapie (`mock`) log pokazuje przebieg rozmowy z agentami - po jednej linii
na żądanie, z nazwą roli i wywoływanym narzędziem. To najszybszy sposób, żeby
zobaczyć, w którym kroku pipeline utknął.
| Backend | Warunki | Uwagi |
|---|---|---|
| `vllm-gpu` | Linux, GPU NVIDIA, Docker | pierwsze uruchomienie pobiera model (kilka GB), `start_period` w healthchecku to 5 minut |
| `vllm-metal` | macOS Apple Silicon, arm64 Python 3.12, Xcode CLT | plugin instaluje się do `~/.venv-vllm-metal` przy pierwszym `task llm:up` |
| `ollama` | `ollama` w PATH albo Docker | wariant awaryjny; na macOS instaluj natywnie, w kontenerze liczy na CPU |
| `mock` | nic | atrapa z `llm/mock_server.py`, deterministyczna, zestrojona z fixture'em |
Wybór ręczny: `LLM_BACKEND=ollama task llm:up`. Konfiguracja: `llm/models.yml`.
### Zdalny endpoint (np. vLLM na OpenShifcie)
```bash
export CODEMOD_MODEL_PROVIDER=vllm
export CODEMOD_LLM_BASE_URL=https://vllm.apps.ocp.internal/v1
export CODEMOD_LLM_API_KEY=... # w CI: zmienna masked
export CODEMOD_MODEL_CODER=Qwen/Qwen3-Coder-30B
```
## Przebieg z modelem
```bash
eval "$(task llm:env)" # przy backendzie lokalnym
task run -- \
--repo /sciezka/do/repo \
--package acme-sdk --module acme --to-version 2.1.0
```
Najpierw `task plan -- --repo ... --package ... --to-version ...`. Plan czyta się szybciej niż diff.
## Kody wyjścia
| Kod | Status | Znaczenie |
|---|---|---|
| 0 | `success` / `no_changes` | zmiana gotowa albo nie było czego zmieniać |
| 1 | `failed` | weryfikacja czerwona lub błąd przebiegu |
| 3 | `blocked` | recenzent zgłosił problem blokujący - wymagana decyzja człowieka |
## Wyzwalanie w GitLabie
1. **Formularz** - Build > Pipelines > Run pipeline, pola `CODEMOD_PACKAGE`, `CODEMOD_TO_VERSION`.
2. **Issue z labelką** - webhook na zdarzenie issue → trigger token → pipeline ze zmiennymi z tytułu issue.
3. **Harmonogram** - audyt zależności (`--prompt dependency-audit --plan-only`) raz w tygodniu.
4. **Include w repozytorium docelowym** - patrz `.gitlab/ci/agentic-codemod.template.yml`.
Job `codemod:apply` jest **manualny**. To jest bramka, nie niedopatrzenie.
## Typowe sytuacje
**`EcosystemNotDetected`** - repozytorium nie ma pliku markerowego (`pyproject.toml`, `pom.xml`,
`package.json`). Dopisz adapter w `adapters/` albo wskaż komendę weryfikacji przez `--verify-command`.
**`Brak skilli w kontekście APM`** - nie wykonano `apm install` albo pakiet nie jest zadeklarowany
w `apm.yml`. Job `codemod:context` jest bramką właśnie na taką sytuację.
**Status `blocked`** - przeczytaj `review.json`. Findingi `severity: blocker` opisują konkretny problem;
`requires_human` w `plan.json` mówi, czego agent świadomie nie ruszył.
**Agent nie wywołuje żadnych narzędzi, tylko opisuje co by zrobił** - serwer nie ma włączonego
tool-callingu. vLLM wymaga `--enable-auto-tool-choice --tool-call-parser hermes` (jest w `llm/models.yml`);
przy zdalnym endpointcie sprawdź to po stronie wdrożenia.
**`task llm:up` kończy się timeoutem** - pobieranie modelu trwa dłużej niż `LLM_WAIT_TIMEOUT`.
Zajrzyj do `.runs/llm/*.log` albo `task llm:logs`; zwiększ limit: `LLM_WAIT_TIMEOUT=1800 task llm:up`.
**macOS: `vllm-metal` nie chce się zainstalować** - wymaga natywnego arm64 Pythona 3.12
(Rosetta nie wystarczy) i Xcode Command Line Tools (`xcode-select --install`).
Wariant awaryjny: `LLM_BACKEND=ollama task llm:up`.
**Weryfikacja czerwona po limicie iteracji** - `changes.patch` zawiera stan po ostatniej próbie.
Zwykle oznacza, że migracja wykracza poza wiedzę z pakietu APM. Uzupełnij notatkę migracyjną
i regułę codemod, zamiast podnosić limit iteracji.
**Nie ma deklaracji pakietu do podbicia** - `profile.json` w polu `gaps`. Sprawdź, czy wersja nie jest
pinowana w pliku lock albo w obrazie bazowym.
## Dostrajanie budżetów
| Zmienna | Domyślnie | Kiedy zmieniać |
|---|---|---|
| `CODEMOD_MAX_ITERATIONS` | 4 | rzadko - wysoki limit maskuje braki w kontekście |
| `CODEMOD_MAX_FILES_CHANGED` | 40 | monorepo z rozlanymi użyciami |
| `CODEMOD_TOOL_CALL_LIMIT` | 60 | duże repozytoria wymagające dużo rozpoznania |
| `CODEMOD_VERIFY_TIMEOUT_S` | 900 | wolne buildy (Maven, testy integracyjne) |
## Zmiana modelu
Modele per rola są w `llm/models.yml`, sekcja `models` danego backendu. Kolejność
inwestowania w większy model: `coder` (stabilne tool-calling), potem `planner`
(rozumowanie o zakresie), na końcu `reviewer`. `scribe` może zostać najmniejszy.
Po zmianie: `eval "$(task llm:env)"` w bieżącej powłoce.
## Dodanie nowego ekosystemu
1. Nowa klasa w `adapters/` dziedzicząca po `EcosystemAdapter` (5 metod).
2. Rejestracja w `adapters/__init__.py`.
3. Test w `test_adapters.py` na odczyt i podbicie wersji (`task test`).
4. Opcjonalnie: instrukcja APM z konwencjami języka (`.apm/instructions/`).
Warstwa agentowa nie wymaga zmian.
## Dodanie migracji nowego SDK
1. Notatka migracyjna dla człowieka i modelu: `references/<pakiet>-<wersja>-migration.md`.
2. Reguły maszynowe: `references/<pakiet>-<wersja>-migration.codemod.yaml`.
3. Publikacja jako pakiet APM z tagiem, dopisanie do `apm.yml` repozytoriów docelowych.
Nic w Pythonie się nie zmienia.