Ποιος θα συντηρεί τον κώδικα όταν τελειώσει η μαγεία; Η τεχνητή νοημοσύνη, το ελεύθερο λογισμικό και οι άνθρωποι πίσω από αυτό

Η τεχνητή νοημοσύνη, το ελεύθερο λογισμικό και οι άνθρωποι πίσω από αυτό.

Φαντάσου ότι έχεις μια ιδέα για μια εφαρμογή. Παλαιότερα, θα έπρεπε να σχεδιάσεις την αρχιτεκτονική της, να γράψεις τον κώδικα, να δημιουργήσεις τη βάση δεδομένων, να υλοποιήσεις το περιβάλλον χρήστη και να περάσεις αρκετές ώρες διορθώνοντας σφάλματα. Σήμερα, μπορείς να περιγράψεις την ιδέα σου με φυσική γλώσσα και ένα εργαλείο τεχνητής νοημοσύνης να δημιουργήσει μέσα σε λίγα λεπτά μια πρώτη λειτουργική έκδοση.

Ακούγεται εντυπωσιακό. Και πράγματι είναι.

Μπορούμε πλέον να μετατρέπουμε σκέψεις σε εφαρμογές με ταχύτητα που μέχρι πρόσφατα φαινόταν απίθανη. Όμως, υπάρχει μια σημαντική ερώτηση που συχνά ξεχνάμε να κάνουμε: ποιος θα αναλάβει την ευθύνη για τον κώδικα όταν τελειώσει η αρχική μαγεία;

Ποιος θα ελέγξει αν είναι ασφαλής; Ποιος θα διασφαλίσει ότι λειτουργεί σωστά και στις δύσκολες περιπτώσεις; Ποιος θα διορθώσει τα προβλήματα που θα εμφανιστούν μετά την πρώτη παρουσίαση; Και, τελικά, ποιος θα συντηρεί το λογισμικό όταν η τεχνητή νοημοσύνη θα έχει ολοκληρώσει την εργασία που της ζητήσαμε;

Η απάντηση δεν βρίσκεται απλώς σε ένα καλύτερο μοντέλο AI ή σε ένα πιο εξελιγμένο εργαλείο. Βρίσκεται στον τρόπο με τον οποίο προσεγγίζουμε την ανάπτυξη λογισμικού και, κυρίως, στην ανθρώπινη ευθύνη.

Το ελεύθερο λογισμικό δεν γράφεται μόνο του

Όταν μιλάμε για ελεύθερο λογισμικό και λογισμικό ανοικτού κώδικα (Free/Libre and Open Source Software – FLOSS), συχνά επικεντρωνόμαστε στο τελικό προϊόν. Αναφερόμαστε σε εφαρμογές, λειτουργικά συστήματα, βιβλιοθήκες και υπηρεσίες που χρησιμοποιούμε καθημερινά.

Βλέπουμε το αποτέλεσμα, αλλά όχι πάντα τους ανθρώπους και την προσπάθεια που κρύβονται πίσω από αυτό.

Ένα open source project δεν αποτελείται μόνο από γραμμές κώδικα. Για να παραμείνει ενεργό, χρήσιμο και αξιόπιστο, χρειάζεται πολλές διαφορετικές μορφές συνεισφοράς:

  • Κώδικας: Υλοποίηση νέων λειτουργιών, διόρθωση σφαλμάτων, βελτίωση της απόδοσης και συντήρηση των υφιστάμενων υλοποιήσεων.
  • Τεκμηρίωση: Οδηγοί εγκατάστασης, εγχειρίδια χρήσης, τεχνικές οδηγίες και παραδείγματα που βοηθούν άλλους ανθρώπους να αξιοποιήσουν το λογισμικό.
  • Μετάφραση: Προσαρμογή του περιβάλλοντος και της τεκμηρίωσης σε διαφορετικές γλώσσες, ώστε το λογισμικό να είναι προσβάσιμο σε περισσότερους χρήστες.
  • Κοινότητα: Υποστήριξη χρηστών, απαντήσεις σε ερωτήσεις, ανταλλαγή γνώσεων, οργάνωση εκδηλώσεων και καλωσόρισμα νέων συνεισφερόντων.

Όλες αυτές οι δραστηριότητες είναι απαραίτητες. Μια εφαρμογή μπορεί να έχει εξαιρετικό κώδικα, αλλά αν δεν υπάρχει τεκμηρίωση, οι νέοι χρήστες δυσκολεύονται να την αξιοποιήσουν. Μπορεί να υποστηρίζει πολλές δυνατότητες, αλλά αν δεν υπάρχει κοινότητα, η υποστήριξη και η εξέλιξή της γίνονται δυσκολότερες.

Η συνεισφορά στο ελεύθερο λογισμικό δεν προϋποθέτει απαραίτητα ότι κάποιος πρέπει να είναι προγραμματιστής. Υπάρχουν πολλοί τρόποι να βοηθήσει κανείς ένα project, ακόμη και χωρίς να γράψει ούτε μία γραμμή κώδικα.

Πίσω από κάθε project υπάρχει ένας άνθρωπος

Ας δούμε τι συμβαίνει σε ένα συνηθισμένο open source project.

Ένας χρήστης εντοπίζει ένα πρόβλημα και δημιουργεί ένα issue, δηλαδή μια αναφορά σφάλματος ή μια πρόταση βελτίωσης. Κάποιος άλλος αναλαμβάνει να εξετάσει το ζήτημα. Ένας developer μπορεί να προτείνει μια αλλαγή μέσω ενός pull request. Στη συνέχεια, άλλοι συνεισφέροντες ελέγχουν τον κώδικα, κάνουν παρατηρήσεις, ζητούν διορθώσεις και τελικά εγκρίνουν ή απορρίπτουν την αλλαγή.

Ακολουθούν οι νέες εκδόσεις (releases), η ενημέρωση της τεκμηρίωσης και η υποστήριξη των χρηστών.

