[2/3] 为异常检测设置中心点(2种类型)(农作物数据集)
高级
这是一个AI, SecOps领域的自动化工作流,包含 48 个节点。主要使用 Set, Code, Merge, SplitOut, HttpRequest 等节点,结合人工智能技术实现智能自动化。 为异常检测设置聚类中心和阈值 [2/3 - 异常检测]
前置要求
- •可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "m9aACcHqydEbH4nR",
"meta": {
"instanceId": "205b3bc06c96f2dc835b4f00e1cbf9a937a74eeb3b47c99d0c30b0586dbf85aa"
},
"name": "[2/3] 为异常检测设置中心点(2种类型)(农作物数据集)",
"tags": [
{
"id": "spMntyrlE9ydvWFA",
"name": "anomaly-detection",
"createdAt": "2024-12-08T22:05:15.945Z",
"updatedAt": "2024-12-09T12:50:19.287Z"
}
],
"nodes": [
{
"id": "edaa871e-2b79-400e-8328-333d250bfdd2",
"name": "点击“测试工作流”时",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-660,
-220
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ebd964de-faa4-4dc0-9245-cc9154b9ce02",
"name": "集合中的总点数",
"type": "n8n-nodes-base.httpRequest",
"position": [
180,
-220
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').item.json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').item.json.collectionName }}/points/count",
"method": "POST",
"options": {},
"jsonBody": "={\n \"exact\": true\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "b51f6344-d090-4341-a908-581b78664b07",
"name": "聚类距离矩阵",
"type": "n8n-nodes-base.httpRequest",
"position": [
1200,
-360
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/search/matrix/offsets",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"sample\": $json.maxClusterSize,\n \"limit\": $json.maxClusterSize,\n \"using\": \"voyage\",\n \"filter\": {\n \"must\": {\n \"key\": \"crop_name\",\n \"match\": { \"value\": $json.cropName }\n }\n }\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "bebe5249-b138-4d7a-84b8-51eaed4331b8",
"name": "Scipy 稀疏矩阵",
"type": "n8n-nodes-base.code",
"position": [
1460,
-360
],
"parameters": {
"mode": "runOnceForEachItem",
"language": "python",
"pythonCode": "from scipy.sparse import coo_array\n\ncluster = _input.item.json['result']\n\nscores = list(cluster['scores'])\noffsets_row = list(cluster['offsets_row'])\noffsets_col = list(cluster['offsets_col'])\n\ncluster_matrix = coo_array((scores, (offsets_row, offsets_col)))\nthe_most_similar_to_others = cluster_matrix.sum(axis=1).argmax()\n\nreturn {\n \"json\": {\n \"medoid_id\": cluster[\"ids\"][the_most_similar_to_others]\n }\n}\n"
},
"typeVersion": 2
},
{
"id": "006c38bb-a271-40e1-9c5b-5a0a29ea96de",
"name": "设置中心点ID",
"type": "n8n-nodes-base.httpRequest",
"position": [
2000,
-680
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/payload",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"payload\": {\"is_medoid\": true},\n \"points\": [$json.medoid_id]\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "aeeccfc5-67bf-4047-8a5a-8830e4fc87e8",
"name": "获取中心点向量",
"type": "n8n-nodes-base.httpRequest",
"position": [
2000,
-360
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"ids\": [$json.medoid_id],\n \"with_vector\": true,\n \"with_payload\": true\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "11fe54d5-9dc8-49ce-9e3f-1103ace0a3d5",
"name": "准备搜索阈值",
"type": "n8n-nodes-base.set",
"position": [
2240,
-360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6faa5949-968c-42bf-8ce8-cf2403566eba",
"name": "oppositeOfCenterVector",
"type": "array",
"value": "={{ $json.result[0].vector.voyage.map(value => value * -1)}}"
},
{
"id": "84eb42be-2ea5-4a76-9c76-f21a962360a3",
"name": "cropName",
"type": "string",
"value": "={{ $json.result[0].payload.crop_name }}"
},
{
"id": "b68d2e42-0dde-4875-bb59-056f29b6ac0a",
"name": "centerId",
"type": "string",
"value": "={{ $json.result[0].id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "4051b488-2e2e-4d33-9cc9-e1403c9173ed",
"name": "搜索分数",
"type": "n8n-nodes-base.httpRequest",
"position": [
2500,
-360
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/query",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"query\": $json.oppositeOfCenterVector,\n \"using\": \"voyage\",\n \"exact\": true,\n \"filter\": {\n \"must\": [\n {\n \"key\": \"crop_name\",\n \"match\": {\"value\": $json.cropName }\n }\n ]\n },\n \"limit\": $('Medoids Variables').first().json.furthestFromCenter,\n \"with_payload\": true\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "1c6cb6ee-ce3a-4d1a-b1b4-1e59e9a8f5b6",
"name": "阈值分数",
"type": "n8n-nodes-base.set",
"position": [
2760,
-360
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "579a2ee4-0ab2-4fde-909a-01166624c9d8",
"name": "thresholdScore",
"type": "number",
"value": "={{ $json.result.points.last().score * -1 }}"
},
{
"id": "11eab775-f709-40a9-b0fe-d1059b67de05",
"name": "centerId",
"type": "string",
"value": "={{ $('Prepare for Searching Threshold').item.json.centerId }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "1bab1b9e-7b80-4ef3-8e3d-be4874792e58",
"name": "设置中心点阈值分数",
"type": "n8n-nodes-base.httpRequest",
"position": [
2940,
-360
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/payload",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"payload\": {\"is_medoid_cluster_threshold\": $json.thresholdScore },\n \"points\": [$json.centerId]\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "cd5af197-4d79-49c2-aba6-a20571bd5c2e",
"name": "拆分输出1",
"type": "n8n-nodes-base.splitOut",
"position": [
860,
80
],
"parameters": {
"options": {
"destinationFieldName": ""
},
"fieldToSplitOut": "['text anchors']"
},
"typeVersion": 1
},
{
"id": "956c126c-8bd6-4390-8704-3f0a5a2ce479",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
1200,
-80
],
"parameters": {
"mode": "combine",
"options": {},
"fieldsToMatchString": "cropName"
},
"typeVersion": 3
},
{
"id": "54a5d467-4985-49b5-9f13-e6563acf08b3",
"name": "文本(视觉)农作物描述",
"type": "n8n-nodes-base.set",
"position": [
380,
80
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "{\"text anchors\": [{\"cropName\": \"pearl_millet(bajra)\", \"cropDescription\": \"pearl_millet(bajra) - Tall stalks with cylindrical, spiked green grain heads.\"},\n{\"cropName\": \"tobacco-plant\", \"cropDescription\": \"tobacco-plant - Broad, oval leaves and small tubular flowers, typically pink or white.\"},\n{\"cropName\": \"cherry\", \"cropDescription\": \"cherry - Small, glossy red fruits on a medium-sized tree with slender branches and serrated leaves.\"},\n{\"cropName\": \"cotton\", \"cropDescription\": \"cotton - Bushy plant with fluffy white fiber-filled pods and lobed green leaves.\"},\n{\"cropName\": \"banana\", \"cropDescription\": \"banana - Tall herbaceous plant with broad, elongated green leaves and hanging bunches of yellow fruits.\"},\n{\"cropName\": \"cucumber\", \"cropDescription\": \"cucumber - Creeping vine with yellow flowers and elongated green cylindrical fruits.\"},\n{\"cropName\": \"maize\", \"cropDescription\": \"maize - Tall stalks with broad leaves, tassels at the top, and ears of corn sheathed in husks.\"},\n{\"cropName\": \"wheat\", \"cropDescription\": \"wheat - Slender, upright stalks with narrow green leaves and golden, spiky grain heads.\"},\n{\"cropName\": \"clove\", \"cropDescription\": \"clove - Small tree with oval green leaves and clusters of unopened reddish flower buds.\"},\n{\"cropName\": \"jowar\", \"cropDescription\": \"jowar - Tall grass-like plant with broad leaves and round, compact grain clusters at the top.\"},\n{\"cropName\": \"olive-tree\", \"cropDescription\": \"olive-tree - Medium-sized tree with silvery-green leaves and small oval green or black fruits.\"},\n{\"cropName\": \"soyabean\", \"cropDescription\": \"soyabean - Bushy plant with trifoliate green leaves and small pods containing rounded beans.\"},\n{\"cropName\": \"coffee-plant\", \"cropDescription\": \"coffee-plant - Shrub with shiny dark green leaves and clusters of small white flowers, followed by red berries.\"},\n{\"cropName\": \"rice\", \"cropDescription\": \"rice - Short, water-loving grass with narrow green leaves and drooping golden grain heads.\"},\n{\"cropName\": \"lemon\", \"cropDescription\": \"lemon - Small tree with glossy green leaves and oval yellow fruits.\"},\n{\"cropName\": \"mustard-oil\", \"cropDescription\": \"mustard-oil - Small herbaceous plant with yellow flowers and slender seed pods.\"},\n{\"cropName\": \"vigna-radiati(mung)\", \"cropDescription\": \"vigna-radiati(mung) - Low-growing plant with trifoliate leaves and small green pods containing mung beans.\"},\n{\"cropName\": \"coconut\", \"cropDescription\": \"coconut - Tall palm tree with feathery leaves and large round fibrous fruits.\"},\n{\"cropName\": \"gram\", \"cropDescription\": \"gram - Low bushy plant with feathery leaves and small pods containing round seeds.\"},\n{\"cropName\": \"pineapple\", \"cropDescription\": \"pineapple - Low plant with spiky, sword-shaped leaves and large, spiky golden fruits.\"},\n{\"cropName\": \"sugarcane\", \"cropDescription\": \"sugarcane - Tall, jointed stalks with long narrow leaves and a sweet interior.\"},\n{\"cropName\": \"sunflower\", \"cropDescription\": \"sunflower - Tall plant with rough green leaves and large bright yellow flower heads.\"},\n{\"cropName\": \"chilli\", \"cropDescription\": \"chilli - Small bushy plant with slender green or red elongated fruits.\"},\n{\"cropName\": \"fox_nut(makhana)\", \"cropDescription\": \"fox_nut(makhana) - Aquatic plant with floating round leaves and spiny white seeds.\"},\n{\"cropName\": \"jute\", \"cropDescription\": \"jute - Tall plant with long, straight stalks and narrow green leaves.\"},\n{\"cropName\": \"papaya\", \"cropDescription\": \"papaya - Medium-sized tree with hollow trunk, large lobed leaves, and yellow-orange pear-shaped fruits.\"},\n{\"cropName\": \"tea\", \"cropDescription\": \"tea - Small shrub with glossy dark green leaves and small white flowers.\"},\n{\"cropName\": \"cardamom\", \"cropDescription\": \"cardamom - Low tropical plant with broad leaves and clusters of small, light green pods.\"},\n{\"cropName\": \"almond\", \"cropDescription\": \"almond - Medium-sized tree with serrated leaves and oval green pods containing edible nuts.\"}]}\n"
},
"typeVersion": 3.4
},
{
"id": "14c25e76-8a2c-4df8-98ea-b2f31b15fd1f",
"name": "嵌入文本",
"type": "n8n-nodes-base.httpRequest",
"position": [
1460,
-80
],
"parameters": {
"url": "https://api.voyageai.com/v1/multimodalembeddings",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"inputs\": [\n {\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": $json.cropDescription\n }\n ]\n }\n ],\n \"model\": \"voyage-multimodal-3\",\n \"input_type\": \"query\"\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "Vb0RNVDnIHmgnZOP",
"name": "Voyage API"
}
},
"typeVersion": 4.2
},
{
"id": "8763db0a-9a92-4ffd-8a40-c7db614b735f",
"name": "通过文本获取中心点",
"type": "n8n-nodes-base.httpRequest",
"position": [
1640,
-80
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/query",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"query\": $json.data[0].embedding,\n \"using\": \"voyage\",\n \"exact\": true,\n \"filter\": {\n \"must\": [\n {\n \"key\": \"crop_name\",\n \"match\": {\"value\": $('Merge').item.json.cropName }\n }\n ]\n },\n \"limit\": 1,\n \"with_payload\": true,\n \"with_vector\": true\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "5c770ca2-6e1a-4c4b-80e0-dcbeeda43a0f",
"name": "设置文本中心点ID",
"type": "n8n-nodes-base.httpRequest",
"position": [
2000,
160
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/payload",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"payload\": {\"is_text_anchor_medoid\": true},\n \"points\": [$json.result.points[0].id]\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "c08ff472-51ab-4c3d-b9c0-2170fda2ccef",
"name": "准备搜索阈值1",
"type": "n8n-nodes-base.set",
"position": [
2300,
80
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6faa5949-968c-42bf-8ce8-cf2403566eba",
"name": "oppositeOfCenterVector",
"type": "array",
"value": "={{ $json.result.points[0].vector.voyage.map(value => value * -1)}}"
},
{
"id": "84eb42be-2ea5-4a76-9c76-f21a962360a3",
"name": "cropName",
"type": "string",
"value": "={{ $json.result.points[0].payload.crop_name }}"
},
{
"id": "b68d2e42-0dde-4875-bb59-056f29b6ac0a",
"name": "centerId",
"type": "string",
"value": "={{ $json.result.points[0].id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "84ba4de5-aa9b-43fb-89cb-70db0b3ca334",
"name": "阈值分数1",
"type": "n8n-nodes-base.set",
"position": [
2820,
80
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "579a2ee4-0ab2-4fde-909a-01166624c9d8",
"name": "thresholdScore",
"type": "number",
"value": "={{ $json.result.points.last().score * -1 }}"
},
{
"id": "11eab775-f709-40a9-b0fe-d1059b67de05",
"name": "centerId",
"type": "string",
"value": "={{ $('Prepare for Searching Threshold1').item.json.centerId }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f490d224-38a8-4087-889d-1addb4472471",
"name": "搜索文本中心点分数",
"type": "n8n-nodes-base.httpRequest",
"position": [
2560,
80
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/query",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"query\": $json.oppositeOfCenterVector,\n \"using\": \"voyage\",\n \"exact\": true,\n \"filter\": {\n \"must\": [\n {\n \"key\": \"crop_name\",\n \"match\": {\"value\": $json.cropName }\n }\n ]\n },\n \"limit\": $('Text Medoids Variables').first().json.furthestFromCenter,\n \"with_payload\": true\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "f5035aca-1706-4c8d-bd26-49b3451ae04b",
"name": "中心点变量",
"type": "n8n-nodes-base.set",
"position": [
-140,
-220
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5eb23ad2-aacd-468f-9a27-ef2b63e6bd08",
"name": "furthestFromCenter",
"type": "number",
"value": 5
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c9cad66d-4a76-4092-bfd6-4860493f942a",
"name": "文本中心点变量",
"type": "n8n-nodes-base.set",
"position": [
-140,
80
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5eb23ad2-aacd-468f-9a27-ef2b63e6bd08",
"name": "furthestFromCenter",
"type": "number",
"value": 1
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ecab63f7-7a72-425a-8f5a-0c707e7f77bc",
"name": "Qdrant 聚类变量",
"type": "n8n-nodes-base.set",
"position": [
-420,
-220
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "58b7384d-fd0c-44aa-9f8e-0306a99be431",
"name": "qdrantCloudURL",
"type": "string",
"value": "=https://152bc6e2-832a-415c-a1aa-fb529f8baf8d.eu-central-1-0.aws.cloud.qdrant.io"
},
{
"id": "e34c4d88-b102-43cc-a09e-e0553f2da23a",
"name": "collectionName",
"type": "string",
"value": "=agricultural-crops"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6e81f0b0-3843-467e-9c93-40026e57fa91",
"name": "关于农作物聚类的信息",
"type": "n8n-nodes-base.set",
"position": [
600,
-220
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "5327b254-b703-4a34-a398-f82edb1d6d6b",
"name": "=cropsNumber",
"type": "number",
"value": "={{ $json.result.hits.length }}"
},
{
"id": "79168efa-11b8-4a7b-8851-da9c8cbd700b",
"name": "maxClusterSize",
"type": "number",
"value": "={{ Math.max(...$json.result.hits.map(item => item.count)) }}"
},
{
"id": "e1367cec-9629-4c69-a8d7-3eeae3ac94d3",
"name": "cropNames",
"type": "array",
"value": "={{ $json.result.hits.map(item => item.value)}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "20191c0a-5310-48f2-8be4-1d160f237db2",
"name": "农作物计数",
"type": "n8n-nodes-base.httpRequest",
"position": [
380,
-220
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/facet",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"key\": \"crop_name\",\n \"limit\": $json.result.count,\n \"exact\": true\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "a81103bb-6522-49a2-8102-83c7e004b9b3",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1260,
-340
],
"parameters": {
"width": 520,
"height": 240,
"content": "## 设置异常检测的中心点"
},
"typeVersion": 1
},
{
"id": "38fc8252-7e27-450d-b09e-59ceaebc5378",
"name": "便签 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-420,
-340
],
"parameters": {
"height": 80,
"content": "再次说明,Qdrant 的变量:集群 URL 和我们正在使用的集合"
},
"typeVersion": 1
},
{
"id": "2d0e3b52-d382-428c-9b37-870f4c53b8e7",
"name": "便签 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-140,
-360
],
"parameters": {
"height": 100,
"content": "我们使用聚类中的哪个点来绘制阈值:离中心最远的点,还是第二远...第 X 远的点;"
},
"typeVersion": 1
},
{
"id": "b0b300f3-e2c9-4c36-8a1d-6705932c296c",
"name": "便签 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
-500
],
"parameters": {
"width": 180,
"height": 240,
"content": "这里我们获取[分面计数](https://qdrant.tech/documentation/concepts/payload/?q=facet#facet-counts):关于*\"crop_name\"*有效载荷存在哪些唯一值以及有多少点具有这些值的信息(例如,我们有31个*\"cucumber\"*和29个*\"cotton\"*)"
},
"typeVersion": 1
},
{
"id": "0d2584da-5fd0-4830-b329-c78b0debf584",
"name": "便签 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-140,
260
],
"parameters": {
"height": 120,
"content": "我们使用聚类中的哪个点来绘制阈值:离中心最远的点,还是第二远...第 X 远的点;"
},
"typeVersion": 1
},
{
"id": "f4c98469-d426-415c-916d-1bc442cf6a21",
"name": "便签 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
120,
-400
],
"parameters": {
"height": 140,
"content": "我们需要获取 Qdrant 集合中的[总点数](https://qdrant.tech/documentation/concepts/points/?q=count#counting-points),以便在*\"农作物计数\"*节点中将其用作`limit`,这样我们就不会丢失任何信息;"
},
"typeVersion": 1
},
{
"id": "037af9df-34c4-488d-8c89-561ac25247c4",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
600,
-640
],
"parameters": {
"width": 220,
"height": 380,
"content": "这里我们提取并收集所有关于农作物聚类的信息,以便我们可以为每个聚类调用[Qdrant 距离矩阵 API](https://qdrant.tech/documentation/concepts/explore/?q=distance+#distance-matrix)。"
},
"typeVersion": 1
},
{
"id": "b4e635e3-233d-4358-ad11-250a2b14a2f7",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
260
],
"parameters": {
"height": 200,
"content": "关于每种农作物通常外观的硬编码描述;这些是通过 chatGPT 生成的,技术上可以直接在 n8n 中基于农作物名称或农作物图片完成(我们需要一个关于农作物最正常样本外观的良好描述)"
},
"typeVersion": 1
},
{
"id": "4fda1841-e7e3-4bd2-acf2-ee7338598184",
"name": "便签9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
-800
],
"parameters": {
"height": 400,
"content": "为每个聚类调用一次[距离矩阵 API](https://qdrant.tech/documentation/concepts/explore/?q=distance+#distance-matrix)。"
},
"typeVersion": 1
},
{
"id": "19c4bb6d-abcb-423b-b883-48c779d0307d",
"name": "拆分输出",
"type": "n8n-nodes-base.splitOut",
"position": [
860,
-220
],
"parameters": {
"include": "allOtherFields",
"options": {
"destinationFieldName": "cropName"
},
"fieldToSplitOut": "cropNames"
},
"typeVersion": 1
},
{
"id": "f6d74ced-1998-4dbd-ab04-ca1b6ea409a5",
"name": "便签 10",
"type": "n8n-nodes-base.stickyNote",
"position": [
840,
-60
],
"parameters": {
"width": 150,
"height": 80,
"content": "拆分成每个唯一的农作物聚类"
},
"typeVersion": 1
},
{
"id": "b3adb2bc-61f5-42ff-bb5d-11faa12189b7",
"name": "便签11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1460,
-640
],
"parameters": {
"width": 180,
"height": 240,
"content": "使用 Qdrant 生成的距离矩阵和`scipy`的`coo_array`,我们为每个聚类找到一个**代表性**点(基于**余弦**距离,与聚类内所有其他点最相似的点)"
},
"typeVersion": 1
},
{
"id": "d9d3953e-8b69-4b6a-86f2-b2d2db28d4ad",
"name": "便签 12",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
100
],
"parameters": {
"height": 280,
"content": "要使用此方法找到**代表性**点,我们:"
},
"typeVersion": 1
},
{
"id": "8751efd4-d85e-4dc8-86ef-90073d49b6df",
"name": "便签 13",
"type": "n8n-nodes-base.stickyNote",
"position": [
1460,
100
],
"parameters": {
"width": 160,
"height": 140,
"content": "使用 Voyage 模型嵌入描述"
},
"typeVersion": 1
},
{
"id": "652bc70a-4e6f-416a-977b-5d29ae9cb4f0",
"name": "便签14",
"type": "n8n-nodes-base.stickyNote",
"position": [
1640,
100
],
"parameters": {
"height": 260,
"content": "找到与描述嵌入最接近的图像(按聚类完成)"
},
"typeVersion": 1
},
{
"id": "a5836982-0de0-4692-883c-267602468ed2",
"name": "设置文本中心点阈值分数",
"type": "n8n-nodes-base.httpRequest",
"position": [
3000,
80
],
"parameters": {
"url": "={{ $('Qdrant cluster variables').first().json.qdrantCloudURL }}/collections/{{ $('Qdrant cluster variables').first().json.collectionName }}/points/payload",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"payload\": {\"is_text_anchor_medoid_cluster_threshold\": $json.thresholdScore },\n \"points\": [$json.centerId]\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "qdrantApi"
},
"credentials": {
"qdrantApi": {
"id": "it3j3hP9FICqhgX6",
"name": "QdrantApi account"
}
},
"typeVersion": 4.2
},
{
"id": "5354d197-be5e-4add-b721-9e5e3943e53d",
"name": "便签15",
"type": "n8n-nodes-base.stickyNote",
"position": [
1960,
-460
],
"parameters": {
"width": 200,
"height": 80,
"content": "通过ID获取中心点的向量"
},
"typeVersion": 1
},
{
"id": "93043602-92bc-40ac-b967-ddb7289e5d22",
"name": "便签 16",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
-820
],
"parameters": {
"height": 100,
"content": "在 Qdrant 中为通过*\"距离矩阵方法\"*定义为中心的点设置*\"is_medoid\"*[有效载荷](https://qdrant.tech/documentation/concepts/payload/)"
},
"typeVersion": 1
},
{
"id": "cb1364ad-e21c-4336-9a5b-15e80c2ed2f2",
"name": "便签 17",
"type": "n8n-nodes-base.stickyNote",
"position": [
2280,
260
],
"parameters": {
"height": 180,
"content": "这里,我们不需要像*\"距离矩阵方法\"*那样通过点ID获取向量,因为[上一个节点中的 API 调用](https://api.qdrant.tech/api-reference/search/query-points)能够返回存储在 Qdrant 中的向量作为响应,而距离矩阵 API 只返回点ID。"
},
"typeVersion": 1
},
{
"id": "6d735a28-a93e-41f1-9889-2557a1dd7aec",
"name": "便签 18",
"type": "n8n-nodes-base.stickyNote",
"position": [
1980,
320
],
"parameters": {
"height": 140,
"content": "在 Qdrant 中为通过*\"多模态嵌入模型方法\"*定义为中心的点设置*\"is_text_anchor_medoid\"*[有效载荷](https://qdrant.tech/documentation/concepts/payload/)。"
},
"typeVersion": 1
},
{
"id": "7c6796a9-260b-41c0-9ac7-feb5d4d95c19",
"name": "便签19",
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
-500
],
"parameters": {
"width": 440,
"height": 100,
"content": "从这里开始,此节点和接下来的三个节点对两种方法都是类似的,仅在变量名称上有区别。目标是找到一个**类别(聚类)阈值分数**,以便我们可以将其用于异常检测(对于每个类别)。"
},
"typeVersion": 1
},
{
"id": "5025936d-d49c-4cc1-a675-3bde71627c40",
"name": "便签20",
"type": "n8n-nodes-base.stickyNote",
"position": [
2280,
-180
],
"parameters": {
"height": 220,
"content": "找到与中心向量最不相似的点(在每个类别内)等同于找到与中心向量[相反](https://mathinsight.org/image/vector_opposite)向量最相似的点,也就是所有坐标乘以-1的中心向量。这对于我们使用的**余弦**向量相似度度量总是成立的。"
},
"typeVersion": 1
},
{
"id": "fa9026e4-0c92-4755-92a0-5e400b5f04c9",
"name": "便签21",
"type": "n8n-nodes-base.stickyNote",
"position": [
2580,
-140
],
"parameters": {
"width": 520,
"height": 140,
"content": "所以在这里,我们找到了农作物类别内与类别中心最不相似的点(或第X不相似的点,取决于此流水线开头设置的变量)。我们的**阈值分数**是这个点与类别中心之间的相似度分数。现在我们将其保存为每个类别中心点的元信息。异常检测的所有准备工作已完成。"
},
"typeVersion": 1
},
{
"id": "8e172a7c-6865-4daf-9d9c-86e0dba2c0a2",
"name": "便签22",
"type": "n8n-nodes-base.stickyNote",
"position": [
-900,
-820
],
"parameters": {
"color": 4,
"width": 540,
"height": 300,
"content": "### 对于异常检测"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "a23fc305-7ecd-4754-b208-2d964d9b1eda",
"connections": {
"Merge": {
"main": [
[
{
"node": "Embed text",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Cluster Distance Matrix",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Embed text": {
"main": [
[
{
"node": "Get Medoid by Text",
"type": "main",
"index": 0
}
]
]
},
"Split Out1": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Crop Counts": {
"main": [
[
{
"node": "Info About Crop Clusters",
"type": "main",
"index": 0
}
]
]
},
"Set medoid id": {
"main": [
[]
]
},
"Searching Score": {
"main": [
[
{
"node": "Threshold Score",
"type": "main",
"index": 0
}
]
]
},
"Threshold Score": {
"main": [
[
{
"node": "Set medoid threshold score",
"type": "main",
"index": 0
}
]
]
},
"Threshold Score1": {
"main": [
[
{
"node": "Set text medoid threshold score",
"type": "main",
"index": 0
}
]
]
},
"Get Medoid Vector": {
"main": [
[
{
"node": "Prepare for Searching Threshold",
"type": "main",
"index": 0
}
]
]
},
"Medoids Variables": {
"main": [
[
{
"node": "Total Points in Collection",
"type": "main",
"index": 0
}
]
]
},
"Get Medoid by Text": {
"main": [
[
{
"node": "Set text medoid id",
"type": "main",
"index": 0
},
{
"node": "Prepare for Searching Threshold1",
"type": "main",
"index": 0
}
]
]
},
"Scipy Sparse Matrix": {
"main": [
[
{
"node": "Set medoid id",
"type": "main",
"index": 0
},
{
"node": "Get Medoid Vector",
"type": "main",
"index": 0
}
]
]
},
"Text Medoids Variables": {
"main": [
[
{
"node": "Textual (visual) crop descriptions",
"type": "main",
"index": 0
}
]
]
},
"Cluster Distance Matrix": {
"main": [
[
{
"node": "Scipy Sparse Matrix",
"type": "main",
"index": 0
}
]
]
},
"Info About Crop Clusters": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Qdrant cluster variables": {
"main": [
[
{
"node": "Medoids Variables",
"type": "main",
"index": 0
},
{
"node": "Text Medoids Variables",
"type": "main",
"index": 0
}
]
]
},
"Total Points in Collection": {
"main": [
[
{
"node": "Crop Counts",
"type": "main",
"index": 0
}
]
]
},
"Searching Text Medoid Score": {
"main": [
[
{
"node": "Threshold Score1",
"type": "main",
"index": 0
}
]
]
},
"Prepare for Searching Threshold": {
"main": [
[
{
"node": "Searching Score",
"type": "main",
"index": 0
}
]
]
},
"Prepare for Searching Threshold1": {
"main": [
[
{
"node": "Searching Text Medoid Score",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Qdrant cluster variables",
"type": "main",
"index": 0
}
]
]
},
"Textual (visual) crop descriptions": {
"main": [
[
{
"node": "Split Out1",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 人工智能, 安全运维
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
[3/3] 异常检测工具(农作物数据集)
异常(图像)检测工具 [3/3 - 异常]
Set
Code
Http Request
+2
17 节点Jenny
人工智能
[1/3 - 异常检测] [1/2 - KNN分类] 批量上传数据集到Qdrant(农作物数据集)
将图像数据集上传到Qdrant [1/3异常检测][1/2 KNN分类]
If
Set
Code
+5
25 节点Jenny
人工智能
自动化AWS IAM密钥泄露响应,使用Slack和Claude AI
自动化AWS IAM密钥泄露响应,使用Slack和Claude AI
Set
Code
Merge
+12
40 节点Niranjan G
人工智能
使用 Elevenlabs 和 Hailuo AI 自动创建 YouTube 短视频
使用 Elevenlabs 和 Hailuo AI 自动创建 YouTube 短视频
If
Set
Code
+10
38 节点Nguyen Quoc Hai
人工智能
使用 Anthropic Claude API 批量处理提示
使用 Anthropic Claude API 批量处理提示
If
Set
Code
+13
39 节点Greg Evseev
构建模块
CSV到HubSpot上传器(动态字段映射与Google Sheets集成)
具有动态字段映射和Google Sheets集成的CSV到HubSpot上传器
If
Set
Code
+10
36 节点PollupAI
人工智能