Files
agentic-studio/network-poc/SUPERAGENTS.md
jaakko 838d5fbd73 SUPERAGENTS.md: mallisuositukset VRAM-luokittain benchmark-datan perusteella
4GB qwen3:4b, 8GB qwen3:8b (95p), 16GB qwen3:14b (100p),
24GB qwen3-coder:30b (97p, 123 tok/s), 48GB molemmat rinnakkain.
Thinking-moodi huonontaa tuloksia. Yleismallit voittivat kooderimallit.
2026-04-14 10:33:35 +03:00

354 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Superagentti — itseoppiva koodausjärjestelmä
Visio: järjestelmä joka **oppii joka iteraatiolla** ja kehittyy lopulta superagentiksi ohjelmointitehtäviin.
## Miksi tämä on realistista
Benchmark-järjestelmä (`model-benchmark.mjs`) tarjoaa jo valmiin **fitness-funktion**: pytest-tulokset antavat yksiselitteisen signaalin (6/6 vs 0/6). Se on itseoppivan järjestelmän vaikein osa — ja se on valmis.
Puuttuvat palaset ovat analysoija ja promptin evoluutio.
## Arkkitehtuuri
```
┌──────────────┐
│ Benchmark │ ← nykyinen model-benchmark.mjs
│ (suorita) │
└──────┬───────┘
│ results.json + _pytest.txt + _code_raw.txt
┌──────────────┐
│ Analysoija │ ← luokittele virheet automaattisesti
│ │ "pyproject: poetry vs pep621"
│ │ "testi kutsuu olematonta endpointia"
└──────┬───────┘
│ virheluokat + korjausohjeet
┌──────────────┐
│ Promptin │ ← muokkaa prompteja tulosten perusteella
│ evoluutio │ lisää sääntöjä, few-shot-esimerkkejä
└──────┬───────┘
│ parannetut promptit
┌──────────────┐
│ Benchmark │ ← aja uudestaan parannetuilla prompteilla
│ (uusinta) │
└──────────────┘
↻ toista kunnes 100%
```
## Toteutustasot
### Taso 1 — Virhepohjainen promptin korjaus
Helpoin ja nopein toteuttaa. Pytest-virheistä tunnistetaan virheluokka ja lisätään sääntö promptiin automaattisesti.
**Esimerkki:**
- Benchmark tuottaa: `pyproject.toml` käyttää Poetry-muotoa
- Analysoija tunnistaa: `[tool.poetry]` → virheluokka `wrong-pyproject-format`
- Evoluutio lisää promptiin: `"pyproject.toml MUST use PEP 621 [project] format, NOT [tool.poetry]"`
- Seuraava ajo onnistuu
**Virheluokkia** (havaittu ensimmäisistä ajoista):
| Virheluokka | Kuvaus | Promptikorjaus |
|-------------|--------|----------------|
| `wrong-pyproject-format` | Poetry-muoto PEP 621:n sijaan | Lisää sääntö: "use [project], not [tool.poetry]" |
| `missing-endpoint-test` | Testi kutsuu endpointia jota ei ole | Lisää sääntö: "only test endpoints defined in main.py" |
| `missing-import` | Puuttuva import | Korjaussilmukan asia (taso 4) |
| `unique-constraint` | Testi ei käsittele duplikaatteja | Lisää sääntö: "use unique test data per test" |
### Taso 2 — Few-shot oppiminen
Onnistuneet generoinnit talteen "kultaisiksi esimerkeiksi" joita syötetään tuleviin prompteihin.
**Miten toimii:**
1. Benchmark-ajo tuottaa 100% PASS -tuloksen (esim. blog-skenaario)
2. Generoidut tiedostot tallennetaan `golden-examples/blog/` -hakemistoon
3. Seuraavissa ajoissa CODE_SYSTEM-promptiin liitetään: "Tässä on toimiva blog-projekti, generoi vastaava todo-projektille"
4. Malli näkee konkreettisesti mitä odotetaan
**Etu:** Laatu nousee nopeasti koska malli saa tarkan esimerkin odotetusta rakenteesta — tiedostomarkerit, importit, pyproject-muoto.
### Taso 3 — Monimalliorkesteri
Eri malli eri vaiheeseen. Benchmark-data kertoo mikä malli on missä paras.
**Esimerkki:**
| Vaihe | Paras malli | Perustelu |
|-------|-------------|-----------|
| Vaatimukset | qwen3:30b | Nopea, hyvä suomenkielinen ymmärrys |
| JSON-speksi | gemma4:31b | Tarkka strukturoitu output |
| Koodigenerointi | qwen3-coder-next | Suunniteltu koodaukseen |
| Korjaus | devstral:24b | Hyvä virheiden analysointi |
**Kahden GPU:n hyödyntäminen:** Vaiheita voi ajaa rinnakkain eri malleilla eri GPU:illa. Esim. speksi GPU1:llä samalla kun edellinen koodi validoidaan GPU2:lla.
### Taso 4 — Itsekorjaava agenttilooppi
Nykyinen korjaussilmukka (max 2 kierrosta) käyttää staattista validaattoria. Taso 4 syöttää **oikean pytest-virheviestin** mallille.
**Nykyinen (rajoitettu):**
```
validaattori → "ISSUE: relatiivinen import" → LLM korjaa → aja uudestaan
```
**Taso 4 (itsekorjaava):**
```
pytest → "IntegrityError: UNIQUE constraint failed" → LLM analysoi → korjaa → pytest → ✓
```
**Iteraatiolooppi:**
1. Aja pytest
2. Jos virheitä: syötä virheilmoitus + koodi mallille
3. Malli korjaa koodin
4. Aja pytest uudestaan
5. Toista kunnes PASS tai max N kierrosta
Tämä on lähellä sitä miten Claude Code ja Cursor toimivat sisäisesti.
### Taso 5 — Promptin evoluutio (geneettinen)
Automaattinen promptien optimointi geneettisellä algoritmilla.
**Algoritmi:**
1. Generoi N promptivarianttia (mutaatiot: lisää sääntö, poista sääntö, muokkaa sanamuotoa)
2. Aja benchmark jokaisella variantilla
3. Pisteytä: `fitness = testsPassed / testsTotal`
4. Valitse parhaat (top-K)
5. Risteytä ja mutaatioi uusia variantteja
6. Toista
**Mutaatio-operaatiot:**
- `add_rule`: Lisää uusi sääntö promptiin (peräisin virheanalyysistä)
- `remove_rule`: Poista sääntö joka ei vaikuta tuloksiin
- `rephrase`: Muotoile sääntö uudelleen (esim. "MUST" → "ALWAYS", esimerkin lisäys)
- `reorder`: Vaihda sääntöjen järjestystä (promptin alku painottuu enemmän)
## Superagentti syntyy kun
Yhdistetään kaikki tasot: järjestelmä **valitsee parhaan mallin tehtävään** (taso 3), **käyttää opittuja prompteja** (taso 2), **korjaa virheensä itse** (taso 4), ja **parantaa promptejaan joka kierroksella** (taso 5).
## Benchmark — kehityksen todentaminen
Ilman kunnollista pisteytystä ja historiaa ei voi todentaa kehitystä. Benchmark-järjestelmä tarvitsee kolme kerrosta: **metriikat**, **vaikeustasot** ja **historiavertailu**.
### Metriikat
Yksittäinen "PASS/FAIL" ei riitä. Jokainen ajo pisteytetään moniulotteisesti:
| Metriikka | Mitä mittaa | Pisteytys |
|-----------|------------|-----------|
| **Parsittavuus** | Tuottiko malli kaikki 5 tiedostoa oikeilla markereilla? | 05 (tiedostoa) |
| **Syntaksi** | Parsitaanko koodi virheettä? | 04 (.py-tiedostot) |
| **Importit** | Ovatko kaikki importit resolvable? | 0/1 per tiedosto |
| **Testit** | Pytest pass rate | passed / total (0.01.0) |
| **Korjauskierrokset** | Montako korjausta tarvittiin? | 0 = paras, >2 = huono |
| **Token-tehokkuus** | Tokenia per läpäisty testi | pienempi = parempi |
| **Nopeus** | tok/s ja kokonaisaika | isompi tok/s = parempi |
| **Varoitukset** | Deprecation warnings, style issues | 0 = paras |
**Kokonaispistemäärä** (0100):
```
score = (
parsittavuus/5 * 15 + # 15p: tiedostot syntyvät
syntaksi/4 * 15 + # 15p: koodi parsitaan
testit * 40 + # 40p: testit menevät läpi (tärkein)
(1 - korjaukset/max) * 10 + # 10p: ei tarvitse korjauksia
tehokkuus_norm * 10 + # 10p: vähän tokeneita per testi
nopeus_norm * 10 # 10p: nopea generointi
)
```
Testien paino on 40% koska toimiva koodi on tärkein. Parsittavuus ja syntaksi ovat "pääsyvaatimuksia" — ilman niitä testejä ei voi edes ajaa.
### Vaikeustasot
Kolme nykyistä skenaariota (todo, users, blog) ovat kaikki samaa tasoa. Kehityksen mittaamiseen tarvitaan portaikko:
**Taso 1 — Perus-CRUD** (nykyiset)
- Yksi entiteetti, ei relaatioita
- Esim. todo, users
- Odotettu tulos: 100% kaikilla kelvollisilla malleilla
**Taso 2 — Relaatiot** (nykyinen blog)
- 23 entiteettiä, foreign key -viittaukset
- Esim. blog (author → post), kirjasto (author → book)
- Haaste: relaatioiden oikea käsittely, cascade
**Taso 3 — Liiketoimintalogiikka**
- Validointisääntöjä, tilasiirtymiä, laskentaa
- Esim. verkkokauppa (tuote → tilaus → tilausrivi, varastosaldo, hintalaskenta)
- Haaste: pelkkä CRUD ei riitä, tarvitaan custom-endpointeja
**Taso 4 — Kehittyneet patternit**
- Autentikointi, middleware, taustatehtävät, WebSocket
- Esim. chat-sovellus (käyttäjä → huone → viesti, reaaliaikainen, online-status)
- Haaste: arkkitehtuuriosaamisesta, ei vain tietomallista
**Skenaariot per taso:**
```python
SCENARIOS = [
# Taso 1 — Perus-CRUD
{"id": "todo", "level": 1, "prompt": "Todo-sovellus: tehtävien hallinta, deadline, prioriteetti ja status"},
{"id": "users", "level": 1, "prompt": "REST API käyttäjähallinnalle SQLite-tietokannalla"},
{"id": "notes", "level": 1, "prompt": "Muistiinpanosovellus: otsikko, sisältö, tagit, luontipäivä"},
# Taso 2 — Relaatiot
{"id": "blog", "level": 2, "prompt": "Blogi-API: kirjoittajat ja artikkelit, julkaisupäivämäärä ja status"},
{"id": "library", "level": 2, "prompt": "Kirjasto-API: kirjailijat, kirjat ja lainaukset, palautuspäivä ja sakko"},
{"id": "school", "level": 2, "prompt": "Kouluhallinto: opettajat, kurssit ja ilmoittautumiset, arvosanat"},
# Taso 3 — Liiketoimintalogiikka
{"id": "shop", "level": 3, "prompt": "Verkkokauppa: tuotteet, tilaukset ja tilausrivit, varastosaldo vähenee tilauksessa, kokonaishinta lasketaan automaattisesti"},
{"id": "booking", "level": 3, "prompt": "Varausjärjestelmä: resurssit ja varaukset, päällekkäiset varaukset estetään, peruutus vapauttaa ajan"},
{"id": "project", "level": 3, "prompt": "Projektinhallinta: projektit, tehtävät ja kommentit, tehtävän status-siirtymät (todo→doing→done), projektin edistymisprosentti lasketaan tehtävistä"},
]
```
### Historiavertailu
Tulokset tallennetaan aikasarjana jotta kehitys näkyy:
```
benchmark-history/
├── 2026-04-14_1200_v1.json ← ensimmäinen ajo
├── 2026-04-14_1500_v2.json ← prompti paranneltu
├── 2026-04-15_0900_v3.json ← few-shot lisätty
└── latest.json ← symlink uusimpaan
```
**Jokainen tallennus sisältää:**
```json
{
"version": "v3",
"timestamp": "2026-04-15T09:00:00Z",
"prompts_hash": "a3f2c1...",
"results": [
{
"model": "qwen3-coder-next",
"scenario": "todo",
"level": 1,
"score": 85,
"metrics": {
"parsability": 5,
"syntax": 4,
"tests_passed": 6,
"tests_total": 6,
"fix_rounds": 0,
"tokens": 2100,
"tok_per_sec": 72,
"warnings": 0
}
}
],
"summary": {
"avg_score": 72,
"pass_rate": 0.67,
"by_level": {"1": 95, "2": 72, "3": 48}
}
}
```
**Kehitysraportti** (automaattinen vertailu edelliseen):
```
╔═══════════════════════════════════════╗
║ Kehitysraportti v2 → v3 ║
╠═══════════════════════════════════════╣
║ Kokonaispistemäärä: 62 → 72 (+10) ║
║ Pass rate: 44% → 67% (+23) ║
║ Taso 1: 80 → 95 (+15) ║
║ Taso 2: 60 → 72 (+12) ║
║ Taso 3: 45 → 48 (+3) ║
║ ║
║ Parantunut: pyproject-muoto ✓ ║
║ Parantunut: import-ongelmat ✓ ║
║ Ennallaan: liiketoimintalogiikka ║
╚═══════════════════════════════════════╝
```
### Regressiotunnistus
Jos promptimuutos parantaa yhtä skenaariota mutta rikkoo toisen, se pitää havaita:
- Jokaisella ajolla verrataan **kaikkia skenaarioita** edelliseen
- Jos mikä tahansa skenaario laskee >10 pistettä → **varoitus**
- Jos taso 1 (perus-CRUD) laskee → **esto** (perustason pitää aina toimia)
## Toteutusjärjestys
```
Taso 1 ██████████ ← aloita tästä (päivä)
Taso 4 ████████ ← seuraavaksi (päivä)
Taso 2 ██████ ← golden examples (päivä)
Taso 3 ████ ← monimalli (2-3 päivää)
Taso 5 ██ ← evoluutio (viikko)
```
Taso 1 antaa suurimman hyödyn nopeimmin. Taso 4 (itsekorjaava looppi) on toiseksi tärkein koska se moninkertaistaa onnistumisprosentin. Taso 5 on pitkän aikavälin investointi.
## Mallisuositukset VRAM-luokittain
Testattu 2026-04-14 Kipinä CodeBench -benchmarkilla (3 skenaariota: todo, users, blog). Kaikki ajot `think: false`, `num_ctx: 16384`.
### Suositellut mallit
| VRAM | Malli | Pisteet | Testit | tok/s | VRAM-käyttö |
|------|-------|---------|--------|-------|-------------|
| **4 GB** | qwen3:4b | ★★☆☆☆ 33p | 6/6* | 47 | ~3.5 GB |
| **8 GB** | **qwen3:8b** | **★★★★★ 95p** | 25/27 (93%) | **99** | ~7 GB |
| **16 GB** | **qwen3:14b** | **★★★★★ 100p** | 25/25 (100%) | 60 | ~11 GB |
| **24 GB** | **qwen3-coder:30b** | **★★★★★ 97p** | 23/24 (96%) | **123** | ~22 GB |
| **48 GB** | qwen3-coder:30b + qwen3:14b | — | — | — | ~33 GB |
*qwen3:4b: todo 6/6 täydellinen, mutta users ja blog epäonnistuvat speksivaiheessa
### Perustelut
**4 GB** — qwen3:4b (2.5 GB + ~1 GB KV-cache). Ainoa toimiva vaihtoehto. Riittää yksinkertaisiin CRUD-tehtäviin mutta monimutkaisten skenaarioiden speksivaihe epäonnistuu.
**8 GB** — qwen3:8b on benchmarkin paras hinta-laatu. 95p ja 99 tok/s viidellä gigalla. Lähes yhtä hyvä kuin 2× isompi qwen3:14b.
**16 GB** — qwen3:14b, benchmarkin kokonaisvoittaja: 100p kaikissa skenaarioissa. 4 GB jää muulle käytölle (IDE, selain, OS).
**24 GB** — qwen3-coder:30b, nopein huippumalli (123 tok/s). Agenttiloopissa nopeusero on merkittävä: 3 skenaariota 94 sekunnissa vs. qwen3:14b 152 sekunnissa.
**48 GB** — kaksi mallia rinnakkain: qwen3-coder:30b raskaaseen koodingenerointiin, qwen3:14b kevyempiin tehtäviin (korjaukset, speksit, refaktorointi). Yhteensä ~33 GB, 15 GB puskuria.
### Hylätyt vaihtoehdot
| Malli | Koko | Pisteet | Miksi ei |
|-------|------|---------|----------|
| qwen2.5-coder:3b | 1.9 GB | 33p | qwen3:4b parempi samoilla pisteillä |
| qwen2.5-coder:7b | 4.7 GB | 26p | qwen3:8b päihittää selvästi (95p vs 26p) |
| qwen2.5-coder:32b | 19.9 GB | 79p* | qwen3-coder:30b parempi ja nopeampi |
| qwen3.5:35b | 24 GB | 4060p | Epätasainen, 0/1 collection erroreja |
| qwen3.5:27b | 17.4 GB | 54p | qwen3:14b parempi ja pienempi |
| gemma4:31b | 19.9 GB | 80p | Hyvä laatu mutta 4× hitaampi (28 tok/s) |
| gemma4:e4b | 9.6 GB | 58p | qwen3:8b parempi ja pienempi |
| codestral:22b | 12.6 GB | 88p | Mistral-perheen paras, varamalli |
| devstral:24b | 14.3 GB | 44p | Agentti-malli, huono koodigeneroinnissa |
| mistral-small3.1:24b | 15.5 GB | 30p | Heikko, test_main.py puuttui usein |
| qwen3-coder-next | 51 GB | 69p | Pettymys suhteessa kokoon |
*epätasainen: todo 100p, users 0p, blog 63p
### Thinking-moodi
Testattu qwen3:14b ja qwen3:8b thinking-moodilla (`--think`). Tulos: **thinking huonontaa tuloksia**.
| Malli | No-think | Think | Ero |
|-------|----------|-------|-----|
| qwen3:14b | ★★★★★ 100p | ★★★☆☆ 51p | 49p |
| qwen3:8b | ★★★★★ 95p | ★★★★☆ 77p | 18p |
Ajattelu tuottaa 23× enemmän tokeneita mutta laatu laskee. Suositus: **käytä aina `think: false`** koodingenerointiin.
### Yllätykset
1. **Yleismallit voittivat kooderimallit.** qwen3:8b (5 GB yleismalli, 95p) päihittää qwen2.5-coder:32b (20 GB kooderimalli, 79p).
2. **qwen3:14b on paras.** 9.3 GB malli sai 100p — parempi kuin mikään isompi malli.
3. **Koko ei ratkaise.** qwen3-coder-next (51 GB) sai vain 69p. gemma4:31b (20 GB) sai 80p. qwen3:14b (9.3 GB) sai 100p.