Skip to Content
DocsArchitecturesRecursive composition

Recursive composition

Architectures wrap each other naturally. The property no sibling-only framework gives you. Wrap a Supervisor in Reflexion for cross-session learning of delegation patterns; nest Supervisors for hierarchical teams; wrap an entire pipeline in Reflexion to retry on low scores.

The killer combination: Reflexion of Supervisor

┌────── Reflexion attempt loop ──────┐ │ │ │ prompt ──► Supervisor ──► output ─┤── score ≥ threshold ──► done │ (manager + 3 workers) │ │ │ │ └── below ──► lesson ──► retry │ │ └────────────────────────────────────────────────────────────────┘
from loomflow import Agent, HashEmbedder from loomflow.architecture import Reflexion, Supervisor from loomflow.vectorstore import InMemoryVectorStore agent = Agent( "Manage the pipeline.", model="claude-opus-4-7", architecture=Reflexion( base=Supervisor(workers={ "researcher": researcher, "writer": writer, "reviewer": reviewer, }), max_attempts=3, threshold=0.85, lesson_store=InMemoryVectorStore(embedder=HashEmbedder()), ), )

The Supervisor delegates; the output gets scored; below threshold, the reflector emits a lesson like “the writer over-quoted the researcher’s draft. Paraphrase next time”; the lesson is embedded into the lesson store. The next attempt sees the relevant lesson recalled into the supervisor’s prompt.

For cross-process learning, swap InMemoryVectorStore for PostgresVectorStore.

Hierarchical Supervisors

Nested Supervisors give you a tree of teams:

from loomflow import Agent from loomflow.architecture import Supervisor content_team = Supervisor(workers={ "researcher": researcher, "writer": writer, }) review_team = Supervisor(workers={ "fact_checker": fact_checker, "editor": editor, }) # Top-level supervisor delegates to two sub-teams agent = Agent( "Run the article pipeline.", model="claude-opus-4-7", architecture=Supervisor(workers={ "content": Agent("Coordinate content generation.", model="claude-opus-4-7", architecture=content_team), "review": Agent("Coordinate the review pass.", model="claude-opus-4-7", architecture=review_team), }), )

Each sub-team is itself an Agent(architecture=Supervisor(...)), which can be passed as a worker to the parent supervisor.

ActorCritic of ReWOO

ActorCritic typically wraps a “single-shot” actor. Drop in a ReWOO actor when the task is tool-heavy. The critic still gets to inspect the final answer, but the actor benefits from the cheaper plan-then- parallel-tools dispatch:

from loomflow import Agent from loomflow.architecture import ActorCritic, ReWOO actor = Agent( "Research and synthesize.", model="claude-opus-4-7", architecture=ReWOO(), tools=[search, fetch], ) critic = Agent( "Critic. Return JSON {score, issues, summary}.", model="gpt-4o", ) agent = Agent( "Manage actor + critic.", model="claude-opus-4-7", architecture=ActorCritic(actor=actor, critic=critic, max_rounds=3, approval_threshold=0.9), )

Why this matters

Sibling-only frameworks (CrewAI, AutoGen, swarm-style) make you pick ONE coordination shape and live with it. Recursive composition lets you pick the right shape at each level. A Supervisor that delegates to specialists who themselves use Reflexion, with the overall pipeline wrapped in best-of-N via ActorCritic.

Team vs nested Agent(architecture=...). Team.supervisor(...) is exactly Agent(architecture=Supervisor(...)) under the hood. Use Team for single-level teams (cleaner builder syntax); use the nested form when you’re composing. Passing one architecture as a field of another.

Last updated on