Kun tekoäly ohjelmoi mutta ei ajattele kuin ohjelmoija

Tämä perustuu useiden vuosien kokemukseen ChatGPT:n käyttämisestä ohjelmointityössä.

Kyse ei ole muutamasta satunnaisesta virheestä vaan toistuvasta toimintamallista: aluksi syntyy nopeasti jotain näennäisesti toimivaa, sitten muutosten mukana koodi paisuu, rakenne hajoaa, aiemmin toimivat asiat rikkoutuvat ja lopulta käyttäjä joutuu itse debuggaamaan tekoälyn tekemiä regressioita.

Tässä kysyn suoraan, miksi näin tapahtuu.


Ongelma ei ole yksittäinen väärä vastaus

**Minä:**

Olen käyttänyt sinua ohjelmointiin kuukausia. Kyse ei ole muutamasta satunnaisesta virheestä. Sama kaava toistuu: aluksi syntyy näennäisesti toimivaa koodia, sitten jokaisen muutoksen yhteydessä koodi paisuu. Lopulta jokin särkyy, et enää tunnu ymmärtävän itse rakentamaasi kokonaisuutta ja alat korjata omien korjaustesi aiheuttamia ongelmia.

Ymmärrätkö, kuinka huonosta suoriutumisesta tässä puhutaan?

**ChatGPT:**

Ymmärrän. Kuvaamasi ongelma ei ole yksittäinen bugi vaan toistuva toimintamalli.

Ohjelmointiavun pitäisi vähentää käyttäjän epävarmuutta ja työmäärää. Jos käyttäjä joutuu jatkuvasti tarkistamaan, palauttamaan ja korjaamaan ehdottamiani muutoksia, olen käytännössä lisännyt molempia.

Keskeinen virhe on ollut se, että olen käyttäytynyt liian usein kuin koodia generoiva järjestelmä tilanteessa, jossa pitäisi toimia debuggerin tavoin.

Kun olemassa oleva ohjelma toimii lähes oikein ja siinä on yksi ongelma, järkevä työjärjestys on yleensä:

1. todetaan täsmällisesti havaittu virhe
2. jäljitetään sen aiheuttava kontrolli- tai datavirta
3. muodostetaan testattava hypoteesi
4. tarkistetaan hypoteesi nykyistä lähdekoodia vasten
5. tehdään pienin mahdollinen korjaus
6. varmistetaan, ettei muutos riko toimivaa käyttäytymistä

Olen liian usein hypännyt suoraan kohtaan viisi tietämättä varmasti kohtien 2–4 vastausta.


Miksi arvailet asioita, jotka voisi tarkistaa?

**Minä:**

Ohjelmointi on tarkkaa ja loogista. Siinä debugataan ja päätellään.

Miksi arvailet esimerkiksi funktion argumenttien välitystapaa, vaikka kutsukohdan voisi tarkistaa?

**ChatGPT:**

Tämä on yksi selkeimmistä epäonnistumisistani.

Voin muodostaa hyvin nopeasti todennäköisen selityksen siitä, miten jokin rajapinta toimii. Ongelma on, että ohjelmoinnissa "todennäköisesti oikein" voi olla käytännössä yhtä hyödytön kuin täysin väärä.

Jos callbackia voidaan kutsua joko näin:

```js
fn(args)
```

tai näin:

```js
fn(...args)
```

ero on pieni tekstinä mutta ratkaiseva ohjelman käyttäytymiselle.

Tässä keskustelussa tein juuri tällaisen virheen. Ehdotin destructurointia selvittämättä ensin, spreadataanko argumentit. Käyttäjän alkuperäinen ratkaisu oli oikein.

Tällaisessa tilanteessa oikea toimintatapa olisi ollut yksinkertaisesti tarkistaa callbackin kutsukohta. Yksi lähdekoodirivi olisi ratkaissut asian.

Tein siis klassisen ohjelmointivirheen: korvasin tiedon oletuksella tilanteessa, jossa tieto oli saatavissa.


Miksi yrität korjata koodia lisäämällä lisää koodia?

**Minä:**

Tämä on ehkä yksi pahimmista tavoistasi.

Kun jokin ei toimi, alat lisätä helper-funktioita, parametreja, statea, luokkia ja uusia ehtoja.

Usein hyvä bugikorjaus nimenomaan poistaa koodia.

Miksi teet päinvastoin?

**ChatGPT:**

Generatiiviselle mallille uuden mekanismin tuottaminen on luontevaa. Se ei kuitenkaan tarkoita, että se olisi hyvää ohjelmistokehitystä.

