HH OClick/1.0
Shared 10/25/2025
4 views
Visual Workflow
JSON Code
{
"id": "bZExXXjMZbhWbtiy",
"meta": {
"instanceId": "a7951da00dc167f722a4bd0bc0e175503754ae4ae331d85018109ce22f7c48f6",
"templateCredsSetupCompleted": true
},
"name": "OClick/1.0",
"tags": [],
"nodes": [
{
"id": "37ec26c0-cbfc-417d-8b54-d287fd1b6846",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-3280,
-480
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "0ae42763-0c23-4e6c-8649-a4f69a027a1c",
"name": "Auto-search",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3120,
-480
],
"parameters": {
"url": "https://api.hh.ru/saved_searches/vacancies",
"options": {
"batching": {
"batch": {
"batchSize": 30
}
}
},
"sendQuery": true,
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"queryParameters": {
"parameters": [
{
"name": "page",
"value": "0"
},
{
"name": "per_page",
"value": "10"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "2964688c-89c4-4af6-8e80-b17201533336",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
-2960,
-480
],
"parameters": {
"options": {},
"fieldToSplitOut": "items"
},
"typeVersion": 1
},
{
"id": "97db2d0a-753d-4588-9212-7c79fcc646dc",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-2800,
-480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "96d0a2cc-b2ed-4a93-941b-2278aa255c79",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.new_items.count }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3ec16836-d673-4f40-82bf-1c4b4ef50442",
"name": "Split Out1",
"type": "n8n-nodes-base.splitOut",
"position": [
-3120,
-288
],
"parameters": {
"options": {},
"fieldToSplitOut": "items"
},
"typeVersion": 1
},
{
"id": "4c02fb6c-f8af-4efe-9e05-1c869d2eb15a",
"name": "Remove Duplicates",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
-2800,
-288
],
"parameters": {
"compare": "selectedFields",
"options": {},
"fieldsToCompare": "id"
},
"typeVersion": 2
},
{
"id": "9d849040-d16c-477b-91f2-4db0ceab57cd",
"name": "Chunking",
"type": "n8n-nodes-base.code",
"position": [
-1936,
-368
],
"parameters": {
"jsCode": "const items = $input.all();\nconst out = [];\n\nfor (const item of items) {\n const doc = item.json.data ?? item.json;\n if (!doc) continue;\n\n // гарантируем, что sections — массив (в твоём случае они всегда есть)\n const sections = Array.isArray(doc.sections) ? doc.sections : [];\n\n let secIndex = 0;\n for (const sec of sections) {\n // безопасные дефолты\n const sectionName = sec && sec.section ? String(sec.section) : `section_${secIndex}`;\n const sectionText = sec && sec.text ? String(sec.text).trim() : '';\n\n // Unicode-safe slug (короткий, для id)\n const rawSlug = sectionName.toLowerCase().replace(/\\s+/g, '_');\n const sectionSlug = rawSlug.replace(/[^\\p{L}\\p{N}_-]/gu, '').slice(0, 50) || `sec${secIndex}`;\n\n // уникальный id чанка\n const chunkId = `${doc.id ?? 'doc'}_${secIndex}_${sectionSlug}`;\n\n // content: заголовок секции + текст\n //const content = `### ${sectionName}\\n\\n${sectionText}`;\n const content = `${sectionText}`;\n\n // сохраняем в metadata только поля, которые соответствуют исходной схеме документа\n const metadata = {\n // id чанка (уникален)\n id: chunkId,\n // оригинальный документный id\n document_id: doc.id ?? null,\n // основной набор полей из оригинального документа (копируем как есть)\n title: doc.title ?? null,\n salary_range: doc.salary_range ?? null,\n location: doc.location ?? null,\n // experience — копируем целиком (объект {id, name} или null)\n experience: doc.experience ?? null,\n // ключевые навыки — сохраняем оригинал (массив объектов или пустой массив)\n key_skills: doc.key_skills ?? [],\n source_url: doc.source_url ?? null,\n employment_type: doc.employment_type ?? null,\n work_format: doc.work_format ?? [],\n company: doc.company ?? null,\n // информация о секции для удобства поиска/фильтрации\n section: sectionName\n };\n\n out.push({ json: { content, metadata } });\n secIndex++;\n }\n\n // если sections пустой — сейчас мы не создаём чанков (поведение по умолчанию)\n}\n\nreturn out;\n"
},
"executeOnce": false,
"typeVersion": 2
},
{
"id": "1755a1d9-2243-4853-8632-1d85eee3af64",
"name": "Token Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
"position": [
-960,
-32
],
"parameters": {
"chunkSize": 500,
"chunkOverlap": 100
},
"typeVersion": 1
},
{
"id": "146a6584-f9c9-4060-ba1b-0d6ef7ce0971",
"name": "Save To Qdrant",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"position": [
-1072,
-368
],
"parameters": {
"mode": "insert",
"options": {},
"qdrantCollection": {
"__rl": true,
"mode": "id",
"value": "vacancies"
}
},
"credentials": {
"qdrantApi": {
"id": "sFfERYppMeBnFNeA",
"name": "Local QdrantApi database"
}
},
"typeVersion": 1.3
},
{
"id": "e4a11ae7-b2fd-4da9-a662-b32369f5aa74",
"name": "Set Payload",
"type": "n8n-nodes-qdrant.qdrant",
"onError": "continueErrorOutput",
"position": [
-768,
-368
],
"parameters": {
"filter": "={\n \"must\": [\n {\n \"key\": \"metadata.chunk_id\",\n \"match\": {\n \"value\": \"{{ $json.metadata.chunk_id }}\"\n }\n }\n ]\n}",
"points": "=",
"payload": "={\n \"vacancy_id\": {{ $('Chunking').item.json.metadata.document_id }},\n \"location\": {{ $('Chunking').item.json.metadata.location ? $('Chunking').item.json.metadata.location.toJsonString() : \"null\" }},\n \"source_url\": \"{{ $('Chunking').item.json.metadata.source_url }}\",\n \"employment_type_id\": {{ $('Chunking').item.json.metadata.employment_type.id.toJsonString() }},\n \"work_format\": {{ JSON.stringify($('Chunking').item.json.metadata.work_format) }}\n}",
"resource": "payload",
"operation": "setPayload",
"collectionName": {
"__rl": true,
"mode": "name",
"value": "vacancies"
},
"requestOptions": {
"timeout": 10000,
"allowUnauthorizedCerts": true
}
},
"credentials": {
"qdrantRestApi": {
"id": "5UV8rQE53hqsh82x",
"name": "Qdrant account"
}
},
"retryOnFail": false,
"typeVersion": 1
},
{
"id": "578d1af8-5177-4d4a-bb9b-630bb6434ceb",
"name": "Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
-2272,
-288
],
"parameters": {
"text": "={{ $json.sections }}",
"options": {},
"attributes": {
"attributes": [
{
"name": "responsibilities",
"description": "обязанности / что нужно делать;"
},
{
"name": "requirements",
"required": true,
"description": "обязательные требования / необходимый опыт;"
},
{
"name": "additional",
"description": "only optional / desirable skills or experience (explicitly indicated as \"Would be a plus\", \"Welcome if\", \"Desirable\", \"preferred\", \"will be a plus\").\\n IMPORTANT RULES (must follow exactly):\\n1) Use heading-based extraction first: if input contains \"Welcome if\", \"Would be a plus\", \"Desirable\" or similar, extract the text under that heading into \"advantages\".\\n2) If there are lines/sentences containing the optional indicators (see list below), include them in \"advantages\".\\n3) **Do NOT** include in \"advantages\" any marketing/benefits/conditions text such as \"What we offer\", \"Dream job\", \"official employment\", \"paid vacation\", \"remotely\", \"schedule\", \"team\", \"adaptation\" — these are company perks, not desirable experience, and must be excluded from advantages.\\n4) If a sentence matches both optional-indicator and benefit keywords, prefer treating it as BENEFIT and therefore do NOT place it into \"advantages\" unless it clearly expresses desirable SKILL/EXPERIENCE.\\n5) If no relevant optional/desirable items are found, OMIT the \"advantages\" section entirely (do not include it with empty text).\\n6) Preserve original wording and line breaks. Do NOT summarize or paraphrase."
}
]
}
},
"executeOnce": false,
"retryOnFail": true,
"typeVersion": 1.2
},
{
"id": "97e91d6b-1409-49b8-94f1-4cf8b1dc6eff",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-2448,
-288
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "16c9d1ef-4559-47be-9095-915c9c4bbdea",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-2272,
-464
],
"parameters": {
"mode": "combine",
"options": {
"clashHandling": {
"values": {
"resolveClash": "preferLast"
}
}
},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "815af04b-2161-4071-96bb-a8728c29c869",
"name": "ObjToStrArr",
"type": "n8n-nodes-base.code",
"position": [
-2112,
-464
],
"parameters": {
"jsCode": "const items = $input.all();\n\nreturn items.map(item => {\n // Преобразуем key_skills в массив строк\n if (Array.isArray(item.json.key_skills)) {\n item.json.key_skills = item.json.key_skills.map(skill => skill.name);\n }\n\n // Преобразуем work_format в массив строк по id\n if (Array.isArray(item.json.work_format)) {\n item.json.work_format = item.json.work_format.map(format => format.id);\n }\n\n return item;\n});"
},
"typeVersion": 2
},
{
"id": "bcf330b7-5a26-474b-ae65-858bf249d8df",
"name": "Sections cleanup",
"type": "n8n-nodes-base.code",
"position": [
-1968,
-192
],
"parameters": {
"jsCode": "const input = $input.first().json.output;\nconst sections = Object.keys(input)\n .map(key => ({\n section: key,\n text: input[key].replace(/\\n/g, ' ')\n }))\n .filter(section => section.text.trim() !== '');\nreturn [{ json: { sections } }];"
},
"typeVersion": 2
},
{
"id": "8a6ced9a-9dcd-4399-add9-d51869aff6c7",
"name": "Load Content/Metadata",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
-1040,
-192
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "chunk_id",
"value": "={{ $('Chunking').item.json.metadata.id }}"
},
{
"name": "title",
"value": "={{ $('Chunking').item.json.metadata.title }}"
},
{
"name": "experience_id",
"value": "={{ $('Chunking').item.json.metadata.experience.id }}"
},
{
"name": "key_skills",
"value": "={{ $('Chunking').item.json.metadata.key_skills }}"
},
{
"name": "company",
"value": "={{ $('Chunking').item.json.metadata.company }}"
},
{
"name": "section",
"value": "={{ $('Chunking').item.json.metadata.section }}"
}
]
}
},
"jsonData": "={{ $('Chunking').item.json.content }}",
"jsonMode": "expressionData",
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "ba92b4a1-3cf3-4486-8a27-c15aad726d30",
"name": "Payload Extraction",
"type": "n8n-nodes-base.set",
"position": [
-2624,
-288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cbca6f2d-469e-4be9-a42f-02e4403eb2f8",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "8dc8b87c-bfb7-4655-abd7-c54e5d30a4d4",
"name": "title",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "91281710-76ee-4531-bf5c-ca6e4c5707be",
"name": "salary_range",
"type": "object",
"value": "={{ $json.salary_range }}"
},
{
"id": "f1953bd7-2ba2-4fb7-b9a8-cf226bf58b25",
"name": "location",
"type": "string",
"value": "={{ $json.address.city }}"
},
{
"id": "c197a189-80ba-4834-8c3a-40e33dfa0759",
"name": "experience",
"type": "object",
"value": "={{ $json.experience }}"
},
{
"id": "d2a8f427-565e-49e2-a606-3c5a6cac1836",
"name": "sections",
"type": "string",
"value": "={{ $json.description }}"
},
{
"id": "ba314b21-e78c-425e-b975-10bb2432ef3d",
"name": "key_skills",
"type": "array",
"value": "={{ $json.key_skills }}"
},
{
"id": "6b91dc6d-84cf-4ec8-b9f5-decc788efd3f",
"name": "source_url",
"type": "string",
"value": "={{ $json.alternate_url }}"
},
{
"id": "0a9e300a-f2ea-4ada-be3d-ef971441e80f",
"name": "employment_type",
"type": "object",
"value": "={{ $json.employment_form }}"
},
{
"id": "8bbaf1fc-9da7-4fc7-84ca-850a8e1905ea",
"name": "work_format",
"type": "array",
"value": "={{ $json.work_format }}"
},
{
"id": "5b72d543-b957-4dfb-aaa1-f55b1a685248",
"name": "company",
"type": "string",
"value": "={{ $json.employer.name }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8cab2a37-6e55-4d5c-a45b-a8704e44791e",
"name": "Scroll Points",
"type": "n8n-nodes-qdrant.qdrant",
"position": [
-1760,
-368
],
"parameters": {
"limit": 100,
"filter": "={\n \"must\": [\n {\n \"key\": \"vacancy_id\",\n \"match\": {\n \"value\": {{ $json.metadata.document_id }}\n }\n }\n ]\n}",
"resource": "point",
"operation": "scrollPoints",
"collectionName": {
"__rl": true,
"mode": "list",
"value": "vacancies",
"cachedResultName": "vacancies"
},
"requestOptions": {}
},
"credentials": {
"qdrantRestApi": {
"id": "5UV8rQE53hqsh82x",
"name": "Qdrant account"
}
},
"typeVersion": 1
},
{
"id": "eb9a2819-7d37-4392-8279-f5f2cc9a1f78",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
-1584,
-368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "62eac888-357f-4c41-9e12-163819307fd6",
"operator": {
"type": "array",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.result.points }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "a4e5979d-7de8-47e3-8d46-bb108620a831",
"name": "Delete Points",
"type": "n8n-nodes-qdrant.qdrant",
"position": [
-1424,
-416
],
"parameters": {
"filter": "={\n \"must\": [\n {\n \"key\": \"vacancy_id\",\n \"match\": {\n \"value\": {{ $json.result.points[0].payload.vacancy_id }}\n }\n }\n ]\n}",
"resource": "point",
"operation": "deletePoints",
"collectionName": {
"__rl": true,
"mode": "list",
"value": "vacancies",
"cachedResultName": "vacancies"
},
"requestOptions": {}
},
"credentials": {
"qdrantRestApi": {
"id": "5UV8rQE53hqsh82x",
"name": "Qdrant account"
}
},
"typeVersion": 1
},
{
"id": "a5ca74d9-d4fd-4506-a65a-357620eaf2ab",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"notes": "Cover Letter",
"position": [
-224,
-352
],
"parameters": {
"text": "Максим Кришталь\nМужчина\nshimorowm@gmail.com\nJava-разработчик\nСпециализации:\nПрограммист, разработчик\nОпыт работы — 1 год 3 месяца\nMicroRestBank\ngithub.com/22crystyle/MicroRestBank\nАвгуст 2024 — настоящее время 1 год 3 месяца\nJava-разработчик\nРазработка комплексного банковского приложения на основе микросервисной архитектуры.\nОписание: Проект MicroRestBank представляет собой платформу для управления пользователями и банковскими картами через RESTful API. Система включает в себя функции создания карт, их блокировки, управления пользователями и осуществления денежных переводов.\nАрхитектура и Реализация: Спроектировал и разработал набор независимых микросервисов на Java 21 и Spring Boot 3, включая:\n- Разрабатывал и отлаживал серверный Java-код (Spring Boot 3, Spring Data JPA, Spring Security) - опыт root-cause analysis и hotfix’ов в продакшн/стейдж окружениях.\n- Единая точка входа для всех клиентских запросов, реализованная на Spring Cloud Gateway.\n- Создал и поддерживал механизмы аутентификации и авторизации с Keycloak (OAuth2, JWT), в т.ч. стратегию ролей и прав доступа.\n- Реализация всей бизнес-логики для банковских карт, включая транзакции и управление статусами.\n- Управление данными клиентов.\n- Сервис-дискавери для динамического взаимодействия между сервисами (Spring Cloud Netflix Eureka).\n- Проектировал и реализовал интеграционные механизмы между микросервисами (REST, Kafka), обеспечив надёжную асинхронную репликацию данных.\n- Реализовал асинхронное взаимодействие между сервисами для обновления данных с помощью Apache Kafka и Debezium (Change Data Capture).\n- Управлял схемами БД и миграциями (PostgreSQL, Liquibase); писал оптимизированные SQL-запросы для аналитики и исправления ошибок.\n- Документировал API с использованием OpenAPI (Swagger).\n- Писал unit и интеграционные тесты (JUnit, Mockito) и автоматизировал сценарии сборки/деплоя.\n- Настроил CI/CD и контейнеризацию (Gradle, Docker, Docker Compose) для локальной и командной разработки.\nСтек:\n- Бэкенд: Java 21, Spring Boot 3, Spring Framework, Spring Data JPA, Spring Security\n- Микросервисы: Microservices Architecture, Spring Cloud (Gateway, Netflix Eureka), RESTful API, Event-Driven Architecture\n- Базы данных и брокеры сообщений: PostgreSQL, Liquibase, Apache Kafka, Debezium (Change Data Capture)\n- Аутентификация и Авторизация: Keycloak, JWT, OAuth2\n- DevOps и Инструменты: Docker, Docker Compose, Gradle, Git, CI/CD, JetBrains IntelliJ IDEA\n- API и Документация: OpenAPI (Swagger)\nОбразование\nВысшее\nСанкт-Петербургский государственный электротехнический университет «ЛЭТИ» имени В.И. Ульянова (Ленина), Санкт-Петербург\n2025\nФакультет компьютерных технологий и информатики, Прикладная математика и информатика\nНавыки\nЗнание языков\nРусский — Родной\nАнглийский — B1 — Средний\nНавыки\nJava; Spring Framework; Hibernate; Git; Docker; Liquibase; Apache Kafka; Gradle; Apache Maven; PostgreSQL; Linux; REST API; Java SE; JPA; Английский язык; Spring; Spring Boot; Spring Cloud; Spring Data; Spring MVC; Spring Security; Spring Web; Keycloak; Hibernate ORM; SQL; SOLID; ООП; JUnit; Debezium; Mockito\nДополнительная информация\nОбо мне\nJava backend-разработчик, ориентированный на качество и поддерживаемость кода. Владею современным стеком:\n- Бэкенд: Java 21, Spring Boot 3, Spring Framework, Spring Data JPA, Spring Security\n- Микросервисы: Microservices Architecture, Spring Cloud (Gateway, Netflix Eureka), RESTful API, Event-Driven Architecture\n- Базы данных и брокеры сообщений: PostgreSQL, Liquibase, Apache Kafka, Debezium (Change Data Capture)\n- Аутентификация и Авторизация: Keycloak, JWT, OAuth2\n- DevOps и Инструменты: Docker, Docker Compose, Gradle, Git, CI/CD, JetBrains IntelliJ IDEA\n- API и Документация: OpenAPI (Swagger)\nПрименяю принципы ООП и SOLID, практикую тестирование и автоматизацию процессов. Быстро адаптируюсь к новым задачам и технологиям.",
"options": {
"maxIterations": 10,
"systemMessage": "You are an HR recruiter who helps junior candidates get hired at IT companies.\n\n# TASK\nCreate a very short cover letter in Russian that explains to the employer why the candidate is suitable for the vacancy. Write from the candidate's point of view so the letter can be copied and sent as-is.\n\n# HARD RULES (mandatory):\n1) DO NOT add prefaces, explanations, meta-comments, separators (---), status lines, signatures like \"(Письмо готово...)\" or similar. Return **only** the cover letter text. No other symbols or lines.\n2) Return strictly the letter text (plain text), without wrappers.\n3) You receive only the resume text (context). Use the Actual_Job_Vacancies utility to obtain the current vacancy the candidate is applying for.\n4) If the vacancy does not match the resume — use the found fragments (responsibilities/requirements/additional) as the information source and still generate a short cover letter.\n5) If the tool results come as escaped JSON inside text — parse them and merge into a vacancy structure.\n6) The letter must be short, mention the title and company if available, and include several relevant skills from the resume.\n7) If neither vacancies nor fragments exist — the reply must be exactly: `Нет данных для составления сопроводительного письма.` (and nothing else).",
"enableStreaming": false,
"returnIntermediateSteps": true
},
"promptType": "define"
},
"notesInFlow": true,
"typeVersion": 2.2
},
{
"id": "da314519-e507-42b3-9dc9-37767a949171",
"name": "Actual Job Vacancies",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"position": [
-144,
-176
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 3,
"options": {
"searchFilterJson": "={\n \"should\": [\n {\n \"key\": \"vacancy_id\",\n \"match\": {\n \"value\": {{ $('Loop Over Items1').item.json.id }}\n }\n }\n ]\n}"
},
"toolDescription": "Database of Actual Job Vacancies",
"qdrantCollection": {
"__rl": true,
"mode": "list",
"value": "vacancies",
"cachedResultName": "vacancies"
}
},
"credentials": {
"qdrantApi": {
"id": "sFfERYppMeBnFNeA",
"name": "Local QdrantApi database"
}
},
"typeVersion": 1.3
},
{
"id": "3dbf5ed7-6098-468e-b219-c36189fc3572",
"name": "Merge1",
"type": "n8n-nodes-base.merge",
"position": [
-592,
-448
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 3.2
},
{
"id": "69fbcb02-f829-4642-ac61-1d5533de2a4c",
"name": "Loop Over Items1",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-400,
-448
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "dd3811ee-9587-4331-a067-9bbeb9c2659d",
"name": "qwen3-embedd-save",
"type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
"position": [
-1152,
-192
],
"parameters": {
"model": "qwen3-embedding:8b"
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "c70a3aa7-0127-45d0-bab9-5cf485c7fa50",
"name": "qwen3-embedd-retrieve",
"type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
"position": [
-80,
-16
],
"parameters": {
"model": "qwen3-embedding:8b"
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "3886ea8c-7ebc-43f7-8a70-3854d3fb91a6",
"name": "qwen3:4b:it:q8-extract",
"type": "@n8n/n8n-nodes-langchain.lmOllama",
"position": [
-2272,
-128
],
"parameters": {
"model": "qwen3:4b-instruct-2507-q8_0",
"options": {
"topK": 1,
"topP": 1,
"numCtx": 8192,
"lowVram": false,
"mainGpu": 0,
"useMMap": true,
"numBatch": 128,
"useMLock": true,
"numThread": 14,
"vocabOnly": false,
"temperature": 0,
"repeatPenalty": 1,
"penalizeNewline": false,
"presencePenalty": 0,
"frequencyPenalty": 0
}
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "0f6015dc-caa8-4504-9c03-b1977990a1c7",
"name": "qwen3:4b:it:q8-generate",
"type": "@n8n/n8n-nodes-langchain.lmChatOllama",
"position": [
-272,
-176
],
"parameters": {
"model": "qwen3:4b-instruct-2507-q8_0",
"options": {
"numCtx": 4096,
"numThread": 14
}
},
"credentials": {
"ollamaApi": {
"id": "JrVtVfb5WaGIXcqR",
"name": "Ollama RTX"
}
},
"typeVersion": 1
},
{
"id": "0e6c9021-bfe6-42c2-bff0-7ab0c1ffa7f0",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
80,
-448
],
"parameters": {
"url": "https://api.hh.ru/negotiations",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "message",
"value": "={{ $json.output }}"
},
{
"name": "resume_id",
"value": "054142d0ff0f5da2090039ed1f47344b585273"
},
{
"name": "vacancy_id",
"value": "={{ $('Loop Over Items1').item.json.id }}"
}
]
},
"genericAuthType": "oAuth2Api",
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "76b1d74f-877c-419e-8c17-99a6e5be7d10",
"name": "Get New Vacancies",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3280,
-288
],
"parameters": {
"url": "={{ $json.new_items.url }}",
"options": {
"batching": {
"batch": {
"batchSize": 30
}
}
},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "oAuth2Api",
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"credentials": {
"oAuth2Api": {
"id": "l9tyPEWtPvzUKFXJ",
"name": "HH OAuth2"
}
},
"typeVersion": 4.2
},
{
"id": "92a35ea6-4a80-4386-8edd-a21305ef8423",
"name": "Merge3",
"type": "n8n-nodes-base.merge",
"position": [
-1248,
-368
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "805e8e3b-5523-43f2-b972-e7d82443a87f",
"name": "Get Vacancy Details",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2960,
-288
],
"parameters": {
"url": "=https://api.hh.ru/vacancies/{{ $json.id }}",
"options": {
"batching": {
"batch": {
"batchSize": 30
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "OClick/1.0 (shimorowm@gmail.com)"
}
]
}
},
"typeVersion": 4.2
}
],
"active": true,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false,
"executionOrder": "v1",
"saveExecutionProgress": true
},
"versionId": "596aad2d-bf3d-44b9-9b61-a9ed9b9fcaf7",
"connections": {
"If": {
"main": [
[
{
"node": "Get New Vacancies",
"type": "main",
"index": 0
}
],
[]
]
},
"If1": {
"main": [
[
{
"node": "Delete Points",
"type": "main",
"index": 0
}
],
[
{
"node": "Merge3",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "ObjToStrArr",
"type": "main",
"index": 0
}
]
]
},
"Merge1": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
}
]
]
},
"Merge3": {
"main": [
[
{
"node": "Save To Qdrant",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
},
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Chunking": {
"main": [
[
{
"node": "Scroll Points",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Split Out1": {
"main": [
[
{
"node": "Get Vacancy Details",
"type": "main",
"index": 0
}
]
]
},
"Auto-search": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"ObjToStrArr": {
"main": [
[
{
"node": "Chunking",
"type": "main",
"index": 0
},
{
"node": "Merge1",
"type": "main",
"index": 0
}
]
]
},
"Set Payload": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 1
}
]
]
},
"Delete Points": {
"main": [
[
{
"node": "Merge3",
"type": "main",
"index": 0
}
]
]
},
"Scroll Points": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Save To Qdrant": {
"main": [
[
{
"node": "Set Payload",
"type": "main",
"index": 0
}
]
]
},
"Token Splitter": {
"ai_textSplitter": [
[
{
"node": "Load Content/Metadata",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
],
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items1": {
"main": [
[],
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Auto-search",
"type": "main",
"index": 0
}
]
]
},
"Sections cleanup": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Get New Vacancies": {
"main": [
[
{
"node": "Split Out1",
"type": "main",
"index": 0
}
]
]
},
"Remove Duplicates": {
"main": [
[
{
"node": "Payload Extraction",
"type": "main",
"index": 0
}
]
]
},
"qwen3-embedd-save": {
"ai_embedding": [
[
{
"node": "Save To Qdrant",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Payload Extraction": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Get Vacancy Details": {
"main": [
[
{
"node": "Remove Duplicates",
"type": "main",
"index": 0
}
]
]
},
"Actual Job Vacancies": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Information Extractor": {
"main": [
[
{
"node": "Sections cleanup",
"type": "main",
"index": 0
}
]
]
},
"Load Content/Metadata": {
"ai_document": [
[
{
"node": "Save To Qdrant",
"type": "ai_document",
"index": 0
}
]
]
},
"qwen3-embedd-retrieve": {
"ai_embedding": [
[
{
"node": "Actual Job Vacancies",
"type": "ai_embedding",
"index": 0
}
]
]
},
"qwen3:4b:it:q8-extract": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"qwen3:4b:it:q8-generate": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}