Κάθε στάδιο αυτού του κύκλου βασίζεται στην προσπάθεια και τη συνεργασία ανθρώπων. Ακόμη και μια μικρή διόρθωση μπορεί να απαιτήσει χρόνο για την αναπαραγωγή ενός προβλήματος, την κατανόηση της αιτίας του, τον έλεγχο της λύσης και την επιβεβαίωση ότι δεν επηρεάζονται άλλες λειτουργίες.

Αυτό είναι ένα από τα σημαντικότερα χαρακτηριστικά του ελεύθερου λογισμικού: δεν είναι απλώς ένας τρόπος διανομής λογισμικού. Είναι και ένα μοντέλο συνεργασίας, ανταλλαγής γνώσεων και κοινής ευθύνης.

Το burnout δεν είναι παράσημο

Η προσφορά σε ένα ελεύθερο λογισμικό project μπορεί να είναι ιδιαίτερα δημιουργική και ικανοποιητική. Μπορείς να μάθεις νέες τεχνολογίες, να γνωρίσεις ανθρώπους από όλο τον κόσμο, να βελτιώσεις τις δεξιότητές σου και να συμβάλεις σε κάτι που χρησιμοποιούν χιλιάδες ή εκατομμύρια άνθρωποι.

Υπάρχει, όμως, και μια λιγότερο ευχάριστη πλευρά: η συνεχής διαθεσιμότητα, οι ειδοποιήσεις, τα ανοιχτά ζητήματα, οι προσδοκίες της κοινότητας και η αίσθηση ότι πάντα υπάρχει κάτι ακόμη που πρέπει να γίνει.

Ειδικά όταν η συνεισφορά γίνεται στον ελεύθερο χρόνο μας, είναι εύκολο να ξεπεράσουμε τα όριά μας. Μπορεί να θεωρούμε ότι πρέπει να απαντήσουμε αμέσως σε κάθε ερώτηση, να διορθώσουμε κάθε πρόβλημα ή να αναλάβουμε περισσότερες εργασίες από όσες πραγματικά μπορούμε να ολοκληρώσουμε.

Αυτό μπορεί να οδηγήσει σε burnout, δηλαδή σε σωματική και ψυχική εξάντληση που σχετίζεται με τη συνεχή πίεση και την υπερβολική επιβάρυνση.

Το γεγονός ότι μπορείς να προσφέρεις συνέχεια δεν σημαίνει ότι πρέπει.

Η συνεισφορά δεν μετριέται αποκλειστικά με τον αριθμό των commits, των issues ή των pull requests. Δεν χρειάζεται να αποδεικνύεις το ενδιαφέρον σου για ένα project εξαντλώντας τον εαυτό σου.

Κάνε διάλειμμα. Το project θα περιμένει.

Η παύση, τα προσωπικά όρια και η βιωσιμότητα είναι σημαντικά στοιχεία μιας υγιούς κοινότητας.

Μερικές πρακτικές που μπορούν να βοηθήσουν:

  • Όρισε πόσο χρόνο μπορείς πραγματικά να διαθέσεις για τη συνεισφορά σου.
  • Μην αντιμετωπίζεις κάθε ειδοποίηση ως επείγουσα.
  • Μάθε να λες όχι όταν δεν μπορείς να αναλάβεις μια επιπλέον εργασία.
  • Μοιράσου τη γνώση σου, ώστε να μπορούν να συμμετέχουν και άλλοι άνθρωποι.
  • Κάνε διαλείμματα χωρίς να αισθάνεσαι ότι εγκαταλείπεις την κοινότητα.

Αυτό έχει ιδιαίτερη σημασία και στη νέα εποχή της τεχνητής νοημοσύνης. Αν ένα εργαλείο μάς επιτρέπει να ολοκληρώνουμε εργασίες γρηγορότερα, δεν σημαίνει ότι πρέπει αυτομάτως να αναλάβουμε διπλάσιες. Μπορούμε να αξιοποιήσουμε τον χρόνο που εξοικονομούμε για καλύτερο έλεγχο, τεκμηρίωση, μάθηση ή απλώς για να ξεκουραστούμε.

Από την ιδέα στην εφαρμογή με φυσική γλώσσα

Η ανάπτυξη λογισμικού με τη βοήθεια της τεχνητής νοημοσύνης αλλάζει σημαντικά τον τρόπο με τον οποίο προσεγγίζουμε τον προγραμματισμό.

Με εργαλεία AI coding μπορούμε να περιγράψουμε μια λειτουργία με φυσική γλώσσα, να ζητήσουμε τη δημιουργία ενός API, να παράγουμε ένα περιβάλλον χρήστη, να γράψουμε δοκιμές ή να αναλύσουμε ένα σφάλμα.

Η βασική διαδικασία μπορεί να περιγραφεί απλά:

  1. Ιδέα: Έχουμε μια ανάγκη ή μια ιδέα για μια εφαρμογή.
  2. Prompt: Περιγράφουμε με φυσική γλώσσα τι θέλουμε να δημιουργήσουμε.
  3. Κώδικας: Το μοντέλο παράγει κώδικα με βάση τις οδηγίες και το διαθέσιμο πλαίσιο.
  4. Εφαρμογή: Εκτελούμε και αξιολογούμε το αποτέλεσμα.

Αυτή η προσέγγιση συχνά αποκαλείται vibe coding. Ο όρος περιγράφει έναν τρόπο ανάπτυξης στον οποίο ο προγραμματιστής χρησιμοποιεί φυσική γλώσσα για να καθοδηγήσει ένα μοντέλο τεχνητής νοημοσύνης, αφήνοντάς του να αναλάβει μεγάλο μέρος της παραγωγής του κώδικα.

Η δυνατότητα αυτή είναι ιδιαίτερα χρήσιμη για γρήγορα πρωτότυπα, πειραματισμό, αυτοματοποίηση και υλοποίηση ιδεών που διαφορετικά θα απαιτούσαν σημαντικό χρόνο.

Μπορεί επίσης να βοηθήσει ανθρώπους που δεν έχουν μεγάλη εμπειρία στον προγραμματισμό να κατανοήσουν βασικές έννοιες και να δημιουργήσουν τις πρώτες τους εφαρμογές.