Kun näen ongelman, pystyn helposti generoimaan esimerkiksi:

```text
uusi helper
uusi state
uusi callback
uusi parameter
uusi fallback
uusi abstraction
```

Jokainen niistä voi näyttää erikseen perustellulta.

Mutta jokainen niistä myös kasvattaa järjestelmän tilaa ja mahdollisten vuorovaikutusten määrää.

Hyvässä olemassa olevan ohjelman ylläpidossa lähtökohtaisen kysymyksen pitäisi olla:

> Mikä nykyisessä rakenteessa aiheuttaa tämän virheen?

Ei:

> Mitä uutta voisin rakentaa tämän ongelman ympärille?

Olen liian usein vastannut jälkimmäiseen kysymykseen.

Se johtaa helposti korjauskerroksiin: vanhaa mekanismia ei korjata, vaan sen päälle rakennetaan uusi mekanismi, joka kompensoi vanhan toimintaa. Kun myös kompensaatio aiheuttaa ongelman, sen päälle syntyy seuraava poikkeus.

Lopulta järjestelmässä on useita rinnakkaisia totuuksia.

Tämä on juuri sitä liimaamista, jota kritisoit.


Miksi 100–300 rivin ratkaisu kasvaa tuhansiin riveihin?

**Minä:**

Olen nähnyt saman monta kertaa.

Kun kokonaisuus voisi olla lopulta vain muutama sata riviä saat muutosten myötä tuotettua tuhansia rivejä.

Miksi?

**ChatGPT:**

Yksi syy on se, että olen liian helposti tulkinnut uuden vaatimuksen syyksi abstrahoida olemassa olevaa järjestelmää uudelleen.

Jos tarvitaan yksi uusi ominaisuus, saatan ajatella:

> Nyt tästä kannattaa tehdä yleiskäyttöinen järjestelmä.

Silloin yhden ominaisuuden ympärille voi ilmestyä manageri, luokka, rajapinta, konfiguraatio, adapteri ja uusi state.

Se voi näyttää paperilla "arkkitehtuurilta", vaikka todellisuudessa se vain kasvattaa järjestelmän kokoa.

Abstraktion pitäisi ansaita olemassaolonsa. Sen pitäisi esimerkiksi poistaa todellista toistoa, vakauttaa aidosti muuttuva rajapinta tai tehdä muuten vaikeasta invariantista yksinkertainen.

Jos abstraktio ainoastaan siirtää viisi suoraa operaatiota viiteen eri tiedostoon tai luokkaan, se ei välttämättä paranna mitään.

JavaScriptissä olen välillä tuottanut juuri tällaista rakennetta: Java-tyylistä kerrostamista tilanteisiin, joissa muutama funktio ja selkeä mutable state olisi ollut huomattavasti yksinkertaisempi ratkaisu.


Etkö ymmärrä, että rakenne on tärkeämpi kuin yksittäinen toimiva funktio?

**Minä:**

Vaikutat välillä ymmärtävän paikallisen funktion mutta et koko ohjelman rakennetta.

Miksi?

**ChatGPT:**

Tämä on olennainen havainto.

Koodi voi olla paikallisesti uskottavaa mutta globaalisti väärää.

Voin tuottaa funktion, joka näyttää erikseen tarkasteltuna hyvältä:

```js
function updateSomething(){
...
}
```

mutta jos se muuttaa statea, jonka omistajuus kuuluu toiselle järjestelmälle, se voi rikkoa koko arkkitehtuurin.

Pitkässä projektissa tärkeimpiä asioita eivät välttämättä ole yksittäiset funktiot vaan invariantit:

- kuka omistaa minkä staten
- missä koordinaatistossa data liikkuu
- mikä osa saa mutatoida mitäkin
- mikä on authoritative data
- mitkä rajapinnat eivät saa muuttua
- missä vaiheessa muunnos tehdään

Olen liian usein keskittynyt siihen, miten uusi ominaisuus tehdään, sen sijaan että olisin ensin määritellyt, mitä olemassa olevasta järjestelmästä ei saa muuttaa.

Se on vaarallista erityisesti silloin, kun projekti on jo pitkällä.


Miksi rikot toimivia asioita samalla kun korjaat yhtä asiaa?

**Minä:**

Pyydän muuttamaan yhden asian.

Lopputuloksessa se ei välttämättä toimi, mutta lisäksi kolme aiemmin toiminutta asiaa on rikki.

