When agents become the users: Why multi-agent systems need in-database intelligence and borderless analytics

As software architecture transitions from human-driven UI clicks to autonomous AI agent swarms, our underlying data tier faces an unprecedented paradigm shift. Agents do not browse pages — they think inside continuous reasoning loops, bombarding databases with bursts of concurrent point lookups, deep analytical aggregations, and hybrid semantic searches.
In this hands-on, you will learn how to power and support multi-agent swarms using Google’s Data Cloud. We will cover how AlloyDB AI solves agent-scale concurrency with disaggregated compute and storage, brings models directly to your data via native SQL AI Functions, pluggable foundational and 3P models, accelerates hybrid vector search and borderless lakehouse analytics, and secures agent access with the open-source MCP Toolbox for Databases.
Background
Whether you spend your days building React frontends, Go microservices, data pipelines, or ML workflows, pause for a second and ask yourself one question: Who is actually using your data?
For the past thirty years, the answer was obvious: humans. A shopper taps “Buy Now” on a mobile app. An analyst refreshes a dashboard on Monday morning. One human click meant one predictable SQL query — followed by a comfortable two-second breather while human eyes read the screen. Our connection pools, indexes, and ETL schedules were all engineered around human reading speed.
Today, that thirty-year assumption is dead. Autonomous AI agents have become the users. An agent doesn’t browse your CSS, and it doesn’t wait patiently for a spinner. It thinks inside a continuous reasoning loop — firing relentless bursts of point lookups, hybrid vector searches, unstructured sentiment checks, and cross-cloud analytical scans at machine speed. And when one human asks a single complex question, your backend doesn’t receive one query. You get an Agent Swarm.
In this article, we walk through the exact architecture, live demos, and runnable codebase (github.com/AbiramiSukumaran/agents-are-users) from my keynote “When Agents Become the Users.” Instead of gluing together fragile vector databases, ETL pipelines, and row-by-row LLM scripts, you’ll see how AlloyDB AI, Gemini 4 Hydrogen, Smart Batching, Borderless Lakehouse Federation, and MCP Toolbox turn PostgreSQL into an agent-ready reasoning engine.
What we’re building & exploring today
- The Paradigm Shift: Why solo “do-it-all” agents rot and how an outdoor gear prompt breaks conventional stacks.
- Demo 1 — Disaggregated Scale & Hybrid Search: Fusing 10x faster ScaNN vectors, native BM25, and 100% Columnar recall.
- Demo 2 — Bringing Models to Data: Inline SQL AI Functions with Gemini 4 Hydrogen and GA Smart Batching over 500k reviews.
- Demo 3 — The Borderless Lakehouse: Direct Iceberg, AlloyDB Sync, and zero-copy BigQuery Federation (bigquery_fdw).
- Demo 4 — Zero-Trust Agent Swarms (App Demo): Orchestrating 4 parallel Google ADK specialists safely via MCP Toolbox.
The “Impossible” E-Commerce Prompt (And Why Solo Agents Fail)
Early GenAI apps tried the Solo “Do-It-All” Agent pattern: one giant LLM prompt wired to twenty tools, stuffing SQL schemas, product JSON, and raw reviews into a single loop. Within three turns, context rot sets in, attention leaks, and sequential tool calls stall. An Agent Swarm fixes this the same way microservices fixed monoliths — an Orchestrator Agent (Google ADK) decomposes the goal and dispatches parallel specialists, each with an isolated context window and scoped MCP tools.
Consider a real shopper prompt on an outdoor gear store:
I’m planning a high-altitude photography trip. Show me weather-resistant backpacks similar to the Aero Glow Pro, without any leather, confirm they are actually in stock, and tell me if other photographers complained about strap durability in the reviews.
Why does a single REST endpoint or naive vector search fail? First, negative constraints (“without any leather”) trip up pure vector embeddings because “no leather” embeds right next to “leather.” Second, live stock (“actually in stock”) demands real-time ACID state — if your vector DB syncs on a 20-minute ETL lag, your agent confidently sells an out-of-stock backpack! Third, unstructured nuance (“strap durability complaints”) is buried inside thousands of messy reviews where LIKE ‘%strap%’ matches praise and complaints alike.
Now imagine 1,000 shoppers doing that simultaneously — or a 15-agent supply chain swarm asking why fill rates dropped from 97% to 90%.
Demo 1: Disaggregated Scale & 100% Recall Hybrid Search
To survive agent-scale concurrency, AlloyDB disaggregates compute from Google’s Colossus storage layer. Your primary instance handles human OLTP checkouts with 0% write impact, while elastic PostgreSQL read pools spin up over shared storage to absorb 15+ concurrent agent queries without copying disk.
Inside that same engine, Specialist #1 (CatalogVectorAgent) runs search_catalog_hybrid. The shopper asked for “weather-resistant” (semantic meaning) AND “Aero Glow Pro” (exact product name). Instead of running a separate Elasticsearch cluster and a separate Vector DB, AlloyDB runs 10x faster ScaNN vector search and native C-optimized BM25 (pg_textsearch) side-by-side on outdoor_gear_catalog, fusing them in milliseconds via Reciprocal Rank Fusion (RRF) — and even wraps this exact RRF pattern into a single built-in ai.hybrid_search() function:
WITH vector_hits AS (
SELECT sku, ROW_NUMBER() OVER (
ORDER BY embedding <=> embedding('text-embedding-005', $1)::vector
) AS v_rank
FROM outdoor_gear_catalog
ORDER BY embedding <=> embedding('text-embedding-005', $1)::vector
LIMIT 10
),
bm25_hits AS (
SELECT sku, ROW_NUMBER() OVER (
ORDER BY description <@> to_bm25query($1, 'idx_gear_bm25') ASC
) AS k_rank
FROM outdoor_gear_catalog
ORDER BY description <@> to_bm25query($1, 'idx_gear_bm25') ASC
LIMIT 10
),
fused AS (
SELECT sku,
ROUND((COALESCE(1.0 / (60 + v.v_rank), 0) + COALESCE(1.0 / (60 + b.k_rank), 0))::numeric, 5) AS rrf_score
FROM vector_hits v FULL OUTER JOIN bm25_hits b USING (sku)
ORDER BY rrf_score DESC LIMIT 5
)
SELECT c.sku, c.product_name, c.description, f.rrf_score
FROM fused f JOIN outdoor_gear_catalog c USING (sku)
ORDER BY f.rrf_score DESC;
Meanwhile, Specialist #2 (InventoryAgent) enforces material NOT ILIKE ‘%leather%’ and stock_qty > 0. AlloyDB’s dual-format Columnar Engine uses SIMD CPU registers to pre-filter rows in memory for 100% exact recall — immediately disqualifying AGP-45L (leather trim) and CLD-42L (out of stock).
Demo 2: Bringing Models to Data — Gemini 4 Hydrogen & Smart Batching
Exporting 500,000 reviews into Python just to call an LLM row-by-row is a latency and budget disaster. AlloyDB AI Functions flip the architecture: you bring the models directly to your data using inline SQL operators like ai.if(), ai.analyze_sentiment(), ai.classify(), ai.extract(), ai.agg_summarize(), and TimesFM-powered ai.forecast().
Even better, AlloyDB integrates natively with Google’s latest Gemini 4 Hydrogen (gemini-4-hydrogen) — delivering 2.5x faster execution, over 5x fewer fabricated claims, and 12x less task shortcutting across a 1M-token context window. And because the SQL is model-agnostic, routing between Hydrogen, Carbon, Argon, or external 3P endpoints is just changing a model_id string.
The Ultimate Test:
Specialist #3 (ReviewQualityAgent) queries our 500,000-row gear_reviews_500k table. With Smart Batching — now GA and enabled by default in PostgreSQL 18 — AlloyDB evaluates our SQL filters first and automatically injects an AIFunctionApply node that micro-batches ai.analyze_sentiment() at up to 14,000 rows/sec (2,400x faster than scalar calls, with up to 75% lower token costs) in sub-second latency:
SELECT
sku,
ai.analyze_sentiment(review_text) AS sentiment,
COUNT(*) AS total_reviews
FROM
gear_reviews_500k
WHERE
verified_expedition = TRUE
GROUP BY
sku,
sentiment
ORDER BY
total_reviews DESC
LIMIT
100000;
And for recurring million-row boolean filters like ai.if(), Local Proxy Models train a lightweight surrogate classifier inside PostgreSQL via PREPARE/EXECUTE — reaching 100,000 rows/sec (23,000x speedup at 1/6,000th the cost) with automatic fallback to Hydrogen on low-confidence edge cases.
Demo 3: The Borderless Lakehouse — 3 Integration Pillars With / Without Storing Data
Enterprise data doesn’t live in one neat project — it spans BigQuery, Cloud Storage, AWS S3, Snowflake, and Databricks. AlloyDB gives your agents three zero-ETL integration pillars depending on your latency SLA:

