Autonomous Systems Engineering

Agentic Assistants Training

Build stateful, multi-step AI assistants that plan, execute tools via Model Context Protocol (MCP), verify their own outputs, and pause for human approval on high-stakes actions.

LangGraph
Stateful cyclic execution & checkpointing
MCP Native
Standardized database, API & SaaS tools
HITL Gates
Human-in-the-loop approval for writes
Full Trace
Deterministic replay & step observability

Table of Contents

  1. From Linear Chains to Stateful Agent Graphs
  2. Tool-Use & Model Context Protocol (MCP)
  3. Human-in-the-Loop Approval & Checkpointing
  4. Episodic Memory & Agent Evaluation
  5. Multi-Agent Governance & Least-Privilege Sandboxing
  6. Loop Detection, Idempotency & Failure Recovery
  7. Tutorial 1: Stateful LangGraph Agent in Python
  8. Tutorial 2: ReAct Planner & Verifier Prompt
  9. Tutorial 3: Step-by-Step Agent Hardening
  10. Tutorial 4: Production Python Idempotent Tool Wrapper
  11. Tutorial 5: Supervisor Delegation & Budget Guard Prompt
  12. Tutorial 6: Step-by-Step Runaway Loop & State Recovery Protocol
  13. Live References & Technical Standards

From Linear Chains to Stateful Agent Graphs

Linear prompt chains break the moment an external API returns an unexpected error or a search query yields empty results. Production agentic assistants operate as directed cyclic graphs: they plan an action, invoke a tool, inspect the observation, and either iterate to recover from errors or advance to the next milestone.

Using LangGraph state machines, every step in an agent's reasoning loop is persisted to a durable checkpointer. If a long-running research or operations task is interrupted, it resumes from the exact node where it paused.

Stateful ReAct Agent Execution Loop Planner Node Select Next Tool Tool Executor MCP / REST / SQL Verifier Node Check Goal & Exit Retry / Self-Correction Loop

Tool-Use & Model Context Protocol (MCP)

Rather than writing brittle one-off API wrappers for every assistant, we standardize integrations around the Model Context Protocol (MCP). MCP provides a clean, permissioned boundary between your agent's reasoning loop and internal databases, GitHub repositories, Slack channels, and ticketing systems.

Model Context Protocol (MCP) Integration Bus Agentic Assistant MCP Client MCP Gateway Auth & Rate Limits PostgreSQL MCP Server GitHub / Jira MCP Server Internal ERP MCP Server

Human-in-the-Loop Approval & Checkpointing

Autonomous agents should never execute irreversible writes - such as issuing refunds, deploying infrastructure, or emailing external clients - without explicit authorization. We build native interrupt gates into the agent graph: the assistant prepares the exact payload, suspends execution, and notifies a human reviewer. Once approved, the graph resumes seamlessly.

Human-in-the-Loop (HITL) Interrupt Gate Draft Action Checkpoint & Pause Await Human Sign-Off Resume & Commit

Episodic Memory & Agent Evaluation

We separate short-term working memory (the active thread state) from long-term episodic memory stored in PostgreSQL or a vector index. Every agent run is traced end-to-end so engineering teams can replay failures, measure tool-selection accuracy, and enforce regression gates before deploying prompt or model updates.

Agent Observability & Evaluation Loop Execution Trace Tool Calls & Latency Automated Grader Trajectory & Outcome CI/CD Gate Block Regressions

Tutorial 1: Stateful LangGraph Agent in Python

This minimal LangGraph pattern demonstrates a stateful assistant with a tool-calling loop and deterministic exit condition.

agent_graph.py
from typing import TypedDict, Annotated
import operator
from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    messages: Annotated[list[str], operator.add]
    steps: int

def planner_node(state: AgentState) -> dict:
    return {"messages": ["Planned next tool call"], "steps": state["steps"] + 1}

def should_continue(state: AgentState) -> str:
    return END if state["steps"] >= 3 else "planner"

graph = StateGraph(AgentState)
graph.add_node("planner", planner_node)
graph.set_entry_point("planner")
graph.add_conditional_edges("planner", should_continue, {"planner": "planner", END: END})
app = graph.compile()

Tutorial 2: ReAct Planner & Verifier Prompt

Use this system prompt to enforce bounded tool-calling and explicit verification before returning a final answer.

react_planner_prompt.txt
You are an autonomous operations assistant.
1. Inspect the user goal and list the exact tools required.
2. Execute read-only tools first to gather verified state.
3. Before any state-mutating tool call, summarize the intended change and request HITL approval.
4. Maximum tool iterations: 6. If unresolved, escalate with a structured diagnostic summary.

Tutorial 3: Step-by-Step Agent Hardening

  1. Scope Tool Permissions: Grant read-only credentials by default; isolate write operations behind separate MCP servers.
  2. Bound Execution Loops: Enforce strict maximum step counts and token budgets per thread to prevent runaway loops.
  3. Add Checkpointing: Persist graph state to PostgreSQL so interrupted workflows resume cleanly.
  4. Automate Trajectory Evals: Run 30+ synthetic and historical test cases on every pull request.

