Agentit koodaa yöllä, minä katselmoin aamulla

Taas on vettä virrannut sitten viime postauksen. Kaikenlaista on tapahtunut: nykyään lapsia on kaksi, oon töissä Fintrafficilla Tech Leadina ja käsin clojuren väkertäminen on vaihtunut, kuten kaikilla muillakin alalla, aikalailla agenttiseen touhuun. Ajatukset on kaksijakoiset: on kiva saada hommia eteenpäin ja moni harrasteprojekti on saanut uutta energiaa alleen, mutta sitten taas toisaalta se ilo siitä, kun koodi toimii pitkän säädön jälkeen ja voi olla ylpeä siitä, että on saanut IHAN ITSE tämän aikaan, se on nyt poissa. Vaan entinen ei koskaan palaa ja parempi siis syleillä uusia tapoja tehdä.

No mutta, tässäpä nyt vähän tätä, miten olen itse omaa projektia tekemässä. Projekti on osakkeisiin liittyvä tämmöinen oma softa, jossa katselen taulukkomuodossa osakkeiden hintoja. Toki käytän kaupallisiakin softia, kuten Tradinview, mutta mistään en löytänyt taulukkomuodossa nousuja ja laskuja sillä tavalla, kuin haluan, joten siksipä sitten tämä oma softa. Koska en jaksa joka kerta muistaa, mitä siviilikoneessa olikaan konffattuna, ja käsin käskytellä agentteja, tein tällaisen linjaston.

Tiketit mulla on github projects-seinällä, niin niitä saapi paikallisesti lukea helposti gh cli:llä.

Periaatteessa homma toimii näin helposti

  • Teen issueita (tai höpöttelen claudelle, joka tekee issueita suoraan ja kirjoittelee hienon speksin) githubiin.
  • Merkitsen GitHub-issuen labelilla agent:ready
  • Pistän illalla linjasto run-next pörräämään omalla kotikoneella.
  • Aamulla korjaus odottaa develop-ympäristössä valmiina katselmoitavaksi.
  • AWS Amplifyssä mulla on sekä mainista, että develop-haarasta deploy ja developpiin saa agentti mergetä kaikki ne, jotka läpäise review-loopin.
  • Review tehdään kahdella agentilla, jotka palloittelee havaintoja keskenään. Olen läiskässyt hard limitiksi 3, ettei tokenit ole aamulla käytetty. Vain blokkavat muutokset estää mergen.
  • Developista linjasto kokoaa release-PR:n mainiin, ja agentti kirjoittaa siihen release notesit. Sovellus pyörii AWS Amplifyssa. Main menee tuotantoon ja develop omaan ympäristöönsä, joten jokainen merge näkyy heti develop-ympäristössä. Aamulla kokeilen muutokset siellä, luen release-PR:n ja hyväksyn sen, jos kaikki näyttää hyvältä. Tuotantoon ei mene mitään ilman minua.

Labelit määrittelevät työnkulun

Koko linjaston tila on GitHub-labeleissa, samaan tapaan kuin Jirassa tiketin tila on sarakkeessa. Ei erillistä tietokantaa eikä jonopalvelua.

  1. agent:ready: minä hyväksyn työn. Tämä on ainoa label, jonka laitan käsin.
  2. agent:working: implementer toteuttaa.
  3. agent:review: katselmointisilmukka on käynnissä.
  4. agent:in-develop: muutos on developissa ja odottaa release-PR:ssä.
  5. Suljettu: muutos on mainissa.

Jos toteutus tai katselmointi jumittuu, issue saa labelin agent:needs-human ja agentti kirjoittaa syyn kommenttiin. Kun olen selvittänyt asian, laitan issuen takaisin agent:ready-tilaan.

Hyvä esimerkki on issue, jossa pyysin “Avaa Nordnetissa” -linkkiä TradingView-linkin viereen. Fixer kokeili Nordnetin hakuosoitteita, mutta /etsi ja /haku palauttivat 404:n ja muut vaihtoehdot ohittivat hakusanan. Se pysähtyi ja totesi, että linkin muodosta pitää päättää ihmisen. Juuri näin sen kuuluukin mennä: agentti ei arvannut vaan kysyi.

Dashboard näyttää, mitä linjalla tapahtuu

Linjasto kirjoittaa jokaisen vaiheen ja työkalukutsun tapahtumalokiin, tiedostoon ~/.local/state/linjasto/<projekti>.jsonl. Kun loki on valmiiksi JSON-riveissä, dashboardin tekeminen sen päälle oli helppoa. Se on pieni sivu, joka kuuntelee vain osoitetta localhost:8787 ja päivittyy kahden sekunnin välein.

  • Valmiina mainiin: release-PR ja siihen kerätyt issuet.
  • Pysähtyneet: agent:needs-human-issuet ja -PR:t sekä syy, miksi ne jäivät jumiin.
  • Valittu ajo: issue ja PR linkkeinä, vaihe sekä agentti mallineen ja kestoineen.
  • Tapahtumat: jokainen vaihe ja työkalukutsu rooleittain (implementer, reviewer-a, reviewer-b, fixer, release-notes).
  • Jonossa: agent:ready-issuet prioriteettijärjestyksessä, seuraava korostettuna.

Sama status tulee myös terminaaliin, mutta dashboardista näkee yhdellä silmäyksellä, mitä yöllä tapahtui.

Mitä seuraavaksi

Implementer pyörii tällä hetkellä halvoilla kaupallisilla malleilla OpenCode Go:n kautta. Seuraava askel on ajaa se kokonaan paikallisella mallilla kotona olevalla Linux-koneellani, jossa muistia ja GPU:ta riittää. Silloin toteutuksen hinta olisi käytännössä pelkkä sähkölasku.

Ehkä tässä tärkein oppi on kuitenkin se, mihin ihminen jää. En kirjoita koodia enkä ohjaa agenttia rivi riviltä, mutta päätän yhä kolmesta asiasta: mitä tehdään (agent:ready), mitä tehdään kun agentti on jumissa (agent:needs-human) ja mitä menee tuotantoon (release-PR). Agentti katselmoi agentin työn, mutta tuotantoon vie ihminen.

Linjasto on vaan kokeilu yhden ihmisen harrasteprojektia varten, mutta ajatus skaalautuu. Kun toteutus ja katselmointi pyörivät itsestään, kehittäjän työ siirtyy hyvien issueiden kirjoittamiseen ja valmiiden muutosten arviointiin.

Ja sanottakoot, että kaupallisia softiahan tähän on kaksitoista tusinassa, esmes hermes, grok bot jne. Halusin kuitenkin kokeilla, että mikä on pienin määrä, mitä voin tehdä tuollaisen orkestroinnin toteuttaakseni ja kevyin tapa ajaa sitä minimoiden pilvitilien luominen.