AI Agentic Workflow: Build Automated DevOps Pipelines

AI Agentic Workflow: What It Is and How to Build One

Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

If you’ve spent any time around DevOps or platform engineering lately, you’ve heard the phrase “agentic workflow” thrown around like it’s the new microservices. Strip away the hype and an ai agentic workflow is just a system where an LLM-driven agent plans, executes, and evaluates a sequence of tasks with minimal human babysitting — calling tools, reading their output, and deciding what to do next based on that output, rather than following a fixed script.

This guide breaks down what actually makes a workflow “agentic” instead of just “scripted,” walks through a real implementation using Docker and a task queue, and covers the monitoring setup you need before you trust an agent anywhere near production infrastructure.

What Is an AI Agentic Workflow?

At its simplest, an agentic workflow is a loop: the agent receives a goal, decides on an action, executes that action through a tool (a shell command, an API call, a database query), observes the result, and decides whether to continue, retry, or stop. The key difference from a traditional CI/CD pipeline is that the decision points are made by a model at runtime instead of being hardcoded by a developer in advance.

Agentic vs. Traditional Automation

A traditional bash script or Ansible playbook executes a fixed sequence: step 1, then step 2, then step 3, with if/else branches a human wrote ahead of time. An agentic workflow instead gives the model:

  • A goal (“restart the failing service and confirm health checks pass”)
  • A set of tools it’s allowed to call (shell, HTTP client, database driver)
  • A feedback loop so it can see whether its last action worked
  • The model decides which tool to call and in what order, and can recover from unexpected states without a developer having anticipated every branch. That’s genuinely useful for operational tasks like log triage, incident diagnosis, or dependency upgrades where the failure modes are too varied to script exhaustively.

    The Core Loop: Plan, Act, Observe, Repeat

    Most production agent frameworks — LangGraph, CrewAI, AutoGen, or a hand-rolled loop — implement some version of the ReAct pattern (Reason + Act). You can read the original research behind this approach in the ReAct paper on arXiv. The loop looks like this:

    1. Plan — the model reasons about the current state and picks the next action.
    2. Act — the action is executed against a real tool or system.
    3. Observe — the tool’s output (stdout, HTTP response, exit code) is fed back to the model.
    4. Repeat or terminate — the model decides if the goal is met or another iteration is needed.

    The hard engineering problem isn’t the model call — it’s building a safe, observable execution environment around that loop.

    Core Components You Need

    Before you wire an LLM up to docker exec, you need three pieces of infrastructure in place.

    The Model and Tool-Calling Layer

    This is whatever LLM API you’re using (Anthropic, OpenAI, or a self-hosted model) combined with a structured tool-calling interface. The model doesn’t run code itself — it returns a structured request (“call restart_service with argument nginx“), and your code executes it.

    The Orchestrator

    Something has to own the loop state: which step the agent is on, what tools are available, and when to stop. This is typically a lightweight Python process or a task queue worker, not the LLM itself.

    State and Memory

    Agents need somewhere to persist context between steps — a Redis instance, a Postgres table, or even a JSON file for simple cases. Without persisted state, a crash mid-workflow means starting from zero.

    Building a Simple Agentic Pipeline with Docker

    Let’s build a minimal but real example: an agent that monitors a Docker container, and if it’s unhealthy, inspects logs, attempts a restart, and verifies recovery.

    Start with a docker-compose.yml that isolates the agent from the host, similar to the pattern we cover in our guide to Docker Compose for microservices:

    version: "3.9"
    services:
      agent:
        build: ./agent
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
        environment:
          - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
        depends_on:
          - redis
      redis:
        image: redis:7-alpine
        ports:
          - "6379:6379"

    The agent container gets read-only access to the Docker socket so it can inspect container state without full host access — a small but important guardrail. Full Docker socket security guidance is available in Docker’s own documentation.

    Here’s the core agent loop in Python, using a tool-calling pattern:

    import docker
    import anthropic
    
    client = anthropic.Anthropic()
    docker_client = docker.from_env()
    
    tools = [
        {
            "name": "get_container_logs",
            "description": "Fetch the last 50 lines of logs for a container",
            "input_schema": {
                "type": "object",
                "properties": {"name": {"type": "string"}},
                "required": ["name"],
            },
        },
        {
            "name": "restart_container",
            "description": "Restart a named Docker container",
            "input_schema": {
                "type": "object",
                "properties": {"name": {"type": "string"}},
                "required": ["name"],
            },
        },
    ]
    
    def execute_tool(name, tool_input):
        if name == "get_container_logs":
            container = docker_client.containers.get(tool_input["name"])
            return container.logs(tail=50).decode()
        if name == "restart_container":
            container = docker_client.containers.get(tool_input["name"])
            container.restart()
            return f"Restarted {tool_input['name']}"
        return "Unknown tool"
    
    def run_agent(goal, container_name, max_steps=5):
        messages = [{"role": "user", "content": f"{goal} Container: {container_name}"}]
        for step in range(max_steps):
            response = client.messages.create(
                model="claude-sonnet-5",
                max_tokens=1024,
                tools=tools,
                messages=messages,
            )
            if response.stop_reason != "tool_use":
                return response.content
            tool_call = next(b for b in response.content if b.type == "tool_use")
            result = execute_tool(tool_call.name, tool_call.input)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({
                "role": "user",
                "content": [{
                    "type": "tool_result",
                    "tool_use_id": tool_call.id,
                    "content": result,
                }],
            })
        return "Max steps reached without resolution"

    This is intentionally minimal — no retries, no timeout handling — but it demonstrates the full plan/act/observe loop with real tool execution against the Docker API.

    Orchestrating Multi-Agent Pipelines

    A single agent handling one container is fine for a demo. Real infrastructure needs a queue so multiple agents can run concurrently without stepping on each other. A common pattern uses Redis as both the state store and the queue, with Celery or a lightweight custom worker pulling jobs:

    from redis import Redis
    from rq import Queue
    
    redis_conn = Redis(host="redis", port=6379)
    queue = Queue("agent-tasks", connection=redis_conn)
    
    job = queue.enqueue(run_agent, "Diagnose and fix", "web-app-1")
    print(job.id)

    Each job carries its own conversation history and tool scope, so one misbehaving agent can’t affect another container it wasn’t authorized to touch. This is the same isolation principle we discuss in our piece on self-hosted monitoring stacks — least privilege, scoped credentials, and no shared blast radius between workers.

    Guardrails You Cannot Skip

    Before letting an agent touch anything resembling production, put these in place:

  • Explicit tool allowlists — never give the model a raw shell; expose only named, scoped functions.
  • Max-step limits — cap iterations so a confused agent can’t loop indefinitely and burn API spend.
  • Human approval gates for destructive actions (deletes, force-pushes, scaling down production).
  • Full audit logging of every tool call, input, and output the agent produced.
  • Rate limits on both API calls and infrastructure-affecting actions per time window.
  • Monitoring and Observability for Agentic Systems

    Agentic workflows fail silently if you’re not watching closely — a model can “succeed” at a task in a way that’s technically correct but operationally wrong (restarting the wrong container, for instance). You need three layers of visibility:

    1. Uptime and health checks on anything the agent manages. A service like BetterStack gives you incident alerting and status pages without building your own from scratch.
    2. Infrastructure metrics for the hosts running your agent workers — CPU, memory, and queue depth matter here as much as they do for any worker fleet, and providers like DigitalOcean make it straightforward to spin up isolated droplets per environment.
    3. Edge protection if any part of your agent’s tool surface is exposed via webhook or API — Cloudflare in front of that endpoint adds WAF rules and rate limiting cheaply.

    Log every single tool call the agent makes, with timestamps and full input/output. When something goes wrong at 3 a.m., that log is the only way to reconstruct what the agent actually did versus what you assumed it did.

    Common Pitfalls

    Teams adopting agentic workflows tend to hit the same set of problems:

  • Giving the agent unscoped shell access instead of named tools
  • No maximum step count, leading to runaway API costs
  • Treating agent output as ground truth without verification steps
  • Skipping structured logging until after the first incident
  • Running agents with the same credentials as human operators instead of scoped service accounts
  • None of these are exotic — they’re the same operational discipline you’d apply to any automated system with write access to production, just applied to a system whose decisions are less predictable than a static script.


    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    What’s the difference between an AI agentic workflow and a normal automation pipeline?
    A normal pipeline follows a fixed sequence written by a developer. An agentic workflow lets a model decide the sequence of actions at runtime based on the results of previous steps, so it can adapt to situations the developer didn’t explicitly script for.

    Do I need a specific framework like LangGraph or CrewAI to build one?
    No. Frameworks help with boilerplate (state management, tool schemas, retries) but the core loop — plan, act, observe, repeat — can be built with a plain API client and a few dozen lines of Python, as shown above.

    Is it safe to let an agent restart production containers on its own?
    Only with strict guardrails: scoped tool access, step limits, audit logging, and human approval for high-risk actions. Start agentic workflows in staging environments before granting any production write access.

    How do I control the cost of running agentic workflows?
    Cap the number of loop iterations per task, set a token budget per run, and cache repeated tool calls where possible. Runaway loops are the most common source of unexpected API spend.

    Can agentic workflows replace CI/CD pipelines entirely?
    No — they complement them. CI/CD is deterministic and auditable by design, which is exactly right for build and deploy steps. Agentic workflows are better suited to diagnosis, triage, and remediation tasks where the failure space is too broad to script exhaustively.

    What’s the best first project to try this on?
    A read-only diagnostic agent: something that inspects logs and metrics and produces a summary, without any write access to infrastructure. It lets you validate the model’s reasoning quality before you ever give it a tool that can change system state.

    AI agentic workflows aren’t magic — they’re a plan/act/observe loop wrapped around tools you already trust, with a model making the routing decisions. Get the guardrails right first, and the automation follows naturally.

    Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *