{ "meta": { "instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" }, "nodes": [ { "id": "192d3e4f-6bb0-4b87-a1fa-e32c9efb49cc", "name": "When clicking \"Test workflow\"", "type": "n8n-nodes-base.manualTrigger", "position": [ 336, 34 ], "parameters": {}, "typeVersion": 1 }, { "id": "32a7a772-76a6-4614-a6ab-d2b152a5811f", "name": "OpenAI Chat Model1", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [ 1220, 180 ], "parameters": { "model": "gpt-4o", "options": { "temperature": 0 } }, "credentials": { "openAiApi": { "id": "8gccIjcuf3gvaoEr", "name": "OpenAi account" } }, "typeVersion": 1 }, { "id": "8c444314-ed7d-4ca0-b0fa-b6d1e964c698", "name": "Get Applicable Rows", "type": "n8n-nodes-base.airtable", "position": [ 516, 34 ], "parameters": { "base": { "__rl": true, "mode": "list", "value": "appbgxPBurOmQK3E7", "cachedResultUrl": "https://airtable.com/appbgxPBurOmQK3E7", "cachedResultName": "Building Inventory Survey Example" }, "table": { "__rl": true, "mode": "id", "value": "tblEHkoTvKpa4Aa0Q" }, "options": {}, "operation": "search", "returnAll": false, "filterByFormula": "AND(Image!=\"\", AI_status=FALSE())" }, "credentials": { "airtableTokenApi": { "id": "Und0frCQ6SNVX3VV", "name": "Airtable Personal Access Token account" } }, "typeVersion": 2 }, { "id": "f90578fa-b886-4653-8ff7-0c91884dc517", "name": "Execute Workflow Trigger", "type": "n8n-nodes-base.executeWorkflowTrigger", "position": [ 1257, 733 ], "parameters": {}, "typeVersion": 1 }, { "id": "8f5959eb-45bd-4185-a959-10268827e41d", "name": "Edit Fields", "type": "n8n-nodes-base.set", "position": [ 1417, 733 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "7263764b-8409-4cea-8db3-3278dd7ef9d8", "name": "=route", "type": "string", "value": "={{ $json.route }}" }, { "id": "55c3b207-2e98-4137-8413-f72cbff17986", "name": "query", "type": "string", "value": "={{ $json.query }}" }, { "id": "6eb873de-3c3a-4135-9dc0-1d441c63647c", "name": "", "type": "string", "value": "" } ] } }, "typeVersion": 3.3 }, { "id": "2c7f7274-12e9-4dd3-8ee4-679b408d5430", "name": "Fallback Response", "type": "n8n-nodes-base.set", "position": [ 1580, 875 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "{\n \"response\": {\n \"ok\": false,\n \"error\": \"The requested tool was not found or the service may be unavailable. Do not retry.\"\n }\n}\n" }, "typeVersion": 3.3 }, { "id": "09f36f4d-eb88-4d93-a8b3-e9ba66b46b54", "name": "SERP Google Reverse Image API", "type": "n8n-nodes-base.httpRequest", "position": [ 1860, 549 ], "parameters": { "url": "https://serpapi.com/search.json", "options": {}, "sendQuery": true, "authentication": "predefinedCredentialType", "queryParameters": { "parameters": [ { "name": "engine", "value": "google_reverse_image" }, { "name": "image_url", "value": "={{ $json.query }}" } ] }, "nodeCredentialType": "serpApi" }, "credentials": { "serpApi": { "id": "aJCKjxx6U3K7ydDe", "name": "SerpAPI account" } }, "typeVersion": 4.2 }, { "id": "8e3a0f38-8663-4f5c-837f-4b9aa21f14fb", "name": "Reverse Image Search Response", "type": "n8n-nodes-base.set", "position": [ 2037, 547 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "de99a504-713f-4c78-8679-08139b2def31", "name": "response", "type": "string", "value": "={{ JSON.stringify($json.image_results.map(x => ({ position: x.position, title: x.title, link: x.link, description: x.snippet }))) }}" } ] } }, "typeVersion": 3.3 }, { "id": "0cd2269a-5b1f-4f10-b180-7f9cff9b1102", "name": "Reverse Image Search Tool", "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "position": [ 1300, 340 ], "parameters": { "name": "reverse_image_search", "fields": { "values": [ { "name": "route", "stringValue": "serp.google_reverse_image" } ] }, "workflowId": "={{ $workflow.id }}", "description": "Call this tool to perform a reverse image search. Reverse image searches return urls where similar looking products exists. Fetch the returned urls to gather more information. This tool requires the following object request body.\n```\n{\n \"type\": \"object\",\n \"properties\": {\n \"image_url\": { \"type\": \"string\" },\n }\n}\n```\nimage_url should be an absolute URL to the image." }, "typeVersion": 1.1 }, { "id": "9825651e-b382-4e0a-97ef-37764cb5be9e", "name": "Firecrawl Scrape API", "type": "n8n-nodes-base.httpRequest", "position": [ 1860, 889 ], "parameters": { "url": "https://api.firecrawl.dev/v0/scrape", "method": "POST", "options": {}, "sendBody": true, "sendHeaders": true, "authentication": "genericCredentialType", "bodyParameters": { "parameters": [ { "name": "url", "value": "={{ $json.query }}" } ] }, "genericAuthType": "httpHeaderAuth", "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" } ] } }, "credentials": { "httpHeaderAuth": { "id": "OUOnyTkL9vHZNorB", "name": "Firecrawl API" } }, "typeVersion": 4.2 }, { "id": "7f61d60b-b052-4b7c-abfd-9eb8e05a45a2", "name": "Scrape Success?", "type": "n8n-nodes-base.if", "position": [ 2020, 889 ], "parameters": { "options": {}, "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "a15a164f-d0c5-478f-8b27-f3d51746c214", "operator": { "type": "boolean", "operation": "true", "singleValue": true }, "leftValue": "={{ $json.success }}", "rightValue": "" } ] } }, "typeVersion": 2 }, { "id": "29c65ef4-6350-490a-b8e3-a5c869e656b2", "name": "Firecrawl Scrape Success Response", "type": "n8n-nodes-base.set", "position": [ 2180, 889 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "7db5c81f-de90-40e1-8086-3f13d40451c7", "name": "response", "type": "string", "value": "={{ $json.data.markdown.substring(0, 3000) }}" } ] } }, "typeVersion": 3.3 }, { "id": "229b4008-d8a8-4609-854a-fc244a4ed630", "name": "Firecrawl scrape Error Response", "type": "n8n-nodes-base.set", "position": [ 2180, 1049 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "e691d86a-d366-44a2-baa6-3dba42527f6e", "name": "response", "type": "string", "value": "{ error: \"Unable to scrape website due to unknown error. Do not retry.\" }" } ] } }, "typeVersion": 3.3 }, { "id": "f080069b-e849-45e0-88cf-03707d22c704", "name": "Firecrawl Web Scaper Tool", "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "position": [ 1440, 340 ], "parameters": { "name": "webpage_url_scraper_tool", "fields": { "values": [ { "name": "route", "stringValue": "firecrawl.scrape" } ] }, "workflowId": "={{ $workflow.id }}", "description": "Call this tool to retrieve page contents of a url.\n```\n{\n \"type\": \"object\",\n \"properties\": {\n \"url\": { \"type\": \"string\" },\n }\n}\n```\nurl should be an absolute URL." }, "typeVersion": 1.1 }, { "id": "4eff88bb-bd5e-4d6a-b5e1-8521632c461f", "name": "Structured Output Parser", "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "position": [ 1500, 180 ], "parameters": { "jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"title\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"model\": { \"type\": \"string\" },\n \"material\": { \"type\": \"string\" },\n \"color\": { \"type\": \"string\" },\n \"condition\": { \"type\": \"string\" }\n }\n}" }, "typeVersion": 1.1 }, { "id": "328d106b-a473-4f54-82fd-55c30d813da9", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ 280, -260 ], "parameters": { "color": 7, "width": 402.5984702109446, "height": 495.4071184783251, "content": "## 1. Airtable을 사용하여 설문 사진 캡처하기 \n[AirTable에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.airtable) \n\n이 워크플로를 활성화하려면, 제목과 사진을 검색하여 분석하고 생성된 값을 다시 작성할 수 있는 데이터베이스가 필요합니다. Airtable은 강력한 API를 가지고 있어서 이 작업에 적합합니다. \n\n이 데모의 경우, 수동으로 트리거하겠지만, 폼이나 다른 트리거로 변경할 수 있습니다." }, "typeVersion": 1 }, { "id": "e358775d-ff83-411d-9364-b43c87d98134", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ 716.3106363781314, -160 ], "parameters": { "color": 7, "width": 359.40869874940336, "height": 428.4787925736586, "content": "## 2. AI 비전 모델을 사용하여 사진 분석하기.\n\n[OpenAI Vision에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai)\n\n우리는 OpenAI 비전 모델을 사용하여 사진에 있는 제품의 상세한 설명을 생성할 것입니다. 이 단계를 에이전트에서 분리한 이유는 일반적인 텍스트 기반 모델이 아닌 이미지 모델을 사용하기 때문입니다." }, "typeVersion": 1 }, { "id": "51b4a70c-9583-4e8a-8e8d-896a80ad53c3", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ 1111.3914848823072, -293.9250474768817 ], "parameters": { "color": 7, "width": 593.0683948010671, "height": 803.956942672397, "content": "## 3. 인터넷을 검색하는 AI 에이전트 구축\n\n[OpenAI 에이전트에 대해 자세히 읽기](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai)\n\n이 AI 에이전트는 캡처한 사진을 사용하여 역 이미지 검색을 수행할 수 있으며, 외부 웹페이지를 방문하여 정확한 제품 이름과 속성을 얻을 수 있습니다. 에이전트와 도구는 평균적인 인간 사용자가 동일한 작업을 수행하는 것을 모방할 수 있습니다.\n\n* 역 이미지 검색의 경우, SERP API 서비스를 사용하지만, 사용자 지정 매개변수를 지정해야 하므로 내장된 SERP 노드를 사용하지 않을 것입니다. \n* 스크래핑의 경우, [Firecrawl](https://www.firecrawl.dev/)을 사용하겠습니다. 이 서비스는 페이지를 마크다운으로 파싱하고 반환하여 더 효율적입니다." }, "typeVersion": 1 }, { "id": "adfb519b-a5c7-432c-be32-5acfcc388b49", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [ 1740, -149.28190375244515 ], "parameters": { "color": 7, "width": 373.3601237414979, "height": 397.7168664109706, "content": "## 4. 우리의 행을 풍부한 결과로 덮어쓰기\n\n그리고 Voilà! 우리 AI 에이전트가 잠재적으로 우리 설문조사자의 수동 데이터 입력 작업 시간을 몇 시간이나 절약해 주었습니다. 이 기술은 다른 많은 용도로 사용할 수 있습니다." }, "typeVersion": 1 }, { "id": "6444e217-b944-450e-892a-5822d4d390ce", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ 1200, 549 ], "parameters": { "color": 7, "width": 554.6092633638649, "height": 490.7010880746526, "content": "## 5. 사용자 정의 워크플로우 도구 사용 \n[워크플로우 도구에 대해 더 알아보기](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow) \n\nAI 에이전트는 도구에 의존하여 결정을 내리고, 도구가 많을수록 지수적으로 더 강력해집니다. 여러 도구를 관리하기 위한 일반적인 패턴은 API 패턴을 사용하여 도구에 대한 라우팅 시스템을 만드는 것입니다." }, "typeVersion": 1 }, { "id": "bf2459cf-a931-4232-9504-b36b15721194", "name": "Enrich Product Rows", "type": "n8n-nodes-base.airtable", "position": [ 1880, 60 ], "parameters": { "base": { "__rl": true, "mode": "list", "value": "appbgxPBurOmQK3E7", "cachedResultUrl": "https://airtable.com/appbgxPBurOmQK3E7", "cachedResultName": "Building Inventory Survey Example" }, "table": { "__rl": true, "mode": "id", "value": "tblEHkoTvKpa4Aa0Q" }, "columns": { "value": { "id": "={{ $('Get Applicable Rows').item.json.id }}", "Color": "={{ $json.output.output.color }}", "Model": "={{ $json.output.output.model }}", "Title": "={{ $json.output.output.title }}", "Material": "={{ $json.output.output.material }}", "AI_status": true, "Condition": "={{ $json.output.output.condition }}", "Description": "={{ $json.output.output.description }}" }, "schema": [ { "id": "id", "type": "string", "display": true, "removed": false, "readOnly": true, "required": false, "displayName": "id", "defaultMatch": true }, { "id": "Title", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Title", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Image", "type": "array", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Image", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Description", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Description", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Model", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Model", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Material", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Material", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Color", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Color", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Condition", "type": "string", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "Condition", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "AI_status", "type": "boolean", "display": true, "removed": false, "readOnly": false, "required": false, "displayName": "AI_status", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [ "id" ] }, "options": {}, "operation": "update" }, "credentials": { "airtableTokenApi": { "id": "Und0frCQ6SNVX3VV", "name": "Airtable Personal Access Token account" } }, "typeVersion": 2 }, { "id": "19d736bf-c29d-46a2-93bc-b536ff28c4b5", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [ -100, -260 ], "parameters": { "width": 359.6648027457353, "height": 381.0536322713287, "content": "## 직접 해보세요!\n\n### 이 워크플로우는 다음을 수행합니다:\n* Airtable 스프레드시트에서 제품 사진 이미지가 있는 행을 스캔합니다.\n* AI 비전 모델을 사용하여 제품을 식별하려고 시도합니다.\n* AI 에이전트를 사용하여 인터넷에서 제품을 연구하여 제품 데이터를 풍부하게 합니다.\n* 풍부해진 데이터로 우리 Airtable 스프레드시트를 덮어씁니다.\n\n### 도움이 필요하신가요?\n[Discord](https://discord.com/invite/XPKeKXeB7d)에 가입하거나 [Forum](https://community.n8n.io/)에서 물어보세요!\n\n즐거운 해킹!" }, "typeVersion": 1 }, { "id": "25f15c48-16bf-4f92-942d-c224ed88d208", "name": "Analyse Image", "type": "@n8n/n8n-nodes-langchain.openAi", "position": [ 840, 80 ], "parameters": { "text": "=Focus on the {{ $json.Title }} in the image - we'll refer to this as the \"object\". Identify the following attributes of the object. If you cannot determine confidently, then leave blank and move to next attribute.\n* Decription of the object.\n* The model/make of the object.\n* The material(s) used in the construction of the object.\n* The color(s) of the object\n* The condition of the object. Use one of poor, good, excellent.\n", "options": {}, "resource": "image", "imageUrls": "={{ $json.Image[0].thumbnails.large.url }}", "operation": "analyze" }, "credentials": { "openAiApi": { "id": "8gccIjcuf3gvaoEr", "name": "OpenAi account" } }, "typeVersion": 1.3 }, { "id": "e6c99f71-ccc9-426e-b916-cc38864e3224", "name": "Object Identifier Agent", "type": "@n8n/n8n-nodes-langchain.agent", "position": [ 1260, 20 ], "parameters": { "text": "=system: Your role is to help an building surveyor perform a object classification and data collection task whereby the surveyor will take photos of various objects and your job is to try and identify accurately certain product attributes of the objects as detailed below.\n\nThe surveyor has given you the following:\n1) photo url ```{{ $('Get Applicable Rows').item.json.Image[0].thumbnails.large.url }}```.\n2) photo description ```{{ $json.content }}```.\n\nFor each product attribute the surveyor is unable to determine, you may:\n1) use the reverse image search tool to search the product on the internet via the provided image url.\n2) use the web scraper tool to read webpages on the internet which may be relevant to the product.\n3) If after using these tools, you are still unable to determine the required product attributes then leave the data blank.\n\nUse all the information provided and gathered, to extract the following product attributes: title, description, model, material, color and condition.", "agent": "openAiFunctionsAgent", "options": {}, "promptType": "define", "hasOutputParser": true }, "typeVersion": 1.5 }, { "id": "661b14bd-6511-4f20-981c-2e68a7c34ec5", "name": "Actions Router", "type": "n8n-nodes-base.switch", "position": [ 1577, 733 ], "parameters": { "rules": { "values": [ { "outputKey": "serp.google_reverse_image", "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{ $json.route }}", "rightValue": "serp.google_reverse_image" } ] }, "renameOutput": true }, { "outputKey": "firecrawl.scrape", "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "0a1f54ae-39f1-468d-ba6e-1376d13e4ee8", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{ $json.route }}", "rightValue": "firecrawl.scrape" } ] }, "renameOutput": true } ] }, "options": { "fallbackOutput": "extra" } }, "typeVersion": 3 }, { "id": "c5078221-9239-4ec0-b25e-7cd880b58216", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [ 480, 20 ], "parameters": { "width": 181.2788838920522, "height": 297.0159375852115, "content": "🚨필수 \n* Airtable Base와 Table ID를 여기 설정하세요." }, "typeVersion": 1 }, { "id": "c58c0db4-9b99-4a77-90ae-66fa3981b684", "name": "Sticky Note7", "type": "n8n-nodes-base.stickyNote", "position": [ 1840, 40 ], "parameters": { "width": 181.2788838920522, "height": 297.0159375852115, "content": "🚨**필수** \n* Airtable Base 및 Table ID를 여기에 설정하세요." }, "typeVersion": 1 }, { "id": "e3a666d7-d7a5-43f5-8f04-7972332f8916", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [ 1780, 440 ], "parameters": { "color": 7, "width": 460.3301604548244, "height": 298.81538450684064, "content": "## 5.1 구글 역상 이미지 도구 \n이 도구는 구글의 역상 이미지 API를 사용하여 비슷한 이미지가 발견되는 웹사이트를 반환합니다." }, "typeVersion": 1 }, { "id": "d7407cdb-16bb-4bd9-a28e-7a72a5289354", "name": "Sticky Note9", "type": "n8n-nodes-base.stickyNote", "position": [ 1780, 769.9385328672522 ], "parameters": { "color": 7, "width": 575.3216480295998, "height": 463.34699288922565, "content": "## 5.2 웹스크래퍼 도구\n이 도구는 Firecrawl.dev API를 사용하여 웹 페이지를 크롤링하고, 그 페이지들을 마크다운 형식으로 반환합니다." }, "typeVersion": 1 } ], "pinData": {}, "connections": { "Edit Fields": { "main": [ [ { "node": "Actions Router", "type": "main", "index": 0 } ] ] }, "Analyse Image": { "main": [ [ { "node": "Object Identifier Agent", "type": "main", "index": 0 } ] ] }, "Actions Router": { "main": [ [ { "node": "SERP Google Reverse Image API", "type": "main", "index": 0 } ], [ { "node": "Firecrawl Scrape API", "type": "main", "index": 0 } ], [ { "node": "Fallback Response", "type": "main", "index": 0 } ] ] }, "Scrape Success?": { "main": [ [ { "node": "Firecrawl Scrape Success Response", "type": "main", "index": 0 } ], [ { "node": "Firecrawl scrape Error Response", "type": "main", "index": 0 } ] ] }, "OpenAI Chat Model1": { "ai_languageModel": [ [ { "node": "Object Identifier Agent", "type": "ai_languageModel", "index": 0 } ] ] }, "Get Applicable Rows": { "main": [ [ { "node": "Analyse Image", "type": "main", "index": 0 } ] ] }, "Firecrawl Scrape API": { "main": [ [ { "node": "Scrape Success?", "type": "main", "index": 0 } ] ] }, "Object Identifier Agent": { "main": [ [ { "node": "Enrich Product Rows", "type": "main", "index": 0 } ] ] }, "Execute Workflow Trigger": { "main": [ [ { "node": "Edit Fields", "type": "main", "index": 0 } ] ] }, "Structured Output Parser": { "ai_outputParser": [ [ { "node": "Object Identifier Agent", "type": "ai_outputParser", "index": 0 } ] ] }, "Firecrawl Web Scaper Tool": { "ai_tool": [ [ { "node": "Object Identifier Agent", "type": "ai_tool", "index": 0 } ] ] }, "Reverse Image Search Tool": { "ai_tool": [ [ { "node": "Object Identifier Agent", "type": "ai_tool", "index": 0 } ] ] }, "SERP Google Reverse Image API": { "main": [ [ { "node": "Reverse Image Search Response", "type": "main", "index": 0 } ] ] }, "When clicking \"Test workflow\"": { "main": [ [ { "node": "Get Applicable Rows", "type": "main", "index": 0 } ] ] } } }