cv-optimization
Analyse, optimisation de CV + création de lettres de présentation PDF pour postes ciblés (marché Québec). Organisation par dossier d'offre.
Quand l'utiliser (Trigger)
Déclenchement standard selon le contexte de l'écosystème Hermès.
Mode d'emploi (Usage)
Mode d'emploi standard via l'agent Hermès. CV Optimisation
Analyse de profil professionnel et création de CV sur-mesure pour maximiser les chances de candidature à des postes ciblés.
Workflow
1. Analyse du profil source
Extraire le profil complet du candidat depuis son CV, son LinkedIn, ou ses informations fournies :
- Identité, coordonnées, statut (citoyen, permis)
- Formations et certifications (dates, établissements)
- Expérience professionnelle (dates, responsabilités, résultats mesurables)
- Compétences techniques et personnelles
- Langues, intérêts, objectif de carrière
- Résultats chiffrés : disponibilité (99.99%), missions (198), réductions (-40% temps), etc.
2. Recherche du marché cible
Pour chaque type de poste visé :
- Interroger le marché via
web_search: offres d’emploi, compétences requises, mots-clés - Identifier les compétences transférables entre l’expérience du candidat et le poste cible
- Noter les certifications, formations et outils spécifiques au secteur
3. Création de chaque version CV
Pour chaque version, adapter STRATÉGIQUEMENT :
Profil / Objectif de carrière — réécrire complètement pour chaque cible :
- Mots-clés du secteur (LCB-FT, AML, KYC, SOC, OSINT, etc.)
- Angle unique du candidat (ex: “21 ans militaire = rigueur + discipline + gestion crise”)
Compétences clés — reformuler systématiquement :
- Reprendre les mêmes compétences techniques mais avec le vocabulaire de la cible
- Ajouter les qualités personnelles alignées sur le secteur
Expérience professionnelle — NE PAS inventer, MAIS :
- Changer l’angle de présentation des mêmes faits
- Mettre en avant les aspects pertinents pour la cible
- Reformuler les réalisations avec le vocabulaire du secteur
- Conserver tous les chiffres et résultats mesurables
Règles strictes :
- Longueur max : 2 pages (3 pour profils très seniors)
- Format français du Québec (orthographe, expressions)
- Structure sobre et professionnelle
- Résultats mesurables en évidence
- Section “Objectif de carrière” adaptée à chaque cible
4. Conversion en PDF — CVs
Convertir chaque CV en format PDF professionnel (format lettre canadien).
Option A : weasyprint (recommandé)
import markdown
import weasyprint
md_text = Path("cv.md").read_text(encoding="utf-8")
html_body = markdown.markdown(md_text, extensions=['extra'])
html = f'''<!DOCTYPE html>
<html lang="fr">
<head><meta charset="utf-8">
<style>
@page {{ margin: 2.5cm 2cm; size: letter; }}
body {{ font-family: 'DejaVu Serif', Georgia, serif; font-size: 11pt; line-height: 1.6; color: #1a1a1a; }}
h1 {{ font-size: 16pt; margin-top: 0; color: #1a3a5c; }}
h2 {{ font-size: 13pt; color: #2a5a8c; }}
p {{ margin: 0.5em 0; text-align: justify; }}
</style></head>
<body>
{html_body}
</body>
</html>'''
doc = weasyprint.HTML(string=html).render()
doc.write_pdf("output.pdf")
Installation : uv pip install weasyprint markdown
Option B : fpdf2 (fallback)
from fpdf import FPDF
from fpdf.enums import XPos, YPos
FONT_DIR = "/usr/share/fonts/truetype/liberation"
pdf = FPDF(format='LETTER')
pdf.add_font('Sans', '', os.path.join(FONT_DIR, 'LiberationSans-Regular.ttf'))
pdf.add_font('Sans', 'B', os.path.join(FONT_DIR, 'LiberationSans-Bold.ttf'))
5. Lettres de présentation — création et organisation
Pour chaque offre pertinente, créer une lettre de présentation personnalisée.
5.1 Extraction des détails de l’offre (API Québec)
curl -s "https://emplois.carrieres.gouv.qc.ca/search/posting/{ID}/fr" \
-H "User-Agent: Mozilla/5.0" -H "Accept: application/json"
Parser via le tableau data.section[] (l’API a migré des champs plats vers section[]) :
section = data.get('data', {}).get('section', [])
fields = {item['id']: item.get('content', '') for item in section}
Section IDs utiles : titrePoste, dateLimite, ministereOrganisme, descriptionActivite, profilRecherche, conditionsTravail, corpsEmploiClasse, adressesLieuTravail.
5.2 Structure du dossier par offre
cv_versions/
└── {org}/ ← sq/, mcn/, jb/, aut/
└── {OFFRE-ID}/ ← SQ-14839/, MCN-14427/
├── lettre-motivation.pdf ✅ PDF prêt à joindre
├── lettre-motivation.md ✅ Source modifiable
└── details-offre.md ✅ Lien, échéance, notes
Chaque dossier est autonome — toute l’info d’une candidature est au même endroit.
5.3 Personnalisation de la lettre
Adapter la lettre pour chaque offre en mettant en avant les compétences pertinentes. Utiliser le modèle templates/lettre-motivation-html.html comme base de conversion PDF.
5.4 Conversion MD → PDF avec weasyprint (batch)
# Un coup pour tout convertir
cd ~/cv_versions
python3 /home/bf/.hermes/skills/career/cv-optimization/scripts/batch-convert-letters.py
Pour une conversion individuelle :
uv pip install weasyprint markdown
import markdown, weasyprint
from pathlib import Path
def md_to_pdf(md_path: Path, pdf_path: Path):
content = md_path.read_text(encoding="utf-8")
body = markdown.markdown(content, extensions=['extra'])
html = f'''<!DOCTYPE html>
<html lang="fr">
<head><meta charset="utf-8">
<style>
@page {{ margin: 2.5cm 2cm; size: letter; }}
body {{ font-family: 'DejaVu Serif', Georgia, serif; font-size: 11pt; line-height: 1.6; }}
h1 {{ font-size: 16pt; color: #1a3a5c; }}
h2 {{ font-size: 13pt; color: #2a5a8c; }}
p {{ margin: 0.5em 0; text-align: justify; }}
strong {{ color: #1a3a5c; }}
</style></head>
<body>
{body}
</body>
</html>'''
doc = weasyprint.HTML(string=html).render()
doc.write_pdf(str(pdf_path))
5.5 Nettoyage et organisation
Après création des lettres et conversion PDF, nettoyer le répertoire racine :
# 1. Déplacer les fichiers PDF racine dans leurs dossiers
# (lettre_soutien_pol_multiregions.pdf → sq/SQ-14839/)
# 2. Déplacer les versions .old dans archives/
# 3. Ne pas supprimer le script de conversion s'il y en a un
Vérifier qu’il ne reste plus de fichiers orphelins :
find ~/cv_versions -maxdepth 1 -type f | grep -v "convert.*\.py$"
# Devrait retourner 0 fichiers
5.6 Mise à jour du tracker
Maintenir candidature_tracker.md avec les statuts :
🔴 À postuler → 🟡 En préparation → 🟢 Soumis → 🔵 Entrevue → ✅ Accepté / ❌ Refusé
Scripts
cv_versions/convert_to_pdf.py — Conversion MD → PDF
Chemin : ~/.hermes/cv_versions/convert_to_pdf.py
Convertit des CV en format Markdown vers PDF format lettre canadien avec LiberationSans.
Références
references/employeurs-cibles-canada.md— Recensement des organisations canadiennes qui recrutent des analystes fraude, avec ATS, mode de travail et liens carrière.references/nouveau-portail-plateforme-emploi.md— Détails du portail gouvernemental d’emploi.references/mots-cles-par-secteur.md— Mots-clés ATS par secteur d’emploi (absorbé de cv-tailoring-quebec).references/tailoring-quebec.md— Guide d’adaptation CV pour le marché québécois multi-cibles (absorbé de cv-tailoring-quebec).references/creation-cv-workflow.md— Workflow de création de CV markdown→PDF multi-versions (absorbé de creation-cv).templates/lettre-motivation-html.html— Template HTML de lettre de présentation.scripts/convert_cv_to_pdf.py— Conversion MD→PDF principal.scripts/convert_cv_to_pdf_v3.py— Variante avec mots-clés ATS (absorbé de cv-tailoring-quebec).scripts/convert_to_pdf_v2.py— Variante de conversion (absorbé de creation-cv).scripts/batch-convert-letters.py— Conversion batch de plusieurs lettres.
Pitfalls
- weasyprint disponible :
uv pip install weasyprint markdownfonctionne (installe ses propres dépendances). Produit un rendu typographique de qualité avec DejaVu Serif pour les lettres et CVs. Privilégier weasyprint sur fpdf2. - fpdf2 (fallback) : si weasyprint n’est pas disponible, utiliser fpdf2 avec LiberationSans (voir scripts/convert_cv_to_pdf.py). Chemin :
PYTHONPATH=/home/bf/.local/lib/python3.10/site-packages python3 script.pysi fpdf2 est installé hors environnement Hermes. - Emojis non supportés dans LiberationSans → remplacer 📞 ✉ 🔗 par du texte clair dans les PDFs.
- Gmail API non activée par défaut dans le projet Google Cloud. Pour envoyer par email : activer Gmail API dans https://console.cloud.google.com/apis/library/gmail.googleapis.com OU utiliser SMTP avec mot de passe d’application Gmail.
- App password Gmail avec 2FA : peut retourner erreur 534 “Application-specific password required” si le compte utilise la validation en deux étapes avancée. Solution : activer Gmail API OU générer un nouveau mot de passe d’application.
Exemple de CVs créés
Pour un profil Analyste Criminologique / TI avec formation militaire :
| Version | Cible | Angle |
|---|---|---|
| Sûreté Québec | Agent soutien activités policières | Surveillance tech + rigueur militaire |
| Fraude Bancaire | Banques (BNC, RBC, Desjardins) | Détection d’anomalies + conformité LCB-FT |
| Fraude Assurance | Assureurs (Intact, IA, Aviva) | Investigation + croisement de données |
| Sécurité TI | Grandes organisations (Hydro, Revenu QC) | SOC + cybersécurité + gouvernance |