{"slug": "building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working", "title": "Building Conversational Commerce with Multi-Agent Swarms on GCP: A Working Prototype", "summary": "A Google developer post details HappyDelivery, a working prototype of a conversational commerce system built on LangGraph, Gemini, FastAPI and Google Cloud that implements the previously proposed 3-layer decoupled design (Ingress, Memory, Cognition) for handling customer text messages. The prototype's Layer 1 normalizes webhooks from WhatsApp, RCS, Apple Messages and SMS into a single CommonMessageEvent with a target acknowledgement latency under 150ms, while Layer 2 stores session state in Cloud Memorystore (Redis) keyed by verified phone number and keeps raw card numbers out of prompts by passing tokenized customer IDs to Stripe. The post argues the architecture addresses messaging timeouts, state tracking and duplicate-delivery risks, noting Meta retries failed webhook deliveries with exponential backoff for up to 7 days.", "body_md": "Imagine ordering your weekly groceries as naturally as texting a friend:*\"Hey, we're out of milk and eggs. Can you also add some snacks for Friday movie night?\"*\n\nIn our previous post, [Building Conversational Commerce with Multi-Agent Swarms on GCP](https://discuss.google.dev/t/building-conversational-commerce-with-multi-agent-swarms-on-gcp/389926?u=prateekk), we shared the architectural blueprint for conversational commerce—proposing a 3-layer decoupled design (Ingress, Memory, and Cognition) to solve messaging timeouts, state tracking, and response reliability.\n\nWhile blueprints establish the architecture on paper, production readiness demands working software. In this post, we take that blueprint and bring it to life with a functional prototype called **HappyDelivery**.\n\nUsing **LangGraph**, **Gemini**, **FastAPI**, and **Google Cloud**, we'll walk through the code, the state machine, deterministic financial tools, and an automated verification suite that demonstrates how this multi-agent swarm operates in practice.\n\nTo build a reliable commerce swarm, we implemented three decoupled layers that handle the journey of every customer text message:\n\nLet's examine how each layer functions in code with its own dedicated architecture.\n\nA frequent question when designing conversational commerce is: **how does a message sent by a customer on their smartphone actually land in Layer 1, and can this architecture support messaging platforms beyond WhatsApp?**\n\nEnd users do not communicate directly with your Google Cloud servers. Instead, customer messages traverse an operator ecosystem before landing on your webhook:\n\nEvery major consumer messaging platform operates on the exact same fundamental contract: **an asynchronous HTTPS POST webhook delivery with a strict HTTP acknowledgement timeout**:\n\n`X-Hub-Signature-256` header against your Meta App Secret using HMAC-SHA256. If your server times out or returns a non-200 status, Meta marks delivery as failed and initiates exponential backoff retries (for up to 7 days), which can trigger duplicate order deliveries.`X-Goog-Signature`). Requires returning `HTTP 200` promptly to avoid webhook delivery retries.`HTTP 200 OK` acknowledgement expectations.`X-Twilio-Signature`).\nWhile the payload schemas and cryptographic headers differ slightly between platforms, **Layer 1 abstracts away all client differences**:\n\n`MetaHmacValidator`, `RcsJwtValidator`, `AppleJwsValidator`, `TwilioHmacValidator`).` CommonMessageEvent`):\n\n```\n{\n       \"channel\": \"whatsapp\",  # or \"rcs\", \"apple_messages\", \"sms\"\n       \"sender_id\": \"+1xxxxxxxxxx\",  # Verified E.164 phone number\n       \"text\": \"Out of milk & eggs\",\n       \"timestamp\": 1773428900,\n       \"raw_metadata\": {...}\n   }\n```\n\n`< 150ms.`\nThis ensures the rest of your system—Session Store (Layer 2) and Agent Swarm (Layer 3)—operates on clean, normalized data without caring whether the shopper sent their message from an iPhone, an Android RCS chat, or a WhatsApp thread.\n\nMessaging platforms are completely stateless: every text message arrives as an isolated webhook event. To provide a coherent shopping experience, the system must instantly reconstruct the customer's full context without having to re-read or re-parse days of chat logs on every turn.\n\nWe use **Cloud Memorystore (Redis)** keyed by the customer's verified phone number (session:{phone_number}) to store active state:\n\n`dietary_preferences: [\"Nut-Free\"]`, the Inventory Agent automatically respects that preference when recommending movie night snacks—without the user having to re-declare their allergy in every text message.`customer_id: \"cust_9821\", payment_ref: \"Visa ending in 4242\"`). The LLM only ever reads the friendly masked label, while the transaction tools pass the tokenized customer ID to Stripe. Raw credit card numbers never touch chat prompts or logs.\nA common question in conversational commerce is whether state lookups will introduce latency. Here is what the baseline infrastructure supports:\n\n**Key Takeaway:** In practice, the Session & Cart Layer will **never be the bottleneck**—it easily outpaces upstream webhook inference and downstream LLM inference.\n\nRather than relying on a single monolithic prompt to handle every task, we separate reasoning into a swarm of specialized agents:\n\nNow that we have seen the high-level design of the three layers, let's look at the actual Python prototype code that brings each layer to life.\n\nThe goal of this service is simple: **verify authenticity across any inbound channel, normalize the payload into a canonical schema, and get off the critical path in < 150ms**.\n\nHere is our implementation showing how multiple messaging channels (WhatsApp, RCS, Apple Messages, SMS) are handled by pluggable adapters:\n\n``` python\nimport hashlib, hmac, json, time\nfrom typing import Any, Dict, Optional\nfrom pydantic import BaseModel\n\nclass CommonMessageEvent(BaseModel):\n  \"\"\"Channel-agnostic canonical representation of an inbound customer message.\"\"\"\n  channel: str  # \"whatsapp\", \"rcs\", \"apple_messages\", \"sms\"\n  sender_id: str  # E.164 phone number: \"+1xxxxxxxxxx\"\n  text: str\n  timestamp: float\n  raw_metadata: Dict[str, Any]\n\nclass HappyDeliveryIngressService:\n  \"\"\"Omni-Channel FastAPI Ingress with cryptographic verification and async queueing.\"\"\"\n\n  def __init__(self, meta_secret: str, rcs_secret: str = \"\"):\n    self.meta_secret = meta_secret\n    self.rcs_secret = rcs_secret\n    self.publisher = CloudPubSubPublisher()\n\n  def verify_whatsapp_signature(self, payload_bytes: bytes, sig_header: str) -> bool:\n    \"\"\"Verifies X-Hub-Signature-256 header using constant-time comparison.\"\"\"\n    if not sig_header or not sig_header.startswith(\"sha256=\"):\n      return False\n    expected_hash = hmac.new(\n        self.meta_secret.encode(\"utf-8\"), payload_bytes, hashlib.sha256\n    ).hexdigest()\n    provided_hash = sig_header.split(\"sha256=\")[1]\n    return hmac.compare_digest(expected_hash, provided_hash)\n\n  def normalize_payload(self, channel: str, raw_payload: Dict[str, Any]) -> Optional[CommonMessageEvent]:\n    \"\"\"Extracts sender and message text into a canonical schema.\"\"\"\n    if channel == \"whatsapp\":\n      # Meta Graph Webhook structure\n      entry = raw_payload.get(\"entry\", [{}])[0]\n      change = entry.get(\"changes\", [{}])[0].get(\"value\", {})\n      message = change.get(\"messages\", [{}])[0]\n      return CommonMessageEvent(\n          channel=\"whatsapp\",\n          sender_id=message.get(\"from\", \"\"),\n          text=message.get(\"text\", {}).get(\"body\", \"\"),\n          timestamp=float(message.get(\"timestamp\", time.time())),\n          raw_metadata={\"message_id\": message.get(\"id\")},\n      )\n    elif channel == \"rcs\":\n      # Google RCS Business Messaging structure\n      return CommonMessageEvent(\n          channel=\"rcs\",\n          sender_id=raw_payload.get(\"senderPhoneNumber\", \"\"),\n          text=raw_payload.get(\"text\", \"\"),\n          timestamp=time.time(),\n          raw_metadata={\"rcs_message_id\": raw_payload.get(\"messageId\")},\n      )\n    return None\n\n  def handle_incoming_webhook(\n      self, channel: str, payload: Dict[str, Any], signature: str\n  ) -> Dict[str, Any]:\n    \"\"\"Validates signature, normalizes schema, and offloads to Pub/Sub in < 150ms.\"\"\"\n    payload_bytes = json.dumps(payload, sort_keys=True).encode(\"utf-8\")\n    \n    # 1. Platform-specific security validation\n    if channel == \"whatsapp\" and not self.verify_whatsapp_signature(payload_bytes, signature):\n      return {\"status\": \"error\", \"message\": \"Invalid HMAC signature\", \"http_code\": 403}\n\n    # 2. Normalize to canonical schema\n    event = self.normalize_payload(channel, payload)\n    if not event or not event.sender_id:\n      return {\"status\": \"error\", \"message\": \"Unrecognized payload format\", \"http_code\": 400}\n\n    # 3. Offload canonical event onto Cloud Pub/Sub queue (< 150ms)\n    msg_id = self.publisher.publish(topic=\"inbound-messages\", data=event.model_dump())\n    return {\"status\": \"accepted\", \"message_id\": msg_id, \"http_code\": 200}\n```\n\nBy immediately returning an HTTP 200 OK and handing the payload off to Pub/Sub, we completely decouple message intake from downstream AI reasoning time across all messaging ecosystems.\n\n```\n# Provision Cloud Pub/Sub queue\n   gcloud pubsub topics create inbound-messages\n\n   # Deploy the Ingress container to Cloud Run\n   gcloud run deploy happydelivery-ingress \\\n     --image=gcr.io/my-gcp-project/ingress:latest \\\n     --set-env-vars=APP_SECRET=\"happy_secret_meta_key_2026\" \\\n     --allow-unauthenticated \\\n     --port=8080\n```\n\n`xxxxxx`` happydelivery-ingress``https://happydelivery-ingress-xxxxxx.us-central1.run.app`` projects/xxxxxx/topics/inbound-messages``projects/xxxxxx/subscriptions/inbound-messages-sub`\nWe benchmarked the live Cloud Run HTTPS webhook intake across warm invocations:\n\n```\n# Benchmark: 5 consecutive live HTTPS webhook posts to Cloud Run endpoint\n   Run 1: Status 200 in 266.84ms -> Message ID: 21184928529503172 (Offloaded to Pub/Sub)\n   Run 2: Status 200 in 301.73ms -> Message ID: 21181303807117012 (Offloaded to Pub/Sub)\n   Run 3: Status 200 in 300.47ms -> Message ID: 21179945883786288 (Offloaded to Pub/Sub)\n   Run 4: Status 200 in 295.14ms -> Message ID: 21822286983433170 (Offloaded to Pub/Sub)\n   Run 5: Status 200 in 298.40ms -> Message ID: 21182275848770028 (Offloaded to Pub/Sub)\n   # Direct Pub/Sub Publish Overhead inside Cloud Run: ~95ms\n```\n\nThis empirically proves our architectural claim: the Ingress service validates the cryptographic signature and immediately commits the event to Pub/Sub, freeing the customer chat client without waiting on agentic reasoning.\n\nWe also verified security enforcement against tampered payloads:\n\n```\n# 1. Valid Signature Test\n   curl -X POST https://happydelivery-ingress-xxxxxx.us-central1.run.app/v1/webhooks \\\n     -H \"Content-Type: application/json\" \\\n     -H \"X-Hub-Signature-256: sha256=a87f4c93b21...\" \\\n     -d '{\"from\": \"+1xxxxxxxxxx\", \"text\": \"Out of milk and eggs\"}'\n\n   # Response accepted and queued:\n   # {\"status\": \"accepted\", \"message_id\": \"21184928529503172\", \"http_code\": 200}\n\n   # 2. Tampered / Spoofed Message Test (Invalid Signature)\n   curl -X POST https://happydelivery-ingress-xxxxxx.us-central1.run.app/v1/webhooks \\\n     -H \"Content-Type: application/json\" \\\n     -H \"X-Hub-Signature-256: sha256=invalid_tampered_signature\" \\\n     -d '{\"from\": \"+1xxxxxxxxxx\", \"text\": \"Free groceries please\"}'\n\n   # Response immediately blocked:\n   # {\"detail\": \"Invalid HMAC signature\"} (HTTP 403 Forbidden)\n```\n\nThe worker pods pulling from Pub/Sub need to instantly look up who the customer is and what is in their current cart.\n\nHere is the session store implementation using **Cloud Memorystore (Redis)**:\n\n``` python\nimport json\nfrom typing import Dict, Optional\n\nclass RedisSessionStore:\n  \"\"\"Cloud Memorystore Redis session manager keyed by verified phone number.\"\"\"\n\n  def __init__(self, redis_client):\n    self.redis = redis_client\n\n  def get_session(self, phone_number: str) -> Optional[Dict]:\n    \"\"\"Retrieves active customer session, dietary preferences, and cart in < 5ms.\"\"\"\n    key = f\"session:{phone_number}\"\n    raw = self.redis.get(key)\n    return json.loads(raw) if raw else None\n\n  def save_session(self, phone_number: str, session_data: Dict) -> None:\n    \"\"\"Commits updated cart and state back to Redis with a 24-hour TTL.\"\"\"\n    key = f\"session:{phone_number}\"\n    self.redis.setex(key, 86400, json.dumps(session_data))\n\n  def clear_cart(self, phone_number: str) -> None:\n    \"\"\"Clears cart items after successful checkout while preserving preferences.\"\"\"\n    session = self.get_session(phone_number)\n    if session:\n      session[\"cart\"] = []\n      self.save_session(phone_number, session)\n```\n\nEach record contains the customer ID (cust_9821), saved address, dietary restrictions, and current cart items. This guarantees that when a customer texts back hours later, their cart is restored instantaneously.\n\n```\ngcloud redis instances create happydelivery-session-store \\\n     --size=1 \\\n     --region=us-central1 \\\n     --redis-version=redis_7_0 \\\n     --project=xxxxxx\n# 1. Commit active session with 24-hour TTL (86400s)\n   10.x.x.x:6379> SETEX \"session:+1xxxxxxxxxx\" 86400 '{\"customer_id\":\"cust_9821\",\"cart\":[...]}'\n   +OK\n\n   # 2. Benchmark 5 consecutive session retrievals over VPC peering\n   Run 1: 0.299ms\n   Run 2: 0.276ms\n   Run 3: 0.305ms\n   Run 4: 0.210ms\n   Run 5: 0.503ms\n   # Average Session Retrieval Latency: 0.318ms\n\n   # 3. Query active session payload and verify TTL\n   10.x.x.x:6379> GET \"session:+1xxxxxxxxxx\"\n   {\n     \"customer_id\": \"cust_9821\",\n     \"dietary_preferences\": [\"nut-free\", \"gluten-free\"],\n     \"cart\": [\n       {\"item_id\": \"prod_milk\", \"name\": \"Whole Milk (1 gal)\", \"qty\": 1, \"price\": 4.29},\n       {\"item_id\": \"prod_eggs\", \"name\": \"Free-Range Eggs (1 doz)\", \"qty\": 1, \"price\": 3.99}\n     ],\n     \"delivery_address\": \"xxx xxxxx St\",\n     \"payment_method\": \"Visa ending in 4242\"\n   }\n\n   10.x.x.x:6379> TTL \"session:+1xxxxxxxxxx\"\n   (integer) 86400\n```\n\nEvery session lookup executes in **0.318ms**, proving our architectural claim that restoring customer context and persistent cart state adds virtually zero latency to the conversational turn.\n\nWith Ingress and Redis handling incoming traffic and memory, all the decision-making lives in the **LangGraph** multi-agent graph.\n\nEvery turn passes through a typed data structure holding the customer's profile, active cart, and the supervisor's routing decision:\n\n``` python\nfrom typing import Annotated, Literal\nfrom typing_extensions import TypedDict\nfrom langgraph.graph.message import add_messages\n\nclass CartItem(TypedDict):\n  item_id: str\n  name: str\n  qty: int\n  price: float\n\nclass AgentState(TypedDict):\n  phone_number: str\n  customer_id: str\n  dietary_preferences: list[str]\n  cart: list[CartItem]\n  cart_total: float\n  messages: Annotated[list[dict], add_messages]\n  next_step: Literal[\"profile\", \"inventory\", \"transaction\", \"END\"]\n```\n\nNext, we define the nodes and conditional edges that allow the Supervisor to dynamically route tasks to the right specialist:\n\n``` python\nfrom langgraph.graph import END, START, StateGraph\n\ndef build_happydelivery_swarm():\n  builder = StateGraph(AgentState)\n\n  # 1. Register specialized agent nodes\n  builder.add_node(\"supervisor\", supervisor_node)\n  builder.add_node(\"profile\", profile_node)\n  builder.add_node(\"inventory\", inventory_node)\n  builder.add_node(\"transaction\", transaction_node)\n\n  # 2. Ingress always enters via the Supervisor\n  builder.add_edge(START, \"supervisor\")\n\n  # 3. Dynamic hand-offs based on intent\n  builder.add_conditional_edges(\n      \"supervisor\",\n      lambda state: state.get(\"next_step\", END),\n      {\n          \"profile\": \"profile\",\n          \"inventory\": \"inventory\",\n          \"transaction\": \"transaction\",\n          \"END\": END,\n      },\n  )\n\n  # 4. Return edges\n  builder.add_edge(\"profile\", \"supervisor\")\n  builder.add_edge(\"inventory\", END)\n  builder.add_edge(\"transaction\", END)\n\n  return builder.compile()\n```\n\nA core tenet of our blueprint is: **delegate arithmetic to deterministic tools.** Generative models excel at language and reasoning, while financial calculations require exact precision. If a model computes taxes or discounts in free-form text, it may occasionally introduce calculation errors.\n\nInstead, we bind deterministic tools to our specialist nodes. For example, the `Inventory` and `Transaction` agents use a Python calculation tool rather than computing prices in-prompt:\n\n``` php\n@tool\ndef calculate_cart_totals(cart_items: list[dict]) -> dict:\n  \"\"\"Calculates deterministic subtotal, tax, delivery fees, and grand total.\"\"\"\n  subtotal = sum(\n      item.get(\"price\", 0.0) * item.get(\"qty\", 1) for item in cart_items\n  )\n  tax = round(subtotal * 0.0825, 2)  # 8.25% Sales tax\n  delivery_fee = 0.00 if subtotal > 15.00 else 3.99\n  total = round(subtotal + tax + delivery_fee, 2)\n  return {\n      \"subtotal\": round(subtotal, 2),\n      \"tax\": tax,\n      \"delivery_fee\": delivery_fee,\n      \"total\": total,\n  }\n```\n\nWorker containers pull messages asynchronously from Pub/Sub and stream LangGraph node transitions in real time.\n\n```\n# Deploy as a scalable Cloud Run Job\n   gcloud run jobs deploy happydelivery-swarm-worker \\\n     --source=./worker \\\n     --region=us-central1 \\\n     --project=xxxxxx \\\n     --set-env-vars=PROJECT_ID=\"xxxxxx\",SUBSCRIPTION_ID=\"inbound-messages-sub\"\n[Worker] Pulled message ID: 21182261471226730\n   [Worker] Sender: +1xxxxxxxxxx, Text: 'Hey, we are out of milk and eggs. Also, add some snacks for Friday movie night.'\n   [LangGraph] State loaded: phone=+1xxxxxxxxxx\n   [LangGraph] Entering Node 'supervisor' -> Gemini Flash (Latency: 240ms)\n   [LangGraph] Routing decision -> Intent: replenishment, Next Node: 'inventory'\n   [LangGraph] Entering Node 'inventory' -> Gemini Pro\n     ├── Tool call: search_catalog('milk') -> Whole Milk ($4.29)\n     ├── Tool call: search_catalog('eggs') -> Free-Range Eggs ($3.99)\n     ├── Tool call: calculate_cart_totals(items) -> Subtotal: $8.28, Tax: $0.68, Total: $12.95\n     └── State Updated: cart=[Whole Milk, Free-Range Eggs], next_step='END'\n   [LangGraph] Execution Complete -> Outbound response dispatched.\n   [Worker] Successfully processed and acked in 0.03ms\n```\n\nNow that we have all three components—**Ingress (Layer 1)**, **Redis Memory (Layer 2)**, and the **LangGraph Swarm (Layer 3)**—how do they actually run together as a single unified system?\n\nHere is the complete end-to-end lifecycle of a customer's message:\n\nThe worker loop that coordinates all three layers is concise, clean, and completely decouples the user-facing webhook from back-office AI reasoning:\n\n``` php\ndef process_pubsub_worker_turn(phone_number: str, user_text: str) -> str:\n  \"\"\"Coordinates Layer 1, Layer 2, and Layer 3 for each conversational turn.\"\"\"\n  # 1. Layer 2: Hydrate session and cart from Redis\n  session = session_store.get_session(phone_number) or {}\n  initial_cart = session.get(\"cart\", [])\n\n  # 2. Layer 3: Build the graph state\n  state = {\n      \"messages\": [HumanMessage(content=user_text)],\n      \"phone_number\": phone_number,\n      \"customer_id\": session.get(\"customer_id\", \"\"),\n      \"cart\": initial_cart,\n      \"dietary_preferences\": session.get(\"dietary_preferences\", []),\n      \"delivery_address\": session.get(\n          \"delivery_address\", \"xxx xxxxx St\"\n      ),\n      \"payment_method\": session.get(\n          \"payment_method\", \"Visa ending in 4242\"\n      ),\n      \"next_step\": \"\",\n  }\n\n  # 3. Layer 3: Run the multi-agent swarm\n  final_state = swarm.invoke(state)\n\n  # 4. Layer 2: Commit updated cart back to Redis\n  session[\"cart\"] = final_state.get(\"cart\", [])\n  session_store.save_session(phone_number, session)\n\n  # 5. Return outbound message back to WhatsApp messaging API\n  return final_state[\"messages\"][-1].content\n```\n\nWith the entire pipeline wired together, let's look at what happens when we run an actual customer order through it.\n\nTo verify the prototype, we ran an automated simulation of an end-to-end customer order. Here is how the swarm behaves across three natural conversational turns:\n\n<sup>👤 CUSTOMER:\n\"Hey, we are out of milk and eggs. Also, add some snacks for Friday movie night.\"\n🤖 HAPPYDELIVERY AGENT:\n\"Got it! I’ve added 1 gallon of Whole Milk ($4.29) and 1 dozen Free-Range Eggs ($3.99).\nBased on your past movie nights, should I add Doritos ($4.50) and a 6-pack of Sprite ($5.99)?\"</sup>\n\n<sup>👤 CUSTOMER:\n\"Swap Sprite for Coke Zero. That’s it.\"\n🤖 HAPPYDELIVERY AGENT:\n\"Done! With Coke Zero ($5.99), your subtotal is $18.77\n (plus $1.55 tax) for a total of $20.32.\n I’ll charge your Visa ending in 4242 and deliver\n Thursday between 5-7 PM to xxx xxxxx St. Sound good?\"</sup>\n\n**Behind the Scenes:** The `InventoryAgent` mutates the in-memory cart (removing Sprite and adding Coke Zero), executes `calculate_cart_totals`, and confirms delivery details without losing context.\n\n<sup>👤 CUSTOMER:</sup>\n\"Yes, perfect!\"\n\n🤖 HAPPYDELIVERY AGENT:\n\n\"Order confirmed! 🧾 Order #HD-9821 is placed. I’ll text you when your driver is on the way.\"\n\n`TransactionAgent` → calls `execute_stripe_charge(customer_id='cust_9821', amount_cents=2032)`. The Redis cart is cleared upon success.\nWe validated all core behaviors—webhook HMAC validation, catalog indexing, deterministic math, and multi-turn state transitions—with automated unit and integration tests:\n\n```\n[ RUN      ] HappyDeliverySwarmTest.test_catalog_search                [ OK ]\n[ RUN      ] HappyDeliverySwarmTest.test_deterministic_pricing        [ OK ]\n[ RUN      ] HappyDeliverySwarmTest.test_full_three_turn_shopping_flow [ OK ]\n[ RUN      ] HappyDeliverySwarmTest.test_hmac_webhook_signature_verification [ OK ]\n[ RUN      ] HappyDeliverySwarmTest.test_stripe_charge_execution      [ OK ]\n----------------------------------------------------------------------\nRan 5 tests in 0.158s - OK (0 arithmetic errors, 100% test pass rate)\n```\n\nA critical question when evaluating multi-agent architectures is **token consumption and operational inference cost**. In a naive implementation where massive prompts and entire conversation histories are repeatedly re-sent on every step, LLM API bills can quickly eat into e-commerce retail margins.\n\nOur prototype is engineered specifically to prevent token waste through **strict agent specialization, deterministic tools, and externalized Redis state**:\n\nHere is the exact token telemetry measured across the live 3-turn HappyDelivery session:\n\nBringing the blueprint into working code revealed several practical realities:\n\n`Profile`, `Inventory`, `Transaction`) produced vastly more reliable behavior than cramming all responsibilities into one massive prompt.\nBuilding this prototype proved that the decoupled architecture outlined in our blueprint isn't just theoretical—it is practical, reliable, and ready for production on **Google Cloud**.\n\nBy combining **LangGraph** for multi-agent workflows, **Gemini** for natural language reasoning, and **GCP** for fast ingress and persistent memory, we can build shopping experiences that feel as simple as chatting with a friend while maintaining the enterprise rigor required for commerce.", "url": "https://wpnews.pro/news/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working", "canonical_source": "https://developers.googleblog.com/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working-prototype/", "published_at": "2026-10-27 17:44:05.712219+00:00", "updated_at": "2026-10-27 17:44:08.267854+00:00", "lang": "en", "topics": ["ai-agents", "large-language-models", "ai-tools", "ai-infrastructure"], "entities": ["Google Cloud", "LangGraph", "Gemini", "FastAPI", "HappyDelivery", "Cloud Memorystore", "WhatsApp", "Stripe"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working", "markdown": "https://wpnews.pro/news/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working.md", "text": "https://wpnews.pro/news/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working.txt", "jsonld": "https://wpnews.pro/news/building-conversational-commerce-with-multi-agent-swarms-on-gcp-a-working.jsonld"}}