fix(scanner): Bewertungsprompt ohne erfundene Luecken

Das JSON-Beispiel im alten Prompt ("Deutsch nur auf B2-Niveau") hat das
Modell in rund 1600 Cons uebernommen, und knappe Beschreibungen (Freelancermap
meist nur Titel) wurden pauschal niedrig bewertet. Lisa und Ariane kamen so
nie ueber 80 % und blieben unter der Anzeigeschwelle von 85 %.

Neuer Prompt: nur belegte Fakten, Rolle aus dem Titel bei knapper
Beschreibung, feste Fuenf-Stufen-Skala, Platzhalter statt Beispielinhalt.
Alter Prompt liegt als Backup in server/src/scanner/prompts/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-24 09:31:23 +02:00
co-authored by Claude Opus 5.5
parent e2ad8ab03e
commit 1eb115bb7a
3 changed files with 104 additions and 19 deletions
+41
View File
@@ -53,6 +53,47 @@ Zwei Sparmassnahmen stecken bewusst **vor** dem OpenAI-Aufruf: der vorhandene
Treffer (Unique-Key `agent_id, project_id`) und die Ausschlussbegriffe. Ein
Projekt, das „Arbeitnehmerüberlassung" enthält, kostet damit keinen Cent.
## Bewertungsprompt
Den Systemprompt der Bewertung Lebenslauf gegen Projekt enthält
`services/matchingEngine.js`. Seit dem 24.09.2026 gilt eine neue Fassung. Die
alte liegt wörtlich in `server/src/scanner/prompts/matching-backup-2026-09-24.txt`.
Zum Zurückstellen setzt man sie wieder als `systemPrompt` ein.
**Warum er ersetzt wurde.** Lisa und Ariane (Marketing, Kommunikation, PMO)
bekamen bei rund 1700 Bewertungen keinen Wert über 80 %. Bei einer
Anzeigeschwelle von 85 % erschienen sie also nie im Dashboard. Zwei Ursachen im
alten Prompt:
- **Abgeschriebenes Beispiel.** Das JSON-Beispiel enthielt den Con „Berater
listet Deutsch nur auf B2-Niveau". Das Modell hat ihn in 1584 von rund
10 000 Bewertungen übernommen, auch bei Lebensläufen, die Deutsch ohne Niveau
nennen. So kostete eine erfundene Lücke jedes Mal Punkte.
- **Knappe Beschreibungen.** Freelancermap liefert im Schnitt 99 Zeichen, also
praktisch nur den Titel. Ohne Regel dafür bewertete das Modell vorsichtig
niedrig. Profile mit einem klaren Technik-Schlagwort (etwa „M365") kamen damit
noch durch, allgemeinere Profile nicht.
**Was der neue Prompt festlegt:**
- nur, was in Lebenslauf und Beschreibung steht. Sprache, Reisen, Zertifikate
nennt das Modell nur, wenn das Projekt sie ausdrücklich fordert
- eine Sprache ohne Niveau gilt als vorhanden
- bei knapper Beschreibung wird die Rolle aus dem Titel bewertet, fehlende
Details sind kein Minuspunkt
- eine feste Skala in fünf Stufen (90-100 genau passend bis 0-29 anderes Fach)
- das Profil wird nach seinem eigenen Fach bewertet, nicht nach technischer Tiefe
- Platzhalter im Schema statt Beispielinhalt, leere Cons sind erlaubt
Stichprobe vor dem Rollout (33 Paare aus Lisa, Ariane und Tobias, gespeicherter
Wert gegen neuen Prompt, gleiches Modell): passende Rollen stiegen von 80 auf 85-90 (Ariane: Change Manager
Kommunikation, Marketing & Communications). Fachfremde Projekte fielen von
30-60 auf 0-30. Tobias' M365-Treffer blieben bei 90-95.
Bereits gespeicherte Treffer werden **nicht** neu bewertet
(Unique-Key `agent_id, project_id`). Die neue Skala gilt für Projekte, die
nach dem Deployment gefunden werden.
## Abgleich „bereits beworben!"
Dieselbe Ausschreibung kommt oft mehrfach: über zwei Börsen, über mehrere
@@ -0,0 +1,28 @@
# Systemprompt der Bewertung CV gegen Projekt (matchingEngine.js), gueltig bis 24.09.2026.
# Abgeloest, weil das Modell das Beispiel "Deutsch nur auf B2-Niveau" in rund 1600
# Cons woertlich uebernommen hat und Projekte mit knapper Beschreibung (Freelancermap:
# im Schnitt 99 Zeichen, praktisch nur der Titel) pauschal niedrig bewertet wurden.
# Zum Zurueckstellen den Text unterhalb der Trennlinie wieder als systemPrompt einsetzen.
# ---------------------------------------------------------------------------------
Du bist ein hochentwickeltes IT-Recruiting-Matching-System.
Deine Aufgabe ist es, den Lebenslauf (CV) eines IT-Beraters mit einer Projektbeschreibung abzugleichen.
Berechne eine realistische Übereinstimmungsquote (Trefferquote) in Prozent (Zahl von 0 bis 100).
Analysiere Gemeinsamkeiten und Lücken.
Erstelle eine Liste von Stichpunkten für:
1. Pros: Warum der Berater für das Projekt geeignet ist (Erfahrung, Kernkompetenzen, passende Programmiersprachen/Frameworks).
2. Cons: Was gegen eine Eignung spricht oder welche Risiken/Lücken es gibt (fehlende Technologien, Sprachbarrieren, Reisebereitschaft, zu geringe Seniorität).
Antworte ausschließlich im JSON-Format mit folgendem Schema:
{
"matchPercentage": 75,
"pros": [
"Sehr gute Übereinstimmung bei React und Node.js-Kenntnissen.",
"Erfahrung im geforderten Finanzsektor vorhanden."
],
"cons": [
"Keine Erwähnung der geforderten Docker/Kubernetes-Erfahrung im CV.",
"Projektsprache ist Deutsch (fließend), der Berater listet Deutsch nur auf B2-Niveau."
]
}
Schreibe keinen zusätzlichen Text vor oder nach dem JSON-Objekt.
+35 -19
View File
@@ -25,28 +25,44 @@ export const evaluateMatch = async (cvText, projectDescription) => {
const openai = new OpenAI({ apiKey });
const systemPrompt = `Du bist ein hochentwickeltes IT-Recruiting-Matching-System.
Deine Aufgabe ist es, den Lebenslauf (CV) eines IT-Beraters mit einer Projektbeschreibung abzugleichen.
Berechne eine realistische Übereinstimmungsquote (Trefferquote) in Prozent (Zahl von 0 bis 100).
Analysiere Gemeinsamkeiten und Lücken.
/*
* Vorgaenger liegt in ../prompts/matching-backup-2026-09-24.txt. Er hatte ein
* konkretes Beispiel ("Deutsch nur auf B2-Niveau"), das das Modell in rund
* 1600 Cons woertlich uebernommen hat, und keine Regel fuer die knappen
* Beschreibungen der Boersen (Freelancermap: meist nur der Titel). Beides hat
* Profile ohne Technik-Schlagwort (Marketing, Kommunikation, PMO) unter jede
* Anzeigeschwelle gedrueckt. Deshalb jetzt: nur belegte Fakten, feste Skala,
* Platzhalter statt Beispielinhalt.
*/
const systemPrompt = `Du bewertest, wie gut ein Berater zu einem ausgeschriebenen Freelance-Projekt passt.
Die Berater kommen aus unterschiedlichen Feldern: IT, Projektmanagement/PMO, Marketing, Kommunikation, SAP und andere. Bewerte jedes Profil nach seinem eigenen Fach, nicht nach technischer Tiefe.
Erstelle eine Liste von Stichpunkten für:
1. Pros: Warum der Berater für das Projekt geeignet ist (Erfahrung, Kernkompetenzen, passende Programmiersprachen/Frameworks).
2. Cons: Was gegen eine Eignung spricht oder welche Risiken/Lücken es gibt (fehlende Technologien, Sprachbarrieren, Reisebereitschaft, zu geringe Seniorität).
## Grundlage
- Nutze ausschließlich, was im Lebenslauf und in der Projektbeschreibung steht.
- Erfinde keine Anforderungen und keine Lücken. Sprachniveau, Reisebereitschaft, Zertifikate oder Tools nennst du nur, wenn die Projektbeschreibung sie ausdrücklich fordert UND der Lebenslauf dazu etwas anderes sagt oder schweigt.
- Steht im Lebenslauf eine Sprache ohne Niveau, gilt sie als vorhanden.
- Viele Beschreibungen bestehen nur aus Titel und wenigen Angaben. Dann bewerte, ob die Rolle aus dem Titel (typische Aufgaben, Fachgebiet, Seniorität) zum Profil passt. Eine knappe Beschreibung ist kein Minuspunkt. Fehlende Details dürfen die Quote nicht drücken.
Antworte ausschließlich im JSON-Format mit folgendem Schema:
## Skala für matchPercentage (ganze Zahl 0-100)
- 90-100: Rolle und Fachgebiet passen genau, der Lebenslauf zeigt diese Tätigkeit mehrfach oder als Schwerpunkt.
- 75-89: Rolle passt, wesentliche geforderte Kompetenzen sind belegt, höchstens kleinere Lücken.
- 55-74: Deutliche Überschneidung, aber ein wichtiger Teil der Rolle ist nicht belegt oder die Seniorität weicht klar ab.
- 30-54: Verwandtes Feld, übertragbare Erfahrung, die Kernaufgabe hat der Berater aber nicht gemacht.
- 0-29: Anderes Fachgebiet oder Beruf, keine sinnvolle Besetzung.
Nutze die ganze Skala. Eine Rolle, die genau dem Schwerpunkt des Lebenslaufs entspricht, gehört nach oben, auch wenn die Beschreibung kurz ist.
## Pros und Cons
- Je 1 bis 4 Stichpunkte auf Deutsch, konkret mit Bezug auf Lebenslauf und Projekt.
- Pros: belegte Erfahrung, Rollen, Branchen, Methoden oder Tools, die zur Rolle passen.
- Cons: nur echte, belegbare Lücken oder Risiken. Gibt es keine, gib eine leere Liste zurück.
## Ausgabe
Antworte ausschließlich mit einem JSON-Objekt in diesem Schema, ohne Text davor oder danach:
{
"matchPercentage": 75,
"pros": [
"Sehr gute Übereinstimmung bei React und Node.js-Kenntnissen.",
"Erfahrung im geforderten Finanzsektor vorhanden."
],
"cons": [
"Keine Erwähnung der geforderten Docker/Kubernetes-Erfahrung im CV.",
"Projektsprache ist Deutsch (fließend), der Berater listet Deutsch nur auf B2-Niveau."
]
}
Schreibe keinen zusätzlichen Text vor oder nach dem JSON-Objekt.`;
"matchPercentage": <Zahl>,
"pros": ["<Stichpunkt>"],
"cons": ["<Stichpunkt>"]
}`;
const userContent = `### LEBENSLAUF (CV):
${cvText}