How should hybrid patterns compose?

Choosing the composition model shapes every other API decision

A

Graph / DAG

Define nodes (patterns or agents) and explicit edges (data flow). Maximum control over topology.

swarm = Graph()
root = swarm.add(HierarchicalPattern(agents=[...]))
workers = swarm.add(ParallelPattern(agents=[...]))
swarm.edge(root, workers)
swarm.run("task")

Pros

  • Full topology control
  • Explicit data flow
  • Handles cycles

Cons

  • Verbose
  • Overkill for simple cases
B

Builder / Fluent Chain

Compose patterns by chaining them. Output of each pattern feeds next by default.

swarm = (Swarm()
  .hierarchical(agents=[coordinator, ...])
  .parallel(agents=[worker1, worker2])
  .adaptive(agents=[reviewer])
  .run("task"))

Pros

  • Readable, fluent
  • Simple cases are simple
  • No boilerplate

Cons

  • Linear only (no branching)
  • Less explicit data flow
C

Declarative Config

Define full swarm topology as a dict or YAML. Great for CLI usage and serialization.

swarm = Swarm.from_config({
  "patterns": [
    {"type": "hierarchical", "agents": [...]},
    {"type": "parallel",     "agents": [...],
     "after": 0}
  ]
})
swarm.run("task")

Pros

  • Serializable / shareable
  • CLI-native
  • Easy to test

Cons

  • Verbose for dynamic use
  • Less Pythonic