Conversation
Adds PgVectorMemoryService under google.adk.integrations.pgvector, a BaseMemoryService backed by PostgreSQL with the pgvector extension. Events are embedded (via the google-genai client by default, or an injectable embedder) and stored with their vectors in a table the user owns; search_memory returns the nearest memories by cosine distance using a pgvector HNSW index. Unlike VertexAiMemoryBankService and VertexAiRagMemoryService it needs no Google Cloud, and unlike InMemoryMemoryService it persists across restarts and ranks by semantic similarity rather than keyword overlap. This fills the self-hosted, non-GCP semantic-memory gap raised in google#6254 and complements the exact-match SQLite memory service in google#4116. The service follows the existing integrations/redis pattern: a pydantic config plus an injectable connection pool and embedder, which keeps it unit-testable without a live database. Ships as an optional extra, google-adk[pgvector]. Includes unit tests that exercise ingestion, idempotent upserts, semantic ranking, per-(app_name, user_id) scoping, the distance threshold, and serialization round-trips against an in-process fake pool and a deterministic embedder, so they run without psycopg, pgvector, or any network access. Resolves google#7273
Nanduu24
force-pushed
the
feat/pgvector-memory-service
branch
from
September 25, 2026 03:28
96f7abb to
a04727e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to Issue or Description of Change
Problem:
ADK's memory services do not cover persistent, semantic memory on
infrastructure the user controls.
InMemoryMemoryServiceis keyword-only and"for prototyping purpose only" (loses data on restart), while
VertexAiMemoryBankServiceandVertexAiRagMemoryServicerequire Google Cloud.Teams running on-premise, air-gapped, or under data-residency constraints have
no built-in option, and the pending SQLite memory service (#4116) provides
persistence but exact-match retrieval rather than semantic search.
Solution:
Add
PgVectorMemoryServiceundergoogle.adk.integrations.pgvector, aBaseMemoryServicebacked by PostgreSQL +pgvector:add_session_to_memory/add_events_to_memoryembed each event's text andupsert it (idempotent per event) into a table scoped by
(app_name, user_id).add_memorysupports direct writes of explicitMemoryEntryitems.search_memoryembeds the query and returns the nearest memories by cosinedistance using a pgvector HNSW index, with an optional
distance_threshold.google-genaiclient by default; an injectableembeddermakes the service provider-agnostic.
pip install "google-adk[pgvector]".It follows the existing
integrations/redispattern (pydantic config plus aninjectable connection pool and embedder), so the store runs entirely on a
database the user owns and stays unit-testable without a live database. The
table,
vectorextension, and indexes are created on first use. Happy to alignthe table layout with #4116 if a shared schema is preferred.
Testing Plan
Unit Tests:
New tests in
tests/unittests/integrations/pgvector/run against an in-processfake connection pool and a deterministic bag-of-words embedder, so they exercise
ingestion, idempotent upserts, semantic ranking, per-
(app_name, user_id)scoping, the distance threshold, empty-query handling, skipping text-less
events, the direct-write path, serialization round-trips, and the
missing-driver / missing-dsn errors — all without
psycopg,pgvector, or anynetwork access.
The suite passes both with the optional driver installed and with it absent
(matching CI). Lint/format on the changed files:
pyinkandisortclean,pylint10.00/10.Manual End-to-End (E2E) Tests:
Verified against a live PostgreSQL 17 + pgvector 0.8.6 database using the
real
psycopgasync driver (a deterministic local embedder stood in for theembedding API). Confirmed: session ingestion, semantic ranking (a "billing"
query returns the billing turn; a "basketball" query returns the basketball
turn), cross-instance persistence (a fresh service reads the stored rows back),
(app_name, user_id)scoping, idempotent re-ingestion (row count stays at 3after a double ingest), and the created schema (a
vector(64)column and anHNSW index). To reproduce:
Checklist
Additional context
Design mirrors the
integrations/redissession service and thegoogle-genaiembedding usage in
tools/spannerandintegrations/mongodb. The new optionalextra
pgvectorpinspsycopg[binary],psycopg-pool, andpgvector, and isincluded in the
allextra.