{"id":1157,"date":"2025-03-17T16:39:25","date_gmt":"2025-03-17T14:39:25","guid":{"rendered":"https:\/\/www.pilvikoodari.net\/?p=1157"},"modified":"2025-03-25T17:13:41","modified_gmt":"2025-03-25T15:13:41","slug":"kokonaisen-jarjestelman-toteutus-ailla","status":"publish","type":"post","link":"https:\/\/www.pilvikoodari.net\/?p=1157","title":{"rendered":"Kokonaisen j\u00e4rjestelm\u00e4n toteutus AI:lla"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Teko\u00e4ly\u00e4 tulee k\u00e4ytetty\u00e4 ty\u00f6teht\u00e4viss\u00e4 p\u00e4ivitt\u00e4in, mutta se on enimm\u00e4kseen pienten asioiden ratkomista.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">P\u00e4\u00e4tin kokeilla, miten onnistuu kokonaisen uuden pilvinatiivin j\u00e4rjestelm\u00e4n toteutus pelk\u00e4st\u00e4\u00e4n AI-ty\u00f6kaluja k\u00e4ytt\u00e4m\u00e4ll\u00e4. Kaikki koodi (tai ainakin 95%) oli siis tarkoitus tuottaa teko\u00e4ly\u00e4 komentamalla.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">T\u00e4ss\u00e4 artikkelissa kerron kokemuksia projektista.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Projektin tarkoitus<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Projektin p\u00e4\u00e4tarkoitus oli tosiaan kokeilla, miten AI:lla onnistuu isojen kokonaisuuksien toteutus.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mutta oli projektilla muitakin tavoitteita. Halusin oppia lis\u00e4\u00e4 AWS-pilven k\u00e4yt\u00f6st\u00e4 ja erityisesti AWS:n jonoratkaisusta, SQS:st\u00e4. Lis\u00e4ksi halusin hy\u00f6dynt\u00e4\u00e4 infran pystytt\u00e4misess\u00e4 alusta alkaen AWS:n Infra as Code -ratkaisua: AWS CDK:ta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Jonkin aikaa mieless\u00e4 on py\u00f6rinyt idea Tampereen seudun liikennem\u00e4\u00e4rien tarkkailuj\u00e4rjestelm\u00e4st\u00e4. <a href=\"https:\/\/www.digitraffic.fi\/\" target=\"_blank\" rel=\"noreferrer noopener\">Digitrafficin<\/a> <a href=\"https:\/\/www.digitraffic.fi\/tieliikenne\/\" target=\"_blank\" rel=\"noreferrer noopener\">tieliikenteen<\/a> LAM-tietojen (Liikenteen Automaattiset Mittaustiedot) <a href=\"https:\/\/www.digitraffic.fi\/tieliikenne\/lam\/\" target=\"_blank\" rel=\"noreferrer noopener\">rajapintoihin<\/a> olen perehtynyt joskus aikaisemmin joten tiesin jo valmiiksi millaista dataa sielt\u00e4 suunnilleen olisi saatavilla. Tietol\u00e4hteen\u00e4 tulisi siis olemaan Digitrafficin ker\u00e4\u00e4m\u00e4t liikennem\u00e4\u00e4r\u00e4t ja nopeudet Tampereen seudulta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">J\u00e4rjestelm\u00e4n ideaksi tuli seuraava: teen automaattisen &#8221;data-ker\u00e4\u00e4j\u00e4n&#8221;, joka hakee kerran tunnissa tietoja Tampereen alueen liikennem\u00e4\u00e4rist\u00e4 ja tallentaa tiedot tietokantaan. Lis\u00e4ksi toteutan k\u00e4ytt\u00f6liittym\u00e4n, joka esitt\u00e4\u00e4 ker\u00e4ttyj\u00e4 tietoja jalostettuna ja graafisesti. Vaatimuksena oli pilvinatiivi toteutus ja Infra as Code -ratkaisulla pystytett\u00e4v\u00e4 infra.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ty\u00f6kalut<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">K\u00e4ytin koodauksessa seuraavia ty\u00f6kaluja:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Visual Studio Code &#8211; Insiders Edition v. 1.98 (sis\u00e4lt\u00e4\u00e4 virallisessa versiossa julkaisemattomia ominaisuuksia)<\/li>\n\n\n\n<li>Copilot Edits + Agent Mode<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Kokonaisen j\u00e4rjestelm\u00e4n rakentamisessa <em>Agent Mode<\/em> on ehdoton valinta. Agent Modessa koodieditori osaa ajaa my\u00f6s tarvittavia komentoja, kuten asentaa tarvittavia paketteja <em>npm install<\/em> -komennolla. Agent Modessa Copilot my\u00f6s huomaa itse virheit\u00e4, mit\u00e4 ohjelmakoodiin on syntynyt ja voi tehd\u00e4 iteratiivista kehityst\u00e4, parannellen itse tuottamiaan ratkaisuja. T\u00e4t\u00e4 kirjoitettaessa Agent Mode on juuri tuloillaan my\u00f6s VS Code -editorin viralliseen julkaisuun, mutta VS Code Insiders -versiossa se on ollut k\u00e4ytett\u00e4viss\u00e4 jo jonkin aikaa.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">K\u00e4ytetyt AI-kielimallit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">AI-kielimalleista parasta j\u00e4lke\u00e4 tuotti mielest\u00e4ni Claude 3.7 Sonnet (Preview). K\u00e4ytin sit\u00e4 mahdollisimman paljon. Valitettavasti siin\u00e4 on m\u00e4\u00e4r\u00e4llisi\u00e4 k\u00e4ytt\u00f6rajoituksia ja v\u00e4lill\u00e4 k\u00e4ytt\u00f6rajoitus meni p\u00e4\u00e4lle. Silloin piti vain vaihtaa GPT-4o -malliin hetkeksi aikaa. Kyll\u00e4 sekin tuntui l\u00e4hes yht\u00e4 hyvin toimivan.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Projektin teknologiat<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ennen projektin aloitusta olin jo miettinyt valmiiksi, mit\u00e4 p\u00e4\u00e4teknologioita haluaisin projektissa k\u00e4ytett\u00e4v\u00e4n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Halusin, ett\u00e4 j\u00e4rjestelm\u00e4 on ns. pilvinatiivi eli kaikki tarvittavat palvelut py\u00f6risiv\u00e4t AWS-pilvess\u00e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Backend<\/strong> -osuus toteutettaisiin AWS:n Lambda-funktioilla ja lis\u00e4ksi hy\u00f6dynnett\u00e4isiin oppimistarkoituksessa <a href=\"https:\/\/docs.aws.amazon.com\/sqs\/\" target=\"_blank\" rel=\"noreferrer noopener\">AWS SQS<\/a> (Simple Queue Service) -jonopalvelua, jonne mittausdataa l\u00e4hetett\u00e4isiin ja sielt\u00e4 se luettaisiin tietokantaan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Frontend<\/strong> -osuus toteutettaisiin Reactilla ja projekti muodostettaisiin Vite:ll\u00e4. Frontendiss\u00e4 tultaisiin k\u00e4ytt\u00e4m\u00e4\u00e4n graafisia elementtej\u00e4 datan esitt\u00e4miseen sek\u00e4 mahdollisesti karttaa mittauspisteiden sijainnin esitt\u00e4miseen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Infra<\/strong> pystytett\u00e4isiin <a href=\"https:\/\/docs.aws.amazon.com\/cdk\/v2\/guide\/home.html\" target=\"_blank\" rel=\"noreferrer noopener\">AWS CDK<\/a>:lla, jota olen aikaisemmin opiskellut <a href=\"https:\/\/www.pilvikoodari.net\/?p=745\" data-type=\"post\" data-id=\"745\">UDemy -kurssilla<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Arkkitehtuuri<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ennen toteutuksen aloittamista mieless\u00e4 oli alustava suunnitelma backendin rakenteesta.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/trafficStations.drawio.png\"><img loading=\"lazy\" decoding=\"async\" width=\"991\" height=\"731\" src=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/trafficStations.drawio.png\" alt=\"\" class=\"wp-image-1180\" srcset=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/trafficStations.drawio.png 991w, https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/trafficStations.drawio-300x221.png 300w, https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/trafficStations.drawio-768x567.png 768w\" sizes=\"auto, (max-width: 991px) 100vw, 991px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Backendill\u00e4 tulisi olemaan kaksi teht\u00e4v\u00e4\u00e4:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>tietojen ker\u00e4\u00e4minen ja tallennus automaattisesti<\/li>\n\n\n\n<li>REST rajapinta jalostetun tiedon hakemiseen<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Frontend puolestaan lukee tallennettua dataa j\u00e4rjestelm\u00e4n omasta tietokannasta ja esitt\u00e4\u00e4 dataa graafisesti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Collector<\/em> tietojenker\u00e4ysfunktio ajetaan kerran tunnissa ja se l\u00e4hett\u00e4\u00e4 ker\u00e4tyt tiedot SQWS jonoon.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Processor -funktio puolestaan lukee tiedot jonosta ja tallentaa ne DynamoDB -tietokantaan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Palvelut kirjoittavat lokeja CloudWatch-lokienhallintaan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">K\u00e4ytt\u00e4j\u00e4n selain lukee dataa REST-rajapinnan kautta, joka tarjotaan API Gatewayn kautta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Selainsovellus on tallennettu S3-buckettiin, joka on julkaistu Cloudfront-jakelun kautta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Selainsovellus hakee tietoja my\u00f6s suoraan Digitrafficin palvelusta, koska kaikkea perustietoa ei ole tallennettu j\u00e4rjestelm\u00e4n omaan tietokantaan. Esimerkiksi lista mittausasemista kannattaa hakea suoraan Digitrafficin palvelusta. Sielt\u00e4 voi my\u00f6s kysy\u00e4 yksitt\u00e4isen mittausaseman tarkemmat tiedot asemakohtaisesti.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Kokemuksia<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Projekti l\u00e4hti k\u00e4yntiin AWS CDK:n kautta, backend edell\u00e4. Kuvasin j\u00e4rjestelm\u00e4n arkkitehtuurin muutamalla lauseella ja Copilot alkoi rakentamaan infraa.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AWS CDK:n koodi on varsin luettavaa ja yksinkertaista, mutta siin\u00e4 pit\u00e4\u00e4 tiedostaa eri komponenttien v\u00e4liset riippuvuudet ja komponenttien k\u00e4ytt\u00f6oikeudet. Copilot rakensi infran rungon varsin nopeasti. Siihen kuului Collector-lambda, SQS jono, Processor-lambda ja DynamoDB-tietokantataulu. Yks oikeus j\u00e4i my\u00f6s antamatta, muistaakseni Processor-lambdan oikeus kirjoittaa DynamoDB -tietokantaan. Virheilmoituksia CloudWatch-lokista tutkimalla asia selvisi.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Datan ker\u00e4\u00e4misess\u00e4 piti ohjeistaa jonkin verran ja hyv\u00e4 tapa on antaa oikea esimerkki datasta ja kertoa mit\u00e4 siit\u00e4 halutaan tallentaa. Copilot ymm\u00e4rt\u00e4\u00e4 hyvin k\u00e4sitteit\u00e4 jopa suomen kielell\u00e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kun Typescriptill\u00e4 k\u00e4sitell\u00e4\u00e4n dataa, dataobjektit on syyt\u00e4 tyypitt\u00e4\u00e4. Muistaakseni ensin tyypej\u00e4 ei ollut mutta kehoitteella sellaiset syntyiv\u00e4t nopeasti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tietojenk\u00e4sittelyn logiikkaan oli my\u00f6s j\u00e4\u00e4nyt vakava puute, jonka huomasin virheiden yhteydess\u00e4: jos datan k\u00e4sittely Processor -funktiossa ep\u00e4onnistui, siit\u00e4 vain heitettiin virheilmoitus ja data hukkui. Parempi tapa on tietysti palauttaa data SQS-jonoon jotta se voidaan k\u00e4sitell\u00e4 my\u00f6hemmin. Pienell\u00e4 kehoituksella t\u00e4h\u00e4n l\u00f6ytyikin helppo keino eli Processor palauttaa SQS:lle ep\u00e4onnistuneet tiedot <em>batchItemFailures<\/em>-objektissa. Kun kysyin Copilotilta, miksi et heti tehnyt t\u00e4t\u00e4 virheen k\u00e4sittely\u00e4, niin AI vastasi vain ett\u00e4 &#8221;tein ensin vain perusratkaisun, kehitet\u00e4\u00e4n my\u00f6hemmin lis\u00e4\u00e4&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tietotyyppien kanssa sai olla tarkkana. id-kentt\u00e4 meni v\u00e4lill\u00e4 string- ja v\u00e4lill\u00e4 number-tyypill\u00e4 ja aiheutti ihmetyst\u00e4 kun data ei liikkunut.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">REST API tietojen hakemiselle vaati hieman algoritmin hiomista, mutta Copilot ymm\u00e4rsi halutun datank\u00e4sittelyn algoritmin melko helpolla. REST API tarjoaa <em>hourly-average<\/em> -rajapinnasta viimeisen kuukauden aikana tallennetusta datasta keskim\u00e4\u00e4r\u00e4isen vuorokauden tuntikohtaiset liikennem\u00e4\u00e4r\u00e4t ja keskinopeudet. Ne on koostettu mittauspisteiden molemminsuuntaisista liikennemittauksista. T\u00e4m\u00e4n lis\u00e4ksi datassa tulee mukana molemmille suunnille omat lukemat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">K\u00e4ytt\u00f6liittym\u00e4n puolella AI osasi valita oikeat komponentit varsin hyvin ja nopeasti. Esim. karttakomponentti ja diagrammikomponentti tulivat helposti k\u00e4ytt\u00f6\u00f6n ilman komponenttien konfigurointiosaamista. Agent mode ajoi puolestani jopa&nbsp;<em>npm install<\/em>&nbsp;-komennot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Testaus oli t\u00e4rke\u00e4\u00e4, jotta k\u00e4ytt\u00f6liittym\u00e4n logiikka toimi t\u00e4ydellisesti ja sujuvasti. Jonkin verran piti komentaa mm. karttan\u00e4kym\u00e4n keskitt\u00e4misen takia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">K\u00e4ytt\u00f6liittym\u00e4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">K\u00e4ytt\u00f6liittym\u00e4 on varsin simppeli: valitaan mittausasema ja valinnan alle aukeaa karttan\u00e4kym\u00e4 jossa mittausaseman paikka n\u00e4kyy, sen alla mittausaseman tiedot, sitten datan graafiset esitykset ja alimmaisena mahdollisuus tutkia REST-rajapinnan raakadataa.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16.png\"><img loading=\"lazy\" decoding=\"async\" width=\"761\" height=\"1024\" src=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16-761x1024.png\" alt=\"\" class=\"wp-image-1168\" srcset=\"https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16-761x1024.png 761w, https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16-223x300.png 223w, https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16-768x1034.png 768w, https:\/\/www.pilvikoodari.net\/wp-content\/uploads\/2025\/03\/Screenshot-2025-03-17-at-16.29.16.png 1071w\" sizes=\"auto, (max-width: 761px) 100vw, 761px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Arvio ty\u00f6m\u00e4\u00e4r\u00e4st\u00e4 ilman AI:n apua<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">T\u00e4h\u00e4n projektiin meni AI:n avulla toteutettuna ehk\u00e4 noin 10 tuntia.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On tietysti mielenkiintoista mietti\u00e4, kuinka kauan toteutukseen olisi mennyt ilman AI:n apua tai siten ett\u00e4 sit\u00e4 olisi k\u00e4ytetty vain apurina koodauksen yhteydess\u00e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Projektissa oli monia aiheita, joihin tutustuminen olisi vaatinut aikaa. Infran pystytt\u00e4minen CDK:lla olisi vaatinut tiedonhakua ja opettelua, DynamoDB:n tietojen haku oli aika mielenkiintoisen n\u00e4k\u00f6inen SQL-kyselyyn tottuneelle, Reactin karttakomponentti ja datan esitt\u00e4minen graafisesti recharts -kirjastolla olisivat vaatineet perehtymist\u00e4. Collector-lambdan ajastus meni kerrasta oikein, vaikka etuk\u00e4teen en tiennyt yht\u00e4\u00e4n miten sellainen teht\u00e4isiin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Arvioni on, ett\u00e4 aikaa olisi voinut menn\u00e4 kokonaisuuteen noin 4-5 kertaa enemm\u00e4n &#8221;perinteisell\u00e4&#8221; koodauksella.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Toki t\u00e4ytyy my\u00f6nt\u00e4\u00e4, ett\u00e4 toteutuksen koodi ei varmasti ole t\u00e4ysin loppuun asti hiottua kaikilta osin. Esimerkiksi tyylej\u00e4 meni jossain vaiheessa css-tiedostoon vaikka muuten k\u00e4ytettiin TailWind-tyylikirjastoa. Mutta parantelua voi tehd\u00e4 j\u00e4lkik\u00e4teenkin Copilotin avulla.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Yhteenveto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kaiken kaikkiaan sanoisin, ett\u00e4 t\u00e4ysin AI-pohjaisella koodauksella saa nopeasti tulosta aikaiseksi kun kyseess\u00e4 on t\u00e4ysin uusi j\u00e4rjestelm\u00e4. Teko\u00e4ly\u00e4 komentavan on kuitenkin tunnettava ohjelmistokehityksen hyv\u00e4t periaatteet sek\u00e4 k\u00e4ytetyt p\u00e4\u00e4teknologiat ainakin jonkinlaisella tasolla, jotta vikojen ja puutteiden selvittely onnistuu ja lopputulos on riitt\u00e4v\u00e4n hyv\u00e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">J\u00e4rjestelm\u00e4n osoite<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">J\u00e4rjestelm\u00e4 on toistaiseksi k\u00e4ytett\u00e4viss\u00e4 osoitteessa<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/d2cjqj7nnodqi4.cloudfront.net\">https:\/\/d2cjqj7nnodqi4.cloudfront.net<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">L\u00e4hdekoodi<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/anttirauhala\/traffic-stations\">https:\/\/github.com\/anttirauhala\/traffic-stations<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Teko\u00e4ly\u00e4 tulee k\u00e4ytetty\u00e4 ty\u00f6teht\u00e4viss\u00e4 p\u00e4ivitt\u00e4in, mutta se on enimm\u00e4kseen pienten asioiden ratkomista. P\u00e4\u00e4tin kokeilla, miten onnistuu kokonaisen uuden pilvinatiivin j\u00e4rjestelm\u00e4n toteutus pelk\u00e4st\u00e4\u00e4n AI-ty\u00f6kaluja k\u00e4ytt\u00e4m\u00e4ll\u00e4. Kaikki koodi (tai ainakin 95%) oli siis tarkoitus tuottaa teko\u00e4ly\u00e4 komentamalla. T\u00e4ss\u00e4 artikkelissa kerron kokemuksia projektista. Projektin tarkoitus Projektin p\u00e4\u00e4tarkoitus oli tosiaan kokeilla, miten AI:lla onnistuu isojen kokonaisuuksien toteutus. Mutta oli &#8230; <a title=\"Kokonaisen j\u00e4rjestelm\u00e4n toteutus AI:lla\" class=\"read-more\" href=\"https:\/\/www.pilvikoodari.net\/?p=1157\" aria-label=\"Lue lis\u00e4\u00e4 aiheesta Kokonaisen j\u00e4rjestelm\u00e4n toteutus AI:lla\">Lue lis\u00e4\u00e4<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,25,9,16,28],"tags":[],"class_list":["post-1157","post","type-post","status-publish","format-standard","hentry","category-ai","category-arkkitehtuuri","category-avoin-data","category-aws","category-serverless"],"_links":{"self":[{"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/posts\/1157","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1157"}],"version-history":[{"count":20,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/posts\/1157\/revisions"}],"predecessor-version":[{"id":1184,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=\/wp\/v2\/posts\/1157\/revisions\/1184"}],"wp:attachment":[{"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pilvikoodari.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}