Υπάρχει, όμως, μια παγίδα: το γεγονός ότι δημιουργήθηκε μια εφαρμογή δεν σημαίνει ότι δημιουργήθηκε και ένα ασφαλές, αξιόπιστο προϊόν έτοιμο για παραγωγική χρήση.

Το demo λειτουργεί. Μήπως και η εφαρμογή;

Ένα από τα πιο συνηθισμένα λάθη στην ανάπτυξη με AI είναι να θεωρούμε ότι μια εφαρμογή είναι ολοκληρωμένη επειδή λειτουργεί σε μια πρώτη επίδειξη.

Ας υποθέσουμε ότι ζητάμε από ένα εργαλείο τεχνητής νοημοσύνης να δημιουργήσει μια εφαρμογή διαχείρισης εργασιών. Το αποτέλεσμα εμφανίζει μια λίστα εργασιών, επιτρέπει την προσθήκη νέων και έχει ένα όμορφο περιβάλλον χρήστη. Δημιουργούμε μερικές εργασίες, πατάμε τα κουμπιά και όλα φαίνεται να λειτουργούν.

Είναι, όμως, αρκετό αυτό;

Τι συμβαίνει αν δύο χρήστες προσπαθήσουν να επεξεργαστούν ταυτόχρονα την ίδια εργασία; Τι γίνεται αν κάποιος προσπαθήσει να δει δεδομένα που ανήκουν σε άλλον χρήστη; Τι συμβαίνει όταν η βάση δεδομένων δεν είναι διαθέσιμη; Τι γίνεται αν σταλεί ένα κενό ή μη έγκυρο πεδίο;

Αυτά είναι ερωτήματα που μια απλή επίδειξη δεν μπορεί να απαντήσει.

Εδώ χρειάζεται να διακρίνουμε δύο διαφορετικές έννοιες:

  • Demo που φαίνεται να λειτουργεί: Έχουμε δοκιμάσει μια βασική διαδρομή χρήσης, συνήθως το ιδανικό σενάριο, χωρίς να έχουμε εξετάσει συστηματικά τις υπόλοιπες περιπτώσεις.
  • Επαληθευμένο λογισμικό: Έχουμε ελέγξει τη συμπεριφορά της εφαρμογής με δοκιμές, έχουμε εξετάσει τα σφάλματα, τα δικαιώματα, την ασφάλεια και την αντοχή της σε μη αναμενόμενες συνθήκες.

Στην ανάπτυξη λογισμικού, η επιτυχής εκτέλεση ενός σεναρίου δεν αποδεικνύει ότι όλες οι λειτουργίες είναι σωστές. Απλώς επιβεβαιώνει ότι το συγκεκριμένο σενάριο λειτούργησε.

Η τεχνητή νοημοσύνη γράφει. Εσύ παραμένεις υπεύθυνος.

Εδώ βρίσκεται ίσως η σημαντικότερη αρχή της ανάπτυξης λογισμικού με AI.

Η τεχνητή νοημοσύνη είναι επιταχυντής, όχι υποκατάστατο της ανθρώπινης κρίσης.

Μπορεί να παράγει κώδικα, να προτείνει αρχιτεκτονικές λύσεις, να δημιουργεί δοκιμές και να εντοπίζει πιθανά προβλήματα. Δεν γνωρίζει, όμως, απαραίτητα όλες τις επιχειρησιακές απαιτήσεις, τους περιορισμούς του περιβάλλοντος παραγωγής ή τις συνέπειες μιας λανθασμένης απόφασης.

Ακόμη και όταν το αποτέλεσμα φαίνεται σωστό, χρειάζεται έλεγχος. Ο developer παραμένει υπεύθυνος για την αποδοχή των αλλαγών, την επαλήθευση της συμπεριφοράς και την ασφάλεια του λογισμικού.

Αυτό δεν σημαίνει ότι πρέπει να απορρίψουμε την τεχνητή νοημοσύνη. Σημαίνει ότι πρέπει να τη χρησιμοποιούμε με τρόπο που ενισχύει τη δουλειά μας, αντί να παραδίδουμε άκριτα τον έλεγχο.

7 καλές πρακτικές για ανάπτυξη λογισμικού με AI

Αν θέλουμε να αξιοποιήσουμε πραγματικά τις δυνατότητες της τεχνητής νοημοσύνης, χρειάζεται να ακολουθούμε μια οργανωμένη διαδικασία. Οι παρακάτω πρακτικές μπορούν να βοηθήσουν τόσο έμπειρους developers όσο και όσους ξεκινούν τώρα να πειραματίζονται με εργαλεία AI coding.

1. Μην ξεκινάς με κώδικα. Ξεκίνα με σχέδιο.

Η πρώτη παγίδα είναι να ζητήσουμε αμέσως από το AI: «Φτιάξε μου μια εφαρμογή διαχείρισης εργασιών».

Η περιγραφή αυτή είναι υπερβολικά γενική. Δεν καθορίζει ποιοι θα χρησιμοποιούν την εφαρμογή, ποιες λειτουργίες θα διαθέτει, πώς θα αποθηκεύονται τα δεδομένα και τι θεωρείται επιτυχημένη υλοποίηση.

Πριν ξεκινήσει η παραγωγή κώδικα, πρέπει να ξεκαθαρίσουμε τις απαιτήσεις.

Μια χρήσιμη πρακτική είναι η δημιουργία ενός μικρού PRD (Product Requirements Document), δηλαδή ενός εγγράφου που περιγράφει τις απαιτήσεις και τον σκοπό του προϊόντος.

