AI 이력서 최적화기
고급
이것은AI Summarization, Multimodal AI분야의자동화 워크플로우로, 18개의 노드를 포함합니다.주로 Set, Code, Gmail, Merge, Webhook 등의 노드를 사용하며. Gemini 분석 및 이메일 보고서를 사용하여 이력서를 직업 설명에 매칭
사전 요구사항
- •Google 계정 및 Gmail API 인증 정보
- •HTTP Webhook 엔드포인트(n8n이 자동으로 생성)
- •대상 API의 인증 정보가 필요할 수 있음
- •Google Gemini API Key
사용된 노드 (18)
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "TzPKUZdrlcTUenHQ",
"meta": {
"instanceId": "d1dc073e8e3059a23e2730f69cb1b90065a2ac39039fea0727fdf9bee77a9131",
"templateCredsSetupCompleted": true
},
"name": "AI CV Optimizer",
"tags": [],
"nodes": [
{
"id": "08a1bb78-33db-4698-9970-c5b38c25835c",
"name": "Webhook - 이력서 최적화 양식",
"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 응답 - HTML 양식",
"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": "이력서 텍스트 추출 (PDF)",
"type": "n8n-nodes-base.extractFromFile",
"position": [
0,
384
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "=cv"
},
"typeVersion": 1
},
{
"id": "75eb814c-8d04-4310-bc01-3fcaf1640634",
"name": "이력서 텍스트 준비",
"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": "채용 공고 가져오기",
"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": "이력서 + 직무 데이터 병합",
"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 모델 - 기본",
"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 출력 파싱",
"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 모델",
"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": "메모지",
"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": "메모지1",
"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": "메모지2",
"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": "메모지5",
"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": "보고서 전송",
"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": "메모지11",
"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 이력서 분석기",
"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": "직무 텍스트 정리기",
"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": "메모지3",
"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
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - AI 요약, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
경쟁사 콘텐츠 격차 분석기: 자동화된 웹사이트 주제 매핑
Gemini AI, Apify, Google Sheets를 사용한 경쟁사 콘텐츠 격차 분석
If
Set
Code
+
If
Set
Code
30 노드Mychel Garzon
기타
시각화 참조 라이브러리에서 n8n 노드를 탐색
可视化 참조 라이브러리에서 n8n 노드를 탐색
If
Ftp
Set
+
If
Ftp
Set
113 노드I versus AI
기타
여러 채용 사이트의 구직 활동 자동화
5개 채용 플랫폼 및 AI 이력서 생성기를 사용한 구직 및 지원 자동화
If
Set
Code
+
If
Set
Code
34 노드Gerald Denor
개인 생산성
전사 평가기
DeepGram 및 GPT-4o를 사용한 오디오 대화 분석 및 시각화
Set
Code
Html
+
Set
Code
Html
54 노드RealSimple Solutions
인공지능
고객에게 인보이스 자동 발송
OCR.Space, GPT-4 및 Google Drive에서 Gmail로 인보이스 처리 자동화
If
Set
Code
+
If
Set
Code
29 노드Michael Taleb
AI 요약
Groq AI와 GhostGenius를 사용하여 LinkedIn 개인 프로필과 직업 설명을 비교
Groq AI와 GhostGenius를 사용하여 LinkedIn 개인 프로필과 직업 설명의 일치도를 비교합니다.
If
Set
Code
+
If
Set
Code
17 노드Stephan Koning
기타