{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "Priyesh Dave",
  "title_listed": "Battle-Tested Multi-Agent Orchestration Patterns with Google ADK: Parallel, Sequential, and Persistent Sessions",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "技术教程",
  "is_paid_flag": "否",
  "url": "https://dev.to/priyeshdave6/battle-tested-multi-agent-orchestration-patterns-with-google-adk-parallel-sequential-and-5hif",
  "publish_date": "2026-09-14",
  "corpus_stage": "",
  "notes": "",
  "id": "af4dbbcdfca3",
  "collected_at": "2026-10-02T13:49:38",
  "title": "Battle-Tested Multi-Agent Orchestration Patterns with Google ADK: Parallel, Sequential, and Persistent Sessions - DEV Community",
  "body_markdown": "# Multi-Agent Orchestration with Google ADK: Patterns That Don’t Break at Scale\n_Solving orchestration gaps that block productionizing ADK agents, with runnable code, real numbers, and field-tested lessons._\n## Google ADK's Agent Primitives Aren’t Enough for Real Orchestration\nGoogle’s Agent Development Kit (ADK) ships good agent-building primitives: agent factories, tool APIs, agent-to-agent calls, and basic integrations. What it doesn’t provide are orchestration strategies that hold up in production. Its default patterns focus on call chains or basic \"task bots,\" assuming minimal state, simple call order, and zero robustness.\n\nTry real workflows—parallel subtasks, persistent multi-session state, dynamic agent switching—and the base abstractions collapse. Production orchestration requires agent isolation, coordinated state, robust result handling, and routing that doesn’t devolve into Python spaghetti. ADK provides the hammers; orchestration is your problem.\n## Parallel Agent Execution Demands Explicit Control—Naive Threads Fail\n[\n`nandinibajaj28/adk-multiagent-architecture`\n](\nhttps://github.com/Nandinibajaj28/adk-multiagent-architecture\n)\nshows why parallel execution isn’t just threading or async. Coordination, race conditions, DB locks, and aggregation all force hands-on management.\n\nA stripped-down but working pattern from the codebase:\nEnter fullscreen mode\nExit fullscreen mode\npython\nimport threading\nimport queue\nfrom agents.agent_factory import AgentFactory\nfrom persistence.sqlite_handler import SQLiteHandler\ndef worker(agent_id, task, result_queue, db_path):\nagent = AgentFactory.create(agent_id)\nsqlite_handler = SQLiteHandler(db_path)\nwith sqlite_handler.transaction():\nresult = agent.run(task)\nsqlite_handler.save_result(agent_id, result)\nresult_queue.put((agent_id, result))\ndef execute_parallel(tasks, agents, db_path):\nresult_queue = queue.Queue()\nthreads = []\nfor agent_id, task in zip(agents, tasks):\nt = threading.Thread(target=worker, args=(agent_id, task, result_queue, db_path))\nt.start()\nthreads.append(t)\nfor t in threads:\nt.join()\nresults = {}\nwhile not result_queue.empty():\nagent_id, result = result_queue.get()\nresults[agent_id] = result\nreturn results\nWithout explicit transaction boundaries and queue-based collection, concurrent writes to SQLite will fail with `sqlite3.OperationalError: database is locked`. The repo's approach forces local serialization on DB I/O to sidestep SQLite’s broken concurrency. ADK doesn’t handle this: you need coordination or you’ll see lock errors and data loss.\n\n## Inline Routing Chains Collide With Real-World Logic Changes\n\nChaining agents inline—a common beginner move, e.g., `result = agent2(agent1(input))`—collapses when the routing requires dynamic selection, error retries, or any post-processing. This fragile spaghetti can’t absorb workflow changes.\n\nThe repository’s router decouples the workflow from the agents. The core pattern:\nEnter fullscreen mode\nExit fullscreen mode\npython\nclass WorkflowRouter:\ndef\ninit\n(self, agent_sequence):\nself.agent_sequence = agent_sequence\ndef run(self, input_data, session_id):\n    data = input_data\n    for agent_id in self.agent_sequence:\n        agent = AgentFactory.create(agent_id)\n        data = agent.run(data, session_id=session_id)\n    return data\nEnter fullscreen mode\nExit fullscreen mode\nRouting is declarative: provide a list of agent IDs, inject context, and the router steps the data through the pipeline. This structure supports agent graphs, traceability, and avoids inline dependencies.\n\n## SQLite Persistence Works—Until You Push Concurrency\n\nMost multi-agent orchestrators avoid persistent state or punt to in-memory session maps, which break under multi-request sessions or restarts. This codebase uses plain SQLite, skipping Redis/PSQL overhead for agent state that rarely justifies it.\n\nCore implementation:\nEnter fullscreen mode\nExit fullscreen mode\npython\nimport sqlite3\nfrom contextlib import contextmanager\nclass SQLiteHandler:\ndef\ninit\n(self, db_path):\nself.db_path = db_path\n@contextmanager\ndef transaction(self):\n    conn = sqlite3.connect(self.db_path, check_same_thread=False)\n    c = conn.cursor()\n    try:\n        yield c\n        conn.commit()\n    finally:\n        conn.close()\n\ndef save_result(self, agent_id, result, session_id=None):\n    with self.transaction() as c:\n        c.execute(\n            'INSERT INTO results (agent_id, result, session_id) VALUES (?, ?, ?)',\n            (agent_id, result, session_id)\n        )\nEnter fullscreen mode\nExit fullscreen mode\nSQLite handles basic isolation for single-node, low-throughput jobs. But its [locking model](https://sqlite.org/howtocorrupt.html) breaks for multi-writer concurrency; you’ll hit `database is locked` unless all writes are serialized. WAL mode buys some time, but distributed or high-scale concurrency will break this pattern.\n\n## Architecture: Concrete Roles for Each Component\n\nThe core pieces:\n\n- **ADK Agent Primitives:** Define agent skills and tools, but do not own orchestration or state.\n- **Workflow Router:** Holds workflow definitions (agent ID sequences, logic policies) and invokes agents in proper order, passing shared context and results.\n- **Persistence Layer:** Writes inputs, outputs, workflow metadata, and session state to SQLite using transactional APIs.\n- **Session Management:** Every request issues or accepts a session ID for all DB ops and cross-agent calls, ensuring traceability and recovery.\n- **Parallel/Sequential Controller:** Orchestrator chooses—per workflow—parallel agent execution (with `execute_parallel`) or sequential traversal (via the router).\n- **API Layer:** Thin HTTP layer exposes orchestration. Receives input, resolves agents and workflows, persists and returns results.\n\nOperational flow: API request → router picks or builds agent sequence → orchestrator runs agents in parallel or sequence → everything tracked in SQLite per session → results, sessions, and artifacts returned and logged.\n\n## Where Single-Agent Patterns Shatter\n\nMajor pain points arise fast:\n\n- **Concurrency Control:** Naive parallelism explodes without transactional locking, especially with file-based DBs like SQLite.\n- **Flexible Routing:** Hardcoding agent handoffs can’t handle even modest workflow complexity. Declarative routing or agent graphs are required.\n- **Persisted State:** In-memory tricks fail as soon as session continuity or recovery is needed. Even a simple persistent DB takes you far.\n- **Session Isolation:** No session context? No recovery, no traceability, no multi-step workflows.\n- **Observability:** Multi-agent flows demand structured logs and per-step state tracking—or debugging becomes impossible.\n- **Infra Coupling:** Orchestrators hard-locked to sequence-only chains or HTTP-only triggers slow evolution as agents multiply.\n\nSingle-agent chains don’t scale or survive real usage. Invest in real orchestration early: explicit invocation, parallelization, persistent state, and robust session management save you from painful rework.\n\nGoogle ADK is a strong base, but production multi-agent workflows require deliberate orchestration architecture. Patch these gaps or expect brittle systems and firefighting down the road.\nEnter fullscreen mode\nExit fullscreen mode",
  "metadata": {
    "title": "Battle-Tested Multi-Agent Orchestration Patterns with Google ADK: Parallel, Sequential, and Persistent Sessions - DEV Community",
    "description": "# Multi-Agent Orchestration with Google ADK: Patterns That Don’t Break at Scale  _Solving... Tagged with ai, agenticai, machinelearning, llm.",
    "keywords": "ai, agenticai, machinelearning, llm, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/priyeshdave6/battle-tested-multi-agent-orchestration-patterns-with-google-adk-parallel-sequential-and-5hif",
    "og:title": "Battle-Tested Multi-Agent Orchestration Patterns with Google ADK: Parallel, Sequential, and Persistent Sessions",
    "og:description": "# Multi-Agent Orchestration with Google ADK: Patterns That Don’t Break at Scale  _Solving...",
    "og:site_name": "DEV Community",
    "og:image": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcixtjvonfev78y5kx5w7.png",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "Battle-Tested Multi-Agent Orchestration Patterns with Google ADK: Parallel, Sequential, and Persistent Sessions",
    "twitter:description": "# Multi-Agent Orchestration with Google ADK: Patterns That Don’t Break at Scale  _Solving...",
    "twitter:card": "summary_large_image",
    "twitter:widgets:new-embed-design": "on",
    "twitter:image:src": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcixtjvonfev78y5kx5w7.png"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/af4dbbcdfca3/code/body-000.txt",
      "chars": 1366,
      "language": "text"
    },
    {
      "file": "attachments/af4dbbcdfca3/code/body-001.txt",
      "chars": 729,
      "language": "text"
    },
    {
      "file": "attachments/af4dbbcdfca3/code/body-002.txt",
      "chars": 218,
      "language": "text"
    },
    {
      "file": "attachments/af4dbbcdfca3/code/body-003.txt",
      "chars": 533,
      "language": "text"
    },
    {
      "file": "attachments/af4dbbcdfca3/code/body-004.txt",
      "chars": 456,
      "language": "text"
    },
    {
      "file": "attachments/af4dbbcdfca3/code/body-005.txt",
      "chars": 2678,
      "language": "text"
    }
  ],
  "images": [],
  "audio": [],
  "videos": [],
  "links": [],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:48:07Z",
  "source_url": "https://dev.to/priyeshdave6/battle-tested-multi-agent-orchestration-patterns-with-google-adk-parallel-sequential-and-5hif",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 7258,
  "expected_body_images": 0,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/af4dbbcdfca3/pages/source.html",
  "local_html": "attachments/af4dbbcdfca3/pages/article.html",
  "body_base_path": "attachments/af4dbbcdfca3/pages/",
  "body_markdown_path": "attachments/af4dbbcdfca3/pages/article.md"
}