Skip to content

fix(search): expose backend capabilities instead of ignoring lexical and hybrid modes #56

Closed

Description

@spelech

Finding

The public search interface accepts lexical, hybrid, and weighting controls for Chroma and pgvector, but those backends ignore the requested mode/weight and perform dense-only search.

Revision: 41ec093a745f1c0277893dc8f758b96b216c970f.

Reproduced evidence

Insert a synthetic document, then request search_mode="lexical":

Backend Actual result
Embedded Chroma one result, dense score ~0.4997, sparse score 0
Live remote Chroma one result, dense score ~0.4997, sparse score 0
Direct PostgreSQL/pgvector one result, dense score ~0.4990, sparse score 0

Semantic ingestion/retrieval worked for all three. This is a capability/contract mismatch, not a claim that semantic search is unavailable.

Code inspection confirms that Chroma.search() and PgVectorStore.search() accept these arguments but always embed the query and perform dense search.

Expected outcome

  • Expose supported search capabilities for the active backend.
  • Either implement the advertised modes/weighting or explicitly reject unsupported combinations.
  • Gate/label UI controls and MCP/API behavior accordingly; do not describe dense retrieval as lexical/BM25.
  • True lexical mode must not require a dense-embedding gateway call.
  • Add backend-specific semantic/lexical/hybrid and weighting tests. Preserve Qdrant's existing hybrid behavior.

This can be resolved with honest capability handling without necessarily implementing BM25 in every backend.

Activity

  1. spelech commented on Oct 27, 2026

    @spelech
    OwnerAuthor

    Triage & Implementation Brief

    1. Scope & Effort

    • Effort: Medium (Capability reflection & router validation)
    • Component: Vector Store & Search Router (app/services/vector_store/, app/api/routers/search.py)

    2. Root Cause & Context

    Chroma and pgvector backends accept search_mode="lexical" and search_mode="hybrid", but always perform dense-only search (lexical mode embeds the query and runs dense search).

    3. Implementation Plan

    • Expose a supported_search_modes property on all vector store backends:
      • Qdrant: ["dense", "sparse", "hybrid"]
      • pgvector: ["dense"]
      • Chroma: ["dense"]
    • In app/api/routers/search.py, validate the requested mode against the active backend's capabilities:
      • Return HTTP 400 with a clear error message if an unsupported mode is requested.
      • Skip dense embedding generation if true lexical search is requested.
    • Expose backend capabilities in the settings/health metadata so the frontend UI can disable unsupported controls.

    4. Acceptance Criteria

    • Requesting lexical or hybrid search against backends without sparse support produces an explicit error rather than pseudo-dense results.
    • True lexical search does not invoke the dense embedding gateway.
    • Qdrant hybrid search continues to function normally.
  2. google-labs-jules commented on Oct 27, 2026

    @google-labs-jules
    Contributor

    Jules is on it. When finished, you will see another comment and be able to review a PR.

  3. google-labs-jules commented on Oct 27, 2026

    @google-labs-jules
    Contributor

    Ready for a review! A PR has been created.

  4. google-labs-jules commented on Oct 27, 2026

    @google-labs-jules
    Contributor

    I apologize, but I encountered an unexpected error and wasn't able to complete the task.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    julesgoogle-jules-bot

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions