Skip to content

Implementing Agentic VLAN Management Patterns in Langflow

Implementation Patterns Tested

Four Langflow implementation patterns were tested for the VLAN management workflow:

Pattern Description Status
Plain orchestrator A single agent uses MCP tools and prompt rules for the full workflow Working
Guarded orchestrator A single agent uses Python tools for deterministic lookups and guards Working and recommended
Multi-agent pipeline Separate Planner, Lookup, and Patch agents are chained together Abandoned
Tool-guarded agent Python tools handle nearly all logic, including approval and state Abandoned

The guarded orchestrator was selected as the most practical Langflow implementation pattern.

The Working Pattern: Guarded Orchestrator

The guarded orchestrator is a single-agent Langflow flow backed by Python tools. It keeps the conversational interface and tool-calling flexibility of an agent, but moves all safety-critical work into deterministic code.

ChatInput
  └─ Guarded Orchestrator Agent
       ├─ lookup_and_guard
       ├─ netbox_patch_interface
       └─ netbox_rollback_interface
  └─ ChatOutput

The flow has five main components:

  1. ChatInput
  2. Guarded Orchestrator Agent
  3. lookup_and_guard
  4. netbox_patch_interface
  5. netbox_rollback_interface
  6. ChatOutput

The LLM handles the natural-language interaction, while Python tools handle the operational logic.

How the Guarded Orchestrator Works

The workflow uses a two-turn approval pattern.

Turn 1: Request and Proposal

The user asks for a VLAN change:

Add VLAN 20 to ge-0/0/0 on rtr-lab-01

The agent extracts:

{
  "action": "add",
  "device": "rtr-lab-01",
  "interface": "ge-0/0/0",
  "vlan_vid": 20
}

It then calls lookup_and_guard.

The Python tool performs all NetBox lookups, guard checks, and patch computation. If validation succeeds, it returns structured data that the agent uses to produce a proposal table and an APPROVAL_TOKEN.

If validation fails, the tool returns an error and the agent reports it to the user.

Turn 2: Approval or Rejection

If the user replies approve, the agent reads the APPROVAL_TOKEN from the conversation history and calls netbox_patch_interface.

If the user replies reject, the operation is cancelled and no write operation is performed.

After the PATCH call, the result is verified. If verification fails, netbox_rollback_interface restores the previous state.

The lookup_and_guard Tool

The lookup_and_guard tool is the main guard layer. It receives four values from the agent:

Field Meaning
action add or remove
device Device name
interface Interface name
vlan_vid VLAN number visible to the network engineer

The tool performs the following steps:

Step NetBox call Guard
1 Find device by name Not found or ambiguous device produces an error
2 Find interface by device ID and interface name Not found or ambiguous interface produces an error
3 Read interface mode Interface must be in tagged mode
4 Find VLAN by VID Missing VLAN produces an error
5 Check current tagged VLANs Add must not duplicate; remove must not remove an absent VLAN
6 Resolve current tagged VLAN IDs to VIDs Used for display
7 Compute new tagged VLAN ID list Used for PATCH
8 Compute rollback ID list Used if verification fails

On success, the tool returns:

{
  "ok": true,
  "action": "add",
  "device": "rtr-lab-01",
  "interface": "ge-0/0/0",
  "vlan_vid": 20,
  "vlan_status": "active",
  "interface_id": 2,
  "vlan_id": 2,
  "rollback_ids": [3],
  "new_tagged_ids": [2, 3],
  "current_vids": [30],
  "new_vids": [20, 30]
}

The LLM does not compute the PATCH payload and does not extract VLAN IDs from raw NetBox objects.

Avoiding VID and DB-ID Confusion

NetBox uses two different identifiers that are easy to confuse:

Identifier Example Meaning
VLAN VID 20 The 802.1Q VLAN number visible to engineers
VLAN database ID 2 The internal NetBox ID required for API PATCH calls

The guarded orchestrator avoids this problem by separating the values before they reach the LLM:

