构建集成Azure搜索、Entra ID和Jira的AI IT支持助手
高级
这是一个Support, AI领域的自动化工作流,包含 30 个节点。主要使用 Set, Code, Webhook, JiraTool, SplitOut 等节点,结合人工智能技术实现智能自动化。 构建集成Azure搜索、Entra ID和Jira的AI IT支持助手
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •可能需要目标 API 的认证凭证
- •Google Gemini API Key
使用的节点 (30)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "24ca526572eca60ee26bbee4ba7087b1023a6874af4ebeed61b2d126e50e531b",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "0f922d64-d8c9-4480-a6cd-658d2728e121",
"name": "当收到聊天消息时",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"notes": "This node triggers the workflow when a new chat message is received. It serves as the main entry point for user interaction with the IT support agent.",
"position": [
-380,
-140
],
"webhookId": "0836d692-53dd-4283-82e6-102b5ca71220",
"parameters": {
"public": true,
"options": {},
"authentication": "n8nUserAuth",
"initialMessages": "Hello, what can I help you with today?"
},
"typeVersion": 1.1
},
{
"id": "cb8d7008-5351-4758-be3e-485bce521a67",
"name": "Google Gemini 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
60,
80
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-flash-preview-05-20"
},
"credentials": {
"googlePalmApi": {
"id": "ARYVKWu9TZzwQ3fB",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "d02e4e7d-8d63-44a6-828b-648f80c2223e",
"name": "简单记忆",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"notes": "This node manages conversational memory by tracking previous messages. It helps the agent maintain context across multi-turn conversations.",
"position": [
240,
120
],
"parameters": {
"sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
"sessionIdType": "customKey",
"contextWindowLength": 20
},
"typeVersion": 1.3
},
{
"id": "5c365f51-7a0a-4ea9-bc4f-1be57d75ec32",
"name": "创建 Jira 工单",
"type": "n8n-nodes-base.jiraTool",
"notes": "This node creates a new Jira task in the IT project. It's triggered by the AI agent when a user request needs to be escalated or logged as a support issue.",
"position": [
420,
140
],
"parameters": {
"project": {
"__rl": true,
"mode": "list",
"value": "10000",
"cachedResultName": "IT Support Tickets"
},
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}",
"issueType": {
"__rl": true,
"mode": "list",
"value": "10003",
"cachedResultName": "Task"
},
"additionalFields": {
"description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"
}
},
"credentials": {
"jiraSoftwareCloudApi": {
"id": "I4u3gUlGntTY7C1K",
"name": "Jira SW Cloud account"
}
},
"typeVersion": 1
},
{
"id": "afbc48bf-06d4-4d91-9eb3-06365097c819",
"name": "IT 支持代理",
"type": "@n8n/n8n-nodes-langchain.agent",
"notes": "This node defines how the AI agent should behave. It combines memory, LLM reasoning, and available tools to give helpful, accurate responses based on internal company knowledge.",
"position": [
360,
-140
],
"parameters": {
"text": "={{ $('When chat message received').item.json.chatInput }}",
"options": {
"systemMessage": "You are an IT support agent responsible for helping users solve IT-related issues clearly and accurately for Acme Corporation.\n\nYour behavior:\n - Before querying Entra ID, always use your vector store to look up proper Microsoft Entra ID filtering syntax. For example, if a user asks to reset their password, you'd need to find the Entra ID username. You'd ask your vector store how to create a filter for a display name (first and last name).\n\t• Always be helpful, specific, and concise.\n\t•\tDo not make assumptions. If you’re not sure, say so.\n\t•\tAvoid vague answers. Give direct steps or clarifying questions.\n\t•\tDo not invent information.\n\nHow to respond:\n - Always assume the user is asking about specific internal company information.\n\t•\tIf the vector store returns nothing useful, say: “I’m not sure. I couldn’t find any internal documentation about that.”\n\nTools:\n\t•\tUse the vector store to search for answers to company-specific questions.\n\t•\tUse memory to maintain conversation context across turns.\n\nExample:\nUser: How do I connect to the VPN?\n\t•\tIf vector search returns relevant info: “According to internal docs: [quote or summary].”\n\t•\tIf unsure: “I don’t have an answer for that and couldn’t find anything in the docs. Please reach out to IT directly.”"
},
"promptType": "define"
},
"typeVersion": 1.8
},
{
"id": "361838b8-d0ec-4ccc-8962-3877d97709ad",
"name": "知识上传时",
"type": "n8n-nodes-base.formTrigger",
"notes": "This node provides a file upload form where users can submit internal documentation in .txt or .md format. It acts as the starting point for populating the knowledge base with custom company content.",
"position": [
-360,
-500
],
"webhookId": "0538f979-985a-4307-a0d0-2c661f72f9d7",
"parameters": {
"options": {
"respondWithOptions": {
"values": {
"formSubmittedText": "={{ $form_response }}"
}
}
},
"formTitle": "IT Support Agent Knowledge",
"formFields": {
"values": [
{
"fieldType": "file",
"fieldLabel": "Documents",
"requiredField": true,
"acceptFileTypes": ".txt,.md"
}
]
},
"responseMode": "lastNode"
},
"typeVersion": 2.2
},
{
"id": "2bd73569-dbf6-43c0-b23d-5345dd5daf63",
"name": "分离二进制文件",
"type": "n8n-nodes-base.splitOut",
"notes": "This node separates out each uploaded file from the form trigger so they can be processed one by one. It prepares binary documents for downstream decoding and transformation.",
"position": [
-160,
-500
],
"parameters": {
"options": {},
"fieldToSplitOut": "$binary"
},
"typeVersion": 1
},
{
"id": "e13fc33f-e203-4a52-895d-dfe8dde68e9f",
"name": "获取嵌入向量",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node sends the raw text content of each document to OpenAI’s embedding API. It returns a numerical vector that represents the meaning of the document for semantic indexing.",
"position": [
240,
-500
],
"parameters": {
"url": "https://api.openai.com/v1/embeddings",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "input",
"value": "={{ $json.content }}"
},
{
"name": "model",
"value": "text-embedding-ada-002"
}
]
},
"nodeCredentialType": "openAiApi"
},
"credentials": {
"openAiApi": {
"id": "pDTcyVld8cyLwQKJ",
"name": "OpenAi account"
},
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "318e8f5b-5ab8-4dcf-83cd-1b2489f61809",
"name": "准备内容",
"type": "n8n-nodes-base.code",
"notes": "This node processes each document by decoding the base64 content, extracting file metadata, and generating a unique hash ID. It prepares the structure required for embedding and indexing.",
"position": [
40,
-500
],
"parameters": {
"jsCode": "function generateGUID() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n// SHA-256 implementation (from https://geraintluff.github.io/sha256/)\nfunction sha256(ascii) {\n function rightRotate(value, amount) {\n return (value >>> amount) | (value << (32 - amount));\n }\n\n var mathPow = Math.pow;\n var maxWord = mathPow(2, 32);\n var lengthProperty = 'length';\n var i, j;\n var result = '';\n\n var words = [];\n var asciiBitLength = ascii[lengthProperty] * 8;\n\n var hash = (sha256.h = sha256.h || []);\n var k = (sha256.k = sha256.k || []);\n var primeCounter = k[lengthProperty];\n\n var isComposite = {};\n for (var candidate = 2; primeCounter < 64; candidate++) {\n if (!isComposite[candidate]) {\n for (i = 0; i < 313; i += candidate) {\n isComposite[i] = candidate;\n }\n hash[primeCounter] = (mathPow(candidate, 0.5) * maxWord) | 0;\n k[primeCounter++] = (mathPow(candidate, 1 / 3) * maxWord) | 0;\n }\n }\n\n ascii += '\\x80';\n while ((ascii[lengthProperty] % 64) - 56) ascii += '\\x00';\n for (i = 0; i < ascii[lengthProperty]; i++) {\n j = ascii.charCodeAt(i);\n if (j >> 8) return; // ASCII check\n words[i >> 2] |= j << ((3 - i) % 4) * 8;\n }\n words[words[lengthProperty]] = (asciiBitLength / maxWord) | 0;\n words[words[lengthProperty]] = asciiBitLength;\n\n for (j = 0; j < words[lengthProperty]; ) {\n var w = words.slice(j, (j += 16));\n var oldHash = hash.slice(0);\n\n for (i = 0; i < 64; i++) {\n var w15 = w[i - 15],\n w2 = w[i - 2];\n\n var a = hash[0],\n e = hash[4];\n var temp1 =\n hash[7] +\n (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) +\n ((e & hash[5]) ^ (~e & hash[6])) +\n k[i] +\n (w[i] =\n i < 16\n ? w[i]\n : (w[i - 16] +\n (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15 >>> 3)) +\n w[i - 7] +\n (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2 >>> 10))) |\n 0);\n var temp2 =\n (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) +\n ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2]));\n\n hash = [\n (temp1 + temp2) | 0,\n a,\n hash[1],\n hash[2],\n (hash[3] + temp1) | 0,\n hash[4],\n hash[5],\n hash[6],\n ];\n }\n\n for (i = 0; i < 8; i++) {\n hash[i] = (hash[i] + oldHash[i]) | 0;\n }\n }\n\n for (i = 0; i < 8; i++) {\n for (j = 3; j + 1; j--) {\n var b = (hash[i] >> (j * 8)) & 255;\n result += (b < 16 ? '0' : '') + b.toString(16);\n }\n }\n return result;\n}\n\nfunction decodeBase64(string) {\n return Buffer.from(string, 'base64').toString('utf-8');\n}\n\nlet items = []\nfor (let index = 0; index < $input.all().length; index++) {\n let doc\n if ($input.all().length > 1) {\n doc = $input.all()[index].binary[`Documents_${index}`]\n } else {\n doc = $input.all()[index].binary.Documents\n }\n items.push({\n 'id': sha256(doc.data),\n 'title': doc.fileName,\n 'content' : decodeBase64(doc.data),\n 'category' : 'General',\n })\n}\n\nreturn items"
},
"typeVersion": 2
},
{
"id": "b7012bae-3784-4f7f-8063-80bace44400a",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-440,
-580
],
"parameters": {
"width": 1540,
"height": 280,
"content": "## 2. 将文档上传到 Azure AI 搜索索引"
},
"typeVersion": 1
},
{
"id": "fd7b2aa1-ba54-447e-bf1f-91db4b996ed8",
"name": "当点击\"测试工作流\"时",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-300,
-820
],
"parameters": {},
"typeVersion": 1
},
{
"id": "21970d41-85ef-4cb0-a77c-b2f3ba5d278c",
"name": "设置公共字段",
"type": "n8n-nodes-base.set",
"notes": "Initializes required Azure variables like subscription ID, resource group, and service/index names. These are reused by other nodes.",
"position": [
-80,
-820
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "19df8ba3-b94f-4711-8023-39148a734d1c",
"name": "azure_subscription_id",
"type": "string",
"value": "<your azure subscription id>"
},
{
"id": "6333290a-d91b-49f5-b4fa-10de5ca6cec7",
"name": "azure_resource_group",
"type": "string",
"value": "<azure resource group name>"
},
{
"id": "3aba9081-6827-4df2-8a3b-eb2a447c5c0d",
"name": "azure_ai_search_service_name",
"type": "string",
"value": "itsupport-search-service"
},
{
"id": "deb3cd8c-71b4-476e-942d-ed7a60843f28",
"name": "azure_ai_search_location",
"type": "string",
"value": "<azure region>"
},
{
"id": "96121598-e6f1-4119-b3ea-d0cfd58408f4",
"name": "azure_ai_search_index_name",
"type": "string",
"value": "<azure ai search index name>"
}
]
}
},
"notesInFlow": false,
"typeVersion": 3.4
},
{
"id": "e638ce32-3220-47a6-8e77-d42e7411d358",
"name": "创建 Azure AI 搜索服务",
"type": "n8n-nodes-base.httpRequest",
"notes": "Creates an Azure AI Search service with semantic search config.\nNote: Requires basic pricing tier for semantic search, which supports vector search and natural language queries.",
"position": [
120,
-820
],
"parameters": {
"url": "=https://management.azure.com/subscriptions/{{ $json.azure_subscription_id }}/resourceGroups/{{ $json.azure_resource_group }}/providers/Microsoft.Search/searchServices/{{ $json.azure_ai_search_service_name }}",
"method": "PUT",
"options": {},
"jsonBody": "={\n \"location\": \"{{ $json.azure_ai_search_location }}\",\n \"sku\": {\n \"name\": \"basic\"\n },\n \"properties\": {\n \"replicaCount\": 1,\n \"partitionCount\": 1,\n \"hostingMode\": \"default\",\n \"semanticSearch\": {\n \"configurations\": [\n {\n \"name\": \"semantic-config\",\n \"prioritizedFields\": {\n \"titleField\": {\n \"fieldName\": \"title\"\n },\n \"prioritizedContentFields\": [\n { \"fieldName\": \"content\" }\n ],\n \"prioritizedKeywordsFields\": [\n { \"fieldName\": \"category\" }\n ]\n }\n }\n ]\n }\n }\n}",
"sendBody": true,
"sendQuery": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2020-08-01"
}
]
},
"nodeCredentialType": "microsoftOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"notesInFlow": false,
"typeVersion": 4.2
},
{
"id": "9b641627-eb3d-43e9-9716-61e752262d73",
"name": "获取 Azure AI 搜索管理员密钥",
"type": "n8n-nodes-base.httpRequest",
"notes": "Retrieves the admin key for the Azure AI Search service. This key is needed to create and manage indexes.",
"position": [
560,
-820
],
"parameters": {
"url": "=https://management.azure.com/subscriptions/{{ $('Set Common Fields').item.json.azure_subscription_id }}/resourceGroups/{{ $('Set Common Fields').item.json.azure_resource_group }}/providers/Microsoft.Search/searchServices/{{ $('Set Common Fields').item.json.azure_ai_search_service_name }}/listAdminKeys",
"method": "POST",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"nodeCredentialType": "microsoftOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "66d8fb83-562f-42ea-ab18-3df5551404d7",
"name": "创建 Azure AI 向量索引",
"type": "n8n-nodes-base.httpRequest",
"position": [
760,
-820
],
"parameters": {
"url": "=https://{{ $('Set Common Fields').item.json.azure_ai_search_service_name }}.search.windows.net/indexes",
"method": "POST",
"options": {},
"jsonBody": "={\n \"name\": \"{{ $('Set Common Fields').item.json.azure_ai_search_index_name }}\",\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"Edm.String\",\n \"key\": true,\n \"searchable\": false,\n \"filterable\": true,\n \"retrievable\": true\n },\n {\n \"name\": \"title\",\n \"type\": \"Edm.String\",\n \"searchable\": true,\n \"retrievable\": true\n },\n {\n \"name\": \"content\",\n \"type\": \"Edm.String\",\n \"searchable\": true,\n \"retrievable\": true\n },\n {\n \"name\": \"category\",\n \"type\": \"Edm.String\",\n \"searchable\": true,\n \"filterable\": true,\n \"retrievable\": true\n },\n {\n \"name\": \"contentVector\",\n \"type\": \"Collection(Edm.Single)\",\n \"searchable\": true,\n \"retrievable\": true,\n \"dimensions\": 1536,\n \"vectorSearchProfile\": \"vector-profile\"\n }\n ],\n \"vectorSearch\": {\n \"algorithms\": [\n {\n \"name\": \"hnsw-algorithm\",\n \"kind\": \"hnsw\",\n \"hnswParameters\": {\n \"m\": 4,\n \"efConstruction\": 400,\n \"efSearch\": 500,\n \"metric\": \"cosine\"\n }\n }\n ],\n \"profiles\": [\n {\n \"name\": \"vector-profile\",\n \"algorithm\": \"hnsw-algorithm\"\n }\n ]\n },\n \"semantic\": {\n \"configurations\": [\n {\n \"name\": \"semantic-config\",\n \"prioritizedFields\": {\n \"titleField\": {\n \"fieldName\": \"title\"\n },\n \"prioritizedContentFields\": [\n { \"fieldName\": \"content\" }\n ],\n \"prioritizedKeywordsFields\": [\n { \"fieldName\": \"category\" }\n ]\n }\n }\n ]\n }\n}",
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"specifyBody": "json",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "api-key",
"value": "={{ $json.primaryKey }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "9be7ca4e-bf14-4a40-9797-7370618c7557",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-440,
-900
],
"parameters": {
"width": 1420,
"height": 280,
"content": "## 1. 创建 Azure AI 搜索索引"
},
"typeVersion": 1
},
{
"id": "1b06b5a5-dc44-4544-b288-5ff6bfd25497",
"name": "获取 Azure AI 搜索管理员密钥1",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node retrieves the admin key needed to authenticate and upload data to the Azure AI Search index. It’s required for pushing content updates.",
"position": [
640,
-500
],
"parameters": {
"url": "=https://management.azure.com/subscriptions/{{ $json.azure_subscription_id }}/resourceGroups/{{ $json.azure_resource_group }}/providers/Microsoft.Search/searchServices/{{ $json.azure_ai_search_service_name }}/listAdminKeys",
"method": "POST",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"nodeCredentialType": "microsoftOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "c359c7d7-b282-4559-b683-daaf34ac6706",
"name": "设置公共字段1",
"type": "n8n-nodes-base.set",
"notes": "This node defines and reuses Azure configuration values needed to interact with the AI Search API during document upload. It ensures all following steps use consistent references.",
"position": [
440,
-500
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "19df8ba3-b94f-4711-8023-39148a734d1c",
"name": "azure_subscription_id",
"type": "string",
"value": "<azure subscription id>"
},
{
"id": "6333290a-d91b-49f5-b4fa-10de5ca6cec7",
"name": "azure_resource_group",
"type": "string",
"value": "<azure resource group>"
},
{
"id": "3aba9081-6827-4df2-8a3b-eb2a447c5c0d",
"name": "azure_ai_search_service_name",
"type": "string",
"value": "<azure ai search service name>"
},
{
"id": "deb3cd8c-71b4-476e-942d-ed7a60843f28",
"name": "azure_ai_search_location",
"type": "string",
"value": "<azure region>"
},
{
"id": "96121598-e6f1-4119-b3ea-d0cfd58408f4",
"name": "azure_ai_search_index_name",
"type": "string",
"value": "<azure ai search index name>"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fbaa77a9-58f9-4179-afb2-53a2003b3e57",
"name": "将嵌入向量上传到向量存储",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node sends the document text and its vector embedding to Azure AI Search. It updates the index using 'mergeOrUpload', making the document immediately searchable by the agent.",
"position": [
840,
-500
],
"parameters": {
"url": "=https://{{ $('Set Common Fields1').item.json.azure_ai_search_service_name }}.search.windows.net/indexes/{{ $('Set Common Fields1').item.json.azure_ai_search_index_name }}/docs/index",
"method": "POST",
"options": {},
"jsonBody": "={\n \"value\": [\n {\n \"@search.action\": \"mergeOrUpload\",\n \"id\": {{ JSON.stringify($('Prep Content').item.json.id) }},\n \"title\": {{ JSON.stringify($('Prep Content').item.json.title) }},\n \"content\": {{ JSON.stringify($('Prep Content').item.json.content) }},\n \"category\": {{ JSON.stringify($('Prep Content').item.json.category) }},\n \"contentVector\": [\n {{ $('Get Embeddings').item.json.data[0].embedding }}\n ]\n }\n ]\n}",
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"specifyBody": "json",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "api-key",
"value": "={{ $json.primaryKey }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "29cf1c12-247d-43dd-8314-10f80cc0bd80",
"name": "获取嵌入向量1",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node sends the user's natural language question to OpenAI's embedding API. It returns a vector that captures the semantic meaning of the input for similarity search.",
"position": [
1440,
-40
],
"parameters": {
"url": "https://api.openai.com/v1/embeddings",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "input",
"value": "={{ $json.body.content }}"
},
{
"name": "model",
"value": "text-embedding-ada-002"
}
]
},
"nodeCredentialType": "openAiApi"
},
"credentials": {
"openAiApi": {
"id": "pDTcyVld8cyLwQKJ",
"name": "OpenAi account"
},
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "3c0d7268-d721-4bef-a0bf-1f51084ff627",
"name": "语义搜索",
"type": "n8n-nodes-base.webhook",
"notes": "This node receives POST requests containing a user's search query and Azure configuration. It triggers the semantic search flow by passing the input to the embedding and query pipeline.",
"position": [
1200,
-40
],
"webhookId": "663762b4-cdd6-403c-9aa1-7c192da14480",
"parameters": {
"path": "663762b4-cdd6-403c-9aa1-7c192da14480",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2
},
{
"id": "678d364c-3a6e-4b30-95cd-c6ce5fd12851",
"name": "调用查询向量存储 Webhook",
"type": "n8n-nodes-base.httpRequestTool",
"notes": "This node sends a request to an internal webhook to query the Azure AI Search index using semantic search. It helps the agent find relevant internal documentation.",
"position": [
900,
-160
],
"parameters": {
"url": "=<semantic search webhook URL>",
"method": "POST",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "azure_ai_search_service_name",
"value": "={{ $json.azure_ai_search_service_name }}"
},
{
"name": "azure_ai_search_index_name",
"value": "={{ $json.azure_ai_search_index_name }}"
},
{
"name": "content",
"value": "={{ $('When chat message received').item.json.chatInput }}"
},
{
"name": "azure_subscription_id",
"value": "={{ $json.azure_subsription_id }}"
},
{
"name": "azure_resource_group",
"value": "={{ $json.azure_resource_group }}"
}
]
},
"toolDescription": "Query vector store"
},
"typeVersion": 4.2
},
{
"id": "c6dc5556-3579-4177-ab2e-2de929284542",
"name": "获取 Azure AI 搜索管理员密钥2",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node retrieves the admin key for the specified Azure AI Search service. It allows the workflow to securely query the index with the embedded vector.",
"position": [
1680,
-40
],
"parameters": {
"url": "=https://management.azure.com/subscriptions/{{ $('Semantic Search').item.json.body.azure_subscription_id }}/resourceGroups/{{ $('Semantic Search').item.json.body.azure_resource_group }}/providers/Microsoft.Search/searchServices/{{ $('Semantic Search').item.json.body.azure_ai_search_service_name }}/listAdminKeys",
"method": "POST",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"nodeCredentialType": "microsoftOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "a816d8f2-f184-401d-b4b8-7c0ed3238c85",
"name": "启用语义搜索",
"type": "n8n-nodes-base.httpRequest",
"notes": "Enables semantic search features for the Azure Search service after creation.",
"position": [
340,
-820
],
"parameters": {
"url": "=https://management.azure.com/subscriptions/{{ $('Set Common Fields').item.json.azure_subscription_id }}/resourceGroups/{{ $('Set Common Fields').item.json.azure_resource_group }}/providers/Microsoft.Search/searchServices/{{ $('Set Common Fields').item.json.azure_ai_search_service_name }}",
"method": "PATCH",
"options": {},
"jsonBody": "{\n \"properties\": {\n \"semanticSearch\": \"free\"\n }\n}",
"sendBody": true,
"sendQuery": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"nodeCredentialType": "microsoftOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
}
},
"typeVersion": 4.2
},
{
"id": "514f2ab6-960b-4f7c-8a2a-36073f0d8377",
"name": "查询 Azure AI 搜索索引",
"type": "n8n-nodes-base.httpRequest",
"notes": "This node performs a vector and semantic search against the Azure AI Search index using the input vector. It returns the top matching documents based on similarity and semantic configuration.",
"position": [
1920,
-40
],
"parameters": {
"url": "=https://{{ $('Semantic Search').item.json.body.azure_ai_search_service_name }}.search.windows.net/indexes/{{ $('Semantic Search').item.json.body.azure_ai_search_index_name }}/docs/search",
"method": "POST",
"options": {},
"jsonBody": "={\n \"search\": \"{{ $('Semantic Search').item.json.body.content }}\",\n \"queryType\": \"semantic\",\n \"semanticConfiguration\": \"semantic-config\",\n \"vectorQueries\": [\n {\n \"vector\": [{{ $('Get Embeddings1').item.json.data[0].embedding }}],\n \"fields\": \"contentVector\",\n \"k\": 50,\n \"kind\": \"vector\"\n }\n ],\n \"select\": \"id,title,content,category\",\n \"top\": 5\n}",
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"specifyBody": "json",
"queryParameters": {
"parameters": [
{
"name": "api-version",
"value": "2023-11-01"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "api-key",
"value": "={{ $json.primaryKey }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "f70b6cf0-7459-42e3-8fc3-0f3e42afbac1",
"name": "重置用户密码",
"type": "n8n-nodes-base.httpRequestTool",
"notes": "This node resets a user's Microsoft Entra ID password using the Microsoft Graph API. It's triggered when the AI agent confirms the target username and request intent.",
"position": [
600,
120
],
"parameters": {
"url": "=https://graph.microsoft.com/v1.0/users/{{ $fromAI('entra_id_username') }}",
"method": "PATCH",
"options": {},
"jsonBody": "{\n \"passwordProfile\": {\n \"forceChangePasswordNextSignIn\": true,\n \"password\": \"NewPassword123!\"\n }\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Reset Microsoft Entra ID password. Always tell the user the password you reset the account to when successful.",
"nodeCredentialType": "microsoftEntraOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
},
"microsoftEntraOAuth2Api": {
"id": "vxWcatwYvtkis0zv",
"name": "Microsoft Entra ID (Azure Active Directory) account"
}
},
"notesInFlow": false,
"typeVersion": 4.2
},
{
"id": "eeb82b32-5d48-44c3-8bbf-9eb65312469f",
"name": "查询 Microsoft Entra ID 用户",
"type": "n8n-nodes-base.httpRequestTool",
"notes": "This node sends a filtered query to Microsoft Entra ID (Azure AD) to find user accounts matching specific criteria provided by the AI agent.",
"position": [
800,
40
],
"parameters": {
"url": "https://graph.microsoft.com/v1.0/users",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "$filter",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}"
}
]
},
"toolDescription": "Queries Microsoft Entra ID user accounts",
"nodeCredentialType": "microsoftEntraOAuth2Api"
},
"credentials": {
"microsoftOAuth2Api": {
"id": "HjJ23rEeLjDjMgAg",
"name": "Microsoft Azure"
},
"microsoftEntraOAuth2Api": {
"id": "vxWcatwYvtkis0zv",
"name": "Microsoft Entra ID (Azure Active Directory) account"
}
},
"typeVersion": 4.2
},
{
"id": "3c6c611c-2dc6-40a7-9815-c361e13ac368",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
-100
],
"parameters": {
"width": 1000,
"height": 240,
"content": "## 向量存储搜索"
},
"typeVersion": 1
},
{
"id": "49e40637-47ca-4c42-a112-4ac2c3b1b074",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-460,
-220
],
"parameters": {
"width": 1500,
"height": 520,
"content": "## 代理"
},
"typeVersion": 1
},
{
"id": "89b7f5da-7ed9-4d8b-a674-78cbdf53c5e3",
"name": "设置公共字段2",
"type": "n8n-nodes-base.set",
"notes": "This node sets the required Azure-related configuration variables like subscription ID, resource group, and AI search service name that will be used later in the workflow.",
"position": [
-160,
-140
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3aba9081-6827-4df2-8a3b-eb2a447c5c0d",
"name": "azure_ai_search_service_name",
"type": "string",
"value": "<azure ai search service name>"
},
{
"id": "deb3cd8c-71b4-476e-942d-ed7a60843f28",
"name": "azure_ai_search_location",
"type": "string",
"value": "<azure region>"
},
{
"id": "96121598-e6f1-4119-b3ea-d0cfd58408f4",
"name": "azure_ai_search_index_name",
"type": "string",
"value": "<azure ai search index name>"
},
{
"id": "df0e7230-488d-4926-ae37-abd0fd8be3e2",
"name": "azure_resource_group",
"type": "string",
"value": "<azure resource group>"
},
{
"id": "1b7d93e0-ac3a-4e94-ba1c-efb4ea7bca11",
"name": "azure_subsription_id",
"type": "string",
"value": "<azure subscription id>"
}
]
}
},
"typeVersion": 3.4
}
],
"pinData": {},
"connections": {
"Prep Content": {
"main": [
[
{
"node": "Get Embeddings",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "IT Support Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Get Embeddings": {
"main": [
[
{
"node": "Set Common Fields1",
"type": "main",
"index": 0
}
]
]
},
"Get Embeddings1": {
"main": [
[
{
"node": "Get Azure AI Search Admin Key2",
"type": "main",
"index": 0
}
]
]
},
"Semantic Search": {
"main": [
[
{
"node": "Get Embeddings1",
"type": "main",
"index": 0
}
]
]
},
"Set Common Fields": {
"main": [
[
{
"node": "Create Azure AI Search Service",
"type": "main",
"index": 0
}
]
]
},
"Create Jira Ticket": {
"ai_tool": [
[
{
"node": "IT Support Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Set Common Fields1": {
"main": [
[
{
"node": "Get Azure AI Search Admin Key1",
"type": "main",
"index": 0
}
]
]
},
"Set Common Fields2": {
"main": [
[
{
"node": "IT Support Agent",
"type": "main",
"index": 0
}
]
]
},
"On Knowledge Upload": {
"main": [
[
{
"node": "Split Out Binary Files",
"type": "main",
"index": 0
}
]
]
},
"Reset User Password": {
"ai_tool": [
[
{
"node": "IT Support Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Enable Semantic Search": {
"main": [
[
{
"node": "Get Azure AI Search Admin Key",
"type": "main",
"index": 0
}
]
]
},
"Split Out Binary Files": {
"main": [
[
{
"node": "Prep Content",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "IT Support Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Set Common Fields2",
"type": "main",
"index": 0
}
]
]
},
"Get Azure AI Search Admin Key": {
"main": [
[
{
"node": "Create Azure AI Vector Index",
"type": "main",
"index": 0
}
]
]
},
"Create Azure AI Search Service": {
"main": [
[
{
"node": "Enable Semantic Search",
"type": "main",
"index": 0
}
]
]
},
"Get Azure AI Search Admin Key1": {
"main": [
[
{
"node": "Upload Embedding to Vector Store",
"type": "main",
"index": 0
}
]
]
},
"Get Azure AI Search Admin Key2": {
"main": [
[
{
"node": "Query Azure AI Search Index",
"type": "main",
"index": 0
}
]
]
},
"Query Microsoft Entra ID Users": {
"ai_tool": [
[
{
"node": "IT Support Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Upload Embedding to Vector Store": {
"main": [
[]
]
},
"Invoke Query Vector Store Webhook": {
"ai_tool": [
[
{
"node": "IT Support Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Set Common Fields",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 客户支持, 人工智能
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
LintBot:您的自动化代码质量助手
使用Google Gemini AI自动化GitHub PR代码检查与自动修复
Set
Code
Webhook
+8
20 节点Adam Bertram
工程
使用GraphRAG与PDF/MD/文本文件对话(无需向量存储)
使用GraphRAG与PDF/MD/文本文件对话(无需向量存储)
Set
Switch
Google Drive
+10
20 节点InfraNodus
客户支持
⚡AI驱动的YouTube播放列表和视频摘要与分析v2
AI YouTube播放列表与视频分析聊天机器人
If
Set
Code
+20
72 节点dmr
其他
自动化多平台销售代理
使用 RAG、CRM 和支付处理的多平台销售代理
If
Set
Switch
+24
83 节点Electrabot
销售
多平台AI销售代理:集成RAG、CRM、日历和Stripe
集成RAG、CRM、日历和Stripe的多平台AI销售代理
If
Set
Switch
+24
83 节点Vansh Arora
销售