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
              }
            ]
          ]
        }
      }
    }