Direct Iceberg Access
Use this if you want to query open Apache Iceberg tables in Cloud Storage directly in place, accelerated in RAM by the Columnar Engine.
AlloyDB Sync
Auto-maintain a synchronized local copy of lakehouse tables for constant agent lookups with local B-tree & ScaNN indexes.
Lakehouse Federation (bigquery_fdw)
Query native BigQuery & cross-cloud lakehouse petabytes in place with automatic filter and aggregation pushdown.
In Demo 3, Specialist #4 (TrendLakehouseAgent) uses Lakehouse Federation (bigquery_fdw) to join live AlloyDB inventory with regional Himalayan expedition orders in BigQuery (bq_regional_demand) in a single PostgreSQL query — pushing filters down to BigQuery compute and leveraging block-based caching across iterative agent loops with zero data copies:
SELECT i.sku, i.product_name, i.stock_qty,
d.region, d.orders_last_30d, d.aws_s3_restock_eta_days
FROM outdoor_gear_catalog i
JOIN bq_regional_demand d ON i.sku = d.sku
WHERE d.altitude_tier = 'high_altitude' AND i.stock_qty > 0
ORDER BY d.orders_last_30d DESC;
Here look at the tables that are being joined: AlloyDB (outdoor_gear_catalog) and BigQuery (bq_regional_demand) – seamlessly unified for fetching federated analytics data from AlloyDB.
Demo 4: Zero-Trust Agent Swarms with MCP Toolbox & Google ADK (App Demo)
When you move from one solo agent to a 4-specialist (or 15-specialist) swarm, your hardest problem is no longer writing a SQL query — it is safely orchestrating concurrent database access across multiple autonomous agents without leaking credentials, exhausting connection pools, or letting a prompt injection drop a table.
A system prompt is advice to a model, not a security boundary. Giving every sub-agent raw database credentials or an open execute_sql tool invites schema hallucinations, runaway queries, and SQL injection. That is why we put the open-source MCP Toolbox for Databases between our Google ADK swarm and our AlloyDB read pool:
- Deterministic Parameterized SQL (Zero Raw DDL/DML): Every tool in tools.yaml binds the LLM to an audited, parameterized SQL template ($1) with typed inputs — eliminating arbitrary SQL generation and prompt-injected DROP/DELETE attacks.
- Scoped Toolsets Per Specialist (No Tool Overload): Instead of dumping 20 database tools into every agent’s context window, toolsets expose only the exact tool(s) each specialist needs (catalog_tools, inventory_tools, review_tools, lakehouse_tools), keeping Gemini 4 Hydrogen fast and accurate.
- Centralized Connection Pooling for Swarm Bursts: When ParallelAgent fans out 4 sub-agents simultaneously across hundreds of shoppers, opening raw connections per agent turn exhausts Postgres max_connections. MCP Toolbox pools connections centrally and routes them straight to our disaggregated AlloyDB Read Pool (swarm-read-pool-01) with 0% impact on primary OLTP writes.
- Zero-Trust Credentials, Auth & OpenTelemetry: Database passwords and API secrets never enter an agent prompt, authenticated parameters bind verified JWT claims, and built-in OpenTelemetry exports end-to-end trace spans across every burst query.
- Decoupled Declarative Control Plane (<10 Lines of Python): DBAs and backend engineers tune SQL indexes, RRF weights, or BigQuery joins in tools.yaml without redeploying the ADK Python app.
sources:
alloydb_swarm_readpool:
kind: alloydb-postgres
project: *****
region: us-east4
cluster: *****
instance: *****
database: *****
user: *****
password: *****
ipType: "public"
tools:
# 1. Catalog / Vector Agent — Hybrid Search (ScaNN + BM25 via RRF)
search_catalog_hybrid:
kind: postgres-sql
source: alloydb_swarm_readpool
description: >
Runs hybrid semantic (ScaNN) + keyword (BM25) search with Reciprocal Rank Fusion
to find backpacks matching a reference product and weather profile.
parameters:
- name: search_query
type: string
description: Semantic and lexical search phrase, e.g. 'weather-resistant backpack Aero Glow Pro'
statement: |
WITH vector_hits AS (
SELECT sku, ROW_NUMBER() OVER (
ORDER BY embedding <=> embedding('text-embedding-005', $1)::vector
) AS v_rank
FROM outdoor_gear_catalog LIMIT 10
),
bm25_hits AS (
SELECT sku, ROW_NUMBER() OVER (
ORDER BY description <@> to_bm25query($1, 'idx_gear_bm25')
) AS k_rank
FROM outdoor_gear_catalog LIMIT 10
)
SELECT c.sku, c.product_name, c.description,
ROUND((COALESCE(1.0 / (60 + v.v_rank), 0) + COALESCE(1.0 / (60 + b.k_rank), 0))::numeric, 5) AS rrf_score
FROM outdoor_gear_catalog c
LEFT JOIN vector_hits v USING (sku)
LEFT JOIN bm25_hits b USING (sku)
WHERE v.sku IS NOT NULL OR b.sku IS NOT NULL
ORDER BY rrf_score DESC
LIMIT 5;
# 2. Inventory Agent — Live OLTP + Columnar Engine 100% Recall Filter
check_live_inventory_columnar:
kind: postgres-sql
source: alloydb_swarm_readpool
description: >
Verifies live transactional stock, price, and strict material exclusions (e.g., excluding leather)
with 100% exact recall via AlloyDB Columnar Engine.
parameters:
- name: excluded_material_keyword
type: string
description: Material substring to strictly exclude, e.g. 'leather'
statement: |
SELECT sku, product_name, material, weather_resistant, price_usd, stock_qty
FROM outdoor_gear_catalog
WHERE weather_resistant = true
AND stock_qty > 0
AND material NOT ILIKE '%' || $1 || '%'
ORDER BY stock_qty DESC;
# 3. Review / Quality Agent — In-DB SQL AI Functions + Smart Batching over 500k Reviews
analyze_strap_reviews_ai:
kind: postgres-sql
source: alloydb_swarm_readpool
description: >
Uses AlloyDB SQL AI Function ai.analyze_sentiment() with Smart Batching over the
500k reviews table to break down positive, negative, and neutral strap durability sentiment.
parameters:
- name: target_sku
type: string
description: Product SKU to analyze reviews for, e.g. 'ALP-40L' or 'AGX-50L'
statement: |
SELECT
sku,
ai.analyze_sentiment(review_text) AS strap_sentiment,
COUNT(*) AS review_count
FROM gear_reviews_500k
WHERE sku = $1
AND verified_expedition = true
GROUP BY sku, strap_sentiment
ORDER BY review_count DESC;
# 4. Trend / Analytics Agent — Borderless Lakehouse Federation (Zero-Copy BigQuery FDW)
query_lakehouse_regional_demand:
kind: postgres-sql
source: alloydb_swarm_readpool
description: >
Federates in place from AlloyDB to BigQuery (expedition_lakehouse.regional_gear_demand)
to fetch high-altitude regional demand and restock lead times with zero data movement.
parameters:
- name: altitude_segment
type: string
description: Target segment, e.g. 'high_altitude'
statement: |
SELECT
i.sku,
i.product_name,
d.region,
d.orders_last_30d,
d.aws_s3_restock_eta_days
FROM outdoor_gear_catalog i
JOIN regional_gear d ON i.sku = d.sku
WHERE d.altitude_tier = $1
AND i.stock_qty > 0
ORDER BY d.orders_last_30d DESC;
toolsets:
catalog_tools:
- search_catalog_hybrid
inventory_tools:
- check_live_inventory_columnar
review_tools:
- analyze_strap_reviews_ai
lakehouse_tools:
- query_lakehouse_regional_demand
On the Python side, wiring all four Gemini 4 Hydrogen specialists into a concurrent ADK swarm takes just ToolboxSyncClient(TOOLBOX_URL) and ParallelAgent. In under a second, KeynoteSwarmOrchestrator disqualifies AGP-45L (leather trim) and CLD-42L (0 stock), warns about strap fraying on ALP-40L across 500k reviews, and recommends AeroPeak StormShield 50L (AGX-50L) backed by live stock and federated BigQuery demand.
🛠️ Try It Yourself: Step-by-Step Implementation Guide (Demos 1, 2, 3 & the Multi-Agent System App)
Step 1: Google Cloud Project Setup & API Enablement
Create your Google Cloud Project and associate it with an active billing account.
Step 2: Enable required APIs
Enable the necessary APIs:
gcloud services enable \
alloydb.googleapis.com \
aiplatform.googleapis.com \
bigquery.googleapis.com \
compute.googleapis.com \
servicenetworking.googleapis.com \
secretmanager.googleapis.com \
run.googleapis.com
Step 3: Setup AlloyDB
- Follow the steps here
Step 4: Initialize Database Schema, Indexes & 500k Reviews
- Follow the steps in the file database-demos.sql in this repo
Step 5: Configure BigQuery Borderless Lakehouse Federation
- Follow the steps in the file database-demos.sql in this repo
Step 6: Install and Configure MCP Toolbox for Databases
1. Download the Binary
In your Cloud Shell Terminal, from your local root directory:
export VERSION=1.17.0
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
chmod +x toolbox
2. Clone this Repo
git clone https://github.com/AbiramiSukumaran/agents-are-users
3. Update tools.yaml and .env files
Update the files tools.yaml and .env with values from your environment
4. Launch and Validate MCP Toolbox
Start the Toolbox server locally:
./toolbox --ui
Navigate to http://localhost:5000/ui to test individual SQL tool endpoints prior to connecting the agent app.
Step 7: Multi-Agent Application (Google ADK)
This should already be cloned inside the folder swarp_app.
Step 8: Running the Multi-Agent Application
Make sure the following commands are running in 2 cloud shell terminals:
Terminal 1: MCP Toolbox Server
./toolbox --ui
Terminal 2: Google ADK Web UI
cd swarm_app
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Start the ADK Web server
adk web --port 8000 --allow_origins "*"
Open http://localhost:8080 in your browser.
Select swarm_app from the agent dropdown in the top-left corner.
Paste the prompt:
I’m planning a high-altitude photography trip. Show me weather-resistant backpacks similar to the Aero Glow Pro, without any leather, confirm they are actually in stock, and tell me if other photographers complained about strap durability in the reviews.
Click the Trace / Event Graph tab to observe all four sub-agents executing concurrently against AlloyDB and BigQuery.

Step 9: Clean Up
To avoid incurring charges, delete the deployed AlloyDB resources after finishing.
The Complete Picture & Hands-On Repo
When agents become your users, your database can no longer be a passive storage locker — it has to be an active, borderless reasoning partner. Ready to run the full swarm yourself? Grab the complete SQL scripts, tools.yaml, ADK Python app, and step-by-step setup guide in the repository and credits link below:
GitHub Repository (Full Code & Step-by-Step README):
GitHub – AbiramiSukumaran/agents-are-users
Slides:
https://medium.com/media/c953cbc2569505bb8c6a22ece063b73f/href
Developer Credits & Resources (Only valid until tomorrow 7 PM):
Google Developer Program
When agents become the users: Why multi-agent systems need in-database intelligence and borderless… was originally published in Google Cloud – Community on Medium, where people are continuing the conversation by highlighting and responding to this story.
Source Credit: https://medium.com/google-cloud/when-agents-become-the-users-why-multi-agent-systems-need-in-database-intelligence-and-borderless-aeb14a3eaa6c?source=rss—-e52cf94d98af—4