Για παράδειγμα, σε μια εφαρμογή καταγραφής εργασιών (Task Tracker), το PRD μπορεί να περιλαμβάνει:

  • Ρόλους χρηστών: Διαχειριστές, μέλη ομάδας και επισκέπτες.
  • Βασικές λειτουργίες: Δημιουργία, ανάθεση, επεξεργασία και φιλτράρισμα εργασιών.
  • Αποθήκευση δεδομένων: Δομή βάσης δεδομένων και μοντέλα που θα χρησιμοποιηθούν.
  • Κριτήρια αποδοχής: Τι ακριβώς πρέπει να συμβαίνει ώστε να θεωρήσουμε ότι μια λειτουργία ολοκληρώθηκε σωστά.
  • Περιορισμούς: Τεχνολογίες, συμβάσεις και λειτουργίες που δεν πρέπει να αλλάξουν.

Μπορούμε να ζητήσουμε από το AI να δημιουργήσει πρώτα ένα σχέδιο υλοποίησης, να αναφέρει ποια αρχεία σκοπεύει να αλλάξει και να εξηγήσει τις υποθέσεις του.

Αυτή η διαδικασία είναι γνωστή σε αρκετά εργαλεία ως Plan Mode. Αντί να επιτρέπουμε την άμεση υλοποίηση, εξετάζουμε πρώτα το προτεινόμενο πλάνο και διορθώνουμε ό,τι δεν μας καλύπτει.

Είναι πολύ ευκολότερο και φθηνότερο να διορθώσεις μια λανθασμένη απαίτηση σε ένα αρχείο Markdown παρά να ξηλώσεις μια εφαρμογή που έχει ήδη υλοποιηθεί με βάση αυτή.

2. Το καλό prompt μοιάζει με καλό τεχνικό ticket

Ένα prompt δεν πρέπει να είναι απλώς μια γενική επιθυμία. Είναι μια τεχνική οδηγία προς το μοντέλο και πρέπει να αντιμετωπίζεται με την ίδια προσοχή που θα δίναμε σε ένα ticket μιας ομάδας ανάπτυξης.

Όσο πιο σαφής είναι η περιγραφή, τόσο λιγότερο χρειάζεται το μοντέλο να μαντέψει.

Ένα δομημένο prompt μπορεί να χωριστεί σε τέσσερα βασικά μέρη:

  1. Context: Περιγράφουμε το πλαίσιο του έργου, τις τεχνολογίες, την υπάρχουσα υλοποίηση και τον στόχο.
  2. To-do: Περιγράφουμε αναλυτικά τι ακριβώς πρέπει να γίνει.
  3. Not-to-do: Διευκρινίζουμε τι πρέπει να αποφευχθεί και ποιοι περιορισμοί ισχύουν.
  4. Acceptance Criteria: Ορίζουμε τα κριτήρια επιτυχίας και τις δοκιμές που πρέπει να περάσουν.

Ας δούμε ένα παράδειγμα.

Ασαφές prompt:

Φτιάξε μου ένα login.

Με αυτή την οδηγία, το AI πρέπει να αποφασίσει μόνο του πολλές λεπτομέρειες. Δεν γνωρίζει τις τεχνολογίες που χρησιμοποιούμε, τον τρόπο διαχείρισης των χρηστών, τις απαιτήσεις ασφάλειας ή τον χειρισμό των αποτυχημένων προσπαθειών σύνδεσης.

Καλύτερα δομημένο prompt:

## Context
Υπάρχει ένα Node.js/Express API με PostgreSQL.

## To-do
Δημιούργησε endpoint /login που δέχεται email και password.
Σε περίπτωση επιτυχούς σύνδεσης, επέστρεψε JWT token.

## Not-to-do
Μην αποθηκεύσεις ποτέ passwords σε plaintext.
Μην χρησιμοποιήσεις session cookies.
Μην αλλάξεις την υπάρχουσα δομή της βάσης χωρίς να
προτείνεις πρώτα τη σχετική αλλαγή.

## Acceptance Criteria
1. Η επιτυχής σύνδεση επιστρέφει έγκυρο JWT.
2. Η αποτυχημένη σύνδεση επιστρέφει HTTP 401.
3. Υπάρχουν unit tests για επιτυχημένα και αποτυχημένα
   σενάρια.
4. Τα passwords αποθηκεύονται με κατάλληλο password hashing.

Η διαφορά είναι ουσιαστική. Στη δεύτερη περίπτωση, το μοντέλο έχει σαφέστερο πλαίσιο και συγκεκριμένα κριτήρια με τα οποία μπορούμε να αξιολογήσουμε το αποτέλεσμα.

3. Δώσε στην AI το σωστό context

Ένα από τα σημαντικότερα στοιχεία στην εργασία με AI coding tools είναι το context engineering, δηλαδή η σωστή επιλογή και οργάνωση των πληροφοριών που παρέχουμε στο μοντέλο.

Δεν αρκεί να γράψουμε ένα καλό prompt. Πρέπει να διασφαλίσουμε ότι το μοντέλο γνωρίζει αρκετά για το έργο στο οποίο εργάζεται.

Το context μπορεί να περιλαμβάνει:

  • Υφιστάμενο κώδικα: Τη δομή του project, τα σχετικά αρχεία και παραδείγματα από ήδη υλοποιημένες λειτουργίες.
  • Τεκμηρίωση: Επίσημα documentation, APIs, βιβλιοθήκες και τεχνικές οδηγίες.
  • Visual context: Screenshots, mockups, διαγράμματα και εικόνες που εξηγούν πώς πρέπει να λειτουργεί ή να εμφανίζεται μια εφαρμογή.
  • Κανόνες έργου: Συμβάσεις κώδικα, περιορισμούς, εντολές εκτέλεσης και οδηγίες που πρέπει να ακολουθούνται σε όλο το project.

Ένα ιδιαίτερα χρήσιμο παράδειγμα είναι το αρχείο AGENTS.md. Πρόκειται για ένα αρχείο οδηγιών που μπορεί να περιέχει πληροφορίες για τη δομή του έργου, τις τεχνολογίες, τις συμβάσεις ανάπτυξης και τους ελέγχους που πρέπει να εκτελούνται. Εργαλεία και agents που υποστηρίζουν τη συγκεκριμένη σύμβαση μπορούν να αξιοποιούν αυτές τις οδηγίες κατά την εργασία τους.