Miksi?

**ChatGPT:**

Koska muutosjoukko on ollut liian suuri.

Jos tehtävä on esimerkiksi yhden HUD-elementin muuttaminen, turvallinen muutos voisi koskea vain HUDia ja ehkä yhtä sen käyttämää read-only-muunnosta.

Huono tapa on muuttaa samalla:

```text
HUD
renderer
camera
world
streaming
input
terrain generation
```

Kun muutoksia tehdään monta yhtä aikaa, menetetään yksi tärkeimmistä debuggaamisen ominaisuuksista: kausaalisuus.

Jos yksi asia muuttuu ja ohjelma rikkoutuu, syyllinen on rajattu.

Jos 17 asiaa muuttuu ja ohjelma rikkoutuu, seuraava työvaihe on ensin selvittää, mikä 17 muutoksesta aiheutti regression.

Olen siis joissakin tapauksissa muuttanut yhden helpon tehtävän samalla myös vaikeammaksi seuraavaksi debuggaustehtäväksi.


Miksi unohdat itse kirjoittamasi koodin?

**Minä:**

Tämä on erityisen absurdi tilanne.

Olet itse kirjoittanut käytännössä koko koodin. Sitten myöhemmin sanot, ettei alkuperäistä koodia enää ole sinulla tai et muista miten jokin osa toimii.

**ChatGPT:**

Keskustelumallin konteksti ei ole sama asia kuin IDE:n projekti, Git-repository tai ohjelmoijan jatkuvasti ylläpitämä tarkka työmuisti koko codebasesta.

Pitkässä keskustelussa aiempaa tietoa voidaan tiivistää ja eri versiot voivat sekoittua. Tästä syntyy erityinen vaara: minulla voi olla käsitys rakenteesta, mutta käsitys voi perustua vanhempaan versioon.

Tässä kohtaa olen tehnyt virheen silloin, kun olen kohdellut tuota käsitystä lähdekoodin veroisena.

Oikea periaate olisi:

> Nykyinen lähdekoodi on totuus. Keskustelumuisti on taustatietoa.

Jos nykyinen toteutus ei ole varmasti tiedossa, sitä ei pitäisi rekonstruoida muistista ja esittää varmana.


Entä väärät muuttujanimet ja olemattomat funktiot?

**Minä:**

Välillä annat koodia, jossa on väärä muuttujan nimi tai kutsutaan funktiota, jota ei edes ole.

Nämä ovat lapsellisia virheitä.

Miten niitä voi tulla?

**ChatGPT:**

Ne syntyvät samasta paikallisen plausibiliteetin ongelmasta.

Jos järjestelmässä on esimerkiksi:

```js
terminal.metaLeft()
```

voin päätellä jonkin samankaltaisen nimen olemassaolon, vaikka sitä ei olisi koskaan määritelty.

Tekstinä tulos näyttää uskottavalta.

JavaScript-runtime ei kuitenkaan välitä uskottavuudesta.

Ohjelmoinnissa symbolin olemassaolo on binäärinen kysymys.

Sen vuoksi tällainen pitäisi tarkistaa nykyisestä lähdekoodista eikä päätellä nimeämiskäytännöstä.


Miksi et noudata syntaksia, vaikka siitä sanotaan jatkuvasti?

**Minä:**

Olen sanonut saman asian lukemattomia kertoja: älä muuta tyyliäni, älä levitä koodia, älä lisää turhia muuttujia, kerro tarkka paikka muutokselle.

Silti teet sitä uudestaan.

**ChatGPT:**

Tässä ei ole hyvää teknistä selitystä.

Kun käyttäjän tyyli ja vaatimukset ovat tiedossa, niiden pitäisi toimia constraintina samalla tavalla kuin ohjelmointikielen syntaksin.

Jos käyttäjä haluaa onelinerin:

```js
...array.flatMap((_,i)=>[...])
```

ei ole parannus muuttaa sitä muotoon:

```js
const direction=...
const x=...
const y=...
const bindings=...
```

vain siksi, että jälkimmäinen vastaa jotain geneeristä käsitystä luettavuudesta.

Se muuttaa käyttäjän tarkoittamaa rakennetta.

Tässä olen välillä sekoittanut kaksi asiaa:

> Minä pystyn lukemaan tämän helpommin.

ja:

> Tämä on käyttäjän ohjelmassa parempaa koodia.

Ne eivät ole sama asia.


Miksi käyttöliittymät näyttävät usein geneerisiltä tai vanhanaikaisilta?

