Mikko Uuksulaisen kotisivu

7. elokuuta 2025

Claude Code kokemuksia

Claude Code on vuoden 2025 alkupuolella julkaistu, Anthropicin eri Claude-tekoälymalleja hyödyntävä, konsolista ajettava tekoälyagenttisovellus, joka mahdollistaa interaktiivisen kehittämisen kehotteita syöttämällä ja hyödyntäen tekoälyn kykyä ajaa eri työkaluja. Claude Coden käytöstä on jo nyt kantautunut maailmalta positiivisia kokemuksia ja sen suurimpana kulmakivenä on lähinnä Claude-mallien korkeat käyttökustannukset. Claude Coden merkittävimpiä kilpailijoita ovat samalla periaatteella toimivat OpenAI:n Codex, Googlen Gemini CLI, Alibaban Qwen3-Coder ja yhteisön kehittämät Aider, Goose sekä OpenCode.

Halusin itse testata Cloude Coden kykyjä ja sopiva projekti tupsahti syliin kuin itsestään, kun jouduin toteamaan lapsen pikkuautoleikkejä katsoessa, että en enää tunnista eri automerkkejä. Tuumin, että asia täytyy korjata rakentamalla niiden opiskeluun flashcard-sovellus.

Käynnistin Claude Coden Pro-tilauksen hintaan 22,59€ ja ryhdyin lapioimaan.

Projektin lähtöpiste

Suunnittelin ratkaisuni selaimessa ajettavaksi mobiililähtöiseksi sovellukseksi, joka lukisi suunnittelemassani formaatissa annettavia tiedostoja. Tiedostot olisivat zip-paketteja, jotka sisältäisivät json-tiedostossa tekstimuotoisia kysymyksiä ja vastauksia sekä valinnaisesti näihin liittyviä kuvia. Sovellus lukisi tiedoston selaimeen muistiin, jossa se myös säilyisi siihen asti, kunnes se erikseen poistettaisiin.

Aloitin projektin luomalla käsin Parcel-projektin, johon konfiguroin TypeScriptin, ESLintin ja Prettierin. Lisäsin myös packages.json-tiedostoon komennot projektin ajamiseksi. Loin index.html-tiedoston luurangon ja sen kaveriksi App.ts-tiedoston TypeScriptiä varten. Tämän jälkeen käynnistin komentoriviltä Clauden Coden projektin juuressa.

Claude Codeen on sisäänrakennettu erilaisia "slash-komentoja", joita sen syötelaatikkoon voidaan ajaa kehotteiden lisäksi. Ajamalla /init, Claude Code käy läpi koko kansiorakenteen ja kirjoittaa CLAUDE.md-tiedostoon tiiviin näkemyksen projektin sisällöstä. Kyseinen tiedosto ajetaan tekoälyn kontekstiin aina Claude Coden käynnistyessä ja se onkin oiva paikka säilöä esimerkiksi projektin tyylisääntöjä ja käytänteitä, joita tekoälyn tulee generoinnissaan huomioida. Projektin alussa ajamalla se lähinnä toteaa, että projektissa ei ole mitään sisältöä, mutta samalla se oppii miten projektia kuuluisi ajaa. Tätä tiedostoa on syytä päivittää myös matkan varrella koodipohjan muuttuessa ajamalla komento uudestaan.

Kokeellinen työnkulku

Tapoja tekoälyn kanssa työskentelyyn on monia, mutta päätin käyttää mallia, jossa tekoälylle annetaan etukäteen mahdollisimman paljon tietoa vaatimuksista ja yksityiskohdista. Tämä poikkeaa vibe-koodaus-mallista, jossa sovellusta tai ominaisuuksia lähdetään kehittämään pala kerrallaan yksinkertaisia kehotteita (tai jopa yhden lauseen kehotteen) syöttämällä. Omien kokeilujeni pohjalta etukäteen speksaaminen on aina johtanut parempaan lopputulokseen, niin tekoälyn, kuin ihmiskehittäjänkin kanssa.

Ajatuksenani oli, että tekoälylle annettavat tehtävät säilöttäisiin tekstitiedostoina projektin juureen ai/tasks-kansiorakenteeseen, jotta ne olisivat yhdessä paikassa tallessa ja niihin olisi tarvittaessa helppo palata uudestaan.