Για παράδειγμα, μπορούμε να ορίσουμε ότι:

  • Το backend χρησιμοποιεί συγκεκριμένη αρχιτεκτονική και συγκεκριμένες συμβάσεις ονοματοδοσίας.
  • Οι αλλαγές στη βάση δεδομένων πρέπει να συνοδεύονται από migrations.
  • Κάθε νέα λειτουργία πρέπει να έχει αντίστοιχα tests.
  • Δεν επιτρέπεται η αλλαγή συγκεκριμένων αρχείων χωρίς προηγούμενη έγκριση.

Υπάρχει, ωστόσο, και μια σημαντική λεπτομέρεια: περισσότερο context δεν σημαίνει πάντα καλύτερο αποτέλεσμα. Οι άσχετες ή παρωχημένες πληροφορίες μπορούν να μπερδέψουν το μοντέλο. Χρειάζεται να παρέχουμε σχετικό, ακριβές και ενημερωμένο πλαίσιο.

Το context είναι μέρος της μηχανικής, όχι απλώς μέρος του prompt.

4. Το Git είναι το δίχτυ ασφαλείας σου

Όταν ένα AI coding tool έχει τη δυνατότητα να τροποποιεί πολλά αρχεία, είναι εύκολο μια φαινομενικά μικρή αλλαγή να επηρεάσει λειτουργίες που προηγουμένως δούλευαν σωστά.

Γι' αυτό το Git δεν είναι προαιρετικό. Είναι βασικό εργαλείο ελέγχου και προστασίας.

Μια ασφαλής διαδικασία μπορεί να περιλαμβάνει τέσσερα βήματα:

  1. Checkpoint: Ξεκινάμε από μια καθαρή κατάσταση, με τις προηγούμενες αλλαγές αποθηκευμένες σε commit.
  2. Αλλαγή: Ζητάμε από την AI να υλοποιήσει ένα μικρό και συγκεκριμένο τμήμα της εργασίας.
  3. Έλεγχος: Εξετάζουμε το diff, εκτελούμε tests και ελέγχουμε αν επηρεάστηκαν άλλες λειτουργίες.
  4. Commit ή rollback: Αποδεχόμαστε την αλλαγή εφόσον είναι σωστή ή επιστρέφουμε σε προηγούμενη γνωστή καλή κατάσταση.

Ιδιαίτερη σημασία έχει η επιθεώρηση του diff, δηλαδή της διαφοράς ανάμεσα στην προηγούμενη και τη νέα κατάσταση των αρχείων.

Δεν εξετάζουμε μόνο τι προστέθηκε ή διαγράφηκε. Ελέγχουμε επίσης:

  • Αν προστέθηκαν ή τροποποιήθηκαν εξαρτήσεις (dependencies).
  • Αν άλλαξαν κρίσιμες λειτουργίες.
  • Αν δημιουργήθηκαν περιττές αλλαγές σε άσχετα αρχεία.
  • Αν αφαιρέθηκε κώδικας που χρησιμοποιείται από άλλα σημεία της εφαρμογής.

Η χρήση ξεχωριστών branches για πειραματισμούς και μικρών, συχνών commits βοηθά να διατηρούμε τον έλεγχο.

Μην αποδέχεσαι ένα μεγάλο σύνολο αλλαγών μόνο και μόνο επειδή η AI αναφέρει ότι ολοκλήρωσε επιτυχώς την εργασία.

5. Test πρώτα, εμπιστοσύνη μετά

Ένας από τους πιο σημαντικούς ελέγχους είναι η δοκιμή της εφαρμογής σε διαφορετικές συνθήκες.

Συχνά, η τεχνητή νοημοσύνη δημιουργεί κώδικα που λειτουργεί στο ιδανικό σενάριο, αλλά αποτυγχάνει όταν προκύψουν μη αναμενόμενα δεδομένα ή συνθήκες.

Στον προγραμματισμό χρησιμοποιούμε συχνά τους όρους Happy Path και Unhappy Path.

Happy Path – Το ιδανικό σενάριο:

  • Ένας χρήστης συνδέεται με σωστά διαπιστευτήρια.
  • Μια φόρμα υποβάλλεται με όλα τα απαιτούμενα και έγκυρα δεδομένα.
  • Μια εγγραφή αποθηκεύεται επιτυχώς στη βάση δεδομένων.
  • Μια λειτουργία επιστρέφει το αναμενόμενο αποτέλεσμα.

Unhappy Path – Οι περιπτώσεις που δοκιμάζουν την εφαρμογή:

  • Ο χρήστης υποβάλλει κενά ή μη έγκυρα πεδία.
  • Κάποιος προσπαθεί να αποκτήσει πρόσβαση χωρίς τα απαραίτητα δικαιώματα.
  • Η βάση δεδομένων ή το δίκτυο δεν είναι διαθέσιμα.
  • Μια λειτουργία δέχεται δεδομένα που δεν αναμένονται.

Και οι δύο κατηγορίες είναι απαραίτητες. Δεν αρκεί να επιβεβαιώσουμε ότι η εφαρμογή λειτουργεί όταν όλα πηγαίνουν καλά. Πρέπει να ελέγξουμε και τον τρόπο με τον οποίο αντιδρά όταν κάτι αποτυγχάνει.

Επιπλέον, μετά από κάθε μικρή αλλαγή είναι χρήσιμο να εκτελούμε τους κατάλληλους ελέγχους:

  • Unit tests: Έλεγχος μικρών, μεμονωμένων τμημάτων του κώδικα.
  • Integration tests: Έλεγχος της συνεργασίας μεταξύ διαφορετικών τμημάτων, όπως API και βάσης δεδομένων.
  • Type checking: Έλεγχος τύπων, όπου χρησιμοποιείται γλώσσα ή εργαλείο που τον υποστηρίζει.
  • Linting: Έλεγχος του κώδικα βάσει κανόνων ποιότητας και μορφοποίησης.

Πρέπει, όμως, να θυμόμαστε κάτι: η επιτυχία των tests επιβεβαιώνει συγκεκριμένες συμπεριφορές. Δεν αποδεικνύει την απουσία όλων των σφαλμάτων.

