KI-Lebenslauf-Optimierer
Experte
Dies ist ein AI Summarization, Multimodal AI-Bereich Automatisierungsworkflow mit 18 Nodes. Hauptsächlich werden Set, Code, Gmail, Merge, Webhook und andere Nodes verwendet. Lebensläufe mit Gemini-Analyse und E-Mail-Berichten mit Stellenbeschreibungen abgleichen
Voraussetzungen
- •Google-Konto + Gmail API-Anmeldedaten
- •HTTP Webhook-Endpunkt (wird von n8n automatisch generiert)
- •Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
- •Google Gemini API Key
Verwendete Nodes (18)
Kategorie
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
"id": "TzPKUZdrlcTUenHQ",
"meta": {
"instanceId": "d1dc073e8e3059a23e2730f69cb1b90065a2ac39039fea0727fdf9bee77a9131",
"templateCredsSetupCompleted": true
},
"name": "AI CV Optimizer",
"tags": [],
"nodes": [
{
"id": "08a1bb78-33db-4698-9970-c5b38c25835c",
"name": "Webhook - CV Optimizer Form",
"type": "n8n-nodes-base.webhook",
"position": [
-224,
272
],
"webhookId": "d50feff6-c48f-41e8-8df2-62ee9864907c",
"parameters": {
"path": "cv-optimizer",
"options": {},
"responseMode": "responseNode",
"multipleMethods": true
},
"typeVersion": 2.1
},
{
"id": "310ffa59-1f26-4ddd-881d-c5819b89d7f1",
"name": "Webhook Response - HTML Form",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
0,
176
],
"parameters": {
"options": {},
"respondWith": "text",
"responseBody": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>AI CV Optimizer</title>\n <style>\n :root {\n --primary: #2563eb;\n --primary-hover: #1e4ed8;\n --gray-light: #f9fafb;\n --gray: #ccc;\n --text-dark: #333;\n --radius: 10px;\n }\n body {\n font-family: Arial, sans-serif;\n background: var(--gray-light);\n margin: 0;\n padding: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n }\n .container {\n background: white;\n padding: 2rem;\n border-radius: var(--radius);\n box-shadow: 0 6px 16px rgba(0,0,0,0.1);\n max-width: 420px;\n width: 100%;\n }\n h2 {\n margin-bottom: 1.5rem;\n color: var(--text-dark);\n font-size: 1.5rem;\n text-align: center;\n }\n label {\n font-weight: 600;\n display: block;\n margin: 1rem 0 0.5rem;\n }\n input[type=\"file\"], input[type=\"text\"], input[type=\"email\"] {\n width: 100%;\n padding: 0.75rem;\n border: 1px solid var(--gray);\n border-radius: var(--radius);\n font-size: 0.95rem;\n box-sizing: border-box;\n }\n input:focus {\n border-color: var(--primary);\n outline: none;\n box-shadow: 0 0 0 3px rgba(37,99,235,0.15);\n }\n button {\n margin-top: 1.5rem;\n padding: 0.9rem;\n background: var(--primary);\n color: white;\n border: none;\n border-radius: var(--radius);\n width: 100%;\n font-size: 1rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n button:hover {\n background: var(--primary-hover);\n }\n button:disabled {\n background: #9ca3af;\n cursor: not-allowed;\n }\n .status {\n margin-top: 1rem;\n font-size: 0.9rem;\n text-align: center;\n }\n .status.success { color: green; }\n .status.error { color: red; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <h2>AI CV Optimizer</h2>\n <form id=\"cvForm\">\n <label for=\"cv\">Upload your CV (PDF):</label>\n <input type=\"file\" id=\"cv\" name=\"cv\" accept=\"application/pdf\" required />\n\n <label for=\"job_url\">Job Posting URL:</label>\n <input type=\"text\" id=\"job_url\" name=\"job_url\" placeholder=\"https://linkedin.com/job/123\" required />\n\n <label for=\"email\">Your Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\" placeholder=\"you@example.com\" required/>\n\n <button type=\"submit\">Check My CV</button>\n <div class=\"status\" id=\"status\"></div>\n </form>\n </div>\n\n <script>\n const form = document.getElementById(\"cvForm\");\n const statusDiv = document.getElementById(\"status\");\n\n form.addEventListener(\"submit\", async (e) => {\n e.preventDefault();\n\n const formData = new FormData(form);\n statusDiv.textContent = \"⏳ Uploading and analyzing your CV...\";\n statusDiv.className = \"status\";\n\n try {\n const res = await fetch(\"https://n8nworkflow.eu/webhook-test/cv-optimizer\", {\n method: \"POST\",\n body: formData\n });\n\n if (!res.ok) {\n throw new Error(\"Server error: \" + res.statusText);\n }\n\n const data = await res.json();\n console.log(\"n8n response:\", data);\n statusDiv.textContent = \"✅ CV submitted successfully! Check your email for results.\";\n statusDiv.className = \"status success\";\n } catch (err) {\n console.error(err);\n statusDiv.textContent = \"❌ Error: \" + err.message;\n statusDiv.className = \"status error\";\n }\n });\n </script>\n</body>\n</html>"
},
"typeVersion": 1.4
},
{
"id": "5f221527-5476-49cb-a166-eb3213f5d4a6",
"name": "Lebenslauftext extrahieren (PDF)",
"type": "n8n-nodes-base.extractFromFile",
"position": [
0,
384
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "=cv"
},
"typeVersion": 1
},
{
"id": "75eb814c-8d04-4310-bc01-3fcaf1640634",
"name": "Lebenslauftext aufbereiten",
"type": "n8n-nodes-base.set",
"position": [
224,
384
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "be5e5936-7940-43be-b905-62b54d9db076",
"name": "cv_text",
"type": "string",
"value": "={{ $json.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "da50a5a9-a727-45f9-b07c-e75844f89d45",
"name": "Stellenanzeige abrufen",
"type": "n8n-nodes-base.httpRequest",
"position": [
448,
304
],
"parameters": {
"url": "={{ $(' Webhook - CV Optimizer Form').item.json.body.job_url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "405c1c1d-afa1-4b9e-a595-a7eef3772303",
"name": "Lebenslauf- und Stellen-Daten zusammenführen",
"type": "n8n-nodes-base.merge",
"position": [
896,
368
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "f7e1ebf8-5e4e-48b8-a384-d88f53d771bb",
"name": "Gemini Model - Primary",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1120,
592
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "qQGrvqnSPqWFH6I6",
"name": "Google Gemini(PaLM) Api account 5"
}
},
"typeVersion": 1
},
{
"id": "cf43c082-b2ae-42e0-8d3d-83db4a4d9f9d",
"name": "AI-JSON-Ausgabe parsen",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1248,
592
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{\n \"job_title\": \"Frontend Developer (React)\",\n \"location\": \"Helsinki, Finland\",\n \"fit_summary\": \"The candidate has solid React, TypeScript, and JavaScript experience, supported by practical work on full-stack applications. They also demonstrate CI/CD knowledge and testing skills (Cypress, Jest), which align well with the role. However, the CV does not explicitly highlight advanced CSS frameworks or accessibility practices that are emphasized in the job description.\",\n \"recommendation\": \"Consider\",\n \"fit_score\": 7,\n \"missing_critical\": [\n \"Advanced CSS framework experience (e.g., Tailwind, Material UI)\",\n \"Accessibility (WCAG) best practices\"\n ],\n \"cv_optimization\": \"Add a section highlighting hands-on experience with CSS frameworks (Tailwind, Material UI) and accessibility best practices (WCAG). Include concrete project examples that demonstrate user-focused design and frontend performance improvements.\",\n \"final_recommendation\": \" The candidate is a good potential match but should strengthen their CV by explicitly mentioning CSS framework expertise and accessibility knowledge to move from 'Consider' to a stronger 'Apply'.\"\n}"
},
"typeVersion": 1.3
},
{
"id": "51bd8f61-dea2-4763-beb3-d0171ca55660",
"name": "Gemini Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1328,
800
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "qQGrvqnSPqWFH6I6",
"name": "Google Gemini(PaLM) Api account 5"
}
},
"typeVersion": 1
},
{
"id": "a0bbfaab-6717-4a88-9766-97d70dec3f03",
"name": "Haftnotiz",
"type": "n8n-nodes-base.stickyNote",
"position": [
-224,
-304
],
"parameters": {
"width": 512,
"height": 272,
"content": "## AI CV Optimizer: Match Your CV to Job Descriptions with AI\n\nThis workflow uses AI to automatically analyze a candidate’s CV against any job posting. It extracts key skills, requirements, and gaps, then generates a clear fit summary, recommendations, and optimization tips. Candidates also receive a structured email report, helping them improve their CV and focus on the right roles.\n\nNo more guesswork, the workflow delivers objective. \n### AI-powered career insights in minutes."
},
"typeVersion": 1
},
{
"id": "91fb8dbc-2126-47dc-a4ae-a42d8b9c4397",
"name": "Haftnotiz1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
192
],
"parameters": {
"color": 6,
"width": 224,
"content": "### AI - Compare CV with Job\n\nYou can adjust the AI Agent prompt for output schema, scoring, or language.\n"
},
"typeVersion": 1
},
{
"id": "0343291b-6da2-4155-9a52-164f4c4ab1d1",
"name": "Haftnotiz2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1088,
736
],
"parameters": {
"color": 5,
"width": 208,
"height": 112,
"content": "### Gemini / AI \nCredentials: \nUse **Google Gemini/PaLM** credential."
},
"typeVersion": 1
},
{
"id": "14e53603-87f5-4d4e-92ef-216eb5917964",
"name": "Haftnotiz5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1584,
528
],
"parameters": {
"color": 5,
"width": 192,
"height": 96,
"content": "### Send report \nSend Email\nCredentials: Use **Gmail OAuth2** credential. (required)."
},
"typeVersion": 1
},
{
"id": "c05f35ba-eeb9-4752-80ef-23eefbcca0f2",
"name": "Bericht senden",
"type": "n8n-nodes-base.gmail",
"position": [
1616,
368
],
"webhookId": "ce5d269e-ee40-4c92-9479-e5af8baec199",
"parameters": {
"sendTo": "={{ $(' Webhook - CV Optimizer Form').item.json.body.email }}",
"message": "=<p>Hi,</p>\n\n<p>We’ve analyzed your CV against the job posting for <b>{{ $json.output.job_title }}</b> in <b>{{ $json.output.location }}</b>.</p>\n\n<p><b>Summary:</b><br>\n{{ $json.output.fit_summary }}</p>\n\n<p><b>Critical gaps identified:</b></p>\n<ul>\n {{ $json.output.missing_critical.map(gap => `<li>${gap}</li>`).join(\"\") }}\n</ul>\n\n<p><b>FinalFit Score:</b> {{ $json.output.fit_score }} / 10 <b> Recommendation: <b/> {{ $json.output.recommendation }}</p>\n<p>\n<b>Tips for improving CV: </b>{{ $json.output.cv_optimization }}\n</p>\n<p><b>AI Advice:</b><br>\n{{ $json.output.final_recommendation }}\n</p>\n\n<p>Best of luck with your applications,<br>AI CV Optimizer</p>",
"options": {},
"subject": "=Your CV Review: {{ $json.output.job_title }} in {{ $json.output.location }}"
},
"credentials": {
"gmailOAuth2": {
"id": "jkKHvU2Pb9X5WJk5",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "8918b88f-f90d-4e68-b28b-84dd68ad854a",
"name": "Haftnotiz11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
16
],
"parameters": {
"color": 5,
"width": 160,
"height": 144,
"content": "### Submission form\n**POST (required)**\n- `Upload CV`\n- `Job Link` \n- `email` "
},
"typeVersion": 1
},
{
"id": "03491b28-4df7-4be4-88b1-4128e92fe9b7",
"name": "AI-Lebenslauf-Analysator",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1152,
368
],
"parameters": {
"text": "=CV:\n{{ $json[\"cv_text\"] ? $json[\"cv_text\"].slice(0, 18000) : \"\" }}\n\nJOB:\n{{ $json[\"job_text\"] ? $json[\"job_text\"].slice(0, 18000) : \"\" }}\n\nTasks:\n1) Extract the \"job_title\" and \"location\". \n2) Identify \"matched_skills\" and \"missing_critical\" skills. \n3) Write a short \"advice\" paragraph (max 100 words). \n4) Write a friendly \"email_body\" addressed to the candidate, summarizing:\n - Job title & location \n - What they already match well \n - Areas to improve or learn for better fit \n - A motivating closing sentence \n5)5) Write a short final_recommendation paragraph.\n\n6) Provide **two recommendations**: \n - \"recommendation\": Apply / Consider / Not a fit (must align with fit_score) \n - \"cv_optimization\": Clear advice on how to improve the CV for similar roles. \n6) The \"fit_score\" must always align with \"recommendation\": \n - Apply → fit_score between 9 and 10 \n - Consider → fit_score between 7 and 8 \n - Not a fit → fit_score between 1 and 6 \n\n⚠️ IMPORTANT: Return ONLY valid JSON in this schema:\n{\n \"job_title\": \"string\",\n \"location\": \"string\",\n \"fit_score\": 0,\n \"recommendation\": \"Apply|Consider|Not a fit\",\n\"final_recommendation\": [\"string\"],\n \"matched_skills\": [\"string\"],\n \"missing_critical\": [\"string\"],\n \"advice\": \"string\",\n \"cv_optimization\": \"string\",\n \"email_body\": \"string\"\n}",
"options": {
"systemMessage": "You are a professional career assistant. \nYour task is to compare a candidate’s CV with a job description and return a structured JSON output. \n\n⚠️ RULES: \n- Follow the schema exactly. \n- Every field must be included. \n- All values must be plain text, arrays, or integers — never nested objects. \n- `fit_score` must be an integer (1–10) aligned with `recommendation`: \n - \"Apply\" → 9–10 \n - \"Consider\" → 7–8 \n - \"Not a fit\" → 1–6 \n- Do not add responsibilities, requirements, or benefits. \n- Do not include any text outside the JSON. \n\nSchema:\n{\n \"job_title\": \"string\",\n \"location\": \"string\",\n \"fit_score\": 0,\n \"recommendation\": \"Apply|Consider|Not a fit\",\n \"matched_skills\": [\"string\"],\n \"missing_critical\": [\"string\"],\n \"advice\": \"string\",\n \"cv_optimization\": \"string\",\n \"email_body\": \"string\",\n\"final_recommendation\": : \"string\",\n\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "798f0b85-bd22-4ad8-a9c3-a3535d955069",
"name": "Stellentext-Bereiniger",
"type": "n8n-nodes-base.code",
"position": [
672,
304
],
"parameters": {
"jsCode": "const raw = $json.data || \"\";\nconst text = raw\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \"\")\n .replace(/<\\/?[^>]+(>|$)/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\nreturn [{ job_text: text }];"
},
"typeVersion": 2
},
{
"id": "eef4754b-adb0-4859-93df-cfc361f8175c",
"name": "Haftnotiz3",
"type": "n8n-nodes-base.stickyNote",
"position": [
384,
-304
],
"parameters": {
"color": 2,
"width": 304,
"height": 144,
"content": "## Customization checklist\n✅ Update Webhook URL\n✅ Configure Google Gemini credentials\n✅ Set Gmail OAuth2 credentials\n✅ Adjust AI prompt if schema changes"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "039ce290-aa42-4e4a-a346-65841445a6a6",
"connections": {
"51bd8f61-dea2-4763-beb3-d0171ca55660": {
"ai_languageModel": [
[
{
"node": "cf43c082-b2ae-42e0-8d3d-83db4a4d9f9d",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"03491b28-4df7-4be4-88b1-4128e92fe9b7": {
"main": [
[
{
"node": "c05f35ba-eeb9-4752-80ef-23eefbcca0f2",
"type": "main",
"index": 0
}
]
]
},
"75eb814c-8d04-4310-bc01-3fcaf1640634": {
"main": [
[
{
"node": "da50a5a9-a727-45f9-b07c-e75844f89d45",
"type": "main",
"index": 0
},
{
"node": "405c1c1d-afa1-4b9e-a595-a7eef3772303",
"type": "main",
"index": 1
}
]
]
},
"798f0b85-bd22-4ad8-a9c3-a3535d955069": {
"main": [
[
{
"node": "405c1c1d-afa1-4b9e-a595-a7eef3772303",
"type": "main",
"index": 0
}
]
]
},
"da50a5a9-a727-45f9-b07c-e75844f89d45": {
"main": [
[
{
"node": "798f0b85-bd22-4ad8-a9c3-a3535d955069",
"type": "main",
"index": 0
}
]
]
},
"405c1c1d-afa1-4b9e-a595-a7eef3772303": {
"main": [
[
{
"node": "03491b28-4df7-4be4-88b1-4128e92fe9b7",
"type": "main",
"index": 0
}
]
]
},
"cf43c082-b2ae-42e0-8d3d-83db4a4d9f9d": {
"ai_outputParser": [
[
{
"node": "03491b28-4df7-4be4-88b1-4128e92fe9b7",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"5f221527-5476-49cb-a166-eb3213f5d4a6": {
"main": [
[
{
"node": "75eb814c-8d04-4310-bc01-3fcaf1640634",
"type": "main",
"index": 0
}
]
]
},
"f7e1ebf8-5e4e-48b8-a384-d88f53d771bb": {
"ai_languageModel": [
[
{
"node": "03491b28-4df7-4be4-88b1-4128e92fe9b7",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"08a1bb78-33db-4698-9970-c5b38c25835c": {
"main": [
[
{
"node": "310ffa59-1f26-4ddd-881d-c5819b89d7f1",
"type": "main",
"index": 0
}
],
[
{
"node": "5f221527-5476-49cb-a166-eb3213f5d4a6",
"type": "main",
"index": 0
}
]
]
}
}
}Häufig gestellte Fragen
Wie verwende ich diesen Workflow?
Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.
Für welche Szenarien ist dieser Workflow geeignet?
Experte - KI-Zusammenfassung, Multimodales KI
Ist es kostenpflichtig?
Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.
Verwandte Workflows
Konkurrenz-Analyse-Content-Inspector: Automatische Themen-Mapping von Websites
Analyse von Wettbewerbsinhalten und -lücken mit Gemini AI, Apify und Google Sheets
If
Set
Code
+
If
Set
Code
30 NodesMychel Garzon
Verschiedenes
n8n-Knoten in der visuellen Referenzbibliothek erkunden
Erkundung von n8n-Knoten in der visuellen Referenzbibliothek
If
Ftp
Set
+
If
Ftp
Set
113 NodesI versus AI
Sonstiges
Automatisierte Bewerbungsjagd von mehreren Jobbörsen
Automatisierung der Jobsuche und -Bewerbung mit 5 Jobplattformen und AI-Lebenslaufgenerator
If
Set
Code
+
If
Set
Code
34 NodesGerald Denor
Persönliche Produktivität
Transkriptions-Evaluator
Analyse und Visualisierung von Audiogesprächen mit DeepGram und GPT-4o
Set
Code
Html
+
Set
Code
Html
54 NodesRealSimple Solutions
Künstliche Intelligenz
Automatisches Senden von Rechnungen an Kunden
Automatisierte Rechnungsverarbeitung mit OCR.Space, GPT-4 und Google Drive zu Gmail
If
Set
Code
+
If
Set
Code
29 NodesMichael Taleb
KI-Zusammenfassung
Vergleich von LinkedIn-Profilen und Stellenbeschreibungen mit Groq AI und GhostGenius
Vergleich der Übereinstimmung von LinkedIn-Profilen und Stellenbeschreibungen mit Groq AI und GhostGenius
If
Set
Code
+
If
Set
Code
17 NodesStephan Koning
Verschiedenes
Workflow-Informationen
Schwierigkeitsgrad
Experte
Anzahl der Nodes18
Kategorie2
Node-Typen12
Autor
Mychel Garzon
@mychel-garzonExterne Links
Auf n8n.io ansehen →
Diesen Workflow teilen