Skip to content

feat(core): add Milvus semantic vector backend#1041

Open
zc277584121 wants to merge 3 commits into
basicmachines-co:mainfrom
zc277584121:feat/milvus-search-backend
Open

feat(core): add Milvus semantic vector backend#1041
zc277584121 wants to merge 3 commits into
basicmachines-co:mainfrom
zc277584121:feat/milvus-search-backend

Conversation

@zc277584121

Copy link
Copy Markdown

Summary

  • add an optional Milvus vector storage backend for semantic search
  • keep full-text search and vector chunk metadata in SQLite/Postgres while storing embeddings in Milvus
  • document Milvus Lite, Milvus server, and Zilliz Cloud configuration

Testing

  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 ruff check src/basic_memory/config.py src/basic_memory/repository/search_repository.py src/basic_memory/repository/search_repository_base.py src/basic_memory/repository/milvus_search_repository.py src/basic_memory/services/search_service.py src/basic_memory/services/project_service.py src/basic_memory/repository/project_repository.py tests/repository/test_milvus_search_repository.py tests/test_config.py tests/services/test_project_service_embedding_status.py
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 ruff format --check src/basic_memory/config.py src/basic_memory/repository/search_repository.py src/basic_memory/repository/search_repository_base.py src/basic_memory/repository/milvus_search_repository.py src/basic_memory/services/search_service.py src/basic_memory/services/project_service.py src/basic_memory/repository/project_repository.py tests/repository/test_milvus_search_repository.py tests/test_config.py tests/services/test_project_service_embedding_status.py
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 ty check src tests test-int
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 pytest tests/repository/test_milvus_search_repository.py -q
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 pytest tests/test_config.py::TestSemanticSearchConfig tests/services/test_project_service_embedding_status.py tests/services/test_semantic_search.py::test_reindex_all_uses_sqlite_vec_aware_drop tests/services/test_semantic_search.py::test_reindex_vectors_force_full_clears_project_vectors_before_resync tests/services/test_semantic_search.py::test_reindex_vectors_purges_sqlite_vectors_before_sync tests/repository/test_search_repository.py::test_init_search_index -q
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 pytest tests/repository/test_sqlite_vector_search_repository.py tests/repository/test_postgres_search_repository_unit.py -q
  • env UV_CACHE_DIR=/data2/zhangchen_workspace/auto_integrations/basic-memory/.uv-cache uv run --python 3.12 pytest tests/repository/test_postgres_search_repository.py -q (21 skipped)

@CLAassistant

CLAassistant commented Jul 6, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 389a50f42f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

session, table_name="search_vector_embeddings", dialect_name=dialect_name
)
marker_columns = {"chunk_id", "project_id", "embedding_dims", "updated_at"}
marker_mismatch = bool(embedding_columns) and not marker_columns.issubset(embedding_columns)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Drop existing pgvector table before Milvus markers

When a Postgres project already used the database vector backend, search_vector_embeddings has chunk_id, project_id, embedding_dims, and updated_at plus a NOT NULL embedding vector(...) column, so this subset check treats the pgvector table as a valid Milvus marker table. After users follow the documented backend switch and run bm reindex --embeddings --full, _replace_marker_rows inserts marker rows without embedding, causing the first Milvus sync batch to fail instead of migrating the derived table.

Useful? React with 👍 / 👎.

@zc277584121
zc277584121 force-pushed the feat/milvus-search-backend branch from 14b7a53 to f950677 Compare July 8, 2026 11:54
@zc277584121

Copy link
Copy Markdown
Author

Hi @phernandez @groksrc @jope-bm, could you take a look when you have a chance?

This PR adds an optional Milvus semantic vector backend while keeping SQL metadata storage in the existing repository flow. CLA and DCO are passing now. The branch also handles existing pgvector-derived tables separately from Milvus marker tables, with focused coverage in the Milvus repository tests.

@zc277584121
zc277584121 force-pushed the feat/milvus-search-backend branch from f950677 to eb0ac90 Compare July 15, 2026 00:51
@phernandez phernandez added the needs review A human maintainer needs to look at this issue label Jul 15, 2026 — with ChatGPT Codex Connector
@phernandez

phernandez commented Jul 15, 2026

Copy link
Copy Markdown
Member

@zc277584121 Thanks for this PR — and apologies for the slow response. We took a deep look, and the quality is genuinely high: it implements exactly the SearchRepositoryBase vector hooks the way they were designed to be used, keeps pymilvus a properly optional extra, and even cleans up some isinstance branching in search_service.py along the way. Nice work.

Where we're leaning, though, is toward vendor vector backends living as external packages rather than in-tree. Two practical reasons drive that:

  1. Windows: milvus-lite doesn't support Windows, and a meaningful share of Basic Memory users are on Windows. Shipping a basic-memory[milvus] extra from core that fails to install for them would generate confusion and support load we can't absorb.
  2. Ownership: as wired today our CI can't exercise the backend (the behavioral tests skip without the extra installed), which means we'd be carrying 700+ lines we can't regression-test against pymilvus API changes. You and the Zilliz team are the natural owners of that surface.

The shape we have in mind: we add a small extension point in core (a backend registry around create_search_repository) so a basic-memory-milvus package can register its repositories cleanly, you ship and own that package, and we link it prominently from our semantic search docs. Your code here would carry over largely as-is.

We'd really like to talk this through with you directly rather than in review threads — we actually tried to reach you on LinkedIn a while back with no luck. Could you email me at paul@basicmemory.com, or DM me on the Basic Memory Discord (https://discord.com/invite/tyvKNccgqN)? Happy to hop on a call too.

— Paul

@phernandez phernandez added the On Hold Don't review or merge. Work is pending label Jul 15, 2026
Signed-off-by: Cheney Zhang <chen.zhang@zilliz.com>
Signed-off-by: Cheney Zhang <chen.zhang@zilliz.com>
Signed-off-by: Cheney Zhang <chen.zhang@zilliz.com>
@zc277584121
zc277584121 force-pushed the feat/milvus-search-backend branch from eb0ac90 to 218da16 Compare July 17, 2026 00:26
@zc277584121

Copy link
Copy Markdown
Author

@phernandez Thanks for taking a close look and for laying out the external package direction. That makes sense to me, especially around Windows install behavior and long-term ownership of the Milvus-specific surface.

I took another pass over the current repository boundary before moving anything out. Today create_search_repository() still selects SQLiteSearchRepository vs PostgresSearchRepository directly, so a basic-memory-milvus package would not have a clean way to register itself without patching core imports or asking users to modify Basic Memory internals.

Could you share what extension point shape you would prefer before we split this up?

A few concrete points that would help us align:

  1. Should core expose a small backend registry, for example a register_search_repository_backend(...) function plus optional Python entry point loading?
  2. Should the config remain database_backend = sqlite|postgres with a separate semantic/vector backend setting, or should Milvus become a search repository backend value in the same selection path?
  3. Should the external package provide a SearchRepository implementation that still uses Basic Memory SQL tables for metadata/FTS and only stores vector chunks in Milvus, matching the current PR shape?
  4. What install/config experience would you want users to see in docs, e.g. install basic-memory-milvus, set one config/env value, then run bm reindex --embeddings?

If you are open to it, I can rework this into two smaller pieces: a core PR with just the registry/extension point, and a separate basic-memory-milvus package that carries the Milvus implementation and tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review A human maintainer needs to look at this issue On Hold Don't review or merge. Work is pending

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants