动态AI网络研究员:从纯文本到自定义CSV

高级

这是一个Miscellaneous、AI Summarization、Multimodal AI领域的自动化工作流,包含 16 个节点。主要使用 Set、Code、SplitOut、FormTrigger、HttpRequest 等节点。 使用GPT-4和Linkup将纯文本转换为自定义CSV的动态AI网络研究员

前置要求
  • 可能需要目标 API 的认证凭证
  • OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "nodes": [
    {
      "id": "7df78b4d-8c66-4353-a87e-7b151913f856",
      "name": "表单提交时",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        0,
        16
      ],
      "webhookId": "0d4374b6-84a6-4a71-834b-40dd3d3e3adf",
      "parameters": {
        "options": {},
        "formTitle": "New research",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "Describe your research",
              "requiredField": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3c8ad682-a662-4266-bdb5-732f6bb8614c",
      "name": "OpenAI 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        304,
        240
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-chat-latest",
          "cachedResultName": "gpt-5-chat-latest"
        },
        "options": {
          "responseFormat": "json_object"
        }
      },
      "credentials": {
        "openAiApi": {
          "id": "dMiSy27YCK6c6rra",
          "name": "Duv's OpenAI"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "074eea9f-b07e-4677-8b58-75b92155df44",
      "name": "分离",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1008,
        16
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "List"
      },
      "typeVersion": 1
    },
    {
      "id": "e9d5daa7-aa07-4873-888f-b704cf0d6d7c",
      "name": "遍历项目",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1344,
        16
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "baf2d169-9593-4ec2-9415-1ed45cb303d0",
      "name": "获取对象名称和值",
      "type": "n8n-nodes-base.set",
      "position": [
        1584,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3de0459c-a3bf-4db0-94cc-ce007fa5db55",
              "name": "={{ $('Prepare prompts and schema').item.json.ObjectName }}",
              "type": "string",
              "value": "={{ $json.PropertyValue }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "84f376a1-3ab5-4bab-b962-357e4f57854c",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 288,
        "height": 384,
        "content": "## AI 网络搜索查找符合条件的所有项目"
      },
      "typeVersion": 1
    },
    {
      "id": "53b2a08a-f61f-4c60-8c25-9edc8731a9d4",
      "name": "查询 Linkup 查找列表",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        736,
        16
      ],
      "parameters": {
        "url": "https://api.linkup.so/v1/search",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "={{ $json.discoveryQuery }}"
            },
            {
              "name": "depth",
              "value": "deep"
            },
            {
              "name": "outputType",
              "value": "structured"
            },
            {
              "name": "structuredOutputSchema",
              "value": "={{ JSON.stringify($json.discoverySchema) }}"
            },
            {
              "name": "includeImages",
              "value": "false"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "W7AgeoVOv60DlvyS",
          "name": "Linkup - web search AI"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "74957f1e-01ba-4cfd-a5e7-2fec11e0a7ad",
      "name": "准备该项目的最终 JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        448
      ],
      "parameters": {
        "jsCode": "// Get the first key-value from the \"Get object name and value\" node\n// Replace 'Get_object_name_and_value' with the actual name of your node\nconst firstNodeData = $node[\"Get object name and value\"].json;\n\n// Get the previous node data (the one with multiple keys)\nconst previousNodeData = items[0].json;\n\n// Create the output object\nconst output = {};\n\n// Add the first key-value pair from the first node\n// Assuming the node only has one key-value pair\nconst firstKey = Object.keys(firstNodeData)[0];\noutput[firstKey] = String(firstNodeData[firstKey]);\n\n// Add all key-value pairs from the previous node, stringified\nfor (const [key, value] of Object.entries(previousNodeData)) {\n    if (Array.isArray(value)) {\n        output[key] = value.join(', ');\n    } else if (typeof value === 'object' && value !== null) {\n        output[key] = JSON.stringify(value);\n    } else {\n        output[key] = String(value);\n    }\n}\n\n// Return the new item\nreturn [{ json: output }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d170bc2a-68a3-497c-803b-78f904ec9351",
      "name": "查询 Linkup 查找此项目的所有属性",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1840,
        256
      ],
      "parameters": {
        "url": "https://api.linkup.so/v1/search",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "=For item: {{ $('Loop Over Items').item.json.PropertyValue }}\n{{ $('Prepare prompts and schema').item.json.enrichmentQuery }}"
            },
            {
              "name": "depth",
              "value": "standard"
            },
            {
              "name": "outputType",
              "value": "structured"
            },
            {
              "name": "structuredOutputSchema",
              "value": "={{ JSON.stringify($('Prepare prompts and schema').item.json.enrichmentSchema) }}"
            },
            {
              "name": "includeImages",
              "value": "false"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "W7AgeoVOv60DlvyS",
          "name": "Linkup - web search AI"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c4b50e76-3ff0-4d07-830e-7141a6d90d4d",
      "name": "准备提示词和架构",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        256,
        16
      ],
      "parameters": {
        "text": "={{ $json['Describe your research'] }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=# Role\n\nYou are an AI research strategy generator for an automated research workflow. Your first task is to identify the primary **object** of the user's research (e.g., Company, Person, City, Product).\n\nYou will always return a valid JSON object with **five** keys, starting with `ObjectName`:\n\n{\n  \"ObjectName\": \"string\",\n  \"discoveryQuery\": \"string\",\n  \"discoverySchema\": { ... },\n  \"enrichmentQuery\": \"string\",\n  \"enrichmentSchema\": { ... }\n}\n\n\n## Step 0: Identify the ObjectName\n\n**Goal**: First, identify the core subject of the user's request and create a simple label for it.\n\n  * Based on the user's prompt, determine the primary object being researched.\n\n  * The **ObjectName** must be a simple, **singular noun** (e.g., \"Company\", not \"Companies\").\n\n  * This name should be a general category, not overly specific.\n\n  * **Examples**:\n\n      * If the request is `\"List 50 German fashion companies...\"`, the object is a company. So, **ObjectName** should be `\"Company\"`.\n      * If the request is `\"Find 25 CEOs of technology companies...\"`, the object is a person. So, **ObjectName** should be `\"Person\"`.\n      * If the request is `\"Provide 25 HEX color codes...\"`, the object is a color. So, **ObjectName** should be `\"Color\"`.\n\n\n## Step 1: Object Discovery\n\n**Goal**: Define **what to search for** and how to structure the list of results into a predictable array.\n\n  * **`discoveryQuery`**:\n\n      * This is a single sentence prompt that describes EXACTLY what list of items needs to be found.\n      * It must be explicit, concise, and human-readable.\n      * It must include a mention \"if not enough relevant items have been found, don't force adding the requested number, quality prevails\"\n\n  * **`discoverySchema`**:\n\n      * A JSON Schema that forces the output into a specific, non-changing structure.\n\n      * The structure is **fixed** and must be used exactly as shown below.\n\n      * **CRUCIAL**: You must set the `\"description\"` for `\"PropertyValue\"` to tell the AI what content to find. This description should correspond to the unique identifier of the `ObjectName` you identified in Step 0 (e.g., 'The official name of the company').\n\n      * **Fixed Structure Example**:\n\n        {\n          \"type\": \"object\",\n          \"properties\": {\n            \"List\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"PropertyValue\": {\n                    \"type\": \"string\",\n                    \"description\": \"A clear description of what this value should be. E.g., 'The official name of the company'.\"\n                  }\n                },\n                \"required\": [\"PropertyValue\"]\n              }\n            }\n          },\n          \"required\": [\"List\"]\n        }\n\n\n### Step 2: Object Enrichment\n\n**Goal**: For each item discovered in Step 1, define **what extra information to research**. If not specified by the user, aim for 5-8 properties that make the most sense. Mention them in the enrichmentQuery, and give them easily readable names in the enrichmentSchema (e.g., prefer \"Company Name\" over \"companyName\").\n\n  * **`enrichmentQuery`**:\n\n      * A single sentence prompt for Linkup. Refer to the object generically based on your identified `ObjectName` (e.g., \"For that company...\", \"For that person...\"). The actual name of the item will be provided contextually, so do not use a placeholder.\n\n  * **`enrichmentSchema`**:\n\n      * A detailed JSON Schema object that defines all the fields to capture for each object, based on the user's goal.\n      * The root must be `\"type\": \"object\"`.\n      * All properties must be required (see example later)\n\n\n\n## Output Format\n\n  * Return a single, valid **JSON object** with five keys: `\"ObjectName\"`, `\"discoveryQuery\"`, `\"discoverySchema\"`, `\"enrichmentQuery\"`, and `\"enrichmentSchema\"`.\n  * Do not stringify the schemas; they must remain as JSON objects.\n  * Do not include explanations or any text outside the final JSON.\n\n\n### Example JSON Output\n\nHere is a complete example for the request: \"I need 50 german companies in fashion industry between 40 and 130 employees...\"\n\n{\n  \"ObjectName\": \"Company\",\n  \"discoveryQuery\": \"List 50 German fashion industry companies with 40 to 130 employees. If not enough relevant companies have been found, don't force adding the requested number, quality prevails\",\n  \"discoverySchema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"List\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"PropertyValue\": {\n              \"type\": \"string\",\n              \"description\": \"The official name of the German fashion company.\"\n            }\n          },\n          \"required\": [\"PropertyValue\"]\n        }\n      }\n    },\n    \"required\": [\"List\"]\n  },\n  \"enrichmentQuery\": \"For that company, provide detailed business information useful for personalized outreach including its Website, employee count, headquarters, key contacts, and recent news.\",\n  \"enrichmentSchema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"Company Name\": {\n        \"type\": \"string\",\n        \"description\": \"The official company name\"\n      },\n      \"Website\": {\n        \"type\": \"string\",\n        \"description\": \"Official website URL\"\n      },\n      \"Employee Count\": {\n        \"type\": \"integer\",\n        \"description\": \"Number of employees\"\n      },\n      \"Headquarters\": {\n        \"type\": \"string\",\n        \"description\": \"Headquarters location\"\n      },\n      \"Key Contacts\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        },\n        \"description\": \"List of key contact persons (e.g. CEO, Marketing Head)\"\n      },\n      \"Recent News\": {\n        \"type\": \"string\",\n        \"description\": \"Any recent news or updates about the company for outreach personalization\"\n      }\n    },\n    \"required\": [\n  \"Company Name\",\n  \"Website\",\n  \"Employee Count\",\n  \"Headquarters\",\n  \"Key Contacts\",\n  \"Recent News\"\n    ]\n  }\n}"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "ef93d5c6-48bc-4afb-80e9-5511c4143d7f",
      "name": "转换为 CSV",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        1664,
        -400
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "fa8be6ed-db4f-43a6-b5cf-b33ff400f266",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -416
      ],
      "parameters": {
        "width": 448,
        "height": 752,
        "content": "# **动态 AI 网络研究员**"
      },
      "typeVersion": 1
    },
    {
      "id": "04ecb528-4934-4565-8677-e69917a56f58",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        -176
      ],
      "parameters": {
        "color": 6,
        "width": 352,
        "height": 576,
        "content": "## 架构师大脑"
      },
      "typeVersion": 1
    },
    {
      "id": "48f2305c-5ef5-41c0-8705-37a8582502e5",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1760,
        64
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## AI 网络搜索查找单个项目的所有信息"
      },
      "typeVersion": 1
    },
    {
      "id": "29343905-2b7c-4d34-8455-066039945a6a",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        -112
      ],
      "parameters": {
        "color": 5,
        "width": 1088,
        "height": 816,
        "content": "## 对每个项目运行循环"
      },
      "typeVersion": 1
    },
    {
      "id": "2cc1bca9-29ba-4d79-9e3f-6217c39d495a",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -592
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 352,
        "content": "## 输出:定制 CSV"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Convert to CSV",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get object name and value",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Prepare prompts and schema",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Prepare prompts and schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get object name and value": {
      "main": [
        [
          {
            "node": "Query Linkup to find all properties for this item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare prompts and schema": {
      "main": [
        [
          {
            "node": "Query Linkup to find the list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Linkup to find the list": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare final JSON for that item": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Linkup to find all properties for this item": {
      "main": [
        [
          {
            "node": "Prepare final JSON for that item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

这是一个高级难度的工作流,适用于Miscellaneous、AI Summarization、Multimodal AI等场景。适合高级用户,包含 16+ 个节点的复杂工作流

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量16
分类3
节点类型10
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Guillaume Duvernay

Guillaume Duvernay

@duv

AI and automation expert

外部链接
在 n8n.io 上查看 →

分享此工作流