-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 5 Localization el
Στόχος: κατανόησε πώς το LockedIn CLI μιλάει 33 γλώσσες — και εξασκήσου στο να καθοδηγείς έναν πράκτορα να προσθέσει άλλη μία. Η τοπικοποίηση είναι μια φανταστική εργασία για πράκτορα: είναι αρκετά μηχανική για να ανατεθεί, αλλά έχει πραγματικούς περιορισμούς (μια πύλη ελέγχου, κανόνες διάταξης, γραμματικό έλεγχο) που σε διδάσκουν να ελέγχεις.
← Προηγούμενο: Μάθημα 4 Prompting και έλεγχος · Πίσω στην Αρχική
Τρέξε το CLI στα Ισπανικά, Χίντι, Ιαπωνικά, Απλοποιημένα Κινέζικα, ή σε οποιαδήποτε γλώσσα διατίθεται και όλα αλλάζουν — η εναρκτήρια οθόνη, ο πίνακας βοήθειας, η έξοδος κάθε εντολής, η συνεδρία συνομιλίας, ακόμα και τα νομικά ψιλά γράμματα. Όχι μόνο τα αστεία: όλη η ορατή επιφάνεια.
lockedin --lang el post
LOCKEDIN_LANG=hi lockedin
lockedin --lang zh auraΗ γλώσσα αυτοανιχνεύεται κατά την εκκίνηση, επιλύεται με σειρά προτεραιότητας:
- η σημαία
--lang(--lang el,--lang=fr,-l ja) - η μεταβλητή περιβάλλοντος
LOCKEDIN_LANG - το locale σου (
LC_ALL/LC_MESSAGES/LANG, μετά το locale του OS/runtime) - τα Αγγλικά, ως εφεδρεία
Η normalizeLang() κανονικά χρησιμοποιεί το κύριο subtag του locale. Αυτό σημαίνει
ότι το de-DE επιλέγει de, αλλά το tlh δεν γίνεται κατά λάθος tl· τα
πραγματικά ψευδώνυμα fil και tgl σκόπιμα αντιστοιχίζονται στα Ταγκαλόγκ
(tl), τα Νορβηγικά nb και nn αντιστοιχίζονται στο no, το παλαιό
Ινδονησιακό in αντιστοιχίζεται στο id, και το παλαιό Εβραϊκό iw
αντιστοιχίζεται στο he. Δύο περιφερειακοί κωδικοί διατηρούνται αυτούσιοι αντί να
πτυχθούν στο κύριο subtag τους: τα pt-BR/pt_BR επιλέγουν τον κανονικό
περιφερειακό κωδικό ενώ το γενικό pt παραμένει το προς-τα-πίσω-συμβατό bundle
Πορτογαλικών Βραζιλίας (και τα δύο είναι Πορτογαλικά Βραζιλίας και μοιράζονται τα
ίδια pools/UI), και τα en-SG/en_SG κρατούν τα Singlish (το γενικό en
παραμένει Αγγλικά). Τα Παραδοσιακά Κινέζικα Χονγκ Κονγκ είναι το ίδιο είδος
εξαίρεσης:
τα zh-HK, zh_HK.UTF-8 και zh-Hant-HK επιλέγουν zh-HK, ενώ το γενικό zh
και οι ηπειρωτικές ετικέτες επιλέγουν Απλοποιημένα Κινέζικα (zh).
Εναλλαγή εν πτήσει — ο πίνακας /language. Το CLI μπορούσε πάντα να ξεκινά
σε άλλη γλώσσα (--lang, LOCKEDIN_LANG)· τώρα μπορείς να αλλάζεις μέσα στη
συνεδρία. Πληκτρολόγησε /language (ψευδώνυμα /lang και /languages) για να
δεις όλες τις 33 γλώσσες κατά κωδικό, καθεμία στο δικό της script· το
/language el αλλάζει για την υπόλοιπη συνεδρία. Το νόημα είναι η έξοδος διαφυγής: μετά από
μια εναλλαγή, ξανασχεδιάζει στη νέα γλώσσα και μετά, στη γλώσσα που μόλις
άφησες, τυπώνει τον ακριβή δρόμο επιστροφής — /language en τώρα,
lockedin --lang en την επόμενη φορά — ώστε αν προσγειωθείς κατά λάθος στο 日本語 ή στο
ಕನ್ನಡ να μη μείνεις ποτέ αποκλεισμένος/η. (Άλλαξε δύο φορές και προσφέρεται και
η γλώσσα που ονομάζει το LOCKEDIN_LANG σου.) Τα --lang και LOCKEDIN_LANG
μένουν αμετάβλητα. Όπως το /a11y, είναι μια ειλικρινής χρησιμότητα, όχι μέρος
της σάτιρας.
Όλο το μεταφράσιμο κείμενο ζει σε bundles, ένα ανά γλώσσα, καθένα με σχήμα σαν:
{ meta: { lang: 'el', name: 'Ελληνικά', dir: 'ltr' },
pools: { HOOKS: [ /* ~25 */ ], LESSONS: [ /* ... */ ], /* ... */ },
ui: { buzzwordDensity: 'Πυκνότητα buzzwords: ', /* labels, headings */ } }- Τα
poolsείναι οι πίνακες περιεχομένου (τα αστεία) που γνώρισες στο Κεφάλαιο 2. - Το
uiείναι τα strings του chrome: labels, επικεφαλίδες και μικρά πρότυπα.
Τα Αγγλικά είναι το bundle αναφοράς μέσα στο src/lockedin.js· τα άλλα 32 bundle
modules ζουν στο src/content/*.js: ar, bn, bo, de, el, en-SG, es,
eu, fa, fi, fr, he, hi, id, is, it, ja, kn, ms, nl,
no, pl, pt, pt-BR, ru, sv, tl, tr, uk, ur, zh, και zh-HK
(το pt-BR επαναχρησιμοποιεί τα pools/UI του pt αλλά καταχωρείται ξεχωριστά).
Καθένα καταχωρείται στο BUNDLES· το SUPPORTED_LANGS παράγεται από αυτά τα
κλειδιά, και η renderHelp() τυπώνει αυτή την παραγόμενη λίστα κωδικών. Κανένα UI
bundle δεν κάνει hard-code τη λίστα.
setLang('fr'); // στρέψε την ενεργή γλώσσα στο γαλλικό bundle
// L = ενεργά pools, U = ενεργό ui
pick(L.HOOKS) // ένα γαλλικό hook
U.buzzwordDensity // "Densité de jargon : "Επειδή κάθε γεννήτρια διαβάζει το L και το U (ποτέ ένα hardcoded string),
το setLang και μόνο αλλάζει όλη την εμπειρία. Αυτό είναι όλο το κόλπο.
Εδώ είναι το αναλλοίωτο που κάνει ασφαλή την προσθήκη μιας γλώσσας:
Κάθε bundle πρέπει να εκθέτει ακριβώς τα ίδια κλειδιά
poolsκαιuiμε τα Αγγλικά.
Ένα test το επιβάλλει σε όλα τα 33 bundles. Αν προσθέσεις ένα νέο UI string στα
Αγγλικά και ξεχάσεις να το μεταφράσεις στα Ουκρανικά, το npm test γίνεται
κόκκινο και σου λέει ποιο κλειδί λείπει. Δεν μπορείς να δημοσιεύσεις σιωπηλά μια
μισομεταφρασμένη γλώσσα.
Οι γλώσσες πιέζουν τη διάταξη του terminal με διαφορετικούς τρόπους:
- Τα Ιαπωνικά, τα Απλοποιημένα Κινέζικα και τα Παραδοσιακά Κινέζικα Χονγκ
Κονγκ χρησιμοποιούν χαρακτήρες East Asian Wide / Fullwidth.
Το
vw()τους μετρά ως δύο στήλες, και τοwrap()σπάει σκληρά μακριά tokens χωρίς κενά ώστε το κείμενο CJK να μένει μέσα σε κάρτες και πλαίσια. - Τα Χίντι και Κανάντα χρησιμοποιούν συνδυαστικά σημάδια χωρίς διάστημα/που
περικλείουν (
Mn/Me), όπως matras και viramas. Τοvw()τα μετρά ως μηδέν στήλες ώστε να μη φουσκώνουν το μετρημένο πλάτος. - Το
box()αναδιπλώνει κάθε γραμμή σώματος πριν την κάνει padding, ώστε ένα μακρύ μεταφρασμένο banner να μην μπορεί πλέον να διαπεράσει το περίγραμμα. - Κάθε bundle ορίζει
sentenceEndκαιlistSep(για παράδειγμα./。,,/、) ώστε οι προτάσεις που συνθέτει η γεννήτρια να διαβάζονται φυσικά.
Όταν προσθέτεις μια γλώσσα, τα strings επικεφαλίδας κάρτας (cardSubtitle,
cardMeta, cardFooter) πρέπει ακόμα να χωρούν σε ≤ 60 ορατές στήλες. Τα
Αραβικά, Περσικά, Εβραϊκά και Ουρντού ορίζουν meta.dir: 'rtl'. Η έξοδος δεν
περιέχει bidi controls από προεπιλογή, γιατί μερικά terminals τα αποδίδουν ως
labels σε πλαίσια. Το LOCKEDIN_BIDI=on ενεργοποιεί ρητά ισορροπημένα isolates
μετά την αναδίπλωση για terminals γνωστά ότι τα υποστηρίζουν, διατηρώντας το ANSI,
τις εντολές ASCII, και τη λογική σειρά αντιγραφής/επικόλλησης. Η προσβάσιμη έξοδος
πάντα αφαιρεί αυτά τα controls. Χωρίς την προαιρετική ενεργοποίηση, η μεικτή σειρά
RTL/LTR μπορεί να είναι λιγότερο εξελιγμένη· ποτέ μην ανιχνεύεις ή συμπεραίνεις
υποστήριξη.
Ορισμένα πρότυπα UI μπολιάζουν ακατέργαστες προτάσεις χρήστη με placeholders όπως
{cap}. Μην τα μεταφράζεις θέση-προς-θέση. Η πρόταση πρέπει να παραμένει γραμματική
όταν το placeholder είναι μια φράση που πληκτρολόγησε ο χρήστης, όχι ένα καθαρό
ουσιαστικό.
Ένα πραγματικό προειδοποιητικό bug: τα ιαπωνικά πρότυπα που βάζουν は αμέσως
μετά το {cap} μπορούν να ακούγονται λάθος όταν το {cap} είναι μια πλήρης
πρόταση. Η διόρθωση δεν είναι «μετάφρασε πιο σκληρά»· είναι να αναδομήσεις το
πρότυπο (για παράδειγμα, πρόσθεσε έναν ονοματοποιητή ή μετακίνησε το placeholder)
ώστε η αυθαίρετη είσοδος χρήστη να ταιριάζει ακόμα.
Αυτή η άσκηση λειτουργεί ακόμα με ακριβώς τον ίδιο τρόπο. Διάλεξε μια γλώσσα που μπορείς να ελέγξεις για λογική (ή ζήτα από τον πράκτορα), και οδήγησέ την από άκρη σε άκρη. Γράψε πρώτα την προδιαγραφή:
Πρόσθεσε Δανικά (
da). Δημιούργησε τοsrc/content/da.jsως ένα bundle{ meta, pools, ui }με τα ίδια κλειδιά με τα Αγγλικά, μεταφράζοντας κάθε εγγραφή (pools περιεχομένου ~25 το καθένα, όλα τα UI strings). Καταχώρησε τοdaστοBUNDLESστοsrc/lockedin.js. Τα--lang daκαι ένα localeda-*πρέπει να το επιλέγουν. Κράτα τα strings επικεφαλίδας κάρτας εντός του ορίου πλάτους. Τοnpm testπρέπει να μένει πράσινο, και πρόσθεσε αναλλοίωτα + tests ανίχνευσης για τα Δανικά που καθρεφτίζουν τα υπάρχοντα τοπικοποιημένα.
Μετά τρέξε τον βρόχο από τα Κεφάλαια 3–4:
- Πλάνο πρώτα. «Πριν γράψεις κώδικα, πες μου τα αρχεία που θα αλλάξεις και πώς θα κρατήσεις ισοτιμία κλειδιών με τα Αγγλικά.»
-
Tests πρώτα. «Πρόσθεσε tests που αποτυγχάνουν: ανίχνευση
da, ισοτιμία κλειδιών γιαda, και ένα δανικό αναλλοίωτο reflect/connect. Μη δημιουργήσεις ακόμα το bundle.» -
Υλοποίηση. «Τώρα δημιούργησε το
src/content/da.jsμεταφράζοντας ένα υπάρχον bundle κλειδί-προς-κλειδί, καταχώρησέ το, και κάνε τα tests να περνούν. Μόνοpick/shuffleγια την τυχαιότητα.» -
Πύλη + έλεγχος.
npm test, μετάlockedin --lang da post— και διάβασε το diff: μεταφράστηκε κάθε κλειδί; Ευθυγραμμίζονται ακόμα τα περιγράμματα των καρτών; Επιβιώνουν τα πρότυπα με{cap}σε ακατέργαστες προτάσεις χρήστη;
Μικρότερες ασκήσεις προθέρμανσης αν μια ολόκληρη γλώσσα είναι υπερβολή:
- «Πρόσθεσε άλλο ένα
TAGLINEσε όλα τα 33 γλωσσικά bundles, κρατώντας τους αριθμούς ίσους.» - «Έλεγξε αν το
cardFooterτων Κανάντα είναι ≤ 60 ορατές στήλες και εξήγησε πώς μετρήθηκαν τα συνδυαστικά σημάδια.» - «Δείξε μου το test που θα αποτύγχανε αν διέγραφα ένα κλειδί
uiαπό τοja.js.»
- Ξεφύλλισε το
src/content/es.js— παραμένει ένα φιλικό πρότυπο για ένα νέο bundle. - Ξαναδιάβασε το
docs/HANDOFF.md→ «Adding a language». - Απόλαυσε τα πολύγλωσσα αστεία στην Αναφορά εντολών.
Αυτό είναι το πλήρες μάθημα. Μπορείς πλέον να καθοδηγείς έναν πράκτορα AI ώστε να χτίζει χαρακτηριστικά και να τα τοπικοποιεί πίσω από μια πύλη ελέγχου — σε 33 γλώσσες και έτοιμος για περισσότερες. Συμφωνείς; 👇
Tutorial
- 1 · Orientation
- 2 · How the Code Works
- 3 · Your First Agent Task
- 4 · Prompting & Reviewing
- 5 · Localization
Reference
Satire · Sátira · 風刺. Not affiliated with LinkedIn. GPL-3.0-or-later.