DeepSeek-R1 Agent Loop with Tools + Llama Fallback
Two-Model Sandwich using DeepSeek-R1 purely for reasoning, then feeding its structured outputs into a tool-capable Llama 3.2 model for the execution phase.
Shared 8/17/2025
291 views
Visual Workflow
JSON Code
{
"name": "DeepSeek-R1 Agent Loop with Tools + Llama Fallback",
"nodes": [
{
"id": "1",
"name": "Webhook In",
"type": "n8n-nodes-base.webhook",
"position": [
250,
300
],
"parameters": {
"path": "ai-agent-loop",
"options": {}
},
"typeVersion": 1
},
{
"id": "2",
"name": "Init Loop Data",
"type": "n8n-nodes-base.function",
"position": [
500,
300
],
"parameters": {
"functionCode": "return [{ round: 1, query: $json.query, lastResult: null }];"
},
"typeVersion": 1
},
{
"id": "3",
"name": "DeepSeek R1 Reasoning",
"type": "n8n-nodes-base.httpRequest",
"position": [
750,
300
],
"parameters": {
"url": "http://localhost:11434/api/generate",
"body": "={\"model\": \"deepseek-r1:8b\", \"prompt\": $json.round === 1 ? \"You are the reasoning brain. When you need to perform a task, respond ONLY with JSON:\\n{\\n \\\"action\\\": \\\"<tool_name>\\\",\\n \\\"input\\\": { ... }\\n}\\nValid actions: get_weather, calculate, send_telegram, finish. Do not explain reasoning. User query: \" + $json.query : \"You are continuing your reasoning. You previously received this result: \" + JSON.stringify($json.lastResult) + \"\\nIf you are done, respond with {\\\"action\\\":\\\"finish\\\",\\\"input\\\":{\\\"answer\\\":\\\"...\\\"}} else choose another tool.\"}",
"options": {},
"sendBody": true,
"responseFormat": "json"
},
"typeVersion": 1
},
{
"id": "4",
"name": "Parse DeepSeek JSON",
"type": "n8n-nodes-base.function",
"position": [
1000,
300
],
"parameters": {
"functionCode": "const raw = $json.response || $json.output || $json.data || $json;\nlet parsed;\ntry {\n parsed = JSON.parse(raw.trim());\n} catch (e) {\n throw new Error('Failed to parse DeepSeek output: ' + raw);\n}\nreturn [{ action: parsed.action, input: parsed.input, round: $json.round, query: $json.query, lastResult: $json.lastResult }];"
},
"typeVersion": 1
},
{
"id": "5",
"name": "Route by Action",
"type": "n8n-nodes-base.switch",
"position": [
1250,
300
],
"parameters": {
"rules": {
"rules": [
{
"output": 0,
"conditions": [
{
"value1": "={{$json[\"action\"]}}",
"value2": "get_weather",
"operation": "equal"
}
]
},
{
"output": 1,
"conditions": [
{
"value1": "={{$json[\"action\"]}}",
"value2": "calculate",
"operation": "equal"
}
]
},
{
"output": 2,
"conditions": [
{
"value1": "={{$json[\"action\"]}}",
"value2": "send_telegram",
"operation": "equal"
}
]
},
{
"output": 3,
"conditions": [
{
"value1": "={{$json[\"action\"]}}",
"value2": "finish",
"operation": "equal"
}
]
},
{
"output": 4,
"conditions": [
{
"value1": "={{$json[\"action\"]}}",
"value2": "get_weather",
"operation": "notEqual"
},
{
"value1": "={{$json[\"action\"]}}",
"value2": "calculate",
"operation": "notEqual"
},
{
"value1": "={{$json[\"action\"]}}",
"value2": "send_telegram",
"operation": "notEqual"
},
{
"value1": "={{$json[\"action\"]}}",
"value2": "finish",
"operation": "notEqual"
}
]
}
]
}
},
"typeVersion": 1
},
{
"id": "6",
"name": "Weather API",
"type": "n8n-nodes-base.httpRequest",
"position": [
1500,
100
],
"parameters": {
"url": "https://api.openweathermap.org/data/2.5/weather",
"options": {},
"queryParametersUi": {
"parameter": [
{
"name": "q",
"value": "={{$json[\"input\"][\"location\"]}}"
},
{
"name": "appid",
"value": "YOUR_OPENWEATHER_API_KEY"
},
{
"name": "units",
"value": "metric"
}
]
}
},
"typeVersion": 1
},
{
"id": "7",
"name": "Calculator",
"type": "n8n-nodes-base.function",
"position": [
1500,
300
],
"parameters": {
"functionCode": "const math = require('mathjs');\nconst expr = $json.input.expression;\nlet result;\ntry {\n result = math.evaluate(expr);\n} catch (err) {\n result = 'Error: ' + err.message;\n}\nreturn [{ result }];"
},
"typeVersion": 1
},
{
"id": "8",
"name": "Telegram Send",
"type": "n8n-nodes-base.telegram",
"position": [
1500,
500
],
"parameters": {
"text": "={{$json.input.message}}",
"chatId": "YOUR_TELEGRAM_CHAT_ID"
},
"credentials": {
"telegramApi": "Telegram Bot API"
},
"typeVersion": 1
},
{
"id": "9",
"name": "Webhook Out",
"type": "n8n-nodes-base.webhookResponse",
"position": [
2000,
300
],
"parameters": {},
"typeVersion": 1
},
{
"id": "10",
"name": "Llama3.2 Fallback",
"type": "n8n-nodes-base.httpRequest",
"position": [
1500,
700
],
"parameters": {
"url": "http://localhost:11434/api/generate",
"body": "={\"model\": \"llama3.2:3b\", \"prompt\": \"{{$json}}\"}",
"options": {},
"sendBody": true,
"responseFormat": "json"
},
"typeVersion": 1
},
{
"id": "11",
"name": "Prepare Next Loop",
"type": "n8n-nodes-base.function",
"position": [
1750,
500
],
"parameters": {
"functionCode": "return [{ round: $json.round + 1, query: $json.query, lastResult: $json.result || $json }];"
},
"typeVersion": 1
},
{
"id": "12",
"name": "Check Finish",
"type": "n8n-nodes-base.if",
"position": [
1750,
300
],
"parameters": {
"conditions": {
"number": [],
"string": [
{
"value1": "={{$json.action}}",
"value2": "finish",
"operation": "equal"
}
],
"boolean": []
}
},
"typeVersion": 1
}
],
"active": false,
"connections": {
"Calculator": {
"main": [
[
{
"node": "Prepare Next Loop",
"type": "main",
"index": 0
}
]
]
},
"Webhook In": {
"main": [
[
{
"node": "Init Loop Data",
"type": "main",
"index": 0
}
]
]
},
"Weather API": {
"main": [
[
{
"node": "Prepare Next Loop",
"type": "main",
"index": 0
}
]
]
},
"Check Finish": {
"main": [
[
{
"node": "Webhook Out",
"type": "main",
"index": 0
}
]
]
},
"Telegram Send": {
"main": [
[
{
"node": "Prepare Next Loop",
"type": "main",
"index": 0
}
]
]
},
"Init Loop Data": {
"main": [
[
{
"node": "DeepSeek R1 Reasoning",
"type": "main",
"index": 0
}
]
]
},
"Route by Action": {
"main": [
[
{
"node": "Weather API",
"type": "main",
"index": 0
}
],
[
{
"node": "Calculator",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram Send",
"type": "main",
"index": 0
}
],
[
{
"node": "Check Finish",
"type": "main",
"index": 0
}
],
[
{
"node": "Llama3.2 Fallback",
"type": "main",
"index": 0
}
]
]
},
"Llama3.2 Fallback": {
"main": [
[
{
"node": "Prepare Next Loop",
"type": "main",
"index": 0
}
]
]
},
"Prepare Next Loop": {
"main": [
[
{
"node": "DeepSeek R1 Reasoning",
"type": "main",
"index": 0
}
]
]
},
"Parse DeepSeek JSON": {
"main": [
[
{
"node": "Route by Action",
"type": "main",
"index": 0
}
]
]
},
"DeepSeek R1 Reasoning": {
"main": [
[
{
"node": "Parse DeepSeek JSON",
"type": "main",
"index": 0
}
]
]
}
}
}