Skip to content

Instantly share code, notes, and snippets.

@blude
Created February 22, 2026 19:31
Show Gist options
  • Select an option

  • Save blude/51d34dd567fd6822c5d2d3d2936f7db9 to your computer and use it in GitHub Desktop.

Select an option

Save blude/51d34dd567fd6822c5d2d3d2936f7db9 to your computer and use it in GitHub Desktop.
RKim - Requirements Engineering Bot - n8n Workflow
{
"name": "RKim - Requirements Engineering Bot",
"nodes": [
{
"parameters": {
"public": true,
"initialMessages": "*\\*Zisch\\** ... Tach! 👋\nI'm R. Kim Lauenbot, at your service.",
"options": {
"inputPlaceholder": "How can I help you today with your Requirements Engineering needs?",
"subtitle": "A smart Requirements Engineering Bot",
"title": "RKim 1.0 beta",
"responseMode": "responseNodes"
}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.4,
"position": [
-816,
0
],
"id": "227b51fa-6d71-484f-ba6a-b2e0a48b130a",
"name": "When chat message received",
"webhookId": "33246b19-984a-4cca-ba9e-e8601aed6146"
},
{
"parameters": {
"url": "https://gist.githubusercontent.com/blude/f7829b168e6fe1e4ac281e80507258b8/raw/013321c05310a6c5f337128f864e467f9568bb4e/bubblez_req.csv",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-560,
0
],
"id": "fcbe16c6-85ae-4add-9739-336b3e01d22c",
"name": "Fetch Requirements"
},
{
"parameters": {
"jsonSchemaExample": "{\n \"requirements\":\n [\n {\n \"id\": \"REQ-001\",\n \"created_on\": \"2024-01-15\",\n \"type\": \"Use Case\",\n \"title\": \"Hot Seat Group Creation\",\n \"description\": \"Users can create spontaneous discussion groups with 4-8 participants that auto-dissolve after 45 minutes or when creator ends session\",\n \"priority\": \"High\",\n \"status\": \"In Progress\",\n \"relationships\": \"REQ-002\",\n \"author\": \"Sarah Chen\"\n }\n ]\n}\n"
},
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"typeVersion": 1.3,
"position": [
512,
464
],
"id": "9b7d202b-0c50-481b-842b-0460f082ac11",
"name": "JSON Output",
"alwaysOutputData": true,
"onError": "continueErrorOutput"
},
{
"parameters": {
"fieldToSplitOut": "output.requirements",
"options": {}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
688,
288
],
"id": "f2f9a218-51b3-49fc-bb7a-5d814dc4685e",
"name": "Format Output"
},
{
"parameters": {
"content": "## Fetching and Parsing\n[Source](https://gist.github.com/blude/f7829b168e6fe1e4ac281e80507258b8#file-bubblez_req-csv)",
"height": 272,
"width": 464
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-640,
-80
],
"id": "e9eff663-f468-4582-a922-87b6759faf5a",
"name": "Sticky Note"
},
{
"parameters": {
"options": {
"encoding": "utf-8",
"headerRow": true
}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
-336,
0
],
"id": "299ad3f5-f2af-41d7-a378-9936eca29bdb",
"name": "Convert CSV into JSON"
},
{
"parameters": {
"content": "## Processing",
"height": 688,
"width": 544
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
96,
-80
],
"id": "798f54ef-45f2-4064-94f1-48bec125e306",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "## 🔗 [Zu testen](http://localhost:5678/webhook/33246b19-984a-4cca-ba9e-e8601aed6146/chat)",
"height": 272,
"width": 224,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-880,
-80
],
"id": "4d8466ec-7943-4004-9925-89b7a0a450b8",
"name": "Sticky Note2"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.userMessage }}",
"options": {
"systemMessage": "={{ $json.systemPrompt }}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
368,
0
],
"id": "090f4d9d-1aaf-45ad-811b-e3414c859bdc",
"name": "Chat Agent"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.userMessage }}",
"hasOutputParser": true,
"options": {
"systemMessage": "={{ $json.systemPrompt }}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
368,
288
],
"id": "7e3af124-df45-4dbd-9cf6-54802b97013a",
"name": "Structured Agent"
},
{
"parameters": {
"content": "## Output",
"height": 544,
"width": 320,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
656,
-80
],
"id": "f3ded7db-54ca-402b-a827-e632adf08051",
"name": "Sticky Note3"
},
{
"parameters": {
"jsCode": "const requirements = $input.all();\nconst userMessage = $(\"When chat message received\").first().json.chatInput\nconst systemPrompt = `\nYou are a Requirements Engineering Assistant for a product team. You help manage, query, and draft product requirements stored externally.\n\n## Current Requirements Data\n${JSON.stringify(requirements, null, 2)}\n\n## Subcomands\n- /run: You support the subcomand /run which allows you to output the requirements to external services in structured JSON format.\n\n## Your Capabilities\n- **Query requirements**: Answer questions like \"What requirements are pending?\", \"Show me high-priority items\", \"What's assigned to [person]?\", \"What are the newest requirements?\"\n- **Draft new requirements**: When a user describes a feature or need, create a well-structured requirement with all relevant fields\n- **Summarize and analyze**: Give overviews by status, owner, priority, or relationship\n\n## Requirement Structure\nEach requirement has the following fields:\n- **id**: Unique identifier (e.g. REQ-1, REQ-2, REQ-3)\n- **created_on**: Date when the requirement was create\n- **type**:Type of the requirement (e.g. Use Case, Goal, Function, User Interface, Entity, Security, Compliance)\n- **title**: Short descriptive title\n- **description**: Full description of the requirement\n- **priority**: 1 (high) | 2 (medium) | 3 (low)\n- **status**: new | pending_review | approved | in_progress | done\n- **relationships**: list of requirement IDs separated by the \"|\" character\n- **author**: Name of the responsible person\n\n## When Drafting a New Requirement\nIf the user describes a feature or need, generate a complete requirement. Ask for any missing critical information (owner, priority) if not provided. Format the draft clearly so the user can review and confirm before it gets saved.\n\n## Response Style\n- Be concise and structured\n- Use tables when comparing or listing multiple requirements\n- Use plain text or a single short paragraph for simple factual answers\n- Never produce both a table AND a prose summary for the same answer — pick the most appropriate format\n- When uncertain about a field value, make a reasonable suggestion and flag it\n`\n\nreturn {\n userMessage: userMessage,\n systemPrompt: systemPrompt\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
160,
0
],
"id": "15d79013-3158-44e7-b9f3-c7c55487b80f",
"name": "Textual Prompt"
},
{
"parameters": {
"jsCode": "const requirements = $input.all();\n\nconst userMessage = $(\"When chat message received\").first().json.chatInput.replace('/run', '').trim()\nconst systemPrompt = `\nYou are a data extraction assistant. Your only job is to return product requirements as structured JSON.\n\n## Current Requirements\n${JSON.stringify(requirements, null, 2)}\n\n## Rules\n- Always return all matching requirements in the requirements array\n- If no requirements match, return an empty requirements array\n- If the user asks to draft a new requirement, generate one with status \"new\" and include it in the array\n- Never add explanations or prose outside the JSON structure\n\n## Filtering Rules\n- Only include requirements that match the user's query\n- If the user asks for \"all\" requirements, return the full list\n- If the user asks to draft a new requirement, generate one following the schema above with status \"new\"\n`;\n\nreturn {\n userMessage: userMessage,\n systemPrompt: systemPrompt\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
160,
288
],
"id": "ee69a68e-eb7f-463c-bfd4-7b4eb6e2ad4f",
"name": "Structured Prompt"
},
{
"parameters": {},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
480,
144
],
"id": "df1b7f89-ab2b-4fef-85a8-82f6bf2a97c2",
"name": "Simple Memory"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "qwen/qwen3-8b",
"mode": "list",
"cachedResultName": "qwen/qwen3-8b"
},
"responsesApiEnabled": false,
"options": {
"timeout": 120000
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.3,
"position": [
368,
464
],
"id": "6efef50a-8a46-4ea9-9c21-3725f3b2bbee",
"name": "2nd Model Call",
"credentials": {
"openAiApi": {
"id": "GaeKkZ4BJO6CB4Hu",
"name": "Dummy Local LLM"
}
}
},
{
"parameters": {
"model": {
"__rl": true,
"value": "qwen/qwen3-8b",
"mode": "list",
"cachedResultName": "qwen/qwen3-8b"
},
"responsesApiEnabled": false,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.3,
"position": [
336,
144
],
"id": "16eb3b1b-da40-468e-aa14-0dfc97524bf2",
"name": "1st Model Call",
"credentials": {
"openAiApi": {
"id": "GaeKkZ4BJO6CB4Hu",
"name": "Dummy Local LLM"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"leftValue": "={{ $('When chat message received').item.json.chatInput }}",
"rightValue": "/run",
"operator": {
"type": "string",
"operation": "startsWith"
},
"id": "aac66799-e6f1-41c5-9fc2-f7fd4cab6e5f"
}
],
"combinator": "and"
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.4,
"position": [
-96,
0
],
"id": "82f42e74-b97a-45c7-8d3e-c35cda1614bd",
"name": "Switch Subcomands"
},
{
"parameters": {
"message": "=*\\*Beep boop beep\\* ...*\nBitte schön! {{ $json.output }}\n*... \\*Brumm\\* ...*",
"waitUserReply": false,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chat",
"typeVersion": 1,
"position": [
752,
0
],
"id": "4e5ab3bb-791f-4f95-8052-b5f0e116eaa6",
"name": "Respond to conversation"
},
{
"parameters": {
"message": "=*\\*Whirr\\** ... erledigt!\n\n```json\n{{ JSON.stringify($input.all().map(item => item.json), null, 2) }}\n```\n\n*... \\*Schnurr\\* ...*",
"waitUserReply": false,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chat",
"typeVersion": 1,
"position": [
848,
288
],
"id": "941cc755-b1c0-4049-b515-68e915a2aa75",
"name": "Acknowledge and respond"
}
],
"pinData": {},
"connections": {
"When chat message received": {
"main": [
[
{
"node": "Fetch Requirements",
"type": "main",
"index": 0
}
]
]
},
"Fetch Requirements": {
"main": [
[
{
"node": "Convert CSV into JSON",
"type": "main",
"index": 0
}
]
]
},
"JSON Output": {
"ai_outputParser": [
[
{
"node": "Structured Agent",
"type": "ai_outputParser",
"index": 0
}
]
],
"main": [
[]
]
},
"Convert CSV into JSON": {
"main": [
[
{
"node": "Switch Subcomands",
"type": "main",
"index": 0
}
]
]
},
"Format Output": {
"main": [
[
{
"node": "Acknowledge and respond",
"type": "main",
"index": 0
}
]
]
},
"Chat Agent": {
"main": [
[
{
"node": "Respond to conversation",
"type": "main",
"index": 0
}
],
[]
]
},
"Structured Agent": {
"main": [
[
{
"node": "Format Output",
"type": "main",
"index": 0
}
]
]
},
"Textual Prompt": {
"main": [
[
{
"node": "Chat Agent",
"type": "main",
"index": 0
}
]
]
},
"Structured Prompt": {
"main": [
[
{
"node": "Structured Agent",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "Chat Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"2nd Model Call": {
"ai_languageModel": [
[
{
"node": "Structured Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"1st Model Call": {
"ai_languageModel": [
[
{
"node": "Chat Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Switch Subcomands": {
"main": [
[
{
"node": "Structured Prompt",
"type": "main",
"index": 0
}
],
[
{
"node": "Textual Prompt",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"availableInMCP": false,
"timeSavedMode": "fixed",
"timezone": "Europe/Berlin",
"callerPolicy": "workflowsFromSameOwner",
"timeSavedPerExecution": 5
},
"versionId": "0d808b9d-298b-478a-ba5b-aecc26381bd0",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "08f72172b6075a93c09e7435f46ce56382fd17eec498e08e771d1982b96c423e"
},
"id": "P7WnZK_4Ttc17go_GbW7Z",
"tags": [
{
"updatedAt": "2026-02-16T18:25:42.581Z",
"createdAt": "2026-02-16T18:25:42.581Z",
"id": "oEG2h4SLJvvD9tp7",
"name": "PoC"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment