Files
cleveragents-core/benchmarks/faiss_vector_backend_bench.py
aditya eff446f5e8
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 21s
CI / lint (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 50s
CI / quality (pull_request) Successful in 3m44s
CI / integration_tests (pull_request) Successful in 3m58s
CI / unit_tests (pull_request) Successful in 4m5s
CI / security (pull_request) Successful in 4m6s
CI / docker (pull_request) Successful in 1m18s
CI / coverage (pull_request) Successful in 14m17s
CI / e2e_tests (pull_request) Successful in 21m13s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-regression (pull_request) Successful in 58m23s
feat(acms): integrate FAISS into ACMS vector backend protocol
Add FAISS-backed ACMS read and write adapters on top of the shared VectorStoreService, wire them through the DI container, and cover indexing, scoped search, removal, and benchmark behavior with Behave and ASV.

Address review feedback by keeping the commit scoped to the FAISS backend work and replacing the loose vector-store cache typing with explicit FAISS store protocols instead of Any.

ISSUES CLOSED: #871
2026-03-30 13:19:08 +00:00

103 lines
3.4 KiB
Python

"""ASV benchmarks for the FAISS ACMS vector backend adapters."""
from __future__ import annotations
import importlib
import os
import shutil
import sys
import tempfile
from pathlib import Path
from typing import ClassVar
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
sys.path.insert(0, _SRC)
import cleveragents # noqa: E402
importlib.reload(cleveragents)
from cleveragents.application.services.config_service import ConfigService # noqa: E402
from cleveragents.application.services.faiss_vector_backend import ( # noqa: E402
FAISSVectorBackend,
FAISSVectorIndexBackend,
)
from cleveragents.application.services.vector_store_service import ( # noqa: E402
FAISS,
VectorStoreService,
)
from cleveragents.config.settings import Settings # noqa: E402
from cleveragents.infrastructure.database.unit_of_work import UnitOfWork # noqa: E402
class VectorSearchLatencySuite:
"""Benchmark FAISS-backed ACMS vector indexing and search."""
params: ClassVar[list[int]] = [250, 1000]
param_names: ClassVar[list[str]] = ["documents"]
timeout = 120
def setup(self, documents: int) -> None:
if FAISS is None:
raise RuntimeError("FAISS is required for this benchmark")
self._saved_env = {
key: os.environ.get(key)
for key in (
"CLEVERAGENTS_INDEX_VECTOR_BACKEND",
"CLEVERAGENTS_INDEX_VECTOR_DIR",
"CLEVERAGENTS_EMBEDDING_PROVIDER",
"CLEVERAGENTS_EMBEDDING_DIMENSIONS",
)
}
self._tempdir = tempfile.mkdtemp(prefix="asv-faiss-vector-")
os.environ["CLEVERAGENTS_INDEX_VECTOR_BACKEND"] = "faiss"
os.environ["CLEVERAGENTS_INDEX_VECTOR_DIR"] = self._tempdir
os.environ["CLEVERAGENTS_EMBEDDING_PROVIDER"] = "fake"
os.environ["CLEVERAGENTS_EMBEDDING_DIMENSIONS"] = "32"
service = VectorStoreService(
Settings(),
UnitOfWork("sqlite:///:memory:", require_confirmation=False),
ConfigService(),
)
self._index_backend = FAISSVectorIndexBackend(service)
self._vector_backend = FAISSVectorBackend(service)
self._query = [1.0, 2.0, 3.0]
self._scope = frozenset({f"RES{i:04d}" for i in range(min(documents, 32))})
for i in range(documents):
vector = [float(i % 11), float((i * 3) % 17), float((i * 5) % 19)]
self._index_backend.index_embedding(
"local/bench",
f"uko:{i:04d}",
vector,
{
"resource_id": f"RES{i:04d}",
"location": f"src/file_{i:04d}.py",
"resource_type": "python",
},
)
def teardown(self, documents: int) -> None:
_ = documents
shutil.rmtree(self._tempdir, ignore_errors=True)
for key, value in self._saved_env.items():
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
def time_project_search(self, documents: int) -> None:
_ = documents
self._index_backend.search_similar("local/bench", self._query, limit=20)
def time_scoped_similarity_search(self, documents: int) -> None:
_ = documents
self._vector_backend.similarity_search(
self._query,
scope=self._scope,
top_k=20,
)