Skip to content

Multi-agent frameworks survey

Updated 2026-09-23: AGENT-STACK-SURVEY.md re-checks agent4s and llm4s, adds Google's ADK, and maps all three to the MIPs.

What exists for building multi-agent LLM systems on the JVM and in Scala, which ideas from the Python agent frameworks are worth porting, and where Apache Pekko would fit marola. Written from a web survey on 2026-09-05; every external claim links to its source at the bottom, and anything not verified is marked. Same house rule as docs/MIPs/: a library named here is a reference to read, not an adopted dependency, until a MIP says otherwise.

1. What exists today

1.1 Apache Pekko in multi-agent systems

  • A documented architecture, not a framework. Scalac's "AI on the JVM: Multi-Agent Architecture with Apache Pekko, Java, and Rust" describes agents as actors, an A2A client at the edge, an MCP server in the middle and a Pekko HTTP endpoint behind it, with a bearer token carried through all three layers. The closest thing to a published Pekko multi-agent application found. Not verified in detail: the article body could not be fetched from the sandbox; the summary is the search engine's, not a reading of the post.
  • Pekko itself is the Apache fork of Akka 2.6: typed actors (Behavior), supervision, mailboxes, timers, cluster, persistence, streams. Apache-2.0, actively released.
  • Akka's commercial agentic platform (the project Pekko forked from) now ships an Agent component with session memory, declarative model orchestration and error handling, plus workflows, durable entities/views, endpoints and timers in one runtime. Akka cites Fox cutting a personalisation engine from 150,000 to 22,000 cores after porting. It is the most complete "actors as agents" runtime on the JVM, and it's proprietary (BSL), which is exactly why Pekko matters for an open project.

1.2 Scala libraries