Loin käsin ai/tasks-kansion, jonne loin ensimmäisen task-1-basic-functionality.md-tiedoston. Tähän tiedostoon tein oikeaa käyttötapausta mukaillen vaatimusmäärittelyn, johon annoin listan erilaisia vaatimuksia ja yksityiskohtia, joita tekoälyn tulisi tavoitella. Pyrin olemaan mahdollisimman tarkka ja huomioimaan sellaisia asioita, joita itse näin tärkeinä kehittämisen kannalta. Speksasin esimerkiksi, että minkälaisia ja asioita haluaisin käyttäjälle näytettävän, miten sovelluksen eri tilat toimivat ja minkälaisen halusin tiedostoformaatin olevan.

Task 1: Basic functionality

Purpose of this task is to create a working application filling basic functional requirements.

The application is a simple web application with a purpose of loading and showing flashcards for learning different things. It will use a custom zip and json based file format for loading the flashcards and stores the cards to browsers storage.

The application supports two configurable modes: set and forever. With 'set' mode the application goes through a one time randomized deck of flashcards and then return back to start. With 'forever' mode the deck is randomized after every card and it keeps on going until user quits.

Requirements and details

  • Use TypeScript, there is already App.ts for the code.
  • Try to use as vanilla JavaScript as possible, try not to import depedencies unless there is no other way
  • index.html should contain a centered, mobile first responsive layout
  • When deck file is first time loaded, it's deck.json file is read to store a name of the deck to localStorage and reference the zip file stored in IndexedDB
  • When game starts and the deck is selected, the file is extracted to memory, it's metadata is read from deck.json and images are preloaded to be used when they're used by the application
  • Card images can be in any format supported by the browser and in any size. Scale them so that they fit to width of the screen.
  • Application never stores anything server side, it's purely client side browser software.

Verrattuna perinteiseen koodaamiseen huomasin, että ajattelin kyllä täsmälleen samoja asioita, mutta ajattelin niitä vain kovemmin etukäteen. Oppimani koodaustapani on ollut sellainen, että kirjoitan ja iteroin koodia ilman suurempia etukäteissuunnitelmia, mutta nyt nämä vaiheet oli suunniteltava ennen varsinaisen koodaustyön aloittamista. Tavallaan tämä tuntui varsin luonnolliselta tavalta toimia ja ainakin äkkiseltään erilaisia vaatimuksia ei ollut vaikea keksiä, kun ne kuitenkin kokemuksen kautta olivat peruskauraa. Suunnitteluun tuskin kului tuntia kauempaa, mutta prosessia olisi voinut jouduttaa tätäkin haipakammaksi käyttäen tekoälyä ideoinnin pallotteluun tai projektin myöhemmässä vaiheessa kopioimalla edellisen taltioidun tehtävän listauksen pohjaksi.

Lisämausteena loin muutaman oman slash-komennon luomalla .claude/commands kansioon tiedostot task.md, task-update.md ja task-document.md. Command-tiedostojen sisällöt ovat käytännössä kehotteita ja argumentteja, jotka pyydettäessä syötetään agentille. Omat komentoni tein tukemaan työnkulkua luomalla pikapolut uuden tehtävän aloittamiselle, tehdyn työn päivittämiselle, jos olen muuttanut tehtävänkuvausta toteutuksen jälkeen sekä työn dokumentoimiseen takaisin vaatimusmäärittelyyn, jos olen sitä iteroinut lennosta kehotteiden kautta.

Ensimmäisen tehtävän suoritus

Käskin Claude Codea lukemaan kirjoittamani vaatimusmäärittelyn ja aloittamaan toteutuksen, jonka jälkeen se loi siitä itselleen erillisen TODO-listan ja lähti toteuttamaan pyydettyä tehtävää. Suunnitelmani mukaisesti se toteutti pyytämäni yksityiskohdat ja vaatimukset pala kerrallaan.

Muutaman kerran suorituksen aikana Claude Code pyysi lupaa eri työkalujen ajamiseen, mutta enimmäkseen se eteni ilman puuttumista suunnittelmansa mukaisesti. Kyselemisen tarvetta pystyisi vähentämään listaamalla etukäteen Claude Coden asetustiedostoon luvituksia erilaisille työkaluille. Hyviä versiohallintakäytänteitä noudattamalla tekoälylle voi antaa luvan moniin työkaluihin, lähinnä poisto-operaatioiden kanssa kannattaa olla tarkkana ja oikeasti varmistaa mitä tiedostoja ollaan hävittämässä.

