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.
15 KiB
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.tomlkäyttää Poetry-muotoa - Analysoija tunnistaa:
[tool.poetry]→ virheluokkawrong-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:
- Benchmark-ajo tuottaa 100% PASS -tuloksen (esim. blog-skenaario)
- Generoidut tiedostot tallennetaan
golden-examples/blog/-hakemistoon - Seuraavissa ajoissa CODE_SYSTEM-promptiin liitetään: "Tässä on toimiva blog-projekti, generoi vastaava todo-projektille"
- 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:
- Aja pytest
- Jos virheitä: syötä virheilmoitus + koodi mallille
- Malli korjaa koodin
- Aja pytest uudestaan
- 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:
- Generoi N promptivarianttia (mutaatiot: lisää sääntö, poista sääntö, muokkaa sanamuotoa)
- Aja benchmark jokaisella variantilla
- Pisteytä:
fitness = testsPassed / testsTotal - Valitse parhaat (top-K)
- Risteytä ja mutaatioi uusia variantteja
- Toista
Mutaatio-operaatiot:
add_rule: Lisää uusi sääntö promptiin (peräisin virheanalyysistä)remove_rule: Poista sääntö joka ei vaikuta tuloksiinrephrase: 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? | 0–5 (tiedostoa) |
| Syntaksi | Parsitaanko koodi virheettä? | 0–4 (.py-tiedostot) |
| Importit | Ovatko kaikki importit resolvable? | 0/1 per tiedosto |
| Testit | Pytest pass rate | passed / total (0.0–1.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ä (0–100):
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)
- 2–3 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:
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ää:
{
"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 | 40–60p | 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 2–3× enemmän tokeneita mutta laatu laskee. Suositus: käytä aina think: false koodingenerointiin.
Yllätykset
- Yleismallit voittivat kooderimallit. qwen3:8b (5 GB yleismalli, 95p) päihittää qwen2.5-coder:32b (20 GB kooderimalli, 79p).
- qwen3:14b on paras. 9.3 GB malli sai 100p — parempi kuin mikään isompi malli.
- Koko ei ratkaise. qwen3-coder-next (51 GB) sai vain 69p. gemma4:31b (20 GB) sai 80p. qwen3:14b (9.3 GB) sai 100p.