{ "meta": { "instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" }, "nodes": [ { "id": "63501cc8-77c9-4037-9f70-da23b6d20b03", "name": "When clicking ‘Test workflow’", "type": "n8n-nodes-base.manualTrigger", "position": [ 280, 440 ], "parameters": {}, "typeVersion": 1 }, { "id": "00de989c-d9e9-4b42-b5db-7097800a6017", "name": "Zip Entries", "type": "n8n-nodes-base.set", "position": [ 1380, 360 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "833a554d-2b39-4160-9348-18b17b28ce30", "name": "data", "type": "array", "value": "={{ \n $json.review_author.map((review_author, idx) => ({\n review_author,\n review_author_reviews_count: $json.review_author_reviews_count[idx].replace(' reviews', '').toInt(),\n review_country: $json.review_country[idx],\n review_date: $json.review_date[idx].toDate(),\n review_date_of_experience: $json.review_date_of_experience[idx].replace('Date of experience: ', '').toDate(),\n review_rating: $json.review_rating[idx].toInt(),\n review_text: $json.review_text[idx],\n review_title: $json.review_title[idx],\n review_url: $('Get TrustPilot Page').params.url.match(/https:\\/\\/[^/]+/) + $json.review_url[idx],\n }))\n}}" } ] } }, "typeVersion": 3.4 }, { "id": "9290e116-c001-49d5-ae4c-d91cd246f2c2", "name": "Extract Reviews", "type": "n8n-nodes-base.html", "position": [ 1140, 520 ], "parameters": { "options": { "trimValues": true }, "operation": "extractHtmlContent", "extractionValues": { "values": [ { "key": "review_author", "cssSelector": "[data-service-review-card-paper] [data-consumer-name-typography]", "returnArray": true }, { "key": "review_rating", "attribute": "data-service-review-rating", "cssSelector": "[data-service-review-rating]", "returnArray": true, "returnValue": "attribute" }, { "key": "review_title", "cssSelector": "[data-service-review-title-typography]", "returnArray": true }, { "key": "review_text", "cssSelector": "[data-service-review-text-typography]", "returnArray": true }, { "key": "review_date_of_experience", "cssSelector": "[data-service-review-date-of-experience-typography]", "returnArray": true }, { "key": "review_date", "attribute": "datetime", "cssSelector": "[data-service-review-date-time-ago]", "returnArray": true, "returnValue": "attribute" }, { "key": "review_country", "cssSelector": "[data-consumer-country-typography]", "returnArray": true }, { "key": "review_author_reviews_count", "cssSelector": "[data-consumer-reviews-count-typography]", "returnArray": true }, { "key": "review_url", "attribute": "href", "cssSelector": "a[data-review-title-typography]", "returnArray": true, "returnValue": "attribute" } ] } }, "typeVersion": 1.2 }, { "id": "4aa3e50d-fcce-48a7-8237-c12f8592f69e", "name": "Reviews to List", "type": "n8n-nodes-base.splitOut", "position": [ 1380, 520 ], "parameters": { "options": {}, "fieldToSplitOut": "data" }, "typeVersion": 1 }, { "id": "a6b9abf9-a17a-4f30-9f90-6183770c4933", "name": "Default Data Loader", "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader", "position": [ 1980, 520 ], "parameters": { "options": { "metadata": { "metadataValues": [ { "name": "review_author", "value": "={{ $json.review_author }}" }, { "name": "review_author_reviews_count", "value": "={{ $json.review_author_reviews_count }}" }, { "name": "review_country", "value": "={{ $json.review_country }}" }, { "name": "review_date", "value": "={{ $json.review_date }}" }, { "name": "review_date_of_experience", "value": "={{ $json.review_date_of_experience }}" }, { "name": "review_rating", "value": "={{ $json.review_rating }}" }, { "name": "review_date_month", "value": "={{ $json.review_date.toDateTime().format('M') }}" }, { "name": "review_date_year", "value": "={{ $json.review_date.toDateTime().format('yyyy') }}" }, { "name": "review_date_of_experience_month", "value": "={{ $json.review_date_of_experience.toDateTime().format('M') }}" }, { "name": "review_date_of_experience_year", "value": "={{ $json.review_date_of_experience.toDateTime().format('yyyy') }}" }, { "name": "company_id", "value": "={{ $('Set Variables').item.json.companyId }}" }, { "name": "review_url", "value": "={{ $json.review_url }}" } ] } }, "jsonData": "={{ $json.review_title }}\n{{ $json.review_text }}", "jsonMode": "expressionData" }, "typeVersion": 1 }, { "id": "afd8907c-9a59-4dcc-94c5-2114fb2a7d5d", "name": "Recursive Character Text Splitter", "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter", "position": [ 1980, 660 ], "parameters": { "options": {}, "chunkSize": 4000 }, "typeVersion": 1 }, { "id": "e22d92b8-e8e9-42aa-9d02-2e70234f11ed", "name": "Embeddings OpenAI", "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi", "position": [ 1860, 520 ], "parameters": { "model": "text-embedding-3-small", "options": {} }, "credentials": { "openAiApi": { "id": "8gccIjcuf3gvaoEr", "name": "OpenAi account" } }, "typeVersion": 1 }, { "id": "f0ea6b63-c96d-4b3f-8a21-d0f2dbb4efc3", "name": "Set Variables", "type": "n8n-nodes-base.set", "position": [ 520, 440 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "2e58a9fa-a14d-4a6c-8cc8-8ec947c791fb", "name": "companyId", "type": "string", "value": "www.freddiesflowers.com" } ] } }, "typeVersion": 3.4 }, { "id": "0188986f-fbe9-4c06-892a-3cb71b52a309", "name": "Get Payload of Points", "type": "n8n-nodes-base.httpRequest", "position": [ 1740, 1120 ], "parameters": { "url": "=http://qdrant:6333/collections/trustpilot_reviews/points", "method": "POST", "options": {}, "jsonBody": "={{\n {\n \"ids\": $json.points,\n \"with_payload\": true\n }\n}}", "sendBody": true, "specifyBody": "json", "authentication": "predefinedCredentialType", "nodeCredentialType": "qdrantApi" }, "credentials": { "qdrantApi": { "id": "NyinAS3Pgfik66w5", "name": "QdrantApi account" } }, "typeVersion": 4.2 }, { "id": "5fc6e0b6-507f-4cfd-951b-be3709b86ac2", "name": "Clusters To List", "type": "n8n-nodes-base.splitOut", "position": [ 1480, 1120 ], "parameters": { "options": {}, "fieldToSplitOut": "output" }, "typeVersion": 1 }, { "id": "f21369b9-1dd5-4b35-a1f3-00fd67794051", "name": "OpenAI Chat Model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [ 2140, 1340 ], "parameters": { "model": "gpt-4o-mini", "options": {} }, "credentials": { "openAiApi": { "id": "8gccIjcuf3gvaoEr", "name": "OpenAi account" } }, "typeVersion": 1 }, { "id": "b0075699-6513-4781-b5de-81d1ab81dfe1", "name": "Only Clusters With 3+ points", "type": "n8n-nodes-base.filter", "position": [ 1480, 1300 ], "parameters": { "options": {}, "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "328f806c-0792-4d90-9bee-a1e10049e78f", "operator": { "type": "array", "operation": "lengthGt", "rightType": "number" }, "leftValue": "={{ $json.points }}", "rightValue": 2 } ] } }, "typeVersion": 2 }, { "id": "f6a6209c-d269-4238-8e92-230df7b41df9", "name": "Set Variables1", "type": "n8n-nodes-base.set", "position": [ 519, 1220 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "2e58a9fa-a14d-4a6c-8cc8-8ec947c791fb", "name": "companyId", "type": "string", "value": "={{ $json.companyId }}" }, { "id": "37cf8af2-6f0f-40b1-b822-c9bd6a620a3c", "name": "review_date_from", "type": "string", "value": "={{ $today.startOf('month').toISO() }}" }, { "id": "8d72f739-f832-4c25-b62a-2ae70ad2b1e7", "name": "review_date_to", "type": "string", "value": "={{ $today.endOf('month').toISO() }}" } ] } }, "typeVersion": 3.4 }, { "id": "85cb48b1-0ab9-4f88-88f3-82fcfb041ebe", "name": "Find Reviews", "type": "n8n-nodes-base.httpRequest", "position": [ 896, 1160 ], "parameters": { "url": "=http://qdrant:6333/collections/trustpilot_reviews/points/scroll", "method": "POST", "options": {}, "jsonBody": "={\n \"limit\": 500,\n \"filter\":{\n \"must\": [\n {\n \"key\": \"metadata.company_id\",\n \"match\": { \"value\": \"{{ $('Set Variables1').item.json.companyId }}\" }\n },\n {\n \"key\": \"metadata.review_date\",\n \"range\": {\n \"gte\": \"{{ $('Set Variables1').item.json.review_date_from }}\",\n \"gt\": null,\n \"lt\": null,\n \"lte\": \"{{ $('Set Variables1').item.json.review_date_to }}\"\n }\n }\n ]\n },\n \"with_vector\":true\n}", "sendBody": true, "specifyBody": "json", "authentication": "predefinedCredentialType", "nodeCredentialType": "qdrantApi" }, "credentials": { "qdrantApi": { "id": "NyinAS3Pgfik66w5", "name": "QdrantApi account" } }, "typeVersion": 4.2 }, { "id": "69bbd197-c78f-4dae-9300-fe23d4d49855", "name": "Prep Output For Export", "type": "n8n-nodes-base.set", "position": [ 2720, 1203 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "={{ {\n ...$json.output,\n \"CompanyID\": $('Set Variables1').item.json.companyId,\n \"From\": $('Set Variables1').item.json.review_date_from,\n \"To\": $('Set Variables1').item.json.review_date_to,\n \"Number of Responses\": $('Get Payload of Points').item.json.result.length,\n \"Raw Responses\": $('Get Payload of Points').item.json.result.map(item =>\n [\n item.payload.metadata.review_date,\n item.payload.metadata.review_author,\n item.payload.metadata.review_rating,\n item.payload.content.replaceAll('\"', '\\\"').replaceAll('\\n', ' '),\n item.payload.metadata.review_url,\n ]\n ).join('\\n')\n} }}\n" }, "typeVersion": 3.4 }, { "id": "d77daa23-6acf-4daa-bf4c-33da4d05a54c", "name": "Export To Sheets", "type": "n8n-nodes-base.googleSheets", "position": [ 2940, 1203 ], "parameters": { "columns": { "value": {}, "schema": [ { "id": "CompanyID", "type": "string", "display": true, "removed": false, "required": false, "displayName": "CompanyID", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "From", "type": "string", "display": true, "removed": false, "required": false, "displayName": "From", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "To", "type": "string", "display": true, "removed": false, "required": false, "displayName": "To", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Insight", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Insight", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Sentiment", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Sentiment", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Suggested Improvements", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Suggested Improvements", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Number of Responses", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Number of Responses", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Raw Responses", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Raw Responses", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "autoMapInputData", "matchingColumns": [] }, "options": {}, "operation": "append", "sheetName": { "__rl": true, "mode": "name", "value": "=Sheet1" }, "documentId": { "__rl": true, "mode": "id", "value": "=1wAwWCcIZod00IGtxwTbTgjIRbKHu3Yl9wYWJ8GeT2Os" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "XHvC7jIRR8A2TlUl", "name": "Google Sheets account" } }, "typeVersion": 4.4 }, { "id": "1f60c3a5-a47a-4313-9b29-8ea652d573f7", "name": "Clear Existing Reviews", "type": "n8n-nodes-base.httpRequest", "position": [ 760, 440 ], "parameters": { "url": "http://qdrant:6333/collections/trustpilot_reviews/points/delete", "method": "POST", "options": {}, "jsonBody": "={\n \"filter\": {\n \"must\": [\n {\n \"key\": \"metadata.company_id\",\n \"match\": {\n \"value\": \"{{ $('Set Variables').item.json.companyId }}\"\n }\n }\n ]\n }\n}", "sendBody": true, "specifyBody": "json", "authentication": "predefinedCredentialType", "nodeCredentialType": "qdrantApi" }, "credentials": { "qdrantApi": { "id": "NyinAS3Pgfik66w5", "name": "QdrantApi account" } }, "typeVersion": 4.2 }, { "id": "61c3117c-757c-45dd-b9d5-1122b793be30", "name": "Trigger Insights", "type": "n8n-nodes-base.executeWorkflow", "position": [ 2660, 440 ], "parameters": { "options": {}, "workflowId": "={{ $workflow.id }}" }, "typeVersion": 1 }, { "id": "d3c6e81f-34bb-4be9-b869-2c219b87c4fb", "name": "Prep Values For Trigger", "type": "n8n-nodes-base.set", "position": [ 2460, 440 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "24dd90ad-390f-444e-ba6c-8c06a41e836e", "name": "companyId", "type": "string", "value": "={{ $('Set Variables').item.json.companyId }}" } ] } }, "executeOnce": true, "typeVersion": 3.4 }, { "id": "64af9cc7-a194-4427-ba78-d9a1136b962f", "name": "Execute Workflow Trigger", "type": "n8n-nodes-base.executeWorkflowTrigger", "position": [ 316, 1220 ], "parameters": {}, "typeVersion": 1 }, { "id": "7b6ba502-36c2-41e6-9d67-781d0d40a569", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ 186.9455564469605, 263.2301011325764 ], "parameters": { "color": 7, "width": 787.3314861380661, "height": 465.52420584035275, "content": "## 1단계. 새로 시작하기 \n이 데모를 위해, 우리는 선택된 회사의 Qdrant 벡터 저장소에 있는 기존의 모든 기록을 지울 것입니다. 우리는 Qdrant의 delete points API를 사용하여 이 작업을 수행합니다." }, "typeVersion": 1 }, { "id": "a99389d4-8ea6-4379-b725-f30e92b0d29e", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ 1006.3778510483207, 148.50042906971555 ], "parameters": { "color": 7, "width": 638.5221986278162, "height": 580.2538779032135, "content": "## 2단계. TrustPilot에서 회사 리뷰 스크래핑 \n[HTTP Request Node에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/) \n\n예시를 위해 가장 최근 3페이지의 리뷰를 스크래핑할 것입니다. 하지만 필요하다면 모든 리뷰를 쉽게 스크래핑할 수 있습니다. HTML 노드는 반환된 HTML 페이지에서 데이터를 추출하는 편리한 방법을 제공하며, 이를 사용하여 모든 리뷰 데이터를 검색할 것입니다." }, "typeVersion": 1 }, { "id": "139ccadd-9135-4681-b2eb-403b8d8bd710", "name": "Get TrustPilot Page", "type": "n8n-nodes-base.httpRequest", "position": [ 1140, 360 ], "parameters": { "url": "=https://uk.trustpilot.com/review/{{ $('Set Variables').item.json.companyId }}?sort=recency", "options": { "pagination": { "pagination": { "parameters": { "parameters": [ { "name": "page", "value": "={{ $pageCount + 1 }}" } ] }, "maxRequests": 3, "limitPagesFetched": true } } } }, "executeOnce": false, "typeVersion": 4.2 }, { "id": "1c71db65-713b-4c31-9c11-5ff678fb327a", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ 1680, 140 ], "parameters": { "color": 7, "width": 638.5221986278162, "height": 689.8000993522735, "content": "## 3단계. Qdrant에 리뷰 저장\n\n[Qdrant Vector Store에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreqdrant/)\n\n벡터 데이터베이스는 데이터 저장의 훌륭한 방법으로, 유사성 검색에 관심이 있다면 유용합니다. 이는 여기에서도 적용되며, 우리는 유사한 리뷰를 그룹화하여 패턴을 찾고 싶기 때문입니다. Qdrant은 강력한 벡터 데이터베이스로, 강력한 API 구현과 고급 필터링 기능 때문에 선택된 도구입니다." }, "typeVersion": 1 }, { "id": "a4f82a1b-5a76-46b6-a7a3-84ab09b46699", "name": "Qdrant Vector Store", "type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant", "position": [ 1860, 360 ], "parameters": { "mode": "insert", "options": {}, "qdrantCollection": { "__rl": true, "mode": "id", "value": "=trustpilot_reviews" } }, "credentials": { "qdrantApi": { "id": "NyinAS3Pgfik66w5", "name": "QdrantApi account" } }, "typeVersion": 1 }, { "id": "cbad9e73-c5b3-474c-95ef-7269addc4e62", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [ 216, 1000 ], "parameters": { "color": 7, "width": 543.4265511994403, "height": 453.31956386852846, "content": "## 5단계. 통찰 서브워크플로우 \n[Workflow Triggers에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger) \n\n이 서브워크플로우는 companyId를 사용하여 우리 Qdrant 벡터 저장소에서 관련 레코드를 찾습니다. 또한 \"from\"과 \"to\" 날짜를 받아 통찰을 특정 범위로 제한합니다 - 이를 통해 '리뷰의 지난 한 달에 대한 통찰만 원합니다'와 같이 말할 수 있습니다." }, "typeVersion": 1 }, { "id": "9c530716-63f4-4368-8d0e-0cdbe8f5b08e", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ 780, 920 ], "parameters": { "color": 7, "width": 557.7420442679241, "height": 526.2781960611934, "content": "## 6단계. 리뷰에 클러스터링 알고리즘 적용 \n[Python을 n8n에서 사용하는 방법에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code) \n\n우리는 원하는 회사 리뷰에 대한 벡터 임베딩을 검색하고, 그들에 대해 고급 클러스터링 알고리즘을 수행할 것입니다. 이 강력한 기술은 유사한 임베딩을 클러스터로 빠르게 그룹화하여 인기 있는 피드백, 의견 및 문제점을 발견하는 데 사용할 수 있습니다!" }, "typeVersion": 1 }, { "id": "9790b3a5-cc7c-4e12-8038-fc661c8226f8", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [ 1360, 920 ], "parameters": { "color": 7, "width": 598.5585287222906, "height": 605.9905193915599, "content": "## 7단계. 클러스터별 리뷰 가져오기\n\n[코드 노드 사용에 대해 자세히 알아보기](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/)\n\n우리의 코드 노드에 의해 그룹화되고 반환된 Qdrant 포인트 ID를 가지고, 각 항목의 페이로드를 가져오는 것이 남은 일입니다. 클러스터링 알고리즘은 완벽하지 않으므로, 데이터에 따라 조정이 필요할 수 있습니다." }, "typeVersion": 1 }, { "id": "267057b6-9727-4a45-9d87-5429da42f48e", "name": "Sticky Note7", "type": "n8n-nodes-base.stickyNote", "position": [ 1980, 969 ], "parameters": { "color": 7, "width": 587.6069484146701, "height": 552.9535170892194, "content": "## 8단계. 그룹화된 리뷰로부터 통찰 얻기\n\n[Information Extractor Node 사용에 대해 더 읽기](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor)\n\n다음으로, 우리는 우리의 최첨단 LLM을 사용하여 리뷰에 대한 통찰을 생성할 것입니다. 이렇게 하면, 리뷰 내의 많은 주요 주제를 다루는 더 세부적인 결과를 끌어낼 수 있을 것입니다." }, "typeVersion": 1 }, { "id": "b8cc07d0-ffa3-425f-ae74-76dcb68fa88f", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [ 2600, 980 ], "parameters": { "color": 7, "width": 572.5638733479158, "height": 464.4019616956416, "content": "## 9단계. Insights 시트에 작성\n마지막으로, 우리 완료된 인사이트가 워크플로에서 이전에 만든 Insights 시트에 추가됩니다.\n\n샘플 시트를 여기에서 찾을 수 있습니다: https://docs.google.com/spreadsheets/d/e/2PACX-1vQ6ipJnXWXgr5wlUJnhioNpeYrxaIpsRYZCwN3C-fFXumkbh9TAsA_JzE0kbv7DcGAVIP7az0L46_2P/pubhtml" }, "typeVersion": 1 }, { "id": "0dac0854-7106-44e3-bd68-fad7b201a6bc", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [ 2340, 240 ], "parameters": { "color": 7, "width": 519.6419932444072, "height": 429.11782776909047, "content": "## 4단계. Insights 하위 워크플로우 트리거\n\n[워크플로우 트리거에 대해 자세히 알아보기](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow)\n\n하위 워크플로우는 설문조사에 대한 분석을 트리거하는 데 사용됩니다. 이 분리는 선택사항이지만, 두 부분 프로세스를 더 잘 설명하기 위해 여기에서 사용됩니다." }, "typeVersion": 1 }, { "id": "4aa7e73e-c29d-41df-b2f8-a62109285ccb", "name": "Sticky Note9", "type": "n8n-nodes-base.stickyNote", "position": [ 460, 380 ], "parameters": { "width": 226.36363118160727, "height": 327.0249036433755, "content": "여기에 회사를 설정하세요! Trustpilot은 이를 URL의 일부로 인식해야 합니다." }, "typeVersion": 1 }, { "id": "4d895cf9-452c-401e-a6f3-b9d3a359a96d", "name": "Apply K-means Clustering Algorithm", "type": "n8n-nodes-base.code", "position": [ 1116, 1160 ], "parameters": { "language": "python", "pythonCode": "import numpy as np\nfrom sklearn.cluster import KMeans\n\n# get vectors for all answers\npoint_ids = [item.id for item in _input.first().json.result.points]\nvectors = [item.vector.to_py() for item in _input.first().json.result.points]\nvectors_array = np.array(vectors)\n\n# apply k-means clustering where n_clusters = 5\n# this is a max and we'll discard some of these clusters later\nkmeans = KMeans(n_clusters=min(len(vectors), 5), random_state=42).fit(vectors_array)\nlabels = kmeans.labels_\nunique_labels = set(labels)\n\n# Extract and print points in each cluster\nclusters = {}\nfor label in set(labels):\n clusters[label] = vectors_array[labels == label]\n\n# return Qdrant point ids for each cluster\n# we'll use these ids to fetch the payloads from the vector store.\noutput = []\nfor cluster_id, cluster_points in clusters.items():\n points = [point_ids[i] for i in range(len(labels)) if labels[i] == cluster_id]\n output.append({\n \"id\": f\"Cluster {cluster_id}\",\n \"total\": len(cluster_points),\n \"points\": points\n })\n\nreturn {\"json\": {\"output\": output } }" }, "typeVersion": 2 }, { "id": "95c57019-d9d7-4d9f-93dd-21d3d9708861", "name": "Sticky Note10", "type": "n8n-nodes-base.stickyNote", "position": [ -260, 40 ], "parameters": { "width": 400.381109509268, "height": 612.855812336249, "content": "## 시도해 보세요!\n\n### 이 워크플로는 Trustpilot 리뷰에서 고도로 상세한 고객 인사이트를 생성합니다. 많은 수의 리뷰를 다룰 때 가장 잘 작동합니다.\n\n* Trustpilot 리뷰를 가져와 Qdrant 벡터스토어에서 벡터화합니다.\n* 리뷰에서 인기 있는 주제의 클러스터를 K-means 클러스터링 알고리즘을 사용하여 식별합니다. \n* 각 유효한 클러스터를 LLM으로 분석하고 요약합니다.\n* LLM 응답과 클러스터 결과를 시트로 다시 내보냅니다.\n\n참조 Google 시트를 여기에서 확인하세요: https://docs.google.com/spreadsheets/d/e/2PACX-1vQ6ipJnXWXgr5wlUJnhioNpeYrxaIpsRYZCwN3C-fFXumkbh9TAsA_JzE0kbv7DcGAVIP7az0L46_2P/pubhtml\n\n### 도움이 필요하신가요? [Discord](https://discord.com/invite/XPKeKXeB7d)에 가입하거나 [Forum](https://community.n8n.io/)에서 물어보세요!\n\n즐거운 해킹!" }, "typeVersion": 1 }, { "id": "9bba9480-792e-48e3-ad9f-8809ce3aba09", "name": "Customer Insights Agent", "type": "@n8n/n8n-nodes-langchain.informationExtractor", "position": [ 2140, 1180 ], "parameters": { "text": "=The {{ $json.result.length }} reviews were:\n{{\n$json.result.map(item =>\n`* ${item.payload.metadata.review_author} gave ${item.payload.metadata.review_rating} stars: \"${item.payload.content.replaceAll('\"', '\\\"').replaceAll('\\n', ' ')}\"`\n).join('\\n')\n}}", "options": { "systemPromptTemplate": "=You help summarise a selection of trustpilot reviews for a company called \"{{ $json.result[0].payload.metadata.company_id }}\".\nThe {{ $json.result.length }} reviews were selected because their contents were similar in context.\n\nYour task is to: \n* summarise the given reviews into a short paragraph. Provide an insight from this summary and what we could learn from the reviews.\n* determine if the overall sentiment of all the listed responses to be either strongly negative, negative, neutral, positive or strongly positive." }, "schemaType": "fromJson", "jsonSchemaExample": "{\n\t\"Insight\": \"\",\n \"Sentiment\": \"\",\n \"Suggested Improvements\": \"\"\n}" }, "typeVersion": 1 }, { "id": "4488deb9-27f6-4f9d-b17e-9b5e7a1bba33", "name": "Sticky Note12", "type": "n8n-nodes-base.stickyNote", "position": [ 180, 760 ], "parameters": { "color": 5, "width": 323.2987132716669, "height": 80, "content": "### 이것을 한 번만 실행하세요! \n만약 어떤 이유로든 여러 번 실행해야 한다면, 먼저 기존 데이터를 지우세요." }, "typeVersion": 1 }, { "id": "5cb3bd73-1e77-4eba-9d2e-634fdc374330", "name": "Sticky Note11", "type": "n8n-nodes-base.stickyNote", "position": [ 780, 1480 ], "parameters": { "color": 5, "width": 323.2987132716669, "height": 110.05160146874424, "content": "### 처음 실행 시?\n처음 실행 시 약간의 지연이 발생할 수 있습니다. 코드 노드가 필요한 패키지를 다운로드해야 하기 때문입니다." }, "typeVersion": 1 } ], "pinData": {}, "connections": { "Zip Entries": { "main": [ [ { "node": "Reviews to List", "type": "main", "index": 0 } ] ] }, "Find Reviews": { "main": [ [ { "node": "Apply K-means Clustering Algorithm", "type": "main", "index": 0 } ] ] }, "Set Variables": { "main": [ [ { "node": "Clear Existing Reviews", "type": "main", "index": 0 } ] ] }, "Set Variables1": { "main": [ [ { "node": "Find Reviews", "type": "main", "index": 0 } ] ] }, "Extract Reviews": { "main": [ [ { "node": "Zip Entries", "type": "main", "index": 0 } ] ] }, "Reviews to List": { "main": [ [ { "node": "Qdrant Vector Store", "type": "main", "index": 0 } ] ] }, "Clusters To List": { "main": [ [ { "node": "Only Clusters With 3+ points", "type": "main", "index": 0 } ] ] }, "Embeddings OpenAI": { "ai_embedding": [ [ { "node": "Qdrant Vector Store", "type": "ai_embedding", "index": 0 } ] ] }, "OpenAI Chat Model": { "ai_languageModel": [ [ { "node": "Customer Insights Agent", "type": "ai_languageModel", "index": 0 } ] ] }, "Default Data Loader": { "ai_document": [ [ { "node": "Qdrant Vector Store", "type": "ai_document", "index": 0 } ] ] }, "Get TrustPilot Page": { "main": [ [ { "node": "Extract Reviews", "type": "main", "index": 0 } ] ] }, "Qdrant Vector Store": { "main": [ [ { "node": "Prep Values For Trigger", "type": "main", "index": 0 } ] ] }, "Get Payload of Points": { "main": [ [ { "node": "Customer Insights Agent", "type": "main", "index": 0 } ] ] }, "Clear Existing Reviews": { "main": [ [ { "node": "Get TrustPilot Page", "type": "main", "index": 0 } ] ] }, "Prep Output For Export": { "main": [ [ { "node": "Export To Sheets", "type": "main", "index": 0 } ] ] }, "Customer Insights Agent": { "main": [ [ { "node": "Prep Output For Export", "type": "main", "index": 0 } ] ] }, "Prep Values For Trigger": { "main": [ [ { "node": "Trigger Insights", "type": "main", "index": 0 } ] ] }, "Execute Workflow Trigger": { "main": [ [ { "node": "Set Variables1", "type": "main", "index": 0 } ] ] }, "Only Clusters With 3+ points": { "main": [ [ { "node": "Get Payload of Points", "type": "main", "index": 0 } ] ] }, "Recursive Character Text Splitter": { "ai_textSplitter": [ [ { "node": "Default Data Loader", "type": "ai_textSplitter", "index": 0 } ] ] }, "When clicking ‘Test workflow’": { "main": [ [ { "node": "Set Variables", "type": "main", "index": 0 } ] ] }, "Apply K-means Clustering Algorithm": { "main": [ [ { "node": "Clusters To List", "type": "main", "index": 0 } ] ] } } }