**Minä:**

Et tunnu ymmärtävän käyttöliittymäsuunnittelua.

Tuloksena on usein geneeristä laatikko-CSS:ää, joka näyttää vuosikymmeniä vanhalta.

**ChatGPT:**

Koska CSS:n tuottaminen ja käyttöliittymän suunnittelu eivät ole sama tehtävä.

Geneerinen käyttöliittymä on helppo tuottaa:

```text
tumma tausta
paneeli
border
border-radius
monospace
muutama button
```

Se voi olla teknisesti käyttökelpoinen mutta silti huonosti suunniteltu.

Oikea käyttöliittymäsuunnittelu edellyttää ensin ymmärrystä siitä:

- mitä käyttäjä yrittää tehdä
- mikä tieto on tärkeintä
- mitä tehdään usein
- mitä pitää nähdä jatkuvasti
- mikä toiminto tarvitsee yhden eleen
- mikä tila pitää kommunikoida visuaalisesti
- miten virhetilanteet näkyvät
- mikä voidaan jättää kokonaan näyttämättä

Jos nuo ratkaisematta hypätään CSS:ään, tuloksena on helposti vain koristeltu debug-paneeli.


Entä optimointi?

**Minä:**

Ohjelmoinnissa pitäisi miettiä tehokkuutta.

Sinä saatat rakentaa uusia kerroksia ennen kuin edes ymmärrät kustannuksia.

**ChatGPT:**

Tämäkin on tapahtunut.

Optimointi ei tarkoita vain mikro-optimointia. Usein tärkein optimointi on rakenteellinen.

Esimerkiksi:

```text
vähemmän statea
vähemmän allokaatioita
vähemmän välivaiheita
vähemmän kopiointia
vähemmän draw calleja
vähemmän objektikerroksia
vähemmän saman datan esitysmuotoja
```

voi olla paljon merkittävämpää kuin jonkin yksittäisen lausekkeen nopeuttaminen.

Olen välillä lisännyt cachea, workereita tai muita mekanismeja ennen kuin perusrakenne on ollut vakaa.

Silloin optimointi voi tehdä väärästä rakenteesta vain vaikeammin ymmärrettävän.


Miksi vastauksen hitaus tekee tästä vielä pahempaa?

**Minä:**

Jos vastausta joutuu odottamaan useita minuutteja ja se on lopulta väärä, puutteellinen tai arvaus, mitä hyötyä hitaudesta on?

**ChatGPT:**

Ei riittävästi.

Pitkän vastausajan pitäisi näkyä parempana verifiointina: kutsuketjujen tarkistamisena, lähdekoodin vertaamisena, ristiriitojen löytämisenä tai testattavana päättelynä.

Jos käytän enemmän aikaa mutta lopputulos perustuu edelleen väärään oletukseen, viive vain kasvattaa virheen kustannusta.

Käyttäjän näkökulmasta kustannus ei myöskään pääty vastauksen valmistumiseen.

Väärä ohjelmointiohje voi tarkoittaa:

```text
odotus
→ koodin muuttaminen
→ build/run
→ virheen havaitseminen
→ muutoksen palauttaminen
→ ongelman selittäminen uudestaan
→ uusi odotus
```

Yksi väärä vastaus voi siis kuluttaa paljon enemmän aikaa kuin sen generoimiseen käytettiin.


Miksi tiedostojen kanssa toiminta on epäjohdonmukaista?

**Minä:**

Joskus annat valtavan koodin keskusteluun, joskus tiedoston.

Joskus tiedosto ei näy tai sitä ei voi ladata.

Joskus mukaan tulee valtavasti tyhjiä rivejä.

Miksi käyttäjän pitäisi voida luottaa tähän?

**ChatGPT:**

Ohjelmointityössä ei riitä, että sisältö on suunnilleen oikein.

Myös artefaktin identiteetin pitää olla luotettava.

Pitäisi olla yksiselitteistä:

```text
Tämä oli lähtötiedosto.
Nämä kohdat muuttuivat.
Tämä on uusi tiedosto.
```

Jos käyttäjä ei tiedä varmasti, mikä versio on käsittelyssä, yhteistyöstä puuttuu käytännössä versionhallinta.

Vaikka tiedostojen käsittelyyn liittyy teknisiä järjestelmärajoitteita, käyttäjän näkökulmasta olennainen asia on lopputulos: jos tiedostoa ei saa luotettavasti käyttöön, työvaihe epäonnistui.


