Aperçu
Le module de génération d’annonces RH utilise l’IA pour générer des annonces d’emploi attractives et professionnelles basées sur les spécifications de poste que vous fournissez. Il prend les informations de base du poste et produit une annonce complète et formatée prête pour publication.
Ce cas est un exemple, n’hésitez pas à le répliquer pour tout type de génération de contenu
Cas d’usage : Créer rapidement des offres d’emploi pour les plateformes de recrutement, pages carrières d’entreprise, ou job boards.
Note:
Les exemples de cette documentation utilisent un serveur web Flask en local. Soyez vigilant si vous souhaitez mettre en production.
Cet exemple a été effectué avec un frontend HTML qui envoi au backend les variables.
Fonctionnement
- L’utilisateur se connecte sur l’interface front-end
- L’utilisateur fournit les informations du poste (titre, département, expérience, salaire, etc.)
- Le système utilise un prompt structuré avec le template d’annonce + les variables fournies par l’utilisateur
- Le LLM génère une annonce d’emploi complète
- L’offre formatée dans la langue demandée est affichée sur le frontend
Endpoints API Utilisés
| Endpoint | Objectif |
|---|
POST /chat/completions | Générer l’annonce d’emploi |
Note : Ce module utilise Chat Completions (génération de texte pure) sans documents.
Implémentation Étape par Étape
Étape 1 : Initialiser le Service
import requests
from typing import Dict, Any, List
class AdsService:
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Configuration API
self.chat_url = "https://paradigm.lighton.ai/api/v2/chat/completions"
self.model = "alfred-4.2"
self.max_tokens = 2000
self.temperature = 0.7 # Créatif mais cohérent
Étape 2 : Créer le Prompt de Génération
def _create_prompt(self, job_data: Dict[str, Any]) -> str:
"""
Créer le prompt pour la génération d'annonce.
Args:
job_data: Dictionnaire contenant les informations du poste
Returns:
Chaîne de prompt formatée
"""
# Extraire les données du poste
job_title = job_data.get('jobTitle', '')
department = job_data.get('department', '')
contract_type = job_data.get('contractType', '')
experience = job_data.get('experience', '')
salary_min = job_data.get('salaryMin', '')
salary_max = job_data.get('salaryMax', '')
benefits = job_data.get('benefits', [])
job_description = job_data.get('jobDescription', '')
language = job_data.get('language', 'French')
# Template d'annonce
template = """
**[TITRE DU POSTE]**
**Département : [DÉPARTEMENT]**
**Contrat : [TYPE_CONTRAT]**
**Expérience : [EXPÉRIENCE]**
**Salaire : [FOURCHETTE_SALAIRE]**
**Description du Poste :**
[Description détaillée et engageante du poste]
**Responsabilités Principales :**
- [Responsabilité 1]
- [Responsabilité 2]
- [Responsabilité 3]
**Qualifications Requises :**
- [Qualification 1]
- [Qualification 2]
- [Qualification 3]
**Avantages & Bénéfices :**
[Liste des avantages]
**Pourquoi Nous Rejoindre :**
[Raisons convaincantes de rejoindre l'équipe]
**Comment Postuler :**
[Appel à l'action]
"""
# Construire le prompt
prompt = f"""Tu es un générateur professionnel d'offres d'emploi. Utilise ce template :
TEMPLATE :
{template}
INFORMATIONS DU POSTE :
- Titre du Poste : {job_title}
- Département : {department}
- Type de Contrat : {contract_type}
- Niveau d'Expérience : {experience}"""
if salary_min and salary_max:
prompt += f"\n- Fourchette Salariale : {salary_min}€ - {salary_max}€"
elif salary_min:
prompt += f"\n- Salaire Minimum : {salary_min}€"
if benefits:
prompt += f"\n- Avantages : {', '.join(benefits)}"
if job_description:
prompt += f"\n- Contexte Additionnel : {job_description}"
prompt += f"""
INSTRUCTIONS :
1. Rédiger l'intégralité de l'annonce en {language}
2. Traduire TOUS les titres de sections en {language}
3. Remplacer tous les [PLACEHOLDERS] par les informations réelles
4. Créer une offre d'emploi engageante et attractive
5. Utiliser un ton professionnel mais chaleureux
6. Mettre en avant les opportunités d'évolution et la culture d'entreprise
7. Terminer par un appel à l'action convaincant
Générer l'offre d'emploi complète en {language} :"""
return prompt
Étape 3 : Générer l’Annonce d’Emploi
def generate_job_ad(self, job_data: Dict[str, Any]) -> str:
"""
Générer une annonce d'emploi.
Args:
job_data: Dictionnaire contenant :
- jobTitle: Titre du poste (requis)
- department: Nom du département (requis)
- contractType: Type de contrat (requis)
- experience: Niveau d'expérience (requis)
- salaryMin: Salaire minimum (optionnel)
- salaryMax: Salaire maximum (optionnel)
- benefits: Liste des avantages (optionnel)
- jobDescription: Contexte additionnel (optionnel)
- language: Langue de sortie (défaut: French)
Returns:
Annonce d'emploi générée
"""
# Valider les champs requis
is_valid, error = self.validate_job_data(job_data)
if not is_valid:
raise ValueError(error)
# Créer le prompt
prompt = self._create_prompt(job_data)
payload = {
"model": self.model,
"messages": [
{"role": "user", "content": prompt}
],
"max_tokens": self.max_tokens,
"temperature": self.temperature
}
try:
response = requests.post(
self.chat_url,
headers=self.headers,
json=payload,
timeout=150
)
if response.status_code == 200:
data = response.json()
if "choices" in data and data["choices"]:
return data["choices"][0]["message"]["content"]
else:
return self._generate_fallback_ad(job_data)
else:
return self._generate_fallback_ad(job_data)
except Exception as e:
return self._generate_fallback_ad(job_data)
Étape 4 : Valider les Données d’Entrée
def validate_job_data(self, data: Dict[str, Any]) -> tuple:
"""
Valider les données du poste avant génération.
Args:
data: Données du poste à valider
Returns:
Tuple de (is_valid, message_erreur)
"""
required_fields = ['jobTitle', 'department', 'contractType', 'experience']
for field in required_fields:
if not data.get(field):
return False, f'Le champ {field} est requis'
# Valider le salaire
if data.get('salaryMin'):
try:
salary_min = float(data['salaryMin'])
if salary_min < 0:
return False, 'Le salaire minimum doit être >= 0'
except ValueError:
return False, 'Le salaire minimum doit être un nombre valide'
if data.get('salaryMax'):
try:
salary_max = float(data['salaryMax'])
if salary_max < 0:
return False, 'Le salaire maximum doit être >= 0'
if data.get('salaryMin'):
if salary_max < float(data['salaryMin']):
return False, 'Le salaire maximum doit être > salaire minimum'
except ValueError:
return False, 'Le salaire maximum doit être un nombre valide'
return True, ""
Étape 5 : Générateur de Secours
def _generate_fallback_ad(self, job_data: Dict[str, Any]) -> str:
"""Générer une annonce de secours quand l'API échoue."""
job_title = job_data.get('jobTitle', 'Poste')
department = job_data.get('department', 'Général')
contract_type = job_data.get('contractType', 'CDI')
experience = job_data.get('experience', 'Non spécifié')
salary_min = job_data.get('salaryMin', '')
salary_max = job_data.get('salaryMax', '')
benefits = job_data.get('benefits', [])
# Formater le salaire
salary_range = ""
if salary_min and salary_max:
salary_range = f"{int(float(salary_min)):,}€ - {int(float(salary_max)):,}€"
elif salary_min:
salary_range = f"À partir de {int(float(salary_min)):,}€"
ad = f"""**{job_title}**
**Département :** {department}
**Type de Contrat :** {contract_type}
**Niveau d'Expérience :** {experience}"""
if salary_range:
ad += f"\n**Salaire :** {salary_range}"
ad += f"""
**Description du Poste :**
Nous recherchons un professionnel talentueux pour notre poste de {job_title} au sein du département {department}.
**Responsabilités Principales :**
- Diriger et exécuter des initiatives clés
- Collaborer avec les équipes transverses
- Favoriser l'innovation et l'amélioration continue
**Qualifications Requises :**
- {experience} d'expérience pertinente
- Solides compétences en résolution de problèmes
- Excellentes capacités de communication"""
if benefits:
ad += "\n\n**Avantages & Bénéfices :**"
for benefit in benefits:
ad += f"\n- {benefit}"
ad += """
**Pourquoi Nous Rejoindre :**
- Travaillez sur des projets à fort impact
- Environnement de travail collaboratif
- Opportunités de développement professionnel
**Comment Postuler :**
Envoyez votre candidature et rejoignez notre équipe !"""
return ad
Exemple d’Utilisation Complet
# Initialiser le service
ads = AdsService(api_key="votre-cle-api")
# Définir les données du poste
job_data = {
'jobTitle': 'Ingénieur Logiciel Senior',
'department': 'Engineering',
'contractType': 'CDI',
'experience': '5+ ans',
'salaryMin': '55000',
'salaryMax': '75000',
'benefits': [
'Télétravail flexible',
'Mutuelle santé',
'Stock options',
'25 jours de congés',
'Budget formation'
],
'jobDescription': 'Rejoignez notre équipe IA pour construire des produits NLP de nouvelle génération. Vous travaillerez sur des modèles de langage de pointe et contribuerez à notre roadmap technique.',
'language': 'French'
}
# Générer l'annonce
job_ad = ads.generate_job_ad(job_data)
print(job_ad)
# Générer en anglais
job_data['language'] = 'English'
job_ad_en = ads.generate_job_ad(job_data)
print("\n--- Version Anglaise ---\n")
print(job_ad_en)
Intégration Route Flask
from flask import Blueprint, request, jsonify
ads_bp = Blueprint('ads', __name__)
ads_service = None
def init_ads_service(api_key: str):
global ads_service
ads_service = AdsService(api_key)
@ads_bp.route('/generate', methods=['POST'])
def generate_ad():
"""Générer une annonce d'emploi."""
data = request.json
# Valider
is_valid, error = ads_service.validate_job_data(data)
if not is_valid:
return jsonify({'error': error}), 400
# Générer
job_ad = ads_service.generate_job_ad(data)
return jsonify({
'ad': job_ad,
'status': 'success'
})
@ads_bp.route('/validate', methods=['POST'])
def validate():
"""Valider les données du poste avant génération."""
data = request.json
is_valid, error = ads_service.validate_job_data(data)
return jsonify({
'valid': is_valid,
'error': error if not is_valid else None
})
Paramètres d’Entrée
| Paramètre | Type | Requis | Description |
|---|
jobTitle | string | Oui | Titre du poste |
department | string | Oui | Nom du département |
contractType | string | Oui | Type de contrat (CDI, CDD, etc.) |
experience | string | Oui | Niveau d’expérience |
salaryMin | string | Non | Salaire minimum |
salaryMax | string | Non | Salaire maximum |
benefits | array | Non | Liste des avantages |
jobDescription | string | Non | Contexte additionnel |
language | string | Non | Langue de sortie (défaut: French) |
Bonnes Pratiques
- Fournir un contexte détaillé dans jobDescription pour de meilleurs résultats
- Lister les avantages spécifiques pour rendre l’annonce plus attractive
- Utiliser la langue appropriée pour votre audience cible
- Réviser le contenu généré avant publication
- Personnaliser le template pour la voix de marque de votre entreprise