Library Effect stack What it gives Maturity (as seen 2026-09-05)
Kyo AI modules (already marola's effect system) Kyo Typed tool inputs/outputs, resources and prompt templates, OAuth 2.1, MCP 2025-11-25 and 2026-07-28 protocol revisions with negotiation Part of Kyo 1.x; marola pins RC5 — check what's in the pinned jar before relying on it (AGENTS.md rule)
agent4s cats-effect, fs2, http4s Unified providers (Claude, OpenAI, Gemini, DeepSeek, Perplexity), type-safe tool calling with derived JSON schema, a LangGraph-style graph module (state-machine workflows, conditional routing) v0.1.0, 0 stars, no Ollama listed — read the graph module, don't depend on it
llm4s Scala (plain Either, Future for orchestration) "Agentic and LLM programming in Scala"; roadmap aims at stable API contracts, provider parity, Java/Kotlin interop, security hardening. Checked against the 0.4.1 jar in MIP-0012: agent loop + handoffs + guardrails, MCP client (stdio/SSE/Streamable HTTP) and HTTP MCP server, ResponseFormat.JsonSchema; Ollama client drops tool messages; provider auth is key-only; 154 transitive jars Active, pre-production per its own roadmap (v0.4.1, 2026-08-29) — proposed as an opt-in module: docs/MIPs/MIP-0012-llm4s-adoption-and-dspy-deprecation.md
sttp-ai fs2 / ZIO / Pekko Streams / Ox OpenAI, Anthropic, Gemini, Ollama and OpenAI-compatible endpoints; structured outputs, tool calling, streaming Mature client layer; the only one listing Ollama and Pekko Streams explicitly
LangChain4j (Java) plain Java, Quarkus/Spring Unified providers and vector stores, tool calling incl. MCP, agents, RAG The mature JVM option; builder-and-annotation idioms, usable from Scala

Nothing in this list is a Scala-native multi-agent framework with termination, budgets and per-step observability. That absence is the design space, not a reason to import one.

2. Python ideas worth porting, and their Scala shape

Python idea From Scala equivalent marola today
Graph of nodes over typed state with conditional edges LangGraph An enum of node types and a pure step: (State, Event) => (State, Next); run it from an actor or a Kyo loop. Exhaustive match replaces LangGraph's runtime edge validation. Main.summarizeTop → Reviewer.review is a two-node graph hardcoded in a for-comprehension
Roles with a shared task board and handoffs CrewAI, AutoGen One actor per role; the board is an actor holding an event-sourced task list; a handoff is a message. Pekko gives supervision, mailboxes, timeouts and location transparency for free. Summarizer, reviewer, and the escalation agent (MIP-0004 / FUTURE-WORK.md §9.2) are three roles
Tools as typed function signatures OpenAI Agents SDK, PydanticAI case class parameters with a derived JSON schema (Kyo's typed tool I/O or agent4s's registry); MCP as the transport SwimConditionsMcpServer exposes three tools with hand-written schemas
Structured outputs validated at the boundary PydanticAI Opaque types / Iron at the parse boundary, Abort[E] as the failure channel (SCALA3-JDK-REVIEW.md §2.1, §2.3) Reviewer.extractJsonObject is the untyped version
Compiled prompts and optimisers DSPy ds4s (FUTURE-WORK.md §10): Signature as a case class, Predict as a Kyo effect, BootstrapFewShot over a trainset Two DSPy-compiled artifacts loaded by CompiledPrompt
Human-in-the-loop interrupts, checkpoints LangGraph Persistent actors with snapshots, or a Kyo Scope around a durable store — the gate MIP-0004 requires before proactive alerts Not built
Memory across turns and agents AutoGen, Akka Memory An actor per conversation holding a bounded window + KnowledgeStore for long-term recall FileKnowledgeStore is long-term memory without the per-conversation part
Budgets, termination, tracing per step every framework, none of the Scala libs A hard cap on model calls per task and per role; a span per step through the existing Telemetry seam; a Terminated node type in the graph Telemetry.withSpan wraps one call; no budgets anywhere

3. Where Pekko fits marola — and where it doesn't

Pekko earns its place the moment marola has more than one long-lived, stateful thing running concurrently: the Telegram poll loop, per-chat conversations, a digest scheduler, an escalation agent watching conditions. Those are actors: they have state, outlive a request, need supervision and backpressure. The current request-scoped pipeline does not need it; Kyo Async covers fan-out inside one request (SCALA3-JDK-REVIEW.md §3).

Sketch (a natural MIP-0005):

bot/
  ChatActor(chatId)        last location, bounded message window, language; TTL 24h
  RoleActor(summarizer)    pure step fn over a DSPy-compiled prompt
  RoleActor(reviewer)      pure step fn; can rewrite
  RoleActor(escalation)    trend/anomaly over the forecast series; gated by a human
  TaskBoard                event-sourced task list; sequences handoffs; enforces budgets
  DigestScheduler          timers → boards (MIP-0003) → ChatActor.send
  MCP server               unchanged — Claude Desktop and the bot share the same tools

Pekko Typed's Behavior API keeps actors pure and testable with BehaviorTestKit, which fits this repo's "logic outside the effect boundary" rule; Kyo effects run inside message handlers via the same AllowUnsafe boundary the MCP server already uses. Actors give concurrency and resilience, not agent semantics: termination, budgets and observability per step still have to be designed. That is §2's last row, and the part a MIP must not skip.

4. Reading list, in order

  1. Pekko Typed actors guide: the Behavior model and testkit.
  2. agent4s's graph module: the smallest LangGraph-in-Scala to steal the shape from.
  3. sttp-ai's Ollama + tool-calling API, if marola ever replaces Http/JsonValue for LLM calls (FUTURE-WORK.md §2 already considers kyo-http; sttp-ai is the alternative).
  4. Akka SDK's Agent/Workflow docs: the most complete design to compare against, licence aside.
  5. LangGraph's and PydanticAI's docs: for the ideas in §2, not the code.

Sources