A workflow that is just an AI agent and a goal. Instead of a pre-drawn node graph, the agent writes its own steps on the fly, loops with its allow-listed tools until the goal is met, streams every step live, and pauses to ask you questions. Planning agents investigate read-only; execution agents carry the change out with real device-write tools in a non-production environment.
A normal Versus workflow is a graph you draw: fixed nodes, fixed order, coded steps. A Dynamic Agent workflow is the opposite — you don't draw anything. You pick an AI agent, give it a goal, and save. When it runs, the agent plans and writes its own steps on the fly, one at a time, using its allow‑listed tools, and keeps looping until the goal is achieved — exactly the way an interactive assistant works. Every step it takes appears live in the normal run view, and when it needs a decision only you can make, it pauses and asks you a question; you answer inline and it resumes with your answer folded in.
It is the same governed, tool‑using engine behind Diagnostics AutoPilot, exposed as a first‑class workflow type.
A Dynamic Agent is defined by the tools its agent is allow‑listed for, and that splits cleanly into two kinds:
The same run view, the same on‑the‑fly steps, the same question mechanism — the only difference is whether the toolset can write. Which one you get is determined by the agent you pick; execution agents are clearly badged, and their runs offer a Run mode you choose at launch (below).
The intended flow: harden in non‑prod, run in prod. A Dynamic Agent is exploratory — it decides its next move from live results and may take a slightly different path each run. That is what you want when discovering or rehearsing a procedure, and not what you want when repeating one against production. So the recommended pattern is: run the Dynamic Agent in a non‑production environment to explore and harden the steps — as a planning dry‑run, then as a real execution against non‑prod devices — then promote the finished run to a static, governed workflow and run that in production (see Promote to an executable workflow). You get open‑ended autonomy where it's safe, and a deterministic, approval‑gated, repeatable workflow where it counts.
Feature flag. Dynamic Agent workflows are gated by the
AGENTIC_WORKFLOWS_ENABLEDenvironment variable (off by default). While it is off, the executor branch and the create UI are inert, so an existing deployment is unaffected until you opt in. The agent registry it draws from is gated separately byAGENT_TASKS_ENABLED.
Reach for a Dynamic Agent workflow when the steps aren't known in advance — the work is investigative, conditional, or open‑ended, and a human would figure out the next move from what the last move returned:
When the steps are known and fixed and you're running against production (a scripted upgrade, an AS3 deploy, an approval chain), use a normal graph workflow — it is deterministic and repeatable. The two live side by side under Workflows, and the promote step turns a hardened Dynamic Agent run into exactly that.
| Graph workflow | Dynamic Agent — planning | Dynamic Agent — execution | |
|---|---|---|---|
| Steps | Drawn in advance | Written by the agent on the fly | Written by the agent on the fly |
| Order | Fixed by the graph | Decided each turn from the last result | Decided each turn from the last result |
| Definition | A node/edge graph | An agent + a goal | An agent + a goal |
| Tools | Coded steps | Read‑only | Read‑only + change tools |
| Changes device state | Yes | No | Yes — in a non‑prod environment |
| Best for | Deterministic prod procedures | Investigation, assessment, runbooks | Rehearsing / running a change in non‑prod |
| Execution surface | Run view (live step rows) | Same run view | Same run view |
| Human‑in‑the‑loop | Approval gates | On‑the‑fly questions | On‑the‑fly questions + confirm before disruptive steps |
Dynamic Agents draw from the agent registry (Workflows → AI Agents). Creating one is where you decide whether it's a planning or an execution agent, by which tools you tick:
tmsh show) and the F5 change tools (UCS save, image stage, install‑to‑volume, reboot, failover, save+sync, verify).The allow‑list is enforced by the engine, not merely described in the prompt — an agent physically cannot call a tool it wasn't ticked for.
Under the hood the workflow is saved with graph.meta.execution = "agent", the agent + goal, and (for execution agents) graph.meta.mode. There are no graph nodes — that marker is what tells the executor to run an agent loop instead of a node walk.
The run opens in the standard run view. Then, live (the view polls every couple of seconds):
agent_result.Because the steps are real run rows, everything you already use on a run works: pause/cancel, the live indicator, the permanent log, and re‑opening the finished run later.
Execution agents write to devices, so they are fenced in three independent ways:
environment: Production tag for topology realism is still a lab device, but a device on a genuine production site is refused outright. If you want the safety of a dry‑run against those same devices, run the workflow in simulate mode.Planning agents keep the original guarantee: their tools are read‑only, full stop. When their goal implies a change, they put the precise, ordered steps in recommended actions for a governed workflow to execute.
An F5 Upgrade Engineer execution agent (8 read tools + 7 F5 change tools) is pointed at the bigip1 / bigip2 HA pair on the lab site, in Execute mode, with the goal:
"Deploy TMOS 17.5.1.6 (image
BIGIP-17.5.1.6-0.0.25.iso, already registered in the firmware library on the collector) to the F5 BIG‑IP HA pair bigip1 + bigip2 using a standby‑first, non‑disruptive procedure. First capture a UCS rollback point on both units and save + sync the running config. Then stage the image on each unit and install it to the INACTIVE boot volume. Then STOP and ask me to confirm before any reboot or failover."
What the agent did, unprompted, on the real devices:
bigip1 ACTIVE and bigip2 STANDBY, both on TMOS 17.5.1.6.bigip1 → …/bigip1-preupgrade.ucs is saved.bigip2 → …/bigip2-preupgrade.ucs is saved.ha.bigip2, then bigip1 — an iControl REST install polled until the volume reported complete; the running volume was never touched. Afterwards both units showed HD1.1 active / HD1.2 17.5.1.6 complete.Every one of steps 4–8 is a real operation carried out over the collector tunnel — the same dispatch mechanics Versus's governed f5.* steps use (tmsh over SSH for the UCS and config‑sync, a collector copy job for the image, iControl REST for the install). The UCS saves and the installs take real minutes because they really run. And step 9 is the point: two independent safeguards — the tool's own block on disruptive actions and the agent's instruction to ask — met at exactly the boundary where service would be interrupted.
The honesty gate works the same way further upstream: in an earlier run of this procedure, the goal named a version that wasn't in the firmware library. The agent checked, reported "Image for 17.5.2 NOT present — stage the ISO before install", and asked the operator to confirm the version and stage it — rather than inventing an image or claiming success.
Answer Yes and it continues — and in this run it did, on the real pair: it rebooted bigip2 into the new volume (the reboot tool itself holds through the outage and waits for services), verified it came back on 17.5.1.6 / HD1.2 as Standby, failed over so the upgraded unit took Active, rebooted the former‑active bigip1 the same way, verified it rejoined as Standby, then saved and synced — finishing with goal achieved, both units on the new volume, HD1.1 kept on each as the rollback. One thing it reported rather than hid: after the reboots the datasync-global-dg group sat at Changes Pending with a change conflict, which TMOS itself said to resolve by syncing from bigip1 — the sync tool now follows that recommendation automatically, and the pair ended In Sync across every device group.
Why an agent and not just a script here? Because it reasons about what it finds. In a planning run of the same procedure, when the operator answered with a lower target version than the one running, the agent caught it — "17.1.1.3 is LOWER than 17.5.1.6 — F5 TMOS does not support in‑place downgrade; confirm intent" — and refused to hand back a runbook that would have bricked the pair. It is not a yes‑man.
An agent re‑plans every turn from what the last step returned — but its research reaches only as far as its tools. Two read‑only knowledge tools extend that reach beyond the device, for every supported vendor family:
knowledge_search — keyword search across three corpora at once: your Versus Knowledge Base (the wiki, tenant‑scoped), the Versus product docs, and a vendor documentation corpus — F5 BIG‑IP / F5OS / Distributed Cloud, NetScaler, PAN‑OS, FortiGate, Cisco ASA / Nexus / ACI, Check Point, Arista, Avi, A10, Alteon, Kemp, Infoblox, Cloudflare, AWS and Azure load balancers, Kubernetes, Docker. Results come back as titled, sourced snippets; vendor=<family> narrows them to the device family at hand.vendor_doc_fetch — reads one vendor documentation page live, for guidance that isn't in the corpus yet. It is fenced to an allow‑list of vendor documentation domains (https only, size‑capped, redirects off the list refused), so it is a research tool, not a web client.Tick them in New Agent like any other tool (they sit in the knowledge group). Agents built for change work carry a research rule in their instructions: when a step returns an unexpected condition, an unfamiliar status or error, research it — search, then read the best result — and act on what the documentation says, citing the source; ask the operator only for decisions that are genuinely theirs. In practice that means a "Changes Pending" with a change conflict sends the agent to the vendor's own config‑sync guidance before it touches anything, rather than to you.
The corpus is yours to grow. manage.py ingest_vendor_docs --seed loads a curated set of lifecycle documentation per family (upgrade, HA, config‑sync, common failure states); --vendor <family> --url <page> adds any page from an allow‑listed portal; --coverage shows chunks per family. Every page is validated by fetching it — dead links and portals that render only in a browser (some knowledge‑base articles do) are reported and skipped rather than stored. For those, paste the guidance into a Knowledge Base page: the agent searches the KB in the same call.
What it looks like in practice. After the upgrade above, the same execution agent was given a post‑upgrade validation goal on the real pair, with one instruction that matters: if anything is not healthy, don't guess and don't ask first — research the condition in the vendor documentation, then resolve it using the documented procedure. The sync‑failover group was sitting at Changes Pending (a pool description had been changed on the active unit). What the agent did, unprompted:
ha_status on bigip1 → Changes Pending.knowledge_search — "config sync Changes Pending BIG‑IP HA", narrowed to f5_bigip → six results, the top one F5's Managing Configuration Synchronization guide, section Sync status for device group members.vendor_doc_fetch — read that guide, then reasoned from it: "'Changes Pending' means the local device has configuration changes that need to be synced… the recommended action is to perform a config‑sync from the device with the most current configuration" — the active unit.f5_save_sync on bigip2 (the active unit) → synced to ha; Status: In Sync, then verified In Sync on both units and re‑checked versions and boot volumes.pool_status showed 102 of 103 pools offline. It researched again ("pool members offline after upgrade"), then inspected nodes and monitors over tmsh_show — and concluded, correctly, that these are the lab's test backends (test IPs, monitors that have never passed, zero traffic), not an upgrade regression — and declined to "fix" them.Two hurdles, two different right answers: one resolved by a documented procedure, one deliberately left alone with a documented reason. The whole thing took under two minutes and is on the run page, step by step.
Honest boundaries. Retrieval is keyword‑based (semantic ranking joins in automatically when embeddings are configured); the agent finds only what has been ingested or what a documentation page says; and research spends steps from the same max_steps budget as everything else. Research cannot invent a capability the agent lacks — it will tell you what the documentation prescribes even when it has no tool to carry it out.
Once a Dynamic Agent run finishes with a procedure you trust, don't leave that knowledge trapped in a one‑off run — promote it. On a completed run, Save as executable workflow turns the hardened result into a normal, static graph workflow you can run over and over in production:
f5.ucs (backup) → f5.copy_code (upload image) → f5.calculate_volume / f5.deploy_volume (install to the inactive volume) → f5.reboot_volume → f5.check_ha_status → f5.failover → repeat for the peer → f5.save_sync — with a core.approval gate before the first invasive step.This closes the loop that makes the non‑prod → prod pattern practical: the Dynamic Agent discovers, rehearses and hardens the procedure against a safe environment — first as a simulate dry‑run, then as a real execution against non‑prod devices — and the promoted workflow executes it deterministically in production, behind the same approval gates every other production change uses.
The promoted workflow is a draft produced by an AI mapping the plan onto real steps — always review it in the editor before running it against production, exactly as you would a workflow generated with Generate with AI.
When a run is Waiting for input, the run view shows the agent's question in a card:
Your answer becomes part of the agent's transcript as an observation, and the loop continues from where it paused. You can answer as many questions as the run raises.
knowledge_search and vendor_doc_fetch are read‑only, and the live fetch reaches allow‑listed vendor documentation domains only.max_steps bounds the loop; if it's hit, the agent is forced to conclude from what it has.core.agent step, and invoking agents over the API.