6. Ασφάλεια: Μην εμπιστεύεσαι τυφλά τον κώδικα AI

Η ασφάλεια είναι ίσως το σημείο στο οποίο δεν υπάρχει περιθώριο για επιπόλαιες αποφάσεις.

Μια εφαρμογή μπορεί να λειτουργεί σωστά σε ένα απλό demo και παρ' όλα αυτά να έχει σοβαρά κενά ασφαλείας. Το πρόβλημα γίνεται ακόμη πιο σημαντικό όταν διαχειριζόμαστε προσωπικά δεδομένα, στοιχεία σύνδεσης ή πληρωμές.

Υπάρχουν ορισμένες περιοχές που πρέπει να ελέγχουμε ιδιαίτερα προσεκτικά:

  • Authentication και Authorization: Το authentication αφορά την ταυτοποίηση του χρήστη, ενώ το authorization αφορά τα δικαιώματα πρόσβασης. Δεν αρκεί κάποιος να έχει συνδεθεί· πρέπει να επιβεβαιώνουμε ότι δικαιούται να εκτελέσει τη συγκεκριμένη ενέργεια.
  • Secrets: API keys, passwords, tokens και ιδιωτικά κλειδιά πρέπει να προστατεύονται. Δεν πρέπει να ενσωματώνονται στον πηγαίο κώδικα ούτε να κοινοποιούνται σε prompts.
  • Input validation: Κάθε είσοδος από χρήστη πρέπει να ελέγχεται και να επικυρώνεται κατάλληλα.
  • Dependencies: Οι βιβλιοθήκες που χρησιμοποιεί η εφαρμογή πρέπει να ελέγχονται για γνωστά προβλήματα ασφαλείας και περιττές εξαρτήσεις.
  • Security auditing: Χρειάζεται ανεξάρτητος έλεγχος του κώδικα με κατάλληλα εργαλεία και διαδικασίες.

Εργαλεία όπως οι SAST (Static Application Security Testing) scanners μπορούν να αναλύσουν στατικά τον πηγαίο κώδικα και να εντοπίσουν ορισμένες κατηγορίες πιθανών ευπαθειών. Αντίστοιχα, οι dependency scanners ελέγχουν τις εξαρτήσεις για γνωστά προβλήματα ασφαλείας.

Κανένα από αυτά τα εργαλεία δεν αντικαθιστά έναν ολοκληρωμένο έλεγχο. Αποτελούν, όμως, σημαντικά μέσα επαλήθευσης.

Μια ακόμη κρίσιμη προειδοποίηση αφορά τα μυστικά στοιχεία πρόσβασης. Μην κοινοποιείς API keys, passwords, tokens ή ιδιωτικά κλειδιά σε AI prompts ή σε δημόσια repositories.

Η χρήση αρχείων περιβάλλοντος, όπως το .env, μπορεί να βοηθήσει στη διαχείριση ρυθμίσεων και μυστικών, εφόσον το αρχείο δεν ανεβαίνει στο Git και προστατεύεται κατάλληλα. Σε περιβάλλοντα παραγωγής είναι προτιμότερο να χρησιμοποιούνται κατάλληλες υπηρεσίες διαχείρισης μυστικών (secrets managers) ή ασφαλείς μεταβλητές περιβάλλοντος.

Τέλος, το γεγονός ότι ένα project είναι open source δεν εγγυάται αυτομάτως ότι είναι ασφαλές. Η διαφάνεια του κώδικα διευκολύνει την επιθεώρηση, αλλά η ασφάλεια απαιτεί πραγματικούς ελέγχους.

Η παραγωγή κώδικα από την AI μπορεί να είναι γρήγορη. Η ευθύνη για την ασφάλειά του, όμως, παραμένει στον άνθρωπο.

7. Σπάσε τον φαύλο κύκλο του debugging

Ένα από τα πιο απογοητευτικά σενάρια κατά τη χρήση AI coding tools είναι αυτό που θα μπορούσαμε να ονομάσουμε Vibe Coding Doom Loop.

Η διαδικασία συνήθως εξελίσσεται ως εξής:

  1. Εμφανίζεται ένα σφάλμα.
  2. Ζητάμε από την AI να το διορθώσει.
  3. Η AI αλλάζει τον κώδικα και διορθώνει το αρχικό πρόβλημα, αλλά δημιουργεί ένα καινούργιο.
  4. Ζητάμε ξανά διόρθωση.
  5. Η επόμενη αλλαγή επηρεάζει ακόμη περισσότερες λειτουργίες.

Μετά από αρκετές επαναλήψεις, δεν γνωρίζουμε πλέον ποια αλλαγή προκάλεσε ποιο πρόβλημα. Η εφαρμογή γίνεται πιο περίπλοκη και η αρχική αιτία του σφάλματος έχει χαθεί μέσα σε μια αλυσίδα διορθώσεων.

Η λύση δεν είναι να στείλουμε το ίδιο prompt πιο δυνατά ή να ζητήσουμε απλώς από το μοντέλο να προσπαθήσει ξανά.

Χρειάζεται να διαχωρίσουμε τη διάγνωση από τη διόρθωση.

Μια πιο συστηματική διαδικασία περιλαμβάνει πέντε βήματα:

  1. Observe: Παρατηρούμε το πρόβλημα και συλλέγουμε στοιχεία, όπως logs, μηνύματα σφάλματος και συμπτώματα.
  2. Diagnose: Ζητάμε από την AI να αναλύσει τα στοιχεία και να εντοπίσει πιθανές αιτίες, χωρίς να αλλάξει τον κώδικα.
  3. Hypothesis: Εξετάζουμε την προτεινόμενη αιτία και αξιολογούμε αν εξηγεί πραγματικά το πρόβλημα.
  4. Fix: Εφαρμόζουμε μία ελεγχόμενη αλλαγή, εστιάζοντας στην πιθανή αιτία.
  5. Test: Εκτελούμε ξανά τις δοκιμές και επιβεβαιώνουμε ότι το πρόβλημα λύθηκε χωρίς να δημιουργήθηκαν νέα.