Suoritus kaikkiensa kesti alle kymmenen minuuttia ja ulkoista työkalua käyttämällä sain selville, että tokeneita oli kulunut noin dollarin edestä, vaikka Pro-lisenssiä käyttämällä tällä ei niin merkitystä ollutkaan. Pro-lisenssiin kuuluu tietty määrä käyttöä kuukaudessa, viikossa ja viiden tunnin sessioissa, mutta ainakaan tämän projektin parissa nämä rajat eivät vielä tulleet vastaan. Pro-lisenssillä ei myöskään ole pääsyä parhaimpaan (ja kalleimpaan) Opus 4-malliin, mutta varsin hyvään lopputulokseen pääsee myös kakkossijan Sonet 4-mallilla.

Katselmointi ja korjaukset

Lopputuloksena tekoäly toimitti täysin toimivan sovelluksen, joka vastasi käytännössä yksi yhteen sitä, mitä olin vaatimusmääritelmään kirjannut. Kun en antanut tarkkoja määrityksiä ulkoasun suhteen, niin tässä tekoäly oli ottanut taiteellisia vapauksia, mutta mielestäni sovellus oli siltäkin osin varsin kelvollinen ja uskoakseni helposti kustomoitavissa tarpeen vaatiessa.

Silmäilin tekoälyn tuotoksen läpi ja mielestäni se oli monilta osin varsin kelvollista koodia, sellaista jota itsekin olisin kirjoittanut, mutta jonka kirjoittamiseen käsin olisi varmasti kulunut paljon enemmän aikaa. En edes yrittänyt sisäistää jokaista tekoälyn tuottamaan riviä, koska en nähnyt sitä projektin luonteen huomioiden tarpeellisena. Jos kyseessä olisi ollut oikeaa tuotantokoodia, olisin varmasti katselmoinut ja sisäistänyt koodia tarkemmin. Tottuneena siihen, että perinteisesti tuotetusta koodista sisäistää jokaisen itse kirjoitetun rivin, herätti tämä jossain määrin levottomuutta, mutta taas toisaalta luottoni tekoälyyn oli korkealla, varsinkin kun lopputulos oli pitkälti sitä mitä pyysinkin.

Kun en määritellyt tarkemmin koodin tyyliä, oli se esimerkiksi nimennyt muuttujia luovasti lyhentäen, mutta tämäkin olisi korjaantunut kirjaamalla tekoälylle tarkemmat tyylisäännöt CLAUDE.md-tiedostoon. Ei ole vaikea kuvitella, että esimerkiksi tiimi- tai yritystasolla tyyli- ja arkkitehtuuriohjeistuksia säilöisi versionhallintaan ja jakaisi eri projektien välillä, jotta pyörää ei tarvitsisi keksiä joka projektissa ja sovelluksessa uudestaan. Tajusin, että tekoäly oli tarttunut vähän turhan hanakasti siihen, että kaikki TypeScript-koodi tulisi kirjoittaa yhteen ja samaan tiedostoon, mutta varmasti tämänkin olisi saanut korjattua ohjeistamalla se pilkkomaan koodia tarpeen mukaan omiin moduuleihin.

Tajusin nopeasti, että joltain osin vaatimusmäärittelyni oli puutteellinen tai liian lavea. Tästä hyvänä esimerkkinä oli, että kun en määritellyt tiedostoformaattiani kovin tarkasti, oli tekoäly jostain syystä olettanut, että sen zip-tiedostot ovat pakkaamattomassa (Store) muodossa. Korjasin tämän muutamalla kehotteella ja dokumentoin takaisin määrittelyään käyttämällä luomaani /task-document-komentoa. Lisäsin samalla tuen myös tar.gz-tiedostoille.

Iteroin toteutusta lennossa antamalla lisää antamalla lyhyempiä kehotteita. Enimmäkseen tekoäly toimitti tässäkin juuri sitä mitä pyysin, mutta muutaman UI-korjauksen osalta se tuntui jäävän välillä jumiin ja korjausta sai pyytämällä pyytää. Koetin ohjata muutoksia oikeaan suuntaan antamalla syötteenä kuvia sekä käymällä itse läpi koodia kipukohtien ympäriltä.

