feat(ai): refactor AI prompts and add bypass option to Job Positions
This commit is contained in:
@@ -80,42 +80,42 @@ class AIAnalysisService
|
||||
$provider = $provider ?: env('AI_DEFAULT_PROVIDER', 'ollama');
|
||||
|
||||
$job = $candidate->jobPosition;
|
||||
$jobTitle = $job->title;
|
||||
$jobDesc = $job->description;
|
||||
$requirements = implode(", ", $job->requirements ?? []);
|
||||
|
||||
// Static Part: The job context and instructions (Cacheable)
|
||||
$staticPrompt = "Tu es un expert en recrutement technique spécialisé dans l'infrastructure et la cybersécurité. Ton rôle est d'analyser le profil d'un candidat pour le poste de '{$jobTitle}'.";
|
||||
|
||||
if (!$job->ai_prompt) {
|
||||
$staticPrompt .= " Attache une grande importance aux compétences techniques et à l'expérience, mais aussi à la capacité d'intégration et à la motivation.
|
||||
|
||||
DESCRIPTION DU POSTE:
|
||||
{$jobDesc}
|
||||
|
||||
COMPÉTENCES REQUISES:
|
||||
{$requirements}
|
||||
|
||||
Fournis une analyse structurée en JSON avec les clés suivantes:
|
||||
- match_score: note de 0 à 100
|
||||
- summary: résumé de 3-4 phrases sur le profil
|
||||
- strengths: liste des points forts par rapport au poste
|
||||
- gaps: liste des compétences manquantes ou points de vigilance
|
||||
- verdict: une conclusion (Favorable, Très Favorable, Réservé, Défavorable)";
|
||||
// --- BYPASS LOGIC ---
|
||||
if ($job->ai_bypass_base_prompt && !empty($job->ai_prompt)) {
|
||||
$staticPrompt = $job->ai_prompt;
|
||||
// We still append the JSON requirement to ensure the frontend doesn't crash,
|
||||
// unless the user specifically asked for "pure" takeover.
|
||||
// Most users want to control the "logic" not the "serialization format".
|
||||
if (!str_contains(strtolower($staticPrompt), 'json')) {
|
||||
$staticPrompt .= "\n\nRéponds UNIQUEMENT en JSON pur. Format attendu:\n" . config('ai.defaults.json_format');
|
||||
}
|
||||
} else {
|
||||
$staticPrompt .= "
|
||||
// --- STANDARD LOGIC ---
|
||||
// Base instructions from config
|
||||
$baseInstruction = config('ai.defaults.base_instruction');
|
||||
$jsonFormat = config('ai.defaults.json_format');
|
||||
|
||||
$staticPrompt = "{$baseInstruction} Ton rôle est d'analyser le profil d'un candidat pour le poste de '{$job->title}'.\n\n";
|
||||
|
||||
CONTEXTE DU POSTE:
|
||||
{$jobDesc}
|
||||
$staticPrompt .= "DESCRIPTION DU POSTE:\n{$job->description}\n\n";
|
||||
|
||||
COMPÉTENCES REQUISES:
|
||||
{$requirements}
|
||||
if (!empty($job->requirements)) {
|
||||
$staticPrompt .= "COMPÉTENCES REQUISES:\n" . implode(", ", $job->requirements) . "\n\n";
|
||||
}
|
||||
|
||||
if (!$job->ai_prompt) {
|
||||
// Default generalist analysis instructions
|
||||
$staticPrompt .= "CONSIGNES D'ANALYSE:\n" . config('ai.defaults.analysis_instructions') . "\n\n";
|
||||
} else {
|
||||
// Specific instructions from the job position
|
||||
$staticPrompt .= "CONSIGNES D'ANALYSE SPÉCIFIQUES:\n" . $job->ai_prompt . "\n\n";
|
||||
}
|
||||
|
||||
CONSIGNES D'ANALYSE SPÉCIFIQUES:
|
||||
" . $job->ai_prompt;
|
||||
$staticPrompt .= "FORMAT DE RÉPONSE ATTENDU:\n{$jsonFormat}\n";
|
||||
}
|
||||
|
||||
$staticPrompt .= "\n\nRéponds UNIQUEMENT en JSON pur, sans texte avant ou après. Assure-toi que le JSON est valide.";
|
||||
$staticPrompt .= "\nRéponds UNIQUEMENT en JSON pur, sans texte avant ou après. Assure-toi que le JSON est valide.";
|
||||
|
||||
// Dynamic Part: The candidate data (Not cached)
|
||||
$dynamicPrompt = "CONTENU DU CV DU CANDIDAT:\n{$cvText}\n\nCONTENU DE LA LETTRE DE MOTIVATION:\n" . ($letterText ?? "Non fournie");
|
||||
|
||||
Reference in New Issue
Block a user