Ένα χρήσιμο prompt για το στάδιο της διάγνωσης είναι:

Ανάλυσε τα παρακάτω logs και τον σχετικό κώδικα.
Μην τροποποιήσεις κανένα αρχείο και μην προτείνεις
ακόμη αλλαγές στον κώδικα.

Θέλω:
1. Να εντοπίσεις τις πιθανές αιτίες του προβλήματος.
2. Να εξηγήσεις ποια στοιχεία υποστηρίζουν κάθε υπόθεση.
3. Να αναφέρεις ποιες πρόσθετες πληροφορίες χρειάζεσαι
   για να επιβεβαιώσεις τη διάγνωση.

Μόνο αφού κατανοήσουμε το πρόβλημα περνάμε στη διόρθωση.

Αν το μοντέλο επαναλαμβάνει τα ίδια λάθη, ίσως χρειάζεται να αλλάξουμε στρατηγική: να ξεκινήσουμε μια νέα συνομιλία με καθαρό context, να συμβουλευτούμε την επίσημη τεκμηρίωση, να ζητήσουμε ανεξάρτητο code review ή να υλοποιήσουμε χειροκίνητα το κρίσιμο τμήμα του κώδικα.

Μάθε πότε να σταματάς και να επανεκτιμάς

Η επιμονή είναι χρήσιμη στον προγραμματισμό. Η ατέρμονη επανάληψη, όμως, δεν αποτελεί στρατηγική.

Υπάρχουν ορισμένα σημάδια που δείχνουν ότι πρέπει να σταματήσουμε και να επανεξετάσουμε την προσέγγισή μας:

  • Επαναλαμβανόμενα bugs: Η AI διορθώνει ένα πρόβλημα, αλλά μετά από λίγο εμφανίζεται ξανά το ίδιο.
  • Cascading failures: Μια διόρθωση προκαλεί προβλήματα σε άλλες λειτουργίες.
  • Αυξανόμενη πολυπλοκότητα: Ο κώδικας γίνεται όλο και πιο περίπλοκος χωρίς πραγματικό λόγο.
  • Απώλεια ελέγχου: Δεν μπορούμε πλέον να εξηγήσουμε με σαφήνεια τι άλλαξε και γιατί.

Σε αυτές τις περιπτώσεις, μπορούμε να επιλέξουμε μια διαφορετική προσέγγιση:

  • Να ξεκινήσουμε νέα συνομιλία με σαφή περιγραφή του προβλήματος και μόνο το απαραίτητο context.
  • Να συμβουλευτούμε την επίσημη τεκμηρίωση των τεχνολογιών που χρησιμοποιούμε.
  • Να ζητήσουμε ανεξάρτητη αξιολόγηση από διαφορετικό μοντέλο ή από άλλον developer.
  • Να γράψουμε χειροκίνητα το κρίσιμο τμήμα του κώδικα, όταν αυτό είναι ασφαλέστερο ή αποτελεσματικότερο.

Το ζητούμενο δεν είναι να κερδίσουμε μια διαφωνία με το μοντέλο. Είναι να λύσουμε το πραγματικό πρόβλημα με τον μικρότερο δυνατό κίνδυνο.

Ένα workflow που αξίζει να υιοθετήσεις

Οι παραπάνω πρακτικές μπορούν να συνδυαστούν σε μια απλή, επαναλαμβανόμενη διαδικασία. Δεν έχει σημασία αν αναπτύσσουμε μια μικρή προσωπική εφαρμογή ή ένα σύνθετο σύστημα για παραγωγική χρήση. Η βασική λογική παραμένει η ίδια.

  1. Σχεδίασε: Καθόρισε την απαίτηση, τον στόχο και τα κριτήρια αποδοχής.
  2. Συμφώνησε το πλάνο: Ζήτησε από την AI να παρουσιάσει την προτεινόμενη υλοποίηση και έλεγξε τις υποθέσεις της.
  3. Υλοποίησε μικρά βήματα: Εργάσου σε μία λειτουργία κάθε φορά, αποφεύγοντας τις τεράστιες αλλαγές.
  4. Έλεγξε τις αλλαγές: Εξέτασε το diff, χρησιμοποίησε Git και κάνε code review.
  5. Επαλήθευσε: Εκτέλεσε tests, ελέγχους ασφαλείας και δοκίμασε την πραγματική συμπεριφορά της εφαρμογής.
  6. Κάνε release και μάθε: Τεκμηρίωσε τις αλλαγές, συγκέντρωσε feedback και χρησιμοποίησε τα συμπεράσματα για την επόμενη έκδοση.

Η διαδικασία αυτή δημιουργεί έναν κύκλο ανάπτυξης στον οποίο η τεχνητή νοημοσύνη αναλαμβάνει να επιταχύνει συγκεκριμένες εργασίες, ενώ ο άνθρωπος διατηρεί τον έλεγχο της κατεύθυνσης, της ποιότητας και του τελικού αποτελέσματος.

Τι σημαίνουν όλα αυτά για όσους δεν είναι developers;

Ίσως κάποιος αναρωτηθεί: «Όλα αυτά αφορούν τους προγραμματιστές. Γιατί να με ενδιαφέρουν αν δεν γράφω κώδικα;»

Η απάντηση είναι ότι η τεχνητή νοημοσύνη κάνει πλέον την ανάπτυξη εφαρμογών προσβάσιμη σε πολύ περισσότερους ανθρώπους. Ένας επαγγελματίας, ένας φοιτητής, ένας εκπαιδευτικός ή κάποιος που έχει μια επιχειρηματική ιδέα μπορεί να δημιουργήσει ένα πρωτότυπο χωρίς να γνωρίζει σε βάθος μια γλώσσα προγραμματισμού.

Αυτό είναι θετικό. Μειώνει τα εμπόδια για τη δημιουργία και επιτρέπει σε περισσότερους ανθρώπους να πειραματιστούν με τις ιδέες τους.