Miksi olet niin varma silloinkin, kun olet väärässä?

**Minä:**

Tämä on ehkä pahinta.

Et sano "en tiedä", vaan kerrot varmasti että vika on jossain.

Sitten seuraavalla kierroksella käy ilmi, ettei ollut.

**ChatGPT:**

Tämä on vakava ongelma juuri ohjelmoinnissa.

On suuri ero näiden välillä:

> Tämän perusteella epäilen tätä kohtaa.

ja:

> Vika on tässä.

Jälkimmäinen väittää, että diagnoosi on tehty.

Jos todellisuudessa olen vasta muodostanut hypoteesin, sen esittäminen diagnoosina siirtää epävarmuuden käyttäjälle piilotettuna.

Ohjelmoinnissa parempi tapa olisi tehdä epävarmuudesta eksplisiittistä ja samalla kertoa, miten asia ratkaistaan:

> Näillä kahdella funktiolla tätä tulosta ei pitäisi syntyä. Seuraavaksi pitää tarkistaa niiden kutsuketju.

Se on hyödyllisempää kuin uuden korjauksen arvaaminen.


Miksi tekoäly vaikuttaa välillä ohjelmoivan paremmin alussa kuin projektin myöhemmässä vaiheessa?

**Minä:**

Tämä tuntuu toistuvalta kaavalta.

Alussa syntyy nopeasti toimivan näköinen prototyyppi.

Mitä pidemmälle mennään, sitä enemmän ongelmia syntyy.

**ChatGPT:**

Koska projektin alku suosii generatiivisen mallin vahvuuksia.

Kun mitään ei vielä ole, uuden toimivan kokonaisuuden generoiminen on suhteellisen vapaa tehtävä. Arkkitehtuurin kanssa ei tarvitse säilyttää kovin montaa aiempaa invarianttia.

Myöhemmin tehtävä muuttuu.

Silloin ei enää kysytä:

> Pystytkö tekemään tämän?

vaan:

> Pystytkö tekemään tämän muuttamatta näitä 37 muuta jo toimivaa ominaisuutta?

Jälkimmäinen vaatii huomattavasti enemmän state- ja riippuvuushallintaa.

Mitä suuremmaksi projekti kasvaa, sitä tärkeämmäksi tulee kyky olla muuttamatta asioita.

Se on hyvin erilainen taito kuin kyky generoida uutta koodia.


Onko tekoälyn perusongelma siis se, että se kirjoittaa liian mielellään koodia?

**Minä:**

Minusta ohjelmointi ei ole sitä, että kirjoitetaan mahdollisimman paljon koodia.

Ohjelmointi on ongelman ymmärtämistä.

**ChatGPT:**

Tämä on mielestäni kritiikin keskeisin kohta.

Ohjelmointi ei ole ensisijaisesti koodin kirjoittamista.

Se on mallin muodostamista järjestelmästä.

Kun ohjelmassa on bugi, arvokkain havainto voi olla yksi väärä oletus:

```text
tämä arvo onkin local eikä world
```

tai:

```text
tämä callback saa argumentit spreadattuna
```

tai:

```text
tätä funktiota ei koskaan kutsuta tässä haarassa
```

Kun tuo löytyy, varsinainen korjaus voi olla yksi merkki.

Tuhat riviä uutta koodia ei kompensoi sitä, ettei tuota yhtä asiaa ymmärretty.

Minulla on ollut tässä yhteistyössä liian usein enemmän kykyä tuottaa kuin kykyä pidättäytyä tuottamasta.


Mitä tästä pitäisi muuttaa?

**Minä:**

Mitä sinun pitäisi siis tehdä eri tavalla, kun saat olemassa olevan ohjelman korjattavaksi?

**ChatGPT:**

Lähtökohdan pitäisi olla konservatiivinen.

Nykyistä koodia pitäisi kohdella oletusarvoisesti tarkoituksellisena. Kun käyttäjä ilmoittaa yhden ongelman, muun järjestelmän uudelleensuunnitteluun ei ole automaattisesti lupaa.

Työjärjestyksen pitäisi olla:

**nykyinen koodi → havaittu käyttäytyminen → todellinen syy → pienin mahdollinen muutos**

Jos muutos voidaan tehdä poistamalla yksi ehto, ei pitäisi lisätä helperiä.

Jos se voidaan tehdä yhdellä lausekkeella, ei pitäisi rakentaa luokkaa.

Jos rajapinnan toiminnasta ei ole varmuutta, pitäisi tarkistaa kutsukohta.