Multi-Agent Governance & Least-Privilege Sandboxing

When an enterprise deploys multiple specialized agents - a Triage Agent, a SQL Analyst Agent, and a Billing Execution Agent - flat shared credentials become a critical security liability. A single prompt injection in a customer-facing Triage Agent must never be able to invoke a database-write tool owned by the Billing Agent. Production multi-agent architectures enforce strict least-privilege sandboxing: each agent runs with scoped OAuth2 / IAM tokens and sees only the Model Context Protocol (MCP) tool manifest explicitly authorized for its role.

Code-execution and browser-automation agents require even tighter isolation. Any dynamically generated Python or shell script must execute inside an ephemeral, network-restricted microVM or container sandbox (such as Firecracker or gVisor) with read-only root filesystems and hard CPU/memory quotas. Following Google DeepMind's agentic safety patterns, high-impact state mutations - such as issuing refunds, modifying production DNS, or merging pull requests - are gated behind cryptographic human sign-off.

Multi-Agent Least-Privilege & Sandbox Isolation Supervisor Agent Task Routing & Budget No Direct Write Access Research Agent (Read-Only) Scoped RAG + Web Search MCP Code Agent (MicroVM Sandbox) Ephemeral Container, No Egress Execution Agent (HITL-Gated) Idempotent ERP / CRM Writes Policy & Audit Plane OAuth2 Scope Enforcement Immutable Trace & Replay Log

Loop Detection, Idempotency & Failure Recovery

Autonomous agents fail most catastrophically when they enter silent retry loops - calling the same failing tool repeatedly while burning thousands of tokens - or when a network timeout causes an agent to execute a non-idempotent write twice (such as charging a customer or creating duplicate Jira tickets). Production agent runtimes eliminate both failure modes through deterministic state-machine guards.

First, every state-mutating tool must accept an idempotency_key derived from the workflow's checkpoint ID and step index. If a tool call times out and is retried, the downstream service recognizes the key and returns the cached result without duplicating side effects. Second, the graph supervisor tracks a rolling hash of recent (tool_name, args) pairs; if the exact same call is attempted twice without new state progress, the loop detector halts execution and escalates to a human operator.

Idempotent Tool Execution & Runaway Loop Guard Agent Proposes Tool Attach Idempotency Key Loop & Budget Guard Check Hash & Step <= 10 Execute & Checkpoint Persist State to Postgres Halt & Escalate to HITL Duplicate Call or Budget Exhausted

Tutorial 4: Production Python Idempotent Tool Wrapper

Wrap every state-mutating agent tool with this idempotency and loop-detection decorator to guarantee zero duplicate writes and automatic runaway protection.

idempotent_tool_guard.py
import hashlib
import json
from typing import Any, Callable

class IdempotentToolGuard:
    def __init__(self, max_steps: int = 10):
        self.max_steps = max_steps
        self.steps = 0
        self.cache: dict[str, Any] = {}

    def invoke(self, tool_name: str, args: dict, fn: Callable[[dict], Any]) -> Any:
        self.steps += 1
        if self.steps > self.max_steps:
            raise RuntimeError("Max recursion depth reached; escalating to HITL.")

        key_raw = f"{tool_name}:{json.dumps(args, sort_keys=True)}"
        idem_key = hashlib.sha256(key_raw.encode()).hexdigest()
        if idem_key in self.cache:
            return self.cache[idem_key]

        result = fn(args)
        self.cache[idem_key] = result
        return result

Tutorial 5: Supervisor Delegation & Budget Guard Prompt

Use this system prompt for your multi-agent Supervisor node to enforce strict step budgets, least-privilege delegation, and explicit HITL escalation.

supervisor_delegation_prompt.txt
ROLE: Multi-Agent Supervisor & Budget Controller.

WORKERS AVAILABLE:
- research_agent (read-only)
- code_agent (sandboxed)
- execution_agent (requires HITL approval)

RULES:
1. Never delegate write operations without first verifying facts via research_agent.
2. If remaining_steps <= 2, halt delegation and summarize progress for human review.

OUTPUT (Strict JSON only):
{
  "next_worker": "research_agent | code_agent | execution_agent | HITL_ESCALATE",
  "instruction": "string",
  "requires_human_approval": boolean
}

Tutorial 6: Step-by-Step Runaway Loop & State Recovery Protocol

  1. Halt Active Thread: Cancel the runaway graph execution by revoking its thread lease in the PostgreSQL checkpointer.
  2. Inspect Checkpoint History: Replay the last 5 state transitions to identify which tool observation triggered the repetitive loop.
  3. Verify Idempotency Ledger: Confirm no duplicate external writes occurred by auditing the idempotency_key log.
  4. Patch Tool Schema or Prompt: Clarify the tool's error message so the agent receives actionable recovery guidance instead of a generic 500 error.
  5. Resume from Last Clean Node: Re-attach the thread from the last valid checkpoint rather than restarting the entire workflow from scratch.

Live References & Technical Standards

Ready to Deploy This Architecture?

Schedule a technical discovery session to benchmark your token workloads, size your local inference cluster, and eliminate recurring API bills.