Il mio generatore di curriculum
Perché l’ho creato
Da molto tempo sono utilizzatore con discreta soddisfazione della piattaforma per generare CV Europass, che peraltro si è evoluta. Benché il pensare comune (specialmente lato HR) sia “EUROPASS CACCA!” la trovavo una soluzione abbastanza intelligente: hai sempre i dati sincronizzati, c’è uno schema preciso, il PDF finale è tutto sommato ben fatto, hai diversi stili da scegliere. Mi piacerebbe intrattenere un dialogo per capire quali sono le reali motivazioni dell’odio verso i CV Europass, ma credo sia dogmatico e a me i dogmi piacciono molto poco.
Ad ogni modo, negli ultimi tempi l’utilizzo del sito di Europass è diventato più problematico (serve un “login nazionale”, eID, wtf?, la gestione multilingua è farraginosa, i PDF vengono peggio, etc.) e quindi mi sono deciso a rimettere mano al mio CV in maniera più intelligente e personale. Mi sono quindi documentato e ho capito che si poteva fare qualcosa di più soddisfacente per uno smanettone come me. Inoltre, mi andava di farlo dall’inizio alla fine con Claude Code, senza toccare una riga di codice, costruendo una soluzione vera.
L’obiettivo era semplice:
- Versionamento dei dati - voglio tracciare le modifiche ai dati come codice, quindi file JSON
- Build riproducibili - lo stesso input dà sempre lo stesso output
- Multilingua - ho bisogno sia dell’inglese che dell’italiano
- Aspetto professionale - qualità LaTeX, non qualità Word/PDF autogenerati
- Automazione - voglio poter generare facilmente nuovi CV, customizzati per vari motivi, e voglio averli sempre disponibili
Lavorare con Claude Code
Questo progetto è stato un ottimo modo per testare le capacità di Claude Code.
Ho però incominciato scrivendo qualcosa su Claude, per farmi un’idea migliore anch’io di alcuni dettagli. Il primo prompt è stato, semplificando, qualcosa del genere:
Hey, i’d like to build up a github repository that can automatically create different versions of my resume. It should be based on CV data (say, JSON format), a Latex template and a github action that can be able to create a PDF artifacts in different languages for each branch. Can you help me with that? Do you need further details?
Quindi, Claude mi ha risposto con delle soluzioni e un po’ di altre domande per dirimere alcuni dubbi. Altro giro, altra corsa, ho fugato i suoi dubbi e gli ho chiesto di generarmi una specifica utile per sviluppare con Claude Code.
A questo punto mi sono spostato su VS Code e ho incominciato a chiedere a Claude Code di sviluppare seguendo le specifiche. Già dopo pochissimi trial-and-error loop avevo una soluzione funzionante con:
- Il mio JSON multilingua contenente i dati presi dal mio CV esistente in PDF
- Un template LaTeX: mi sono ispirato a Awesome CV
- Uno script Python per prendere i dati del CV e creare un PDF usando il template LaTeX
- Un Dockerfile che installa sulla base image tutti i tool necessari alla generazione del PDF
- La Github action per generare automaticamente il PDF su tag (con release) e su branch (con artifact)
Ogni passaggio ha prodotto risultati tangibili. Claude Code produce i cambiamenti/suggerimenti, facevo una review, e lui automaticamente lancia i comandi per testare il tutto (esclusa la pipeline CI-CD).
Lo stack tecnologico
Docker per la riproducibilità
Le installazioni LaTeX sono complicate. Computer diversi hanno distribuzioni TeX diverse, pacchetti mancanti, problemi con i font. È difficile ottenere output consistenti.
Con Docker cerchiamo di risolvere questo rendendo le build pressoché deterministiche:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
texlive-latex-base \
texlive-latex-extra \
texlive-xetex \
texlive-fonts-recommended \
texlive-fonts-extra \
python3 \
python3-yaml \
fonts-font-awesome \
wget
Nota bene: è stato necessario un giro di ottimizzazione delle performance eliminando una serie di packages molto grandi (~5Gb) che fondamentalmente non servivano a nulla. Claude tende a essere “generoso” essendo molto zelante se non specifichi il contrario. L’ottimizzazione l’ho comunque chiesta a lui: “puoi fare in modo che le build non siano così lente?”. Mi ha suggerito di eliminare i pacchetti inutili e di lavorare col caching sulla pipeline. Ottimo!
Python per l’elaborazione
Lo script del generatore è semplice Python - nessun framework, solo libreria standard più PyYAML. Fa alcune cose:
- Legge il formato JSONResume
- Formatta le date
- Escapa i caratteri speciali LaTeX
- Gestisce le lingue
- Esegue il comando di generazione PDF
Onestamente Python non è il mio linguaggio, ma anche se il codice non sarà ottimizzato e idiomatico (lo ignoro) fa quello che deve fare, è molto comprensibile e funziona. Chiaramente è codice sviluppato per fare quello che devo fare io, non per gestire eventualmente altre lingue o chissà quali casistiche che non esistono né probabilmente mai esisteranno. Non risolvere problemi che non sai di avere ;)
LaTeX per output di qualità
Ho scelto il template LaTeX Awesome-CV. Ha un aspetto chiaro, moderno e professionale. Ho fatto solo alcune modifiche.
Il template ha placeholder che Python sostituisce:
\name{{{NAME}}}{}
\position{{{TITLE}}}
\email{{{EMAIL}}}
\linkedin{{{LINKEDIN}}}
GitHub Actions lo rende automatico
Ogni volta che faccio push del codice, GitHub Actions:
- Costruisce l’immagine Docker (con caching)
- Genera PDF per tutte le lingue
- Li carica come artifact (conservati per 90 giorni)
Quando creo un tag, crea anche una release con i PDF allegati. Questo è utile per gestire varie candidature con diversi CV - posso taggare versioni come v2024-company-X e avere tener traccia di ciò che ho inviato.
La configurazione di caching rende le build veloci:
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
tags: my-resume-generator:latest
load: true
cache-from: type=gha
cache-to: type=gha,mode=max
Vado quindi a riutilizzare i layer Docker tra le esecuzioni. Prima build: ~2 minuti. Dopo: 30-60 secondi. I pacchetti TeX rimangono in cache.
L’evoluzione verso JSONResume
All’inizio, ho semplicemente creato la mia struttura JSON. Qualcosa tipo:
{
"personal": { "name": "...", "email": "..." },
"experience": [...],
"skills": [...]
}
Ok, funzionava. Lo script leggeva il JSON, generava LaTeX, compilava in PDF.
Ma poi ho pensato: “Ma davvero nessuno si è inventato uno standard anche per questa cosa?” e ho scoperto JSONResume. È uno standard aperto che già esiste, con:
- Uno schema appropriato che copre tutto
- Strumenti di validazione
- Altri temi e strumenti che possono leggerlo
- Date ISO 8601 (formato data corretto)
- Una comunità che lo mantiene
Così, in pochi minuti, con Claude Code a convertire tutto nel formato JSONResume. Lo script necessitava di aggiornamenti per leggere la nuova struttura (basics invece di personal, oggetto location annidato, ecc.), ma è tutto ben funzionante.
Se domani decidessi usare uno strumento o un tema diverso, posso. I dati non sono vincolati al mio generatore, e ci sono altri generatori e template che posso usare senza problemi.
Il risultato
Dopo alcune ore di lavoro ho:
- Dati del curriculum con controllo versione in formato standard
- PDF dall’aspetto professionale che sono consistenti ovunque
- Build automatiche ad ogni modifica
- Supporto multilingua (inglese e italiano)
- Release taggate per candidature
- Build veloci con caching Docker
Tutto in un repository. Per aggiornare il mio curriculum: modifico il JSON, faccio push, eventualmente taggo, aspetto che finisca la pipeline, scarico il PDF. Fatto.
Pensieri finali
In mezza giornata ho ottenuto qualcosa di funzionante e utile ai miei scopi. Ho imparato qualcosa di nuovo, mi sono divertito a farlo e ora posso generare curriculum senza che mi venga voglia di piangere. Ma poi… quanto è stato divertente smanettare senza pensieri!? ;)
Il codice completo è qui: my-resume-generator