This release is a pre-release and may not be stable for production use.
Agent Framework PostgreSQL / pgvector
Store and search vector records in PostgreSQL with this alpha integration for Microsoft Agent Framework. The package uses Psycopg 3 and the official pgvector Python adapter.
PostgresCollectionprovides batch upsert, retrieval, deletion, and vector similarity search.PostgresStorecreates collection clients that share a connection pool.PostgresSettingsdescribes connection settings resolved by Agent Framework.
Installation
pip install agent-framework-postgres --pre
Requires Python 3.10+, PostgreSQL 13+, and pgvector 0.8.0+.
Import the connector directly from agent_framework_postgres.
Python 3.10 through 3.14 install Psycopg's binary distribution. Python 3.15+
uses the pure-Python implementation because binary wheels are not yet
published, so a system libpq installation is required.
Connection setup
Have your database administrator install and enable the vector extension and
provide an existing schema. The extension must be visible through the connection's
search_path. The connector never creates schemas, enables extensions, or changes
server-wide configuration. ensure_collection_exists() explicitly creates the
table and requested indexes; it requires the corresponding permissions and does
not migrate existing tables.
Set POSTGRES_CONNECTION_STRING to a PostgreSQL URI or Psycopg conninfo string,
or pass connection_string to either constructor. Both accept a string or AF
SecretString. Settings precedence is explicit argument > selected .env
file > environment. Select a file with env_file_path and optional
env_file_encoding; missing or empty connection strings are rejected.
The schema argument defaults to public.
A connector-created pool is closed by close() or an async context manager.
Alternatively, inject an open Psycopg AsyncConnection or AsyncConnectionPool
using client; it remains caller-owned and bypasses settings loading.
Injected clients cannot be combined with connection-string or .env options.
Collections created by a store borrow its pool, so keep the store open while
using them.
Example
With POSTGRES_CONNECTION_STRING configured, create a typed collection and
search using precomputed embeddings:
import asyncio
from dataclasses import dataclass
from typing import Annotated
from agent_framework import Filter, VectorStoreField, vectorstoremodel
from agent_framework_postgres import PostgresStore
@vectorstoremodel(collection_name="articles")
@dataclass
class Article:
id: Annotated[str, VectorStoreField("key")]
text: Annotated[str, VectorStoreField("data")]
embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
async def main() -> None:
async with PostgresStore() as store:
collection = store.get_collection(Article)
await collection.ensure_collection_exists()
await collection.upsert(
[
Article("1", "PostgreSQL supports vectors", [1, 0, 0]),
Article("2", "A travel journal", [0, 1, 0]),
],
generate_vectors=False,
)
results = await collection.search(
vector=[1, 0, 0],
filter=Filter("text", "contains_text", "PostgreSQL"),
score_threshold=0.25,
top=3,
)
async for result in results:
print(result["record"].text, result["score"])
if __name__ == "__main__":
asyncio.run(main())
Pass generate_vectors=False to preserve supplied embeddings. To generate them
locally, configure an embedding_generator. Retrieval excludes embeddings by
default; use include_vectors=True to return them.
Capabilities and limits
The connector supports typed models, string/integer/UUID keys (including generated keys), multiple nullable vector columns, storage aliases, and database-side filters and paging. Batch writes are transactional; an existing transaction on an injected connection remains under the caller's commit control.
Vector fields support float, float32, and float16 declarations. PostgreSQL
vector storage uses 32-bit floats; float16 defaults to 16-bit halfvec.
The postgres.vector_type provider annotation explicitly selects either storage
type. Ordinary Python floats and integer-valued elements are accepted and rounded
to the selected precision; declared int and float64 vector fields are rejected.
Storage precision does not determine the model's Python scalar type. The default
decoder returns ordinary Python floats: use list[float] annotations even with
explicit float16 or float32 field metadata. Models annotated with
list[numpy.float16] or list[numpy.float32] require a custom decoder passed to
vectorstoremodel or register_vectorstoremodel. That decoder must reconstruct
each component with the declared NumPy scalar type and handle omitted vector
fields when include_vectors=False. NumPy is not a connector runtime dependency.
Exact search is the default. HNSW and IVFFlat are optional approximate indexes;
selective filters can reduce their recall. Use
operation_options={"exact": True} when complete recall is required.
exact=False requires an HNSW or IVFFlat field. Result metadata's approximate
flag identifies ANN-permitted query mode, not proof that PostgreSQL used an ANN
index.
IVFFlat needs data before index creation: first call
ensure_collection_exists(operation_options={"create_indexes": False}), load
records, then call ensure_collection_exists() again.
Storage supports up to 16,000 dimensions; ANN indexes support up to 2,000 for
vector and 4,000 for halfvec.
Scores use the selected metric's units, not probabilities. The default is cosine
distance, where lower is better and score_threshold is a maximum. Cosine
similarity and dot product use minimum thresholds; negative dot product, L2, and
L1 distances use maximum thresholds. IVFFlat does not support L1.
Keyword/hybrid/full-text search, sparse/binary vectors, nested filter paths, schema migration, and server-side embedding generation are not supported.
Documentation
Metadata
Release files for agent-framework-postgres 1.0.0a261002
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agent_framework_postgres-1.0.0a261002.tar.gz | 18.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_framework_postgres-1.0.0a261002-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.7 kB
Release files / agent_framework_postgres-1.0.0a261002.tar.gz
| Download URL | agent_framework_postgres-1.0.0a261002.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
63b6587a7bea7032651cbefe07bb5bb5e0d5b80006b4c90062e40b29452e544f
|
|
BLAKE2b-256 checksum How to use checksums |
a56017cabc2aee00241279fbb0d59f05643695448edfe2dcf4af1401353647d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / agent_framework_postgres-1.0.0a261002-py3-none-any.whl
| Download URL | agent_framework_postgres-1.0.0a261002-py3-none-any.whl |
|---|---|
| Size | 16.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
997a3e9e0c0779935cd36df006e2df4e976df49fdbe3e2a18c292748f7816211
|
|
BLAKE2b-256 checksum How to use checksums |
6194ec78612fc75d188e02538e9e878ee5e16014dcfa2f4a391249aba8c3f725
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|