Field Used for
current_vids Proposal display
new_vids Proposal display
new_tagged_ids PATCH payload
rollback_ids Rollback payload

This makes the workflow structurally safer than a pattern where the LLM reads raw nested NetBox responses and decides which integer to use.

The Approval Token Pattern

The APPROVAL_TOKEN is embedded at the end of the proposal response:

APPROVAL_TOKEN: {"interface_id":2,"vlan_id":2,"new_tagged_ids":[2,3],"rollback_ids":[3],"vlan_vid":20,"action":"add","device":"rtr-lab-01","interface":"ge-0/0/0"}

The token contains all information needed for the approval turn:

Field Purpose
interface_id Interface to patch
vlan_id Target VLAN database ID
new_tagged_ids Complete tagged VLAN list after change
rollback_ids Previous tagged VLAN list
vlan_vid Display value
action Add or remove
device Display value
interface Display value

This avoids external state storage and works reliably in the single-agent Langflow flow.

What the LLM Does and Does Not Do

Task LLM Python tool
Parse natural-language request Yes No
Look up NetBox objects No Yes
Extract database IDs No Yes
Check interface mode No Yes
Check idempotency No Yes
Compute PATCH payload No Yes
Format proposal Yes No
Ask for approval Yes No
Apply PATCH after approval Calls tool Executes PATCH
Roll back if needed Calls tool Executes rollback

The result is not a fully deterministic workflow, because the LLM still controls tool calling inside the agent. However, the parts that must be exact are handled in Python.

Why the Plain Orchestrator Was Not Preferred

The plain orchestrator worked, but it delegated too much responsibility to the LLM. The agent performed several MCP lookups, interpreted raw NetBox responses, extracted IDs, applied guard logic from the prompt, and computed the patch payload.

This works in simple cases, but it leaves important reliability issues:

  • the LLM sees raw nested NetBox objects;
  • VID and database ID values can be confused;
  • guard checks depend on prompt compliance;
  • patch computation depends on LLM reasoning.

The guarded orchestrator keeps the same simple single-agent structure but moves these operations into Python.

Why the Multi-Agent Pipeline Was Abandoned

The multi-agent pipeline attempted to split the workflow into separate agents:

ChatInput
  └─ Planner Agent
  └─ Lookup Agent
  └─ Patch Agent
  └─ ChatOutput

The intended design was:

Agent Responsibility
Planner Parse the natural-language request
Lookup Query NetBox and run guard checks
Patch Format the proposal or apply the approved change

This pattern was abandoned because Langflow has no pause-and-wait node. Every user message runs the full canvas. As a result, all agents run on both the initial request and the approval response.

On the approval turn, the Planner and Lookup agents have no meaningful work to do. They must detect that the message is only an approval response and pass it through unchanged. This passthrough pattern proved unreliable, especially when previous tokens and previous requests remained in the conversation history.

The problem is structural: in Langflow, the agents themselves must decide whether to act. In a graph-routed platform, the graph decides which node runs next.

Why the Tool-Guarded Agent Was Abandoned

The tool-guarded agent attempted to move almost all logic into Python tools, including turn detection, approval parsing, patching, verification, and result formatting. Pending state was stored in /tmp/vlan_pending.json instead of in the conversation history.

This seemed safer, but it exposed a different limitation. After a Python tool returned a successful result, the LangChain agent loop still asked the LLM what to do next. In testing, the LLM sometimes continued calling tools autonomously, including calls for the opposite VLAN action. This could overwrite the pending file and corrupt state for the next request.

This showed that Python can guard what happens inside each tool call, but it cannot fully control which tool the Langflow agent decides to call next.

Selected Pattern

The selected pattern is therefore the guarded orchestrator:

  • one agent;
  • deterministic Python guard tool;
  • explicit approval token;
  • Python PATCH and rollback tools;
  • no multi-agent passthrough;
  • no external pending file.

This pattern fits Langflow's strengths while avoiding the parts of the platform that are difficult to control deterministically.