Pipeline local pour générer un dossier de candidature ciblé : CV, lettre de motivation, validation et tracker.
Pipeline local pour générer un dossier de candidature ciblé à partir d'une offre d'emploi.
ResumeForge produit un CV personnalisé, une lettre de motivation contrôlée, un rapport de validation et un suivi de candidature, en gardant les fichiers privés hors Git.
Exemple de CV généré — voir le PDF complet
| Fonction | Rôle |
|---|---|
| CV ciblé | Sélectionne les expériences et adapte les bullets à l'offre |
| CV Markdown temporaire | Produit une source propre pour Gemini, puis la supprime après LM DOCX réussie |
| Lettre DOCX | Génère uniquement une LM finale Word, sans export Markdown |
| Validation | Bloque la LM si elle invente un chiffre, un outil, une expérience ou un fait entreprise |
| Base métier | Réutilise les termes précis par domaine sans alourdir le prompt |
| Tracker | Met à jour le suivi de candidature sans casser le pipeline si Sheets est indisponible |
| Sécurité | Garde .env, profils, templates privés et outputs hors Git |
Commande principale :
python run_application.pySorties attendues :
data/output/
├── cv/
│ └── CV_....docx
└── cover_letters/
├── LM_....docx
└── LM_...._validation.json
Les fichiers techniques du run restent dans data/output/, mais ils sont masqués dans VS Code pour garder l'explorateur lisible.
Le CV Markdown est un fichier temporaire interne pour Gemini : il est généré, utilisé pour la LM, puis supprimé dès que la LM DOCX est créée. La lettre de motivation finale est exportée uniquement en DOCX. ResumeForge ne génère pas de fichier final LM_....md.
offre d'emploi
+ profil Excel privé
-> CV DOCX recruteur
-> CV Markdown temporaire pour Gemini
-> application_context.json
-> LM DOCX finale
-> suppression du CV Markdown temporaire si succès
-> validation JSON
-> tracker candidatures
La lettre de motivation ne lit jamais directement master_profile.xlsx.
Elle utilise uniquement :
- le CV Markdown temporaire dérivé du CV final ;
- l'offre d'emploi ;
application_context.json;- les faits entreprise autorisés ;
- les fichiers de référence LM.
La validation bloque l'export DOCX si la LM contient un élément inventé : chiffre, outil, expérience, formation, compétence, fait entreprise, annotation, placeholder ou survente d'expertise.
Les commandes prêtes à l'emploi sont dans COMMANDS.md.
Les plus utiles :
# Pipeline complet, affichage propre
python run_application.py --quiet
# Pipeline complet, logs détaillés
python run_application.py
# Ancien pipeline CV seul
python run.py
# Tests
python -m pytest
# Enrichir manuellement une base métier depuis l'offre courante
python scripts/enrich_domain_vocabulary.py --domain retail_operationsgit clone https://github.com/Insular2895/ResumeForge.git
cd ResumeForge
python3 -m venv src/.venv
source src/.venv/bin/activate
pip install -r requirements.txtCopier l'exemple d'environnement :
cp .env.example .envPuis remplir .env localement. Ce fichier est ignoré par Git.
Chaque utilisateur du repo doit avoir sa propre configuration locale.
Le repo versionne seulement :
.env.example
Chaque utilisateur crée ensuite son fichier privé :
cp .env.example .envPuis il remplit ses propres clés et son propre tracker :
GEMINI_API_KEY=your_gemini_cv_key_here
GEMINI_LETTER_API_KEY=your_gemini_letter_key_here
GEMINI_DOMAIN_API_KEY=your_gemini_domain_key_here
GOOGLE_SHEET_ID=your_google_sheet_id_here
GOOGLE_SHEET_TAB=applicationsPour Google Sheets, chaque utilisateur ajoute aussi son propre service account local :
credentials/service_account.json
Ce fichier doit avoir accès au Google Sheet indiqué dans GOOGLE_SHEET_ID.
À ne jamais commit :
.env
credentials/service_account.json
data/input/job_description.txt
data/reference/master_profile.xlsx
templates/base_cv.docx
templates/base_cover_letter.docx
data/tracker/applications.csv
data/output/
En clair : le repo contient le moteur et les exemples, mais chaque personne apporte ses clés Gemini, son Google Sheet, son Excel profil, ses templates Word privés et ses offres d'emploi.
Fichiers privés à créer localement :
.env
data/input/job_description.txt
data/reference/master_profile.xlsx
templates/base_cv.docx
templates/base_cover_letter.docx
credentials/
Ces fichiers ne doivent pas être commit.
.env.example documente les variables sans secrets :
GEMINI_API_KEY=your_gemini_api_key_here
GEMINI_LETTER_API_KEY=your_gemini_letter_api_key_here
GEMINI_DOMAIN_API_KEY=your_gemini_domain_research_api_key_hereRôles recommandés :
GEMINI_API_KEY: génération et optimisation CV ;GEMINI_LETTER_API_KEY: génération LM ;GEMINI_DOMAIN_API_KEY: enrichissement manuel de la base métier.
Si GEMINI_LETTER_API_KEY est absente, le pipeline génère le CV, le Markdown et application_context.json, puis écrit un rapport skipped sans générer de LM.
Configuration recommandée :
GEMINI_ROTATION_MODELS=gemini-3.1-flash-lite,gemini-3-flash-preview,gemini-2.5-flash-lite,gemini-2.5-flash
GEMINI_DAILY_LIMIT_PER_MODEL=20
GEMINI_LETTER_MODEL=gemini-3.1-flash-lite
GEMINI_LETTER_FALLBACK_MODELS=gemini-3-flash-preview,gemini-2.5-flash-lite,gemini-2.5-flash
GEMINI_DOMAIN_MODEL=gemini-3.1-flash-liteGemini 3.1 Flash Lite est utilisé en priorité pour la LM et la base métier, avec fallback automatique si le modèle est indisponible ou en quota.
Avec la limite locale GEMINI_DAILY_LIMIT_PER_MODEL=20, le débit CV est volontairement conservateur. Tu peux augmenter cette limite si tes quotas Google AI Studio le permettent.
Template privé :
templates/base_cv.docx
Il contient les placeholders CV utilisés par run.py et run_application.py.
Le CV généré est rendu en Arial.
Template versionné :
templates/base_cover_letter_example.docx
Template privé de production :
cp templates/base_cover_letter_example.docx templates/base_cover_letter.docxOuvre ensuite templates/base_cover_letter.docx dans Word ou LibreOffice, adapte la mise en page et garde les placeholders exactement identiques.
Placeholders principaux :
[[LM_COMPANY]]
[[LM_COMPANY_ADDRESS_LINE_1]]
[[LM_COMPANY_POSTAL_CITY]]
[[LM_JOB_TITLE]]
[[LM_DATE]]
[[LM_FINAL_LETTER]]
[[LM_SIGNATURE]]
La LM générée est rendue en Arial.
Ces fichiers guident Gemini. Ils ne sont pas des sorties finales :
templates/LM_instructions.md
templates/LM_template.md
templates/LM_demo_validee.md
Leur rôle :
LM_instructions.md: règles de génération, interdictions, ATS, méthode ABC/XYZ, angle apprentissage ;LM_template.md: structure logique attendue ;LM_demo_validee.md: démonstration annotée du style cible.
Les annotations et placeholders de raisonnement ne doivent jamais apparaître dans la lettre finale.
ResumeForge charge une base métier courte selon le domaine détecté :
templates/domain_vocabulary/
├── supply_chain.json
├── retail_operations.json
└── _cross_domain_terms.json
Objectif : réutiliser les bons termes transversaux sans brûler trop de tokens.
Exemples :
- supply chain : Incoterms, FIFO/FEFO, packing list, airway bill, bill of lading, cut-off, douane ;
- retail operations : ADV, précommandes, royalties, litiges, marges, réseau de boutiques, KPI service client ;
- transverse : reporting, coordination, fiabilité des données, parties prenantes, amélioration de process.
Pour enrichir manuellement une base depuis une nouvelle offre :
python scripts/enrich_domain_vocabulary.py --domain retail_operationsCette commande utilise GEMINI_DOMAIN_API_KEY et ne consomme pas la clé CV ni la clé LM.
Le pipeline peut construire un profil entreprise avec cache JSON local :
data/company_profiles/
Les faits entreprise retenus sont injectés dans application_context.json. La LM peut utiliser au maximum 1 à 3 faits autorisés.
Si la recherche entreprise est indisponible, le pipeline reste sobre et ne force pas de faits non vérifiés.
Le rapport de validation est écrit ici :
data/output/cover_letters/LM_...._validation.json
Statuts possibles :
success: LM validée, DOCX généré ;failed: LM rejetée, aucun DOCX final exporté ;skipped: génération LM sautée, souvent à cause d'une clé absente.
En cas d'échec, ResumeForge écrit aussi :
data/output/cover_letters/LM_FAILED_....txt
Le tracker est mis à jour avec :
- timestamp ;
- entreprise ;
- poste ;
- famille métier ;
- chemin CV DOCX ;
- chemin LM DOCX si disponible ;
- statut de validation ;
- statut recherche entreprise ;
- nombre de faits entreprise retenus.
Il n'y a pas de champ lm_md_path.
Si Google Sheets est configuré, la logique existante est réutilisée. Sinon, le pipeline écrit un warning sans casser la génération.
run.py # CV seul, conservé
run_application.py # pipeline complet
src/application/ # contexte, tracking, markdown CV, recherche, base métier
src/letter/ # prompt LM, génération, validation, rendu DOCX
src/render/ # rendu Word
templates/ # templates et références Gemini
docs/ # specs, plans, guide d'utilisation
tests/ # tests sans clé API obligatoire
Guide plus détaillé :
docs/USAGE.md
Avant de commit :
git status --shortÀ ne jamais commit :
.env
data/input/job_description.txt
data/reference/master_profile.xlsx
templates/base_cv.docx
templates/base_cover_letter.docx
data/output/
data/company_profiles/
credentials/
Les exemples versionnés restent publics :
.env.example
templates/base_cover_letter_example.docx
templates/LM_instructions.md
templates/LM_template.md
templates/LM_demo_validee.md
templates/domain_vocabulary/*.json
python -m pytestLes tests ne nécessitent pas de clé Gemini.
Usage personnel uniquement. Voir LICENSE.