Skip to content

feat: add hybrid search as retrieval mode #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
376 changes: 341 additions & 35 deletions rag-core-api/poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions rag-core-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ langgraph = "^0.2.23"
pillow = "^11.0.0"
langchain-ollama = "^0.2.0"
pytest-asyncio = "^0.25.0"
langchain-community = "0.3.19"
fastembed = "^0.6.0"

[tool.poetry.group.dev.dependencies]
debugpy = "^1.8.1"
Expand Down
10 changes: 9 additions & 1 deletion rag-core-api/src/rag_core_api/dependency_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from langchain_community.llms.fake import FakeListLLM
from langchain_ollama import ChatOllama
from langchain_openai import ChatOpenAI
from langchain_qdrant import QdrantVectorStore
from langchain_qdrant import QdrantVectorStore, FastEmbedSparse
from langfuse import Langfuse

from rag_core_api.impl.answer_generation_chains.answer_generation_chain import (
Expand Down Expand Up @@ -50,6 +50,7 @@
from rag_core_api.impl.settings.ragas_settings import RagasSettings
from rag_core_api.impl.settings.reranker_settings import RerankerSettings
from rag_core_api.impl.settings.retriever_settings import RetrieverSettings
from rag_core_api.impl.settings.sparse_embedder_settings import SparseEmbedderSettings
from rag_core_api.impl.settings.stackit_embedder_settings import StackitEmbedderSettings
from rag_core_api.impl.settings.vector_db_settings import VectorDatabaseSettings
from rag_core_api.impl.vector_databases.qdrant_database import QdrantDatabase
Expand Down Expand Up @@ -95,6 +96,7 @@ class DependencyContainer(DeclarativeContainer):
embedder_class_type_settings = EmbedderClassTypeSettings()
stackit_embedder_settings = StackitEmbedderSettings()
chat_history_settings = ChatHistorySettings()
sparse_embedder_settings = SparseEmbedderSettings()
chat_history_config.from_dict(chat_history_settings.model_dump())

class_selector_config.from_dict(rag_class_type_settings.model_dump() | embedder_class_type_settings.model_dump())
Expand All @@ -110,22 +112,28 @@ class DependencyContainer(DeclarativeContainer):
),
)

sparse_embedder = Singleton(FastEmbedSparse, **sparse_embedder_settings.model_dump())

vectordb_client = Singleton(
qdrant_client.QdrantClient,
location=vector_database_settings.location,
)

vectorstore = Singleton(
QdrantVectorStore,
client=vectordb_client,
collection_name=vector_database_settings.collection_name,
embedding=embedder,
sparse_embedding=sparse_embedder,
validate_collection_config=False,
retrieval_mode=vector_database_settings.retrieval_mode,
)

vector_database = Singleton(
QdrantDatabase,
settings=vector_database_settings,
embedder=embedder,
sparse_embedder=sparse_embedder,
vectorstore=vectorstore,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Module contains settings regarding the sparse embedder."""

from pydantic import Field
from pydantic_settings import BaseSettings


class SparseEmbedderSettings(BaseSettings):
"""
Contains settings regarding the sparse embedder.

Attributes
----------
model_name : str
The name of the model to be used (default "Qdrant/bm25").
"""

class Config:
"""Config class for reading Fields from env."""

env_prefix = "SPARSE_EMBEDDER_"
case_sensitive = False

model_name: str = Field(default="Qdrant/bm25")
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from pydantic_settings import BaseSettings
from pydantic import Field

from langchain_qdrant import RetrievalMode


class VectorDatabaseSettings(BaseSettings):
"""
Expand All @@ -27,3 +29,4 @@ class Config:
validate_collection_config: bool = Field(
default=False
) # if true and collection does not exist, an error will be raised
retrieval_mode: RetrievalMode = Field(default=RetrievalMode.HYBRID)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from langchain_core.documents import Document
from langchain_qdrant import QdrantVectorStore
from langchain_qdrant import QdrantVectorStore, SparseEmbeddings
from qdrant_client.http import models
from qdrant_client.models import FieldCondition, Filter, MatchValue

Expand All @@ -25,6 +25,7 @@ def __init__(
self,
settings: VectorDatabaseSettings,
embedder: Embedder,
sparse_embedder: SparseEmbeddings,
vectorstore: QdrantVectorStore,
):
"""
Expand All @@ -43,6 +44,7 @@ def __init__(
settings=settings,
embedder=embedder,
vectorstore=vectorstore,
sparse_embedder=sparse_embedder,
)

@property
Expand Down Expand Up @@ -167,9 +169,11 @@ def upload(self, documents: list[Document]) -> None:
"""
self._vectorstore = self._vectorstore.from_documents(
documents,
self._embedder.get_embedder(),
collection_name=self._settings.collection_name,
embedding=self._embedder.get_embedder(),
sparse_embedding=self._sparse_embedder,
location=self._settings.location,
collection_name=self._settings.collection_name,
retrieval_mode=self._settings.retrieval_mode,
)

def delete(self, delete_request: dict) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from langchain_community.vectorstores import VectorStore
from langchain_core.documents import Document
from langchain_qdrant import SparseEmbeddings

from rag_core_api.embeddings.embedder import Embedder
from rag_core_api.impl.settings.vector_db_settings import VectorDatabaseSettings
Expand All @@ -16,6 +17,7 @@ def __init__(
self,
settings: VectorDatabaseSettings,
embedder: Embedder,
sparse_embedder: SparseEmbeddings,
vectorstore: VectorStore,
):
"""
Expand All @@ -32,6 +34,7 @@ def __init__(
"""
self._settings = settings
self._embedder = embedder
self._sparse_embedder = sparse_embedder
self._vectorstore = vectorstore

@property
Expand Down
74 changes: 41 additions & 33 deletions rag-core-lib/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rag-core-lib/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ packages = [{ include = "rag_core_lib", from = "src" }]
[tool.poetry.dependencies]
python = "^3.11"
langchain = "^0.3.7"
langchain-community = "0.3.7"
langchain-community = "0.3.19"
flashrank = "^0.2.5"
pydantic-settings = "^2.2.1"
pydantic = "^2.7.2"
Expand Down
Loading