Halutunlaisesti tekoäly dokumentoi muutokset kirjoittamaani vaatimusmäärittelyyn, mutta ilman tarkempia ohjeita se otti tässäkin tyylillisiä vapauksia. Tämän johdosta vaatimusmäärittelystä meinasi tulla eri toteutustapojen sillisalaattia. Hyvänä nyrkkisääntönä tässäkin on, että aina, kun tekoälyä pyytää tuottamaan jotain sisältöä, olisi hyvä olla tarkka sen suhteen miltä lopputuloksen haluaa näyttävän.

Jälkipyykki

Esimerkkini oli varsin yksinkertainen ja suoraviivainen, mutta toisaalta siinä oli lisähaastetta, esimerkiksi määrittelemäni tiedostoformaatin suhteen. Näytettäväksi jää, että miten tarkasti tekoäly onnistuisi haastavimmissa tehtävissä ja oikeassa projekteissa, jotka jo vuosia ovat saaneet rakkautta eri ihmiskehittäjiltä ja joiden ymmärtäminen lähtökohtaisesti vaatii kokeneen kehittäjän koodinlukutaitoa. Pitkälti tässä on kuitenkin kyse siitä, että miten pieniksi atomeiksi tehtäviä pystyy itse suunnittelijana pilkkomaan ja näin ohjeistamaan tekoälyä tekemään oikeita asioita.

Anthropicin Claude-mallit ovat varsin suorituskykyisiä ja niiden työskentelyä on välillä taianomaista seurata. Muutaman satunnaisen kerran jouduin puuttumaan tekoälyn puuhiin, kun se esimerkiksi jäi jumiin yrittäessään ajaa sovellusta taustaprosessina ja jäi ikuisuudeksi imemään sovelluksen tuottamaa logitusta. Nämä ovat esimerkkejä ongelmista, jotka ajan kanssa saattavat korjaantua itsestään mallien ja agenttisoftien parantuessa. Mielessä kävi myös, että esimerkiksi projektin suoritusta voisi ohjata tehokkaammin esimerkiksi luomalla MCP-palvelun, jonka kautta ajettavan sovelluksen käskyttäminen sujuisi tekoälyltä vakaammin.

Tekoälytyökaluille ei ole päässyt tähän mennessä vakiintumaan käytänteitä ja omat kokeellinen työnkulkuni oli vain yksi arvaus siitä, miten työkalujen kanssa kannattaisi menetellä. Mielestäni yksi isoimpia dilemmoja tällä hetkellä on, että kuinka paljon tekoälyä hyödynnetään koodaamisessa. Äkkiseltään vaikuttaisi houkuttelevalta laittaa kaikki peliin ja vaihtaa tekemisen malli kokonaan kehotteiden pyörittelyksi, mutta tähän liittyy joitain ongelmia. Välillä on nopeampaa, että kehittäjä itse tekee käsin jotain muutoksia, mutta toisaalta tämä vaatisi tekoälyn tuottaman, nopeasti muuttuvan koodin, jatkuvaa sisäistämistä. Jonkinlainen hybridimalli tässä tuntuu olevan toistaiseksi paras ratkaisu ja tekoäly tuntuu taipuvan siihen varsin hyvin.

Saamani kokemus Claude Codesta vahvisti näkemystäni siitä, että tekoälytyökalut ovat tulleet jäädäkseen. Aika ja kokemukset oikeiden projektien parissa näyttävät miten niitä lopulta tullaan käyttämään. En näe tätä uutta koodaustapaa uhkana, vaan mahdollisuutena kehittää itseään myös suunnittelijana ja nopeuttaa työskentelyä raa'an koodaamisen parissa, joka väistämättä on kehittämisen työläin osuus. Pidän myös jännittävänä ajatuksena, että tekoälyt saattavat pakottaa kehittäjiä tietyn laadun tavoitteluun, kun vaatimusmäärittelyiden ja testaamisen kanssa saa olla tarkempi. Tekoälyissä on paljon potentiaalia, jota jokaisen kehittäjän on suositeltavaa opetella hyödyntämään. Omasta työkalupakistani tekoälyt saavat tästäkin eteenpäin pysyvän paikan.


Jatkoin kirjoituksen kirjoittamisen jälkeen kokeiluja saman projektin äärellä lisäämällä tekoälylle lisää tehtäviä. Löydät koodit GitHubista ja lopputuloksen täältä. Jos haluat seurata jalanjäljissäni ja kokeilla itse miten toteutus onnistuisi valitsemallasi agentilla, pyyhi tyhjäksi src-kansion sisältö ja pyydä tekoälyä aloittamaan työskentely vaatimusmäärittelyni mukaisesti.