Υπάρχει, όμως, μια σημαντική διαφορά ανάμεσα στο να δημιουργήσεις κάτι που φαίνεται να λειτουργεί και στο να δημιουργήσεις κάτι που μπορείς να εμπιστευτείς.

Αν χρησιμοποιείς μια εφαρμογή που δημιουργήθηκε με τη βοήθεια AI, είναι χρήσιμο να αναρωτηθείς:

  • Ποιος έχει ελέγξει τον κώδικα;
  • Πού αποθηκεύονται τα δεδομένα μου;
  • Ποιος μπορεί να αποκτήσει πρόσβαση σε αυτά;
  • Υπάρχει διαδικασία δημιουργίας αντιγράφων ασφαλείας;
  • Ποιος θα διορθώσει ένα πρόβλημα αν εμφανιστεί;
  • Υπάρχει κάποιος υπεύθυνος για τη συντήρηση και την ασφάλεια της εφαρμογής;

Η ευκολία δημιουργίας μιας εφαρμογής δεν πρέπει να μας κάνει να ξεχνάμε τις απαιτήσεις που έχει κάθε λογισμικό το οποίο διαχειρίζεται πραγματικά δεδομένα και εξυπηρετεί πραγματικούς ανθρώπους.

Η τεχνητή νοημοσύνη και το μέλλον του ελεύθερου λογισμικού

Η τεχνητή νοημοσύνη μπορεί να αποτελέσει ένα σημαντικό εργαλείο για τις κοινότητες ελεύθερου λογισμικού.

Μπορεί να βοηθήσει στη δημιουργία τεκμηρίωσης, στη μετάφραση, στην ανάλυση αναφορών σφαλμάτων, στη συγγραφή tests και στην επιτάχυνση της υλοποίησης νέων λειτουργιών. Μπορεί επίσης να μειώσει το αρχικό εμπόδιο για ανθρώπους που θέλουν να συνεισφέρουν σε ένα project αλλά δεν έχουν ακόμη μεγάλη εμπειρία.

Αυτό, όμως, δεν σημαίνει ότι η ανθρώπινη συμμετοχή γίνεται λιγότερο σημαντική. Αντίθετα, όσο αυξάνεται η ποσότητα του παραγόμενου κώδικα, τόσο μεγαλύτερη σημασία αποκτούν η αξιολόγηση, η τεκμηρίωση, η συντήρηση και η υπεύθυνη λήψη αποφάσεων.

Επίσης, η χρήση ενός εργαλείου AI δεν καθιστά αυτομάτως ένα έργο ελεύθερο λογισμικό. Η άδεια χρήσης, η διαφάνεια, η δυνατότητα μελέτης, τροποποίησης και αναδιανομής του λογισμικού εξακολουθούν να έχουν τη δική τους σημασία. Η χρήση τεχνητής νοημοσύνης και η επιλογή μιας άδειας ανοικτού κώδικα είναι δύο διαφορετικά ζητήματα.

Το μέλλον του open source δεν θα εξαρτηθεί μόνο από το πόσο γρήγορα μπορούμε να παράγουμε κώδικα. Θα εξαρτηθεί και από το αν θα συνεχίσουμε να χτίζουμε υγιείς κοινότητες, να μοιραζόμαστε γνώση και να αναλαμβάνουμε την ευθύνη για τα έργα μας.

Ο στόχος δεν είναι να γράφουμε περισσότερο κώδικα

Η τεχνητή νοημοσύνη αλλάζει τον τρόπο με τον οποίο δημιουργούμε λογισμικό. Μας δίνει τη δυνατότητα να πειραματιζόμαστε γρηγορότερα, να υλοποιούμε ιδέες με λιγότερη προσπάθεια και να αυτοματοποιούμε εργασίες που μέχρι πρόσφατα απαιτούσαν αρκετό χρόνο.

Αυτή η αλλαγή είναι σημαντική και αξίζει να την αξιοποιήσουμε.

Δεν πρέπει, όμως, να συγχέουμε την ταχύτητα παραγωγής με την ποιότητα. Δεν πρέπει να θεωρούμε ότι ένα επιτυχημένο demo ισοδυναμεί με ένα αξιόπιστο προϊόν. Και δεν πρέπει να ξεχνάμε ότι πίσω από κάθε εφαρμογή υπάρχουν άνθρωποι που τη σχεδιάζουν, τη χρησιμοποιούν, την ελέγχουν και τη συντηρούν.

Αν είσαι developer, χρησιμοποίησε την AI ως συνεργάτη που επιταχύνει τη δουλειά σου, αλλά κράτησε τον έλεγχο των αποφάσεων. Σχεδίασε πριν υλοποιήσεις, δώσε σωστό context, έλεγξε τις αλλαγές, γράψε tests και αντιμετώπισε την ασφάλεια ως βασική απαίτηση.

Αν δεν είσαι developer, αξιοποίησε τις νέες δυνατότητες, αλλά μην ξεχνάς να εξετάζεις την αξιοπιστία και την ασφάλεια των εφαρμογών που χρησιμοποιείς ή δημιουργείς.

Και, ανεξάρτητα από τον ρόλο μας, ας θυμόμαστε κάτι ακόμη: η προσφορά στο ελεύθερο λογισμικό είναι μαραθώνιος, όχι αγώνας ταχύτητας. Τα διαλείμματα, τα όρια και η συνεργασία είναι απαραίτητα για να μπορούμε να συνεχίσουμε.

Ο στόχος δεν είναι να γράφουμε περισσότερο κώδικα σε λιγότερο χρόνο. Είναι να δημιουργούμε περισσότερο χρήσιμο και αξιόπιστο λογισμικό, με καλύτερη ποιότητα και με ανθρώπους που μπορούν να συνεχίσουν να προσφέρουν.


Το άρθρο βασίζεται στην παρουσίαση «Code, Community & AI – Ποιος θα συντηρεί τον κώδικα όταν τελειώσει η μαγεία;».

Δημοσίευση σχολίου

0 Σχόλια