Files
google-ads-ver-2/DEVELOPMENT.md
2026-05-16 21:55:40 +02:00

352 lines
9.8 KiB
Markdown

# Rozbudowa narzedzia
Ten plik opisuje, jak dodawac nowe grupy zadan, zadania i skrypty, zeby kolejny agent nie musial projektowac procesu od zera.
## Zasada architektury
Kazde zadanie powinno dzialac w tym samym modelu:
1. Pobierz aktualne dane.
2. Zbuduj plan.
3. Zapisz plan do `clients/<domena>/plans/` jako `.json` i `.md`.
4. W trybie `--plan-only` nie wdrazaj zmian.
5. Po akceptacji uzytkownika wdrazaj tylko plan zapisany w JSON.
6. Zapisz historie do:
- `clients/<domena>/history/YYYY-MM-DD.jsonl`
- `clients/<domena>/changes/YYYY-MM-DD.md`
Agent AI prowadzi uzytkownika, ale logika pobierania danych, analizy i wdrozenia zmian ma byc w Pythonie.
## Granice zadan i rytm kontroli
Jedno zadanie powinno miec jeden rytm kontroli i jeden typ decyzji. Nie mieszaj w jednym zadaniu prostych ustawien konfiguracyjnych, budzetow, strategii stawek, zapytan uzytkownikow i reklam, bo te obszary sprawdza sie z rozna czestotliwoscia i niosa inne ryzyka.
Przyklady podzialu:
- ustawienia podstawowe, np. lokalizacje, sieci, jezyki - zwykle raz w miesiacu albo po zmianach,
- budzety i pacing - zwykle co tydzien,
- strategie stawek - zwykle co tydzien albo co dwa tygodnie, z ocena wolumenu konwersji,
- zapytania i wykluczenia - zwykle co tydzien,
- reklamy i zasoby - zwykle co dwa do czterech tygodni,
- struktura konta i kampanii - zwykle miesiecznie albo kwartalnie.
Opis zadania w `config/tasks.toml` ma jasno mowic, co jest w zakresie i czego zadanie nie analizuje. Jesli obszar wymaga innej czestotliwosci, dodaj osobne zadanie albo osobna grupe.
## Dodanie nowej grupy zadan
Przed dodaniem wiekszego zakresu sprawdz:
```text
OLD_COMMANDS_CHECKLIST.md
```
To jest lista rzeczy sprawdzanych przez stary system z `D:\google ads\`.
Edytuj:
```text
config/tasks.toml
```
Dodaj nowa grupe:
```toml
[[groups]]
id = "search"
name = "Kampanie Search"
```
Zadania beda numerowane automatycznie jako `2.1`, `2.2`, itd. w zaleznosci od kolejnosci grup.
## Dodanie nowego zadania do grupy
W `config/tasks.toml` dodaj zadanie pod odpowiednia grupa:
```toml
[[groups.tasks]]
id = "check_search_settings"
name = "Sprawdzenie ustawien"
description = "Sprawdza ustawienia kampanii Search wedlug regul globalnych i wyjatkow klienta."
```
`id` jest techniczne i musi byc stabilne. `name` i `description` sa dla uzytkownika.
## Plik zadania w Pythonie
Dodaj modul w:
```text
src/gads_v2/tasks/
```
Przyklad nazwy:
```text
src/gads_v2/tasks/search_settings_check.py
```
Minimalny wzorzec funkcji:
```python
def run_check_search_settings(
client_config: ClientConfig,
global_rules: dict,
plan_only: bool = False,
apply_plan_path: str | None = None,
confirm_apply: str | None = None,
show_navigation: bool = True,
) -> None:
...
```
Wymagania:
- `plan_only=True` zawsze tylko zapisuje plan.
- `apply_plan_path` wdraza tylko wskazany plan JSON.
- `confirm_apply` musi wymagac wartosci `TAK`.
- `show_navigation=False` musi ukrywac pytanie `Co dalej`, bo uzywa tego tryb sekwencji.
## Struktura planu
Plan powinien miec klase lub slownik z metodami:
```python
to_dict()
from_dict()
```
Plan JSON musi zawierac:
```json
{
"created_at": "...",
"client": "example.pl",
"task": "task_id",
"changes": []
}
```
Plan Markdown powinien zawierac:
- krotkie podsumowanie,
- tabele po kampaniach, jesli zadanie dotyczy kampanii,
- tabele planowanych dzialan,
- ostrzezenia lub pominiete reguly.
## Podpiecie zadania do CLI
Edytuj:
```text
src/gads_v2/cli.py
```
1. Zaimportuj funkcje zadania:
```python
from .tasks.search_settings_check import run_check_search_settings
```
2. Dodaj `id` do argumentu `--task`:
```python
parser.add_argument("--task", choices=["sync_pla_cl1", "check_pla_settings", "check_search_settings"], ...)
```
3. Dodaj obsluge w `run_task()`:
```python
if task_id == "check_search_settings":
run_check_search_settings(
client,
global_rules,
plan_only=plan_only,
apply_plan_path=apply_plan_path,
confirm_apply=confirm_apply,
show_navigation=show_navigation,
)
return
```
## Reguly globalne i wyjatki klientow
Reguly trzymaj w:
```text
config/clients.toml
```
Przyklad globalny:
```toml
[global_rules.search_settings]
require_presence_only = true
require_search_partners_off = true
```
Wyjatek per klient:
```toml
[clients."example.pl".search_settings]
require_search_partners_off = false
```
W kodzie uzywaj:
```python
rules = client_config.effective_rules(global_rules, "search_settings")
```
## Pominiecia zadan przy ALL
Jesli zadanie ma byc pomijane tylko przy pelnym wyborze `ALL` / `--all-groups`,
dodaj je przy konkretnym kliencie:
```toml
[clients."example.pl"]
google_ads_customer_id = "123-456-7890"
skip_in_all = ["split_pla_cl1_bestsellers"]
```
Pominiecie dotyczy tylko `ALL` / `--all-groups`. Reczny wybor zadania albo grupy
nadal uruchamia wskazany zakres.
## Numeracja i wybory
Lista zadan uzywa formatu:
```text
1.1 - pierwsze zadanie w pierwszej grupie
1.2 - drugie zadanie w pierwszej grupie
1.0 - wszystkie zadania z pierwszej grupy
ALL - wszystkie zadania ze wszystkich grup
```
Nie dodawaj recznej numeracji do `tasks.toml`. Numeracja wynika z kolejnosci grup i zadan.
## Test po dodaniu zadania
Uruchom:
```powershell
python -m compileall -q gads.py src
python gads.py analiza-klienta --client-number 1
python gads.py analiza-klienta --client-number 1 --select <nr> --plan-only
```
Jesli zadanie wdraza zmiany, przetestuj najpierw tylko `--plan-only`.
## Format komunikacji agentow
Instrukcja dla agentow jest w:
```text
AGENTS.md
```
Po dodaniu nowego typu zadania dopisz tam tylko specjalne zasady, jesli agent ma wiedziec cos ponad standardowy przeplyw.
## Rozbudowa bazy wiedzy
Baza wiedzy projektu jest w:
```text
knowledge/
```
Najwazniejsze pliki:
- `knowledge/sources/` - materialy zrodlowe, np. artykuly, notatki, eksport ze starej LanceDB.
- `knowledge/rules.jsonl` - atomowe reguly uzywane przez narzedzie.
- `knowledge/imports.jsonl` - historia importow.
- `knowledge/lancedb/` - metadane indeksu semantycznego. Fizyczny indeks LanceDB jest domyslnie w `%LOCALAPPDATA%\google-ads-ver2-knowledge-lancedb`, bo katalog projektu moze byc synchronizowany i blokowac operacje zapisu LanceDB.
Dodawanie wiedzy:
```powershell
python gads.py wiedza dodaj --file "knowledge/sources/plik.md" --source "czytelna_nazwa_zrodla" --dry-run
python gads.py wiedza dodaj --file "knowledge/sources/plik.md" --source "czytelna_nazwa_zrodla"
```
Jednorazowy import starej bazy LanceDB:
```powershell
python gads.py wiedza import-stare --from "D:\google ads\lancedb"
python gads.py wiedza indeksuj
```
Ten import nie przypisuje regul do zadan. `task_ids` oraz `suggested_task_ids` pozostaja puste.
Wznawialny przeglad regul bez przypisan:
```powershell
python gads.py wiedza przypisz
python gads.py wiedza przypisz --restart
```
Domyslnie `wiedza przypisz` pokazuje jedna regule, pelny kontekst decyzji i konczy porcje po jednej odpowiedzi. Reguly sa przegladane w kolejnosci zapisanej w `knowledge/rules.jsonl`, a nie sortowane po tematach. To ulatwia uzytkownikowi porownanie ekranu przegladu z plikiem i kolejnoscia importu. Wieksze partie uruchamiaj tylko jawnie, np. `python gads.py wiedza przypisz --limit 10`.
Zasady przegladu:
- `Q` przerywa bez przesuniecia kursora, wiec wznowienie zacznie od tej samej reguly.
- `P` pomija regule i zapisuje postep.
- `U` pyta o potwierdzenie `USUN`, a potem trwale usuwa biezaca regule z `knowledge/rules.jsonl`.
- Numer zadania lub `task_id` dopisuje regule do zadania.
- Po dodaniu nowych zadan do `config/tasks.toml` uruchom `python gads.py wiedza przypisz --restart`.
- Stan kursora jest w `knowledge/review_state.json`.
- Po usunieciu reguly stan kursora zapisuje takze klucz sortowania, zeby wznowienie zaczelo od nastepnej reguly mimo braku usunietego `id` w pliku.
- Po fizycznym usunieciu regul trzeba odbudowac LanceDB przez `python gads.py wiedza indeksuj`, bo indeks jest tylko lokalna kopia do wyszukiwania.
Zasady:
- Najpierw uruchom `--dry-run`, zeby sprawdzic plik bez kosztu API.
- Import przez API wymaga `OPENAI_API_KEY` w `.env`.
- Opcjonalny model ustaw przez `KNOWLEDGE_OPENAI_MODEL` albo `--model`.
- Reguly przypisuj tylko do istniejacych `task_id` z `config/tasks.toml`.
- Importer moze zapisac propozycje w `suggested_task_ids`, ale nie wolno uznawac ich za aktywne przypisanie do zadania.
- Regula staje sie regula zadania dopiero po akceptacji uzytkownika przez pytanie skryptu albo komenda:
```powershell
python gads.py wiedza zatwierdz --rule-id "<id_reguly>" --task "<task_id>"
```
- Odrzucenie propozycji:
```powershell
python gads.py wiedza odrzuc --rule-id "<id_reguly>" --task "<task_id>"
```
- Jesli wiedza dotyczy zadania, ktorego jeszcze nie ma, zostaw `task_ids` i `suggested_task_ids` puste i zaplanuj osobne zadanie w `config/tasks.toml`.
- Reguly z `knowledge/rules.jsonl` wspieraja analize i uzasadnienie planu. Nie wolno traktowac ich jako automatycznej zgody na wdrozenie zmian.
- `rules.jsonl` jest zrodlem prawdy. LanceDB, gdy zostanie dodane, ma byc tylko indeksem semantycznym odbudowywanym z JSONL.
- Po zmianach w `rules.jsonl` odswiez indeks:
```powershell
python gads.py wiedza indeksuj
```
- Wyszukiwanie semantyczne:
```powershell
python gads.py wiedza szukaj-ai "zapytanie opisowe"
```
- Kazda regula powinna miec metadane: `status`, `created_at`, `updated_at`, `source_file`, `duplicate_of`, `supersedes`.
- Nie kasuj regul recznie przy porzadkowaniu bazy. Zmieniaj status:
```powershell
python gads.py wiedza archiwizuj --rule-id "<id_reguly>"
python gads.py wiedza aktywuj --rule-id "<id_reguly>"
python gads.py wiedza duplikat --rule-id "<id_reguly>" --duplicate-of "<id_reguly_nadrzednej>"
```
- Po imporcie sprawdz wynik:
```powershell
python gads.py wiedza szukaj "temat"
python gads.py wiedza propozycje
python gads.py wiedza reguly --task check_pla_settings
python gads.py wiedza lista --topic shopping
python gads.py wiedza statystyki
```