Mesterséges programozás

Vannak olyan technológiák, amelyek zárójelbe tesznek korábbi feladatokat, adott esetben munkaköröket. Mindenki azt szajkózza, hogy az AI is ilyen, és továbbikban nincs szükség kétkezű egyfejű humánokra. Kicsit azért tamáskodom, mert ahogy mások is rámutattak: “Az ügyfélnek pontosan definiálnia kéne, hogy mit is szeretne. Ezek szerint biztonságban vagyunk.”

Szigorúan magánvéleményem, hogy a ChatGPT és társai az emberiség elhülyítésenek egy újabb eszköze, de a szellemet nem lehet visszazárni a palackba. Ha nem küzdhetsz ellene, használd fel! Így kipróbáltam, hogy hogy is néz ki, lássuk mire megyünk vele.

Robot-android with weapons.png

Projektnek a Corporate Bullshit Generator for Java migrációját tűztem ki célul valamilyen másik nyelven, ami esetünkben a Go lett. Elsősorban azért, mert itt van esélyem kicsit belelátni, de nem értek hozzá eléggé, Pythonban meg már van ilyen.

Kikötésnek annyit tettem magamnak, hogy olyan keveset írjak kódot, amennyire csak lehetséges. A végeredmény a Corporate bullshit generator for Go projekt lett.

*** Ez a cikk is ChatGPT hozzáadásával készült.

CBSG for Go on github

Előkészületek és refactor

Tehát nekiültem, és elővettem a projektet újra, megnéztem, piszkálgattam és arra jutottam, hogy bár a célt teljesíti, így még nem lesz elég jó. A sok kicsi fájlba kiszervezett szótár sajnos nehezen kezelhető, egy fájl jobban kézben tartható.

Ennek eredménye képpen összevontam az összeset egy CSV-be, és egy oszlopot bevezettem a kulcsnak, amit eddig a properties fájlban definiáltam. Az első oszlop lett a kulcs, második a súly, az utána következő string pedig maga a szövegtemplate.

SENW_ARTICULATED_PROPOSITION,270,Text with $template

Előzőleg, ha csak szavak voltak választhatóak, például jelzők esetén (fantastic,extraordinary…) WORD_ előtag különböztette meg és SENW_ előtag szólt a súlyozottaknak. Ha viszont a szavak esetén egyes (1) súlyt használunk, az végeredményben ugyanazt jelenti. Tehát a szókiválasztó helyett maradhatott a súlyozott helyettesítő.

Publikáció

Miután elkészült az átalakítás, előkészítettem egy settings.xml fájlt a Github artifactory feltöltéshez.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <activeProfiles>
        <activeProfile>github</activeProfile>
    </activeProfiles>

    <profiles>
        <profile>
            <id>github</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <url>https://repo1.maven.org/maven2</url>
                </repository>
                <repository>
                    <id>github</id>
                    <url>https://maven.pkg.github.com/lsmhun/cbsg-java</url>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>

    <servers>
        <server>
            <id>github</id>
            <username>githubusername</username>
            <password>ghp_githubgeneratedkey</password>
        </server>
    </servers>
</settings>

Ennek segítségével már manuálisan feltölthető a jar a Github packages közé.

mvn clean deploy -s ~/.m2/settings_github_cbsg.xml -p github

A Github actions ezt sokkal szebben, automatizáltan is megoldja: ha készítünk egy release-t, rögtön publikálja is. Ezt ki kéne kibővíteni a Sonatype, maven central publish funkcióval is, és akkor a https://mvnrepository.com/ címen is elérhető lenne, de egyelőre csak a TODO listára került.

Migráció ChatGPT-vel

Ekkorra készen állt az eredeti projekt a konverzióra.

Beléptem a https://chat.openai.com/ címen, nyitottam egy új beszélgetést és elkezdtem írogatni.

Tapasztalatok:

  • amerikai idő szerinti csúcsidőben, különösen eleinte túlterhelt volt a rendszer és vagy be se tudtam lépni, vagy nem igazán válaszolt. Figyelembe véve, hogy ingyenesen használtam, ezt nem fogtam fel negatívumnak.
  • teljesen jól ért több nyelven is. Nem csak angolul, hanem magyarul és németül is zokszó nélkül elfogadta az utasításokat, és ennek megfelelő nyelven válaszolt.
  • először be szerettem volna másolni egy egész osztály forráskódját, de limitálva van a maximális méret, amit elfogad, így csak darabonként tudtam felkérni a konverzióra
  • ennek következtében az egyes metódusokat nem mindig tette be az osztály alá, emiatt sokszor utólagosan kellett megkérni, hogy (c *CbsgCore) az összes esetben bekerüljön. Így azért nem teljesen volt “automata” az automata.
  • kisebb falatot simán jól kezelt. A CbsgDictionary esetén teszteket is tökéletesen generált, amellett hogy átírta Java nyelvről Go-ra.
  • aránylag jól összegezte, “elemezte” a megkapott kódrészek tevékenységét
  • nyilvánvalóvá tette az eredeti forrás design hibáit. Igaz, ezzel sok újat nem mondott, de tiszta kóddal könnyebb bánni.
  • amikor azt kértem, hogy hogyan lehet a szótárat belefordítani a binárisba, simán hozott rá példát, mintát. Ma is tanultam valamit.
      //go:embed dict/en/cbsg_dictionary.csv
      var defaultDictionary string
    

Felmerült nehézségek

Go module

Itt egy leírás arról, hogy miként is kéne. És hiába egyszerű egy modul, mégis több kérdést is felvet. Mennyire is érdemes bonyolítani, hogyha minimális eredményt szeretnénk elérni?

Végül a go cowsay modulját fél szemmel figyelve alakult ki a végső állapot. Innen lestem el a replace trükköt.

Tehén mondja vagy Dilbert főnöke

A méltán híres cowsay sokakat megihletett, és így született a go átirat. Mivel Dilbert főnöke a corporate bullshit generátor fő felhasználója, ezért az ő arcképe jobban illene ide.

Hozzátartozik, hogy Scott Adams, Dilbert rajzolója “persona non grata” lett, mivel összeakasztotta a bajszot a BLM mozgalommal. Így aztán ki tudja, mikor fogják beolvasztani a pull-requestemet.

Tehát forkoltam az eredeti Neo-cowsay projektet, hozzáadtam az egy darab ASCII art Dilbert főnöke képet és release-eltem egyet. Ez azért szükséges, mert a replacenél meg kell adni egy konkrét verziót.

replace github.com/Code-Hex/Neo-cowsay/v2 => github.com/lsmhun/Neo-cowsay/v2 v2.0.5

Ezzel tulajdonképp az eredeti cowsay helyett a fork lesz használva.

String formázás gondjai

Mikor elkészült a kód, akkor lássuk az eredményét. Nem volt az igazi. :( Bár valamit kiírt, ami hasonlított, de inkább így nézett ki:

[foo bar baz]%!s(MISSING)%!s(MISSING)

Az oka Go mágusoknak egyértelmű, de az átfordított kód alapján azért kellett debugolni. Az ok az Sprintf működésében keresendő, amint itt is írják. Az Sprintf []interface{} vár el, a sima []string slice viszont nem az. Így ennek a string reprezentációját írja ki, aztán a további paramétereknél meg hiány panaszt ír ki.

Megoldásként a var values []interface{} kellett definiálni akkor is, ha amúgy stringeket pakolunk bele. Valamint a az Sprintf meghívásakor a három pontot nem szabad elfelejteni. A javított kóddal már rendben működött a dolog.

func (c *CbsgCore) evaluateValues(template string) string {
	var values []interface{}
	matches := varRegexp.FindAllString(template, -1)

	for _, match := range matches {
		// It will evaluate $thingAtom to its values
		values = append(values, c.templateFunction(match))
	}

	templateReplace := varRegexp.ReplaceAllString(template, "%s")
	return fmt.Sprintf(templateReplace, values...)
}

Kimenet

 __________________________________________ 
/ There can be no gain in task efficiency  \
| until we can achieve a rapid growth      |
| momentum. Decision-maker and             |
| relationship result ins                  |
| innovation-driven and cross-enterprise   |
| style guidelines across the board. Our   |
| marketplace and right emotional impact   |
| organically turbocharges a matrix across |
| the organizations. The organization our  |
| key performance indicators on a          |
| transitional basis. The corporate values |
| cost-effectively strengthen the thought  |
\ leaders across the board.                /
 ------------------------------------------
          \
           \
              @         @
             @@  ..-..  @@
             @@@' _ _ '@@@
              @(  oo   )@
               |  (_)  |
               |   _   |
               |_     _|
              /|_'---'_|\
             / | '\_/' | \
            /  |  | |  |  \

Összegzés

Végeredményben sikerült elérni a célt, megszületett az óhajtott alkalmazás, és még működik is. Minden ellenkező híresztelés ellenére a kód nem lesz jobb, mint a robotot használó fejlesztő szintje. Tehát, ha valaki már ért hozzá valamennyire, akkor tud a keze alá dolgozni. Nem hiszem, hogy érdemben helyettesítené egyelőre a fejlesztőket, mert olyan kódot ír, mintha összegereblyézte volna a netről az alap howto leírásokat az adott témakörben. Nem mintha a fejlesztők nem ugyanezt tennék…

Előnye viszont az azonnali prompt válasz, rögtön fordítható, kipróbálható eredmény, gyakorlatilag template szintjén bármit meg tud csinálni. Sok robotikus munkát jól elvégez.

Mivel könnyen tud összefoglalót, leírást különböző stílusban generálni, így sok helyütt kényelmesebbé teheti a munkát. Alapvetően ha egy nyelvi modellként gondolunk rá, akkor sokkal elfogadhatóbbak az általa gyártott eredmények.