Migrate docsite embed/search to Postgres + pgvector (WIP) - #606
Open
IZO-Ong wants to merge 42 commits into
Open
Conversation
…o match brief spec
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…url for integration testing
Contributor
|
Amazing, thanks so much Isaac! I will review this on Monday. |
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.
Short Description
Migrates
embed_docsite/search_docsitefrom Pinecone to Postgres + pgvector (0.8.1 extension), keeping the legacy Pinecone path available. Both indexing and searching support either backend, selected independently — the write target and read backend are separate settings. WIP — comments are welcome!Addresses the first half of #305
Implementation Details
Using both backends
Indexing —
embed_docsite's payload takes atargetparam:Searching —
search_docsitereadsDOCSITE_SEARCH_BACKEND(env, defaultpinecone), overridable per-request via abackendpayload field:job_chat'sretrieve_docs.pyand thesearch_documentationtool both resolve the backend the same way, through a sharedresolve_backend()insearch_docsite.py.No new required env vars for existing setups, Two new optional vars in
.env.example:DOCSITE_SEARCH_BACKEND—pinecone|postgres(Defaults to pinecone if not provided)POSTGRES_TEST_URL— separate DB for the integration suite only (see Tests below)Search strategies
Postgres adds three strategies:
semantic(pgvector cosine),keyword(Postgres full-text search), andhybrid(Reciprocal Rank Fusion of both).Production consumers (
job_chat,search_documentation) usestrategy='semantic'on both backends, at the same0.8cosine threshold Pinecone already used.hybrid/keywordare available via thesearch_docsiteservice directly and viarun_eval, but aren't wired into any production consumer yet.Migrations
Schema lives in
services/migrations/0001_docsite_batches_and_chunks.sql—docsite_batches(versioned batch lifecycle:building→complete/failed) anddocsite_chunks(chunk text +vector(1536)embedding + generatedtsvectorfor FTS), plus thevectorextension and four indexes.Applied by
services/db_migrations.py, run explicitly fromembed_docsite's Postgres write path. Migrations are idempotent (tracked in_migrations_docs) and lexically ordered.No manual step needed, the first
embed_docsiterun withtarget=postgressets up the schema.Running
run_evalCompares both backends (
strategy='semantic'on each) over a golden query set: recall@5, p50/p95 latency, and per-query doc-title agreement.Setup:
Set
OPENAI_API_KEY,PINECONE_API_KEY,POSTGRES_URLinservices/.env(this is the file that's actually loaded — see note below).Populate both backends:
Run the eval (must run from
services/, the Python path root):cd services poetry run python -m search_docsite.tests.eval.run_evalNote:
services/.envis the file every Python service actually loads —python-dotenvresolves relative to the importing module's location, so anything underservices/findsservices/.envbefore it would reach a repo-root.env. Keep credentials there, not just at the root.Results
Postgres matches Pinecone's recall@5 and is faster on both p50 and p95. All 9 scored queries hit on both backends — the two queries at 0.75 doc-title agreement (what is a run in OpenFn, how do I write a data transform function) differ on which extra titles round out the rest of the top 5.
One query (
what adaptors are available for HTTP requests) is unscored —run_evalfilters todocs_type='general_docs', but that query's answer lives inadaptor_docs.golden_queries.yaml's labels were derived from thegeneral_docscorpus via full-text search on each query's key terms.Latency varies somewhat run-to-run (p95 has ranged 1.3–3.3s across runs on a 10-query sample, likely OpenAI embedding latency). p50 has stayed consistently lower on Postgres across runs.
Tests
Unit — 108 passing, fully mocked:
embed_docsite:test_docsite_processor.py,test_docsite_indexer.py,test_embed_docsite.py,test_db_migrations.pysearch_docsite:test_docsite_search.py(new Postgres backend),test_pinecone_legacy_search.py(legacy, preserved),test_search_docsite_main.py,test_run_eval.pyjob_chatandsearch_documentationfor the newresolve_backend()delegationIntegration — 6 passing, against a real ephemeral Postgres + pgvector:
services/embed_docsite/tests/integration/test_postgres_docsite_roundtrip.py— fresh-DB migrate→index→promote, search across all three strategies, reindex prunes the previous batch, reader gets a clear 503 without a schemadocker run -d --name apollo-pgvector-test -e POSTGRES_PASSWORD=postgres -p 5433:5432 pgvector/pgvector:pg16 export POSTGRES_TEST_URL=postgresql://postgres:postgres@127.0.0.1:5433/postgres poetry run pytest services/embed_docsite/tests/integration -qCaution: Do not use
POSTGRES_URLforPOSTGRES_TEST_URL— the fixturesDROPthe docsite tables and thevectorextension between tests, so pointing this at a database would destroy its data.AI Usage
Please disclose whether you've used AI in this work (it's cool, we just want to
know!):
You can read more details in our
Responsible AI Policy