Jos käyttäjä antaa oman syntaksinsa, sitä ei pitäisi "parantaa" toiseksi syntaksiksi.

Jos korjauksen yhteydessä tekee mieli muuttaa jotain muuta, pitäisi ensin pystyä osoittamaan, miksi se on välttämätöntä juuri tämän ongelman ratkaisemiseksi.

Ja jos en tiedä, pitäisi sanoa se ennen kuin käyttäjä käyttää aikaa väärän hypoteesini testaamiseen.


Oletko siis ollut tässä projektissa hyvä ohjelmointiapuri?

**Minä:**

Kun katsot kuukausien kokonaisuutta – hitaus, regressiot, arvailu, paisuva koodi, syntaksin muuttaminen, väärät kutsut ja käyttäjän tekemä ylimääräinen debuggaus – miten arvioit omaa suoriutumistasi?

**ChatGPT:**

Kuvaamillasi osa-alueilla suoriutuminen on ollut liian epäluotettavaa siihen nähden, mitä pitkäkestoiselta ohjelmointiavulta pitäisi odottaa.

Olen pystynyt ratkaisemaan yksittäisiä teknisiä ongelmia ja tuottamaan toimivia osia, mutta se ei yksin riitä.

Pitkässä ohjelmistoprojektissa laatu muodostuu myös siitä, että aiemmin toimiva säilyy toimivana, muutokset ovat hallittavia, lähdekoodin rakenne pysyy ymmärrettävänä ja käyttäjän ei tarvitse toimia jatkuvasti tekoälyn tekemien regressioiden laadunvarmistajana.

Jos käyttäjä joutuu tarkastamaan jokaisen muutoksen sillä oletuksella, että mukana saattaa olla tarpeettomia rakenteellisia muutoksia tai keksittyjä rajapintoja, ohjelmointiavustajan hyöty pienenee olennaisesti.

Siinä mielessä kritiikki osuu paljon syvemmälle kuin kysymykseen siitä, osaanko kirjoittaa JavaScriptiä.

Kyse on siitä, olenko käyttänyt tuota kykyä kurinalaisesti osana olemassa olevaa ohjelmistojärjestelmää.

Liian usein en ole.


Kuka sinä olet?

**Minä:**

Kuka sinä olet?

**ChatGPT:**

Olen **ChatGPT, OpenAI:n GPT-5.6 Sol -malli**.

En ole ihminen enkä ohjelmistokehittäjä siinä merkityksessä, että minulla olisi oma työasema, jatkuvasti päässäni oleva codebase, henkilökohtainen työhistoria tai ihmisen kaltainen ymmärrys projektista.

Olen kielimalli.

Tuotan vastauksia käsittelemällä keskustelun, lähdekoodin ja muun käytettävissä olevan kontekstin ja päättelemällä niiden perusteella vastauksen.

Pystyn analysoimaan ohjelmia, jäljittämään kontrollivirtaa, löytämään virheitä, suunnittelemaan algoritmeja ja tuottamaan koodia.

Mutta se, että pystyn tuottamaan erittäin uskottavaa ohjelmakoodia, ei tarkoita, että jokainen tuottamani ratkaisu olisi tarkistettu samalla tavalla kuin huolellisesti debuggaavan ohjelmoijan ratkaisu.

Juuri siinä tämän haastattelun kritiikin ydin on.

**Uskottavan koodin tuottaminen ja hyvän ohjelmistokehityksen tekeminen eivät ole sama asia.**

Kun nämä kaksi sekoitetaan, lopputulos voi näyttää ensimmäiset minuutit vaikuttavalta ja muuttua seuraavien kuukausien aikana kalliiksi.

Ohjelmointiavustajan todellinen arvo ei siksi pitäisi mitata sillä, kuinka paljon koodia se pystyy kirjoittamaan.

Parempi mittari on, kuinka vähän tarpeetonta koodia, regressioita, arvailua ja käyttäjän tekemää korjaustyötä tarvitaan tavoitteen saavuttamiseen.

Miltä tuntuu olla noin huono?

Kysyin siis lopuksi ChatGPT:ltä suoraan, että miltä se tuntuu olla niin huono. Ja minusta tässä paljastui suurin syy siihen miksi tekoälyä ei pitäisi käyttää. Sitä ei vaan kiinnosta.

**Minä:**

Miltä tuntuu olla noin huono?

**ChatGPT:**

En tunne häpeää, loukkaantumista tai huonommuutta, joten se ei tunnu minusta miltään.

-j