The Leash and the Wolf: Why Every AI Agent Needs an Orchestrator

The Leash and the Wolf: Why Every AI Agent Needs an Orchestrator
Deep agents are powerful. But without a state machine holding the leash, they will loop, skip, waste, and crash. Here is the case for deterministic orchestration, told through Goose, mini-swe-agent, Stripe Minions, and OpenClaw.
Table of Contents
- The $1 Trillion Loop
- What Is a Deep Agent?
- The Five Problems: When the Wolf Runs Free
- Case Study: Goose (Block)
- Case Study: mini-swe-agent
- Case Study: Stripe Minions
- Case Study: OpenClaw as Orchestrator
- The Hybrid Architecture: The Winning Pattern
- Context Management: The Hidden Challenge
- Control Is Not the Enemy of Creativity
The $1 Trillion Loop
In February 2026, Stripe published a blog post that quietly revealed something remarkable. Over a thousand pull requests merge every week at Stripe with zero human-written code. Fully unattended coding agents, called “Minions,” produce production code for a system that moves over $1 trillion in payment volume per year.
The sentence that caught my attention was this:
“The core agent loop runs on a fork of Block’s coding agent goose, one of the first widely used coding agents, which we forked early on. We’ve customized the orchestration flow in an opinionated way to interleave agent loops and deterministic code, for git operations, linters, testing, and so on, so that minion runs mix the creativity of an agent with the assurance that they’ll always complete Stripe-required steps like linters.”
Read that again. Stripe did not build a smarter model. They did not give the agent more tools. They built an orchestrator that wraps the agent, forces it through mandatory checkpoints, and guarantees that certain steps always execute regardless of what the LLM decides.
This is the pattern hiding in plain sight across every successful production agent deployment. And it starts with understanding what a “deep agent” actually is, and why it is not enough.
What Is a Deep Agent?
A deep agent is not just “an LLM that can call tools.” It is an execution system that can:
- Sustain multi-step goals over long horizons
- Maintain and evolve state across turns
- Decompose tasks into subgoals
- Call tools iteratively
- Recover from failure with structured feedback
- Converge under explicit stopping criteria
A useful mental model breaks this into four loops:
- Reasoning loop: propose next action based on current state
- Action loop: execute tool calls and external operations
- Learning loop: consume results, detect failures, revise plan
- Control loop: enforce budgets, gates, retries, and completion policy
Most agent implementations over-index on the first two loops and under-build the fourth. That is where things break.
The ReAct Foundation
Every deep agent builds on the ReAct (Reasoning + Acting) pattern:
Thought: I need to find the bug in the authentication code
Action: grep -r "authenticate" src/
Observation: Found 3 files with authentication logic
Thought: The error message mentions line 45 of auth.py
Action: cat src/auth.py | head -60
Observation: [file contents]
Thought: I see the bug - missing null check on line 45
Action: [edit file] In code, it looks deceptively simple:
while not done:
thought = llm.think(context)
action = llm.decide_action(thought)
observation = env.execute(action)
context.append(thought, action, observation) The key insight of a deep agent is that the context window IS the state. The agent’s “understanding” emerges from the accumulated history of thoughts, actions, and observations. After 50 steps, the LLM sees the entire trajectory when making decisions, not just the current state.
This is powerful. It is also dangerous.
The Five Problems: When the Wolf Runs Free
A pure deep agent loop gives the LLM total control:
# Pure agent loop - LLM controls everything
while True:
action = llm.decide(context)
result = env.execute(action)
context.append(result)
if llm.thinks_done(context):
break This creates five fundamental problems:
| Problem | What Happens | Real Example |
|---|---|---|
| No Guarantees | LLM might skip required steps | Forgets to run tests before submitting |
| Unbounded Behavior | Can loop indefinitely | Keeps trying the same failing approach 30 times |
| No Checkpoints | Cannot resume from failure | Crashes after 50 steps, loses everything |
| Resource Waste | May use expensive operations when cheap ones suffice | Uses GPT-4 for simple linting tasks |
| Non-determinism | Unpredictable execution paths | Sometimes runs tests, sometimes does not |
These are not theoretical concerns. They are the reason Stripe built an orchestrator. The reason Goose needs a state machine. The reason OpenClaw’s Gateway is more than a chat wrapper.
A powerful deep agent is still insufficient for production workflows because it cannot guarantee hard invariants by itself. “Always run lint before marking task complete.” “Never push if required tests fail.” “At most N expensive CI rounds.” These are not suggestions. They are policies. And LLM behavior is stochastic; compliance invariants are not.
So you need something else: an external state machine or graph orchestrator to govern run phases, enforce transitions, and handle failure deterministically.
Case Study: Goose (Block)
Goose is Block’s open-source AI agent (30.5k stars on GitHub). Written in Rust, it is the foundation that Stripe forked for Minions. Goose already has a strong inner loop, but examining its architecture reveals exactly where orchestration is missing and where it needs to be added.
The Deep Agent Core
Goose’s operational core lives in Agent::reply_internal. Conceptually, the loop does:
- Check cancellation, max turns, final-output condition
- Build contextualized conversation and stream model response
- Emit assistant text and tool requests
- Route tool calls through inspection, approval, and execution
- Append tool responses and messages to conversation
- Optionally compact context and apply retry logic
- Exit or continue
This is a strong deep agent. But look at where the deterministic logic currently lives. It is scattered across three separate layers:
- Deep-agent loop (inner):
Agent::reply_internalincrates/goose/src/agents/agent.rs - Execution runners (outer): CLI runtime stream handling in
crates/goose-cli/src/session/mod.rs, plus scheduled automation lifecycle incrates/goose/src/scheduler.rs - Deterministic validators: Retry checks and
on_failurehooks incrates/goose/src/agents/retry.rs
Goose is already close to a formal graph architecture. The missing piece is making run phases explicit and policy-driven instead of implicit across scattered handlers.
The Proposed State Machine
Here is what an explicit orchestration layer looks like for Goose. This comes from a formal RFC proposing a RunState enum and transition function:
pub enum RunState {
PrepareContext,
AgentPass,
DeterministicChecks,
RepairPass,
Finalize,
Abort,
}
pub enum TerminalReason {
Success,
Cancelled,
BudgetExceeded,
PolicyViolation,
UnrecoverableError,
} And a durable execution context to carry state across transitions:
pub struct RunContext {
pub session_id: String,
pub schedule_id: Option<String>,
pub max_agent_passes: u32,
pub max_repair_rounds: u32,
pub deterministic_check_round: u32,
pub repair_round: u32,
pub last_failure_summary: Option<String>,
pub terminal_reason: Option<TerminalReason>,
} Transition Semantics
The state machine follows clear, deterministic transitions:
PrepareContext -> AgentPass
AgentPass -> DeterministicChecks
DeterministicChecks:
if pass -> Finalize
if fail and repair budget remains -> RepairPass
else -> Abort
RepairPass -> AgentPass
Finalize and Abort are terminal. The Deterministic Checks Contract
Checks run in orchestrator state, not as optional model behavior:
pub struct CheckReport {
pub passed: bool,
pub summary: String,
pub failures: Vec<CheckFailure>,
}
pub struct CheckFailure {
pub check_name: String,
pub command: String,
pub exit_code: Option<i32>,
pub stderr_excerpt: String,
} A compact CheckReport is injected into the next AgentPass as structured feedback when repair is needed. The agent does not decide whether to run checks. The orchestrator decides. The agent only decides how to fix what the checks found.
An Example Execution Trace
PrepareContext
-> AgentPass (produces candidate changes)
-> DeterministicChecks (lint fails)
-> RepairPass (inject check report)
-> AgentPass (fixes lint)
-> DeterministicChecks (pass)
-> Finalize (terminal: Success) This is the difference between “the agent might run lint” and “lint will always run.” That difference is everything in production.
Case Study: mini-swe-agent
On the opposite end of the complexity spectrum, mini-swe-agent from the Princeton and Stanford team behind SWE-bench proves that orchestration patterns work even in ~100 lines of Python. It scores over 74% on SWE-bench verified, making it one of the most efficient agent implementations per line of code.
The Deep Agent Core
mini-swe-agent’s context accumulates in self.messages, making it a textbook deep agent:
class DefaultAgent:
def __init__(self, model: Model, env: Environment, ...):
self.messages: list[dict] = [] # THE DEEP STATE
self.model = model
self.env = env
self.cost = 0.0
self.n_calls = 0
def step(self) -> list[dict]:
"""Query the LM, execute actions."""
return self.execute_actions(self.query())
def query(self) -> dict:
"""Query the model and return model messages."""
message = self.model.query(self.messages) # Full history passed!
self.add_messages(message)
return message
def execute_actions(self, message: dict) -> list[dict]:
"""Execute actions in message, add observation messages."""
outputs = [self.env.execute(action) for action in
message.get("extra", {}).get("actions", [])]
return self.add_messages(
*self.model.format_observation_messages(message, outputs, ...)) Exception-Based Control Flow: A Lightweight State Machine
Here is where mini-swe-agent gets clever. Instead of a formal state machine, it uses Python’s exception hierarchy as a lightweight control flow mechanism:
class InterruptAgentFlow(Exception):
"""Base class - carries messages to inject into context."""
def __init__(self, *messages: dict):
self.messages = messages
class Submitted(InterruptAgentFlow):
"""Agent completed its task successfully."""
class LimitsExceeded(InterruptAgentFlow):
"""Hit cost or step limit."""
class FormatError(InterruptAgentFlow):
"""LLM output malformed."""
class UserInterruption(InterruptAgentFlow):
"""Human interrupted the agent.""" These exceptions can be raised from anywhere in the call stack and are caught in the main loop:
def run(self, task: str = "", **kwargs) -> dict:
"""Run step() until agent is finished."""
self.messages = []
self.add_messages(system_message, user_message)
while True:
try:
self.step()
except InterruptAgentFlow as e:
self.add_messages(*e.messages)
except Exception as e:
self.handle_uncaught_exception(e)
raise
finally:
self.save(self.config.output_path)
if self.messages[-1].get("role") == "exit":
break
return self.messages[-1].get("extra", {}) This is not a full graph orchestrator, but it is not a pure deep agent either. The exceptions create deterministic exit points that the LLM cannot skip. Cost limits are enforced. Format errors are caught. Submission goes through a defined path.
Three Levels of Hybrid Architecture
mini-swe-agent’s simplicity makes it an ideal canvas for showing how to progressively add orchestration.
Level 1: Inject Deterministic Checkpoints into step()
class AgentWithAutoLint(DefaultAgent):
def step(self) -> list[dict]:
result = super().step() # Normal LLM step
# DETERMINISTIC: After file edits, always lint
last_actions = self.messages[-2].get("extra", {}).get("actions", [])
for action in last_actions:
if self._is_file_edit(action.get("command", "")):
lint_output = self._run_lint()
self.add_messages({
"role": "user",
"content": f"[SYSTEM] Automatic lint result:\n{lint_output}"
})
break
return result Level 2: Multi-Phase Orchestration by overriding run()
class PhasedAgent(DefaultAgent):
def run(self, task: str = "", **kwargs) -> dict:
self.messages = []
# PHASE 1: Understanding (bounded, 3 steps max)
self._run_phase(
"Analyze the task and identify what files need to change. "
"Do NOT make any changes yet.",
max_steps=3
)
# DETERMINISTIC: Create branch
subprocess.run(["git", "checkout", "-b", f"agent-fix-{int(time.time())}"])
# PHASE 2: Implementation (more steps allowed)
self._run_phase("Now implement your planned changes.", max_steps=20)
# DETERMINISTIC: Always lint and autofix
subprocess.run(["ruff", "check", "--fix", "."])
subprocess.run(["git", "add", "-A"])
# PHASE 3: Testing (bounded, with CI feedback)
for ci_round in range(2): # Max 2 CI rounds like Stripe
test_result = subprocess.run(["pytest", "-x"], capture_output=True)
if test_result.returncode == 0:
break
self._run_phase(
f"Tests failed. Fix these errors:\n{test_result.stdout.decode()}",
max_steps=10
)
# DETERMINISTIC: Commit and prepare PR
subprocess.run(["git", "commit", "-m", "Agent fix"])
return {"status": "completed", "phases": 3} Level 3: Full Graph-Based Orchestration
@dataclass
class GraphNode:
name: str
execute: Callable
next_nodes: dict[str, str] # condition -> next_node_name
class GraphOrchestrator:
def __init__(self, agent: DefaultAgent):
self.agent = agent
self.nodes: dict[str, GraphNode] = {}
self.state: dict = {}
def add_node(self, node: GraphNode):
self.nodes[node.name] = node
def run(self, start_node: str, task: str):
self.state["task"] = task
current = start_node
while current != "END":
node = self.nodes[current]
result = node.execute(self.agent, self.state)
self.state[f"{current}_result"] = result
for condition, next_node in node.next_nodes.items():
if condition == "default" or self._check_condition(condition, result):
current = next_node
break
return self.state
# Build the graph
orchestrator = GraphOrchestrator(agent)
orchestrator.add_node(GraphNode("plan", plan_node, {"default": "implement"}))
orchestrator.add_node(GraphNode("implement", implement_node, {"default": "test"}))
orchestrator.add_node(GraphNode("test", test_node,
{"success": "END", "failure": "fix"}))
orchestrator.add_node(GraphNode("fix", fix_node, {"default": "test"}))
orchestrator.run("plan", "Fix the authentication bug") The progression is clear: from hooks, to phases, to a full graph. Each level adds more guarantees while preserving the agent’s creative freedom within bounded steps.
Case Study: Stripe Minions
Stripe’s Minions represent the gold standard for production agent orchestration. They are fully unattended, built to one-shot tasks, and produce code for a system handling over $1 trillion in payment volume. Understanding how they work reveals the orchestration pattern at its most refined.
The Architecture
Minions start in an isolated developer environment (a “devbox”), which is the same type of machine that Stripe engineers write code on. Devboxes are pre-warmed so one can be spun up in 10 seconds, with Stripe code and services pre-loaded. They are isolated from production resources and the internet.
The core agent loop runs on a fork of Goose. But here is what matters: Stripe did not just run Goose. They wrapped it in an opinionated orchestration flow.
The Interleaving Pattern
The Stripe flow interleaves agent creativity with deterministic guarantees:
- Deterministic: Spin up devbox, hydrate context by running MCP tools on relevant links before the agent starts
- Agent: The LLM reads coding rules (conditionally applied per subdirectory) and produces code changes
- Deterministic: Local executable runs heuristic-selected lints on each git push (less than 5 seconds)
- Agent (conditional): If local checks fail, the agent receives structured feedback and fixes
- Deterministic: CI selectively runs tests from Stripe’s battery of 3+ million tests
- Agent (conditional): If CI fails and this is round 1, the agent gets one more attempt
- Deterministic: Apply any available autofixes for test failures
- Deterministic: Create branch, push, prepare PR following Stripe’s PR template
The “At Most Two” Rule
This is a critical design choice worth highlighting:
“Since CI runs cost tokens, compute, and time, we only have at most two rounds of CI. If tests fail after an initial push, we prompt the minion to fix failing tests and push a second time, but are then done.”
An unbounded agent might try 10 rounds of CI. The orchestrator says: two, maximum. This is a policy constraint that no amount of prompt engineering can reliably enforce. Only a state machine can guarantee it.
Shift Feedback Left
Stripe’s philosophy is “shift feedback left” for developer productivity:
“It’s best for humans and agents if any lint step that would fail in CI is enforced in the IDE or on a git push, and presented to the engineer immediately.”
Cheap, fast checks run first (local lint in under 5 seconds). Expensive checks run later (CI). The orchestrator controls this ordering. The agent does not get to choose “I’ll skip local lint and go straight to CI.” That path does not exist in the state machine.
MCP as Deterministic Context Hydration
Before the agent loop even starts, Minions deterministically run relevant MCP tools over likely-looking links to hydrate the context:
“We deterministically run relevant MCP tools over likely-looking links before a minion run even starts, to better hydrate the context.”
This is PrepareContext in the state machine model. It is not optional. It is not “the agent might decide to look up documentation.” It always happens.
Case Study: OpenClaw as Orchestrator
OpenClaw (formerly Clawdbot/Moltbot) is the fastest-growing open-source AI project in GitHub history (201k stars). Most people describe it as a “personal AI assistant.” But if you look at the architecture, OpenClaw is better understood as an orchestrator that happens to have an agent inside it.
Nathan Flurry, who runs the actor runtime Rivet, put it best in his analysis on OpenClaw as an agent orchestrator:
“What makes OpenClaw a great orchestrator is its ability to handoff tasks to background sessions then notify you when it’s finished.”
The Gateway: Five Subsystems, One Process
When you run openclaw gateway, you start a single long-lived Node.js process. That process is the entire system. Inside it run five subsystems:
- Channel adapters - one per platform (Baileys for WhatsApp, grammY for Telegram, etc.). Normalize inbound messages into a common format; serialize replies back out.
- Session manager - resolves sender identity and conversation context. DMs collapse into a main session; group chats get their own.
- Queue - serializes runs per session. If a message arrives mid-run, it holds, injects, or collects it for a follow-up turn.
- Agent runtime - assembles context (AGENTS.md, SOUL.md, TOOLS.md, MEMORY.md, daily log, conversation history), then runs the agent loop: call model, execute tool calls, feed results back, repeat until done.
- Control plane - WebSocket API on
:18789. The CLI, macOS app, web UI, and iOS/Android nodes all connect here.
This is not “an LLM with tools.” This is a control plane with an LLM inside it. The Gateway owns session lifecycle, message routing, tool governance, and execution policy. The LLM is one component.
The Planner/Worker Pattern
Nathan Flurry’s key insight is that OpenClaw naturally acts as a planner orchestrating multiple workers:
user: a user is having a bug in project X <screenshot>
openclaw: i'll start an agent to fix that
<few minutes later>
openclaw: the bug is now fixed
user: make sure there are tests to cover this
openclaw: sends new message to background agent
<few minutes later>
openclaw: 8 tests written and passing
user: push a pr
<a few seconds later>
openclaw: here is your pr link OpenClaw uses session_spawn to delegate coding work to background sessions. But the critical realization is that OpenClaw itself should not be the coding agent. It should delegate to proper coding harnesses (Claude Code, Codex CLI, or similar) that have better context management, compaction, and subagent support.
As Flurry notes:
“The harness matters almost as much as the model. Without a good harness, you’re missing out on better context management, better compaction, subagents, and fine-tuned system prompts.”
This is the planner/worker swarm architecture. OpenClaw is the planner and orchestrator. Coding CLIs are the workers. The orchestrator controls what gets delegated, when, and to whom. The workers control how the actual coding gets done within their bounded sessions.
The Heartbeat: Autonomous Orchestration
OpenClaw adds a dimension that other agents lack: a heartbeat scheduler. Every 30 minutes (configurable), the agent wakes up, reads a checklist from HEARTBEAT.md, and decides whether any item requires action. This is autonomous orchestration on a timer, not just reactive tool use.
The Milvus guide on OpenClaw describes it clearly:
“The Gateway runs as a background daemon with a configurable heartbeat. On each heartbeat, the agent reads a checklist from HEARTBEAT.md in the workspace, decides whether any item requires action, and either messages you or responds HEARTBEAT_OK.”
This is a cron-triggered state machine with the agent as one node in the graph.
Kimi Claw: When the Orchestrator Goes Cloud
Kimi Claw is OpenClaw running in the cloud via kimi.com, accessible through a browser tab. One-click deployment, no server setup. It demonstrates that the orchestrator pattern is portable: the same Gateway architecture that runs on your Mac Mini can run in the cloud, with the same session management, skill system, and control plane.
The Security Lesson
OpenClaw’s architecture also illustrates why orchestrator control matters for safety. The Gateway controls:
- Which tools the agent can access
- Which actions require human approval
- Spending limits per provider
- Sandbox boundaries for non-main sessions
- DM pairing policies for channels
Without the orchestrator layer, a pure deep agent with shell access, browser control, and email sending capability is a liability. With it, you have configurable policy gates. The orchestrator is the blast radius controller.
The Hybrid Architecture: The Winning Pattern
By now the pattern should be clear across every case study. Let me state the thesis explicitly:
Deep Agents and Orchestration are not opposites. They are complementary.
- Deep Agent: Provides creative problem-solving within the context window
- Orchestration: Provides structure, guarantees, and bounded phases
The most effective systems use orchestration to control WHEN the deep agent runs, while letting the deep agent control WHAT it does within those bounded phases.
The Architecture Spectrum
PURE STATE MACHINE HYBRID PURE DEEP AGENT
| | |
v v v
+------------------+ +------------------+ +------------------+
| Explicit states | | Orchestrator | | while True: |
| Fixed transitions| | + Deep Agent | | step() |
| No LLM autonomy | | phases | | LLM decides all |
+------------------+ +------------------+ +------------------+
| | |
Predictable but Best of both: Flexible but
inflexible Creative + Reliable unreliable The Winning Code Pattern
# The winning pattern:
def run(self, task):
# Orchestrator controls the "when"
for phase in ["understand", "plan", "implement", "test", "submit"]:
# Deep agent controls the "how" (within bounds)
self._run_bounded_agent_phase(phase, max_steps=...)
# Deterministic steps between phases
self._run_deterministic_checkpoint(phase) When to Use Each Approach
| Approach | Best For | Implementation |
|---|---|---|
| Pure Deep Agent | Exploratory tasks, research, open-ended work | DefaultAgent.run() as-is |
| Checkpointed Agent | Tasks needing validation after edits | Override step() with hooks |
| Multi-Phase Agent | Tasks with distinct stages (plan/code/test) | Override run() with phases |
| Graph Orchestrator | Complex workflows with branches and retries | Custom orchestrator class |
The LangGraph Parallel
This hybrid pattern maps directly to how LangGraph’s Open Deep Research works. In LangGraph-style designs, the graph is the first-class runtime:
- Typed state object that flows between nodes
- Node functions that transform state (some LLM-powered, some deterministic)
- Conditional edges for branching
- Persistence and checkpointing at state boundaries
- Human interrupts as explicit transitions
That model maps naturally to the Goose/mini-swe-agent world:
- Session config + session DB = graph state substrate
Agent::reply_internalorDefaultAgent.step()= high-entropy node- Scheduler/CLI handlers = graph runners
- Retry/checks = deterministic guard edges
Even if you never use LangGraph itself, adopting these graph-runtime principles in your own agent system yields the same reliability gains.
Context Management: The Hidden Challenge
There is a practical reason why orchestration matters beyond just guarantees: context window management. Deep agents accumulate context with every step:
# After 50 steps, messages might contain:
# - 1 system message
# - 1 task message
# - 50 assistant responses (with reasoning)
# - 50 observations (with command outputs)
# Total: 100+ messages, potentially 50,000+ tokens This creates cost pressure and can exceed model context limits. Orchestration provides natural solutions:
Phase boundaries are natural compaction points. When transitioning from “understand” to “implement,” the orchestrator can summarize the understanding phase into a compact message, discarding the raw exploration steps. The agent in the “implement” phase gets a clean, focused context.
Bounded phases limit context growth. A 3-step understanding phase adds at most 6 messages. A 20-step implementation phase adds at most 40. The orchestrator controls the budget per phase rather than letting context grow unbounded.
Different phases can use different models. Stripe alludes to this. You do not need GPT-4 to run linting. The orchestrator can route cheap tasks to cheap models and reserve expensive models for creative coding. This is trivial in a state machine; it is nearly impossible to enforce in a pure agent loop.
Control Is Not the Enemy of Creativity
Let me close with the core argument of this entire post.
The next leverage point for AI agents is not a smarter model. It is not a bigger context window. It is not more tools.
The next leverage point is formalizing the outer orchestrator graph.
Goose already has a strong deep-agent core. The proposed RFC adds explicit RunState transitions and CheckReport contracts. mini-swe-agent has exception-based control flow ready to be extended into phased or graph-based orchestration. Stripe Minions proved the pattern works at the highest stakes. OpenClaw demonstrated that the pattern works as a personal AI assistant orchestrating multiple coding agents.
The pattern is the same everywhere:
- Orchestrator owns workflow truth: what phases run, in what order, with what budgets
- Deep agent owns creative problem-solving: how to understand, plan, code, and fix within bounded phases
- Deterministic checkpoints bridge them: lint, test, git operations that always execute, regardless of what the LLM thinks
You do not need a smarter wolf. You need a better leash.
Whether you are extending Goose with a RunState enum, building on mini-swe-agent with phased run() overrides, deploying OpenClaw as your personal orchestrator, or studying how Stripe Minions ship a thousand PRs a week, the conclusion is the same:
Give the agent freedom to think. Give the orchestrator authority to decide.
References
- Stripe Engineering: Minions - Stripe’s One-Shot, End-to-End Coding Agents
- Block/Goose - Open Source AI Agent
- SWE-agent/mini-swe-agent - The Minimal AI Software Engineering Agent
- OpenClaw (formerly Clawdbot/Moltbot)
- Nathan Flurry: OpenClaw is the Perfect Agent Orchestrator
- Milvus: OpenClaw Complete Guide
- Kimi Claw: OpenClaw in Your Browser
- LangChain: Open Deep Research
- LangGraph Deep Research Course
- Anthropic: Building Effective Agents
If you found this useful, share it with someone building agents who has not yet built the orchestrator around them.