PHPackages                             rivicore/module-semantiq - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. rivicore/module-semantiq

ActiveMagento2-module[Search &amp; Filtering](/categories/search)

rivicore/module-semantiq
========================

Semantic vector search for Adobe Commerce

2.0.6(1mo ago)17↓50%MITPHPPHP ~8.2.0||~8.3.0||~8.4.0

Since Jun 16Pushed 1mo agoCompare

[ Source](https://github.com/bgkavinga/rivicore-semantiq)[ Packagist](https://packagist.org/packages/rivicore/module-semantiq)[ RSS](/packages/rivicore-module-semantiq/feed)WikiDiscussions main Synced 2w ago

READMEChangelogDependencies (18)Versions (8)Used By (0)

Rivicore SemantiQ — Semantic Vector Search for Adobe Commerce
=============================================================

[](#rivicore-semantiq--semantic-vector-search-for-adobe-commerce)

SemantiQ replaces Adobe Commerce's default keyword search with semantic vector search. Instead of matching keywords, it understands the *meaning* of a search query and returns products and CMS pages that are conceptually relevant — even when the exact words do not appear in the product name or description.

When a shopper types "something warm for winter camping", SemantiQ finds sleeping bags, thermal jackets, and base layers rather than only items literally containing those words.

---

Screenshots
-----------

[](#screenshots)

### Search results — "carry things to the gym"

[](#search-results--carry-things-to-the-gym)

[![Search results for 'carry things to the gym'](screenshots/search-results-carry-things-to-gym.png)](screenshots/search-results-carry-things-to-gym.png)

### Search results — "something for my daily commute"

[](#search-results--something-for-my-daily-commute)

[![Search results for 'something for my daily commute'](screenshots/search-results-daily-commute.png)](screenshots/search-results-daily-commute.png)

---

Table of Contents
-----------------

[](#table-of-contents)

1. [Requirements](#requirements)
2. [Installation](#installation)
3. [How It Works](#how-it-works)
4. [Configuration Reference](#configuration-reference)
    - [General Settings](#general-settings)
    - [Vector Store Backend](#vector-store-backend)
    - [Embedding Provider](#embedding-provider)
    - [LLM Provider (RAG)](#llm-provider-rag)
5. [External Service Setup](#external-service-setup)
    - [OpenSearch ML Commons (built-in embeddings)](#1-opensearch-ml-commons-built-in-embeddings)
    - [OpenSearch as Vector Store](#2-opensearch-as-vector-store)
    - [ChromaDB](#3-chromadb)
    - [AWS Bedrock Knowledge Base](#4-aws-bedrock-knowledge-base)
    - [OpenAI](#5-openai)
    - [AWS Bedrock Embeddings (Titan)](#6-aws-bedrock-embeddings-titan)
    - [Ollama (local)](#7-ollama-local)
    - [Anthropic Claude](#8-anthropic-claude)
6. [Indexing](#indexing)
7. [Excluding Entities from the Index](#excluding-entities-from-the-index)
8. [RAG Context Block (Frontend)](#rag-context-block-frontend)
9. [Recommended Combinations](#recommended-combinations)
10. [Troubleshooting](#troubleshooting)

---

Requirements
------------

[](#requirements)

RequirementVersionAdobe Commerce / Magento Open Source2.4.6+PHP8.2, 8.3, or 8.4OpenSearch or Elasticsearch2.x (already required by Magento)Guzzle HTTP7.x (bundled with Magento)Optional (depending on chosen backend):

- AWS account with Bedrock and/or OpenSearch Service
- OpenAI API account
- Anthropic API account
- ChromaDB server
- Ollama installation

---

Installation
------------

[](#installation)

### Via Composer (recommended)

[](#via-composer-recommended)

```
composer require rivicore/module-semantiq
```

If the package is not yet on Packagist, add the VCS repository first:

```
composer config repositories.rivicore-semantiq vcs https://github.com/bgkavinga/rivicore-semantiq
composer require rivicore/module-semantiq
```

### Enable and set up

[](#enable-and-set-up)

```
# 1. Enable the module
bin/magento module:enable Rivicore_SemantiQ

# 2. Apply database schema and data patches
bin/magento setup:upgrade

# 3. Regenerate DI container
bin/magento setup:di:compile

# 4. Flush cache
bin/magento cache:flush
```

After installation, go to **Stores → Configuration → Rivicore → SemantiQ Semantic Search** to configure the module.

---

How It Works
------------

[](#how-it-works)

```
Product/CMS text  ──▶  Embedding Provider  ──▶  float[] vector  ──▶  Vector Store
                                                                            │
Shopper query  ────▶  Embedding Provider  ──▶  float[] vector  ──┐        │
                                                                   └──▶  kNN search  ──▶  Ranked product IDs
                                                                                               │
                                                                            (optional RAG)     │
                                                                   LLM Provider  ◀────────────┘
                                                                        │
                                                                  Context summary  ──▶  Frontend event

```

1. **Indexing** — product and CMS page text is converted to numeric vectors by the embedding provider and stored in the vector store.
2. **Search** — when a shopper submits a query, it is embedded using the same provider, and the vector store returns the nearest neighbours by cosine similarity.
3. **RAG (optional)** — the top results are passed to an LLM, which generates a short contextual summary dispatched as a Magento event for display in a frontend block.

The existing Elasticsearch/OpenSearch search is preserved as an automatic fallback if semantic search is disabled or encounters an error.

---

Configuration Reference
-----------------------

[](#configuration-reference)

Navigate to **Stores → Configuration → Rivicore → SemantiQ Semantic Search**.

---

### General Settings

[](#general-settings)

[![General Settings](screenshots/admin-general-settings.png)](screenshots/admin-general-settings.png)

#### Enable SemantiQ

[](#enable-semantiq)

- **Type**: Yes/No
- **Default**: No
- **What it does**: Master switch. When set to **Yes**, all storefront search queries are routed through the vector search pipeline. When set to **No**, the standard Magento Elasticsearch search is used.
- **Note**: Set up the vector store and run a full reindex *before* enabling this. Enabling with an empty index returns no results.

#### Index Products

[](#index-products)

- **Type**: Yes/No
- **Default**: Yes
- **What it does**: Controls whether products are included in the vector index. Disable this if you only want to use SemantiQ for CMS page search.

#### Index CMS Pages

[](#index-cms-pages)

- **Type**: Yes/No
- **Default**: Yes
- **What it does**: Controls whether CMS pages are included in the vector index. CMS pages appear alongside products in search results.

#### Enable RAG (LLM Context)

[](#enable-rag-llm-context)

- **Type**: Yes/No
- **Default**: No
- **What it does**: When enabled, the top vector search results are sent to the configured LLM provider, which produces a short contextual summary. The summary is dispatched via the Magento event `rivicore_semantiq_rag_context_ready` for use in a frontend block. This does not affect the ranked product results — it only generates an optional explanatory text.
- **Cost warning**: Each search query incurs one additional LLM API call. At high traffic volumes this can be expensive. Consider enabling only for specific pages via a custom observer.

#### Product Attributes to Index

[](#product-attributes-to-index)

- **Type**: Multi-select
- **Default**: `name`, `description`
- **What it does**: The selected product attribute values are concatenated into a single text string, which is then embedded. Adding more attributes gives the model richer context but also increases the text length sent to the embedding provider (and therefore cost/latency for token-based APIs like OpenAI).
- **Recommended attributes**: `name`, `description`, `short_description`, `manufacturer`, `color`, `size`
- **Scope**: Global (per Magento installation, not per store view)

#### Max Search Results

[](#max-search-results)

- **Type**: Integer
- **Default**: 20
- **What it does**: The maximum number of products returned by a vector search. This is the value sent to the vector store as the `k` (number of nearest neighbours) parameter.

---

### Vector Store Backend

[](#vector-store-backend)

The vector store holds the numeric embeddings and performs the k-nearest-neighbour (kNN) search at query time.

[![Vector Store Backend and Embedding Provider](screenshots/admin-vector-store-embedding-provider.png)](screenshots/admin-vector-store-embedding-provider.png)

Navigate to the **Vector Store Backend** group.

#### Backend

[](#backend)

- **Type**: Select
- **Options**: `OpenSearch (built-in)`, `ChromaDB`, `AWS Bedrock Knowledge Base`
- **Default**: `OpenSearch (built-in)`
- **What it does**: Selects where vectors are stored and searched. See [External Service Setup](#external-service-setup) for how to configure each backend.

---

#### OpenSearch fields (shown when Backend = OpenSearch)

[](#opensearch-fields-shown-when-backend--opensearch)

##### OpenSearch Index Name

[](#opensearch-index-name)

- **Type**: Text
- **Default**: `semantiq_vectors`
- **What it does**: The name of the dedicated OpenSearch index used to store vectors. This is separate from Magento's own catalog search index (`magento2_product_1`, etc.) to avoid conflicts. You can change this if the default name conflicts with an existing index.

---

#### ChromaDB fields (shown when Backend = ChromaDB)

[](#chromadb-fields-shown-when-backend--chromadb)

##### ChromaDB URL

[](#chromadb-url)

- **Type**: Text
- **Example**: `http://localhost:8000`
- **What it does**: The base URL of your ChromaDB HTTP server. Must be reachable from the PHP/Magento server. See [ChromaDB setup](#3-chromadb) for installation instructions.

##### ChromaDB Collection Name

[](#chromadb-collection-name)

- **Type**: Text
- **Default**: `semantiq`
- **What it does**: The name of the ChromaDB collection used to store vectors. Created automatically on first index run if it does not already exist.

---

#### AWS Bedrock Knowledge Base fields (shown when Backend = AWS Bedrock Knowledge Base)

[](#aws-bedrock-knowledge-base-fields-shown-when-backend--aws-bedrock-knowledge-base)

##### AWS Region

[](#aws-region)

- **Type**: Text
- **Example**: `us-east-1`
- **What it does**: The AWS region where the Bedrock Knowledge Base is provisioned. Must match the region used when creating the Knowledge Base in the AWS console.

##### Knowledge Base ID

[](#knowledge-base-id)

- **Type**: Text
- **Example**: `ABCDEF1234`
- **What it does**: The unique identifier of the Bedrock Knowledge Base. Found in the AWS console under **Amazon Bedrock → Knowledge Bases**.

##### AWS Access Key ID / AWS Secret Access Key

[](#aws-access-key-id--aws-secret-access-key)

- **Type**: Password (encrypted at rest)
- **What it does**: IAM credentials with permission to call `bedrock:Retrieve`, `bedrock:IngestKnowledgeBaseDocuments`, and `bedrock:DeleteKnowledgeBaseDocuments` on the target Knowledge Base. See [AWS Bedrock Knowledge Base setup](#4-aws-bedrock-knowledge-base) for the required IAM policy.

---

### Embedding Provider

[](#embedding-provider)

The embedding provider converts text into numeric vectors. The same provider must be used for both indexing and search — changing the provider after indexing requires a full reindex.

Navigate to the **Embedding Provider** group.

#### Provider

[](#provider)

- **Type**: Select
- **Options**: `OpenSearch ML Commons (built-in)`, `OpenAI`, `AWS Bedrock (Titan)`, `Ollama (local)`, `Anthropic Claude (experimental)`
- **Default**: `OpenAI`
- **Important**: All documents in the vector store must use vectors from the same provider and model. If you switch providers, you must run `bin/magento indexer:reindex rivicore_semantiq` to rebuild the entire index with the new vectors before re-enabling the module.

---

#### OpenSearch ML Commons fields (shown when Provider = OpenSearch ML Commons)

[](#opensearch-ml-commons-fields-shown-when-provider--opensearch-ml-commons)

##### ML Model ID

[](#ml-model-id)

- **Type**: Text
- **Example**: `bQ1J8ooBpBj3wT4HVemV`
- **What it does**: The ID of the text-embedding model deployed in your OpenSearch cluster via ML Commons. The model must be in `DEPLOYED` status. See [OpenSearch ML Commons setup](#1-opensearch-ml-commons-built-in-embeddings) for how to deploy a model and find its ID.

##### Embedding Dimension

[](#embedding-dimension)

- **Type**: Integer
- **Default**: `768`
- **What it does**: Must match the output dimension of the deployed model exactly. Common values:
    - SBERT / all-MiniLM / BGE-small: `384`
    - most SBERT-large / BGE-base: `768`
    - OpenAI-compatible / BGE-large: `1024` or `1536`
- **Note**: If this does not match the actual model output, the OpenSearch index mapping will reject vectors and indexing will fail.

---

#### OpenAI fields (shown when Provider = OpenAI)

[](#openai-fields-shown-when-provider--openai)

##### OpenAI API Key

[](#openai-api-key)

- **Type**: Password (encrypted at rest)
- **What it does**: Your OpenAI API secret key (`sk-...`). See [OpenAI setup](#5-openai).

##### OpenAI Embedding Model

[](#openai-embedding-model)

- **Type**: Text
- **Default**: `text-embedding-3-small`
- **Options**: ModelDimensionBest for`text-embedding-3-small`1536Best price/quality ratio for most use cases`text-embedding-3-large`3072Highest accuracy, higher cost`text-embedding-ada-002`1536Legacy, lower performance than v3

---

#### AWS Bedrock (Titan) fields (shown when Provider = AWS Bedrock)

[](#aws-bedrock-titan-fields-shown-when-provider--aws-bedrock)

##### AWS Region

[](#aws-region-1)

- **Type**: Text
- **Example**: `us-east-1`

##### Bedrock Embedding Model ID

[](#bedrock-embedding-model-id)

- **Type**: Text
- **Default**: `amazon.titan-embed-text-v2:0`
- **Options**: Model IDDimensionNotes`amazon.titan-embed-text-v2:0`1024Recommended — supports up to 8,192 tokens`amazon.titan-embed-text-v1`1536Older model, max 8,192 tokens`cohere.embed-english-v3`1024English-only, strong performance`cohere.embed-multilingual-v3`1024100+ languages

##### AWS Access Key ID / AWS Secret Access Key

[](#aws-access-key-id--aws-secret-access-key-1)

- **Type**: Password (encrypted at rest)
- **Required IAM permissions**: `bedrock:InvokeModel` on the target model ARN.

---

#### Ollama fields (shown when Provider = Ollama)

[](#ollama-fields-shown-when-provider--ollama)

##### Ollama Base URL

[](#ollama-base-url)

- **Type**: Text
- **Default**: `http://localhost:11434`
- **What it does**: Base URL of the Ollama HTTP server. The PHP/Magento server must be able to reach this URL. If Ollama runs on a different machine, replace `localhost` with the server's IP or hostname.

##### Ollama Embedding Model

[](#ollama-embedding-model)

- **Type**: Text
- **Default**: `nomic-embed-text`
- **Options**: ModelDimensionNotes`nomic-embed-text`768Good general-purpose model, small footprint`mxbai-embed-large`1024Higher accuracy, requires more RAM`bge-m3`1024Multilingual, strong cross-lingual retrieval`all-minilm`384Very fast, lower quality

---

#### Anthropic fields (shown when Provider = Anthropic Claude) — Experimental

[](#anthropic-fields-shown-when-provider--anthropic-claude--experimental)

##### Anthropic API Key

[](#anthropic-api-key)

- **Type**: Password (encrypted at rest)

##### Anthropic Model

[](#anthropic-model)

- **Type**: Text
- **Default**: `claude-haiku-4-5-20251001`
- **Warning**: Anthropic does not provide a dedicated embedding API. This provider sends the text to a Claude model with a structured prompt asking for a JSON float array. This is significantly slower, more expensive, and less accurate than a dedicated embedding model. Use OpenAI, Bedrock, or Ollama for production deployments.

---

### LLM Provider (RAG)

[](#llm-provider-rag)

[![LLM Provider (RAG)](screenshots/admin-llm-provider-rag.png)](screenshots/admin-llm-provider-rag.png)

The LLM provider is only used when **Enable RAG** is set to **Yes**. It takes the top vector search results and the original query and produces a short contextual summary.

All configuration fields mirror the Embedding Provider section — provider selection plus credentials and model name for the chosen provider.

#### Shared RAG Options

[](#shared-rag-options)

##### Max Context Documents

[](#max-context-documents)

- **Type**: Integer
- **Default**: `5`
- **What it does**: How many of the top-ranked search results are included in the LLM context window. Higher values give the LLM more information but increase token usage and latency.

##### RAG Prompt Template

[](#rag-prompt-template)

- **Type**: Textarea
- **Placeholders**: `{{query}}` (the shopper's search query), `{{context}}` (numbered list of top products/pages)
- **Default**: ```
    You are a helpful shopping assistant. Based on the following product information,
    provide a brief and helpful recommendation for the search query "{{query}}".

    Products:
    {{context}}

    Provide a 2-3 sentence summary highlighting the most relevant products for this search.

    ```
- **What it does**: The full prompt sent to the LLM. Customise it to match your brand voice or to focus on specific aspects of the products.

---

External Service Setup
----------------------

[](#external-service-setup)

---

### 1. OpenSearch ML Commons (built-in embeddings)

[](#1-opensearch-ml-commons-built-in-embeddings)

OpenSearch ML Commons allows you to deploy a text-embedding model directly inside your OpenSearch cluster — no external API calls required at search time.

#### Prerequisites

[](#prerequisites)

- OpenSearch 2.4 or later with the ML Commons plugin enabled (it is enabled by default on AWS OpenSearch Service and on the OpenSearch Docker images).
- The cluster must have at least one data node with enough RAM for the model (~1–4 GB depending on model size).

#### Step 1 — Enable ML on all nodes (self-hosted only)

[](#step-1--enable-ml-on-all-nodes-self-hosted-only)

Add this to `opensearch.yml` on every node, then restart:

```
plugins.ml_commons.only_run_on_ml_node: false
plugins.ml_commons.native_memory_threshold: 99
```

For AWS OpenSearch Service, these settings are already configured.

#### Step 2 — Register the model

[](#step-2--register-the-model)

SemantiQ works with any text-embedding model that can be deployed via ML Commons. The full list of pre-built models supported by OpenSearch is available in the [OpenSearch pretrained model catalog](https://docs.opensearch.org/latest/ml-commons-plugin/pretrained-models/). Each entry in the catalog lists the model name, version, format, and — critically — its **embedding dimension**, which you must set in SemantiQ's **Embedding Dimension** field.

The recommended starting point is Hugging Face `sentence-transformers/all-MiniLM-L6-v2` (384 dimensions), which is pre-registered in OpenSearch's model registry.

**Option A: Use the pre-built model registry (recommended)**

```
# Register a pre-built sentence-transformers model (384 dimensions)
POST /_plugins/_ml/models/_register
{
  "name": "huggingface/sentence-transformers/all-MiniLM-L6-v2",
  "version": "1.0.1",
  "model_format": "TORCH_SCRIPT"
}
```

```
# curl equivalent
curl -X POST http://localhost:9200/_plugins/_ml/models/_register \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "huggingface/sentence-transformers/all-MiniLM-L6-v2",
    "version": "1.0.1",
    "model_format": "TORCH_SCRIPT"
  }'
```

The response contains a `task_id`. Check the task status:

```
GET /_plugins/_ml/tasks/
```

```
# curl equivalent
curl -X GET http://localhost:9200/_plugins/_ml/tasks/
```

When `state` is `COMPLETED`, the response includes the `model_id`. Copy this value — you will need it in the SemantiQ admin config.

**Option B: Register a custom model from a URL**

```
POST /_plugins/_ml/models/_register
{
  "name": "my-custom-embedding-model",
  "version": "1.0.0",
  "model_format": "TORCH_SCRIPT",
  "model_task_type": "TEXT_EMBEDDING",
  "model_config": {
    "model_type": "bert",
    "embedding_dimension": 768,
    "framework_type": "sentence_transformers"
  },
  "url": "https://your-server.com/model.zip"
}
```

```
# curl equivalent
curl -X POST http://localhost:9200/_plugins/_ml/models/_register \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "my-custom-embedding-model",
    "version": "1.0.0",
    "model_format": "TORCH_SCRIPT",
    "model_task_type": "TEXT_EMBEDDING",
    "model_config": {
      "model_type": "bert",
      "embedding_dimension": 768,
      "framework_type": "sentence_transformers"
    },
    "url": "https://your-server.com/model.zip"
  }'
```

#### Step 3 — Deploy the model

[](#step-3--deploy-the-model)

```
POST /_plugins/_ml/models//_deploy
```

```
# curl equivalent (local / bare-metal)
curl -X POST http://localhost:9200/_plugins/_ml/models//_deploy

# Docker Compose (service name: opensearch)
curl -X POST http://opensearch:9200/_plugins/_ml/models//_deploy
```

Check deployment status:

```
GET /_plugins/_ml/tasks/
```

```
# curl equivalent (local / bare-metal)
curl -X GET http://localhost:9200/_plugins/_ml/tasks/

# Docker Compose
curl -X GET http://opensearch:9200/_plugins/_ml/tasks/
```

Wait until `state` is `COMPLETED`.

> **Tip — list all models and their deploy status at any time:**
>
> ```
> # local
> curl -X GET http://localhost:9200/_plugins/_ml/models/_search \
>   -H 'Content-Type: application/json' \
>   -d '{"query": {"match_all": {}}, "size": 20}'
>
> # Docker Compose
> curl -X GET http://opensearch:9200/_plugins/_ml/models/_search \
>   -H 'Content-Type: application/json' \
>   -d '{"query": {"match_all": {}}, "size": 20}'
> ```
>
>
>
> Look for `"model_state": "DEPLOYED"` in the response.

#### Step 4 — Verify the model is working

[](#step-4--verify-the-model-is-working)

```
POST /_plugins/_ml/models//predict
{
  "text_docs": ["test product description"]
}
```

```
# curl equivalent (local / bare-metal)
curl -X POST http://localhost:9200/_plugins/_ml/models//predict \
  -H 'Content-Type: application/json' \
  -d '{"text_docs": ["test product description"]}'

# Docker Compose
curl -X POST http://opensearch:9200/_plugins/_ml/models//predict \
  -H 'Content-Type: application/json' \
  -d '{"text_docs": ["test product description"]}'
```

The response should contain an `inference_results` array with a `data` field of floats. Count the floats to confirm the embedding dimension.

#### Step 5 — Configure SemantiQ

[](#step-5--configure-semantiq)

- **Embedding Provider** → `OpenSearch ML Commons (built-in)`
- **ML Model ID** → the `model_id` from step 2
- **Embedding Dimension** → the dimension confirmed in step 4

    Look up the exact value in the [OpenSearch pretrained model catalog](https://docs.opensearch.org/latest/ml-commons-plugin/pretrained-models/) or count the floats in the `data` array from the predict response. Common values: `384` (all-MiniLM-L6-v2, paraphrase-MiniLM), `768` (all-mpnet-base-v2, msmarco-distilbert), `1024` (BGE-large, multilingual-e5-large).

    Set it via CLI to avoid cache issues:

    ```
    bin/magento config:set rivicore_semantiq/embedding/opensearch_ml_dimension
    bin/magento cache:flush
    ```

#### Finding an existing model ID

[](#finding-an-existing-model-id)

```
GET /_plugins/_ml/models/_search
{
  "query": { "match_all": {} },
  "size": 20
}
```

```
# curl equivalent
curl -X GET http://localhost:9200/_plugins/_ml/models/_search \
  -H 'Content-Type: application/json' \
  -d '{"query": {"match_all": {}}, "size": 20}'
```

Look for models with `"model_state": "DEPLOYED"`.

---

### 2. OpenSearch as Vector Store

[](#2-opensearch-as-vector-store)

When **Backend = OpenSearch (built-in)**, SemantiQ creates a dedicated index in the same OpenSearch cluster that Magento already uses. No additional server is required.

#### Prerequisites

[](#prerequisites-1)

- The **k-NN plugin** must be installed. It is included by default in OpenSearch 1.0+ and AWS OpenSearch Service.

Verify the plugin is present:

```
GET /_cat/plugins?v&h=name,component,version
```

```
# curl equivalent
curl -X GET 'http://localhost:9200/_cat/plugins?v&h=name,component,version'
```

Look for a line containing `opensearch-knn`.

#### What SemantiQ creates automatically

[](#what-semantiq-creates-automatically)

When you run the indexer for the first time, SemantiQ creates an index named `semantiq_vectors` (or whatever you configured in **OpenSearch Index Name**) with the following mapping:

```
{
  "settings": {
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "vector":      { "type": "knn_vector", "dimension":  },
      "entity_type": { "type": "keyword" },
      "entity_id":   { "type": "integer" },
      "store_id":    { "type": "integer" },
      "payload":     { "type": "object", "enabled": false }
    }
  }
}
```

No manual index creation is needed. If the index already exists with a different mapping, drop it first:

```
DELETE /semantiq_vectors
```

```
# curl equivalent
curl -X DELETE http://localhost:9200/semantiq_vectors
```

Then rerun the Magento indexer.

---

### 3. ChromaDB

[](#3-chromadb)

ChromaDB is an open-source, self-hosted vector database. It is the simplest option if you prefer not to use the OpenSearch cluster for vector storage.

#### Option A — Docker (recommended)

[](#option-a--docker-recommended)

```
docker run -d \
  --name chromadb \
  -p 8000:8000 \
  -v chroma-data:/chroma/chroma \
  chromadb/chroma:latest
```

Verify it is running:

```
curl http://localhost:8000/api/v1/heartbeat
# Expected: {"nanosecond heartbeat": }
```

#### Option B — pip

[](#option-b--pip)

```
pip install chromadb
chroma run --host 0.0.0.0 --port 8000 --path ./chroma-data
```

#### Option C — Docker Compose

[](#option-c--docker-compose)

```
version: '3.8'
services:
  chromadb:
    image: chromadb/chroma:latest
    ports:
      - "8000:8000"
    volumes:
      - chroma-data:/chroma/chroma
    environment:
      - CHROMA_SERVER_HTTP_PORT=8000
volumes:
  chroma-data:
```

```
docker compose up -d
```

#### Networking

[](#networking)

The ChromaDB server must be reachable from the machine running PHP/Magento. If Magento runs in Docker, use the container name as the hostname, or use the host machine's IP address.

#### Configure SemantiQ

[](#configure-semantiq)

- **Backend** → `ChromaDB`
- **ChromaDB URL** → `http://chromadb:8000` (Docker) or `http://192.168.x.x:8000` (remote server) or `http://localhost:8000` (same machine)
- **ChromaDB Collection Name** → `semantiq` (or any name — created automatically)

#### Persistence

[](#persistence)

Ensure the Docker volume (`chroma-data`) persists across container restarts. Without a volume, the vector index is lost every time the container is restarted.

---

### 4. AWS Bedrock Knowledge Base

[](#4-aws-bedrock-knowledge-base)

AWS Bedrock Knowledge Bases is a fully managed RAG and vector search service. Bedrock handles chunking, embedding, and vector storage automatically. SemantiQ uses it in "ingest + retrieve" mode, bypassing Bedrock's built-in RAG generation in favour of its own LLM provider.

#### Step 1 — Create a Knowledge Base in the AWS Console

[](#step-1--create-a-knowledge-base-in-the-aws-console)

1. Open the **AWS Console** → **Amazon Bedrock** → **Knowledge Bases** → **Create knowledge base**.
2. **Name**: e.g. `semantiq-products`
3. **IAM role**: Let AWS create a new role, or use an existing one.
4. **Data source**: Choose **Inline** (SemantiQ pushes documents directly via the API, no S3 bucket needed).
5. **Embedding model**: Choose `Amazon Titan Text Embeddings V2` (or any supported model — note the dimension).
6. **Vector store**: Choose `Amazon OpenSearch Serverless` (AWS-managed) or bring your own OpenSearch/Pinecone/RDS Aurora cluster.
7. Complete creation and note the **Knowledge Base ID** (format: `ABCDEF1234`).

#### Step 2 — Create an IAM User with the required permissions

[](#step-2--create-an-iam-user-with-the-required-permissions)

In **IAM → Users → Create user**:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:Retrieve",
        "bedrock:IngestKnowledgeBaseDocuments",
        "bedrock:DeleteKnowledgeBaseDocuments",
        "bedrock:GetKnowledgeBase"
      ],
      "Resource": "arn:aws:bedrock:::knowledge-base/"
    }
  ]
}
```

Create an **Access Key** for this user and note the Access Key ID and Secret Access Key.

#### Step 3 — Configure SemantiQ

[](#step-3--configure-semantiq)

- **Backend** → `AWS Bedrock Knowledge Base`
- **AWS Region** → the region where the Knowledge Base was created (e.g. `us-east-1`)
- **Knowledge Base ID** → the ID from step 1 (e.g. `ABCDEF1234`)
- **AWS Access Key ID** / **AWS Secret Access Key** → from step 2

#### Step 4 — Install the AWS SDK

[](#step-4--install-the-aws-sdk)

The AWS SDK is not bundled with Magento. Install it:

```
composer require aws/aws-sdk-php
```

---

### 5. OpenAI

[](#5-openai)

#### Step 1 — Create an API key

[](#step-1--create-an-api-key)

1. Go to [platform.openai.com/api-keys](https://platform.openai.com/api-keys).
2. Click **Create new secret key**.
3. Give it a name (e.g. `semantiq-magento`) and click **Create secret key**.
4. Copy the key immediately — it is only shown once.

#### Step 2 — Set billing limits (recommended)

[](#step-2--set-billing-limits-recommended)

1. In the OpenAI dashboard, go to **Settings → Billing → Usage limits**.
2. Set a **monthly budget** to prevent unexpected charges. Embedding calls are inexpensive ($0.02–$0.13 per million tokens depending on model), but a large catalog with frequent reindexing can add up.

#### Step 3 — Configure SemantiQ

[](#step-3--configure-semantiq-1)

- **Embedding Provider** → `OpenAI`
- **OpenAI API Key** → the key from step 1
- **OpenAI Embedding Model** → `text-embedding-3-small` (recommended) or `text-embedding-3-large`

#### Cost estimate

[](#cost-estimate)

`text-embedding-3-small` costs $0.02 per million tokens. A typical product description with name is ~100 tokens. A catalog of 10,000 products ≈ 1 million tokens ≈ **$0.02 per full reindex**. Daily incremental updates cost a fraction of this.

---

### 6. AWS Bedrock Embeddings (Titan)

[](#6-aws-bedrock-embeddings-titan)

Use this when you prefer to keep data within AWS and do not want to send product information to a third party.

#### Step 1 — Enable model access in AWS Bedrock

[](#step-1--enable-model-access-in-aws-bedrock)

1. Open the **AWS Console** → **Amazon Bedrock** → **Model access**.
2. Click **Manage model access**.
3. Enable **Amazon Titan Text Embeddings V2** (and any other models you plan to use).
4. Click **Save changes**. Access is granted immediately for Titan models.

#### Step 2 — Create an IAM User

[](#step-2--create-an-iam-user)

In **IAM → Users → Create user**:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["bedrock:InvokeModel"],
      "Resource": [
        "arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0",
        "arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v1",
        "arn:aws:bedrock:*::foundation-model/cohere.embed-english-v3",
        "arn:aws:bedrock:*::foundation-model/cohere.embed-multilingual-v3"
      ]
    }
  ]
}
```

Create an **Access Key** for the user.

#### Step 3 — Install the AWS SDK

[](#step-3--install-the-aws-sdk)

```
composer require aws/aws-sdk-php
```

#### Step 4 — Configure SemantiQ

[](#step-4--configure-semantiq)

- **Embedding Provider** → `AWS Bedrock (Titan)`
- **AWS Region** → e.g. `us-east-1` (must be a region where Bedrock is available)
- **Bedrock Embedding Model ID** → `amazon.titan-embed-text-v2:0` (recommended)
- **AWS Access Key ID** / **AWS Secret Access Key** → from step 2

#### Input limits

[](#input-limits)

ModelMax input tokens`amazon.titan-embed-text-v2:0`8,192`amazon.titan-embed-text-v1`8,192`cohere.embed-english-v3`512If product descriptions exceed the token limit, the text is silently truncated by the API. Configure **Product Attributes to Index** to keep concatenated text under the limit.

---

### 7. Ollama (local)

[](#7-ollama-local)

Ollama runs open-source embedding models completely locally. No internet connection, no API keys, no per-token cost. Suitable for development, on-premise deployments, or privacy-sensitive catalogs.

#### Step 1 — Install Ollama

[](#step-1--install-ollama)

**macOS:**

```
brew install ollama
# or download from https://ollama.com/download
```

**Linux:**

```
curl -fsSL https://ollama.com/install.sh | sh
```

**Windows:** Download the installer from [ollama.com/download](https://ollama.com/download).

#### Step 2 — Pull an embedding model

[](#step-2--pull-an-embedding-model)

```
# Recommended: nomic-embed-text (768 dimensions, ~274 MB)
ollama pull nomic-embed-text

# Higher quality (1024 dimensions, ~670 MB)
ollama pull mxbai-embed-large

# Multilingual (1024 dimensions, ~1.2 GB)
ollama pull bge-m3
```

#### Step 3 — Start the Ollama server

[](#step-3--start-the-ollama-server)

```
ollama serve
```

The server starts on `http://localhost:11434` by default. To listen on all interfaces (so other machines can reach it):

```
OLLAMA_HOST=0.0.0.0 ollama serve
```

Verify it is running:

```
curl http://localhost:11434/api/embeddings \
  -d '{"model": "nomic-embed-text", "prompt": "test"}'
```

The response should contain an `embedding` field with 768 floats.

#### Step 4 — Run as a system service (Linux)

[](#step-4--run-as-a-system-service-linux)

```
sudo systemctl enable ollama
sudo systemctl start ollama
```

#### Step 5 — Configure SemantiQ

[](#step-5--configure-semantiq-1)

- **Embedding Provider** → `Ollama (local)`
- **Ollama Base URL** → `http://localhost:11434` (or the server's IP if running remotely)
- **Ollama Embedding Model** → `nomic-embed-text`

#### RAM requirements

[](#ram-requirements)

ModelDiskRAM needed`all-minilm`~46 MB~256 MB`nomic-embed-text`~274 MB~512 MB`mxbai-embed-large`~670 MB~1 GB`bge-m3`~1.2 GB~2 GB---

### 8. Anthropic Claude

[](#8-anthropic-claude)

#### Step 1 — Create an API key

[](#step-1--create-an-api-key-1)

1. Go to [console.anthropic.com](https://console.anthropic.com).
2. Navigate to **API Keys** → **Create Key**.
3. Name it (e.g. `semantiq-magento`) and copy the key.

#### Step 2 — Add credits

[](#step-2--add-credits)

Anthropic requires prepaid credits. Go to **Billing** → **Add credits** and add at least $5 to start.

#### Step 3 — Configure SemantiQ

[](#step-3--configure-semantiq-2)

For **LLM / RAG**:

- **LLM Provider** → `Anthropic Claude`
- **Anthropic API Key** → key from step 1
- **Anthropic Model** → `claude-haiku-4-5-20251001` (fastest/cheapest) or `claude-sonnet-4-6` (higher quality)

For **Embedding** (experimental only — not recommended for production):

- **Embedding Provider** → `Anthropic Claude (experimental)`
- **Anthropic API Key** → same key
- **Anthropic Model** → `claude-haiku-4-5-20251001`

**Why embedding via Anthropic is experimental**: Anthropic does not offer a dedicated vector embedding API. SemantiQ works around this by prompting Claude to output a JSON float array, but this approach is slow (~1–3 seconds per product), expensive (chat token pricing vs. embedding pricing), and produces inconsistent vector quality. Use a dedicated embedding provider instead.

---

Indexing
--------

[](#indexing)

The SemantiQ indexer converts product and CMS page text into vectors and stores them in the configured vector store.

### Full reindex

[](#full-reindex)

Run this after initial setup or after changing the embedding provider or indexed attributes:

```
bin/magento indexer:reindex rivicore_semantiq
```

This re-embeds every enabled, visible, non-excluded product across all store views, and every active non-excluded CMS page. For a catalog of 10,000 products, expect 5–30 minutes depending on the embedding provider's latency.

### Incremental reindex (automatic)

[](#incremental-reindex-automatic)

SemantiQ subscribes to changes in the following database tables via Magento's MView (materialised view) system:

- `catalog_product_entity` and EAV attribute tables — triggers on product saves
- `cms_page` — triggers on CMS page saves

When a product or CMS page is saved in the admin, it is added to the reindex backlog and processed by the next cron run.

To process the backlog immediately:

```
bin/magento indexer:reindex rivicore_semantiq
```

### Indexer status

[](#indexer-status)

```
bin/magento indexer:status rivicore_semantiq
```

### Check indexed document count

[](#check-indexed-document-count)

```
# MySQL
SELECT entity_type, store_id, COUNT(*) as count
FROM rivicore_semantiq_index
GROUP BY entity_type, store_id;
```

---

Excluding Entities from the Index
---------------------------------

[](#excluding-entities-from-the-index)

### Excluding a product

[](#excluding-a-product)

1. Open the product in **Catalog → Products → Edit**.
2. Scroll to the **Search Engine Optimization** section.
3. Set **Exclude from SemantiQ Index** to **Yes**.
4. Save the product.

The product is removed from the vector store on the next reindex.

### Excluding a CMS page

[](#excluding-a-cms-page)

1. Open the page in **Content → Pages → Edit**.
2. Scroll to the **Design** section.
3. Set **Exclude from SemantiQ Index** to **Yes**.
4. Save the page.

### Disabling indexing for all products or all CMS pages

[](#disabling-indexing-for-all-products-or-all-cms-pages)

Use the global toggles in **General Settings**:

- **Index Products** → `No` — no products will be indexed (or reindexed)
- **Index CMS Pages** → `No` — no CMS pages will be indexed (or reindexed)

---

RAG Context Block (Frontend)
----------------------------

[](#rag-context-block-frontend)

When **Enable RAG** is set to **Yes**, SemantiQ dispatches a Magento event after each successful search:

```
rivicore_semantiq_rag_context_ready

```

**Event data:**

- `query` — the original search query string
- `context` — the LLM-generated summary paragraph
- `results` — array of `VectorSearchResultInterface` objects

To display the context on the search results page, create an observer in your theme or custom module:

```

```

```
// Observer/SemantiQContextObserver.php
class SemantiQContextObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        $context = $observer->getData('context');
        // Store in registry, session, or cache for the block to read
        $this->registry->register('semantiq_rag_context', $context);
    }
}
```

---

Recommended Combinations
------------------------

[](#recommended-combinations)

Use caseVector StoreEmbeddingLLM (RAG)Quickest setup, no extra infraOpenSearch (built-in)OpenSearch ML CommonsOpenAIBest accuracy, affordableOpenSearchOpenAI `text-embedding-3-small`OpenAI `gpt-4o-mini`All data stays in AWSBedrock KBBedrock Titan V2Bedrock Claude HaikuFully on-premise, no external callsOpenSearchOllama `nomic-embed-text`Ollama `llama3`Development / local testingChromaDBOllama `nomic-embed-text`Ollama `llama3`---

Troubleshooting
---------------

[](#troubleshooting)

### Search returns no results after enabling

[](#search-returns-no-results-after-enabling)

1. Check the indexer ran successfully: `bin/magento indexer:status rivicore_semantiq`
2. Check the index has documents: `SELECT COUNT(*) FROM rivicore_semantiq_index;`
3. Check `var/log/system.log` and `var/log/exception.log` for embedding or vector store errors.
4. Verify the embedding provider credentials are correct by checking `var/log/system.log` for `SemantiQ:` prefixed messages.

### `knn_vector` mapping error on OpenSearch

[](#knn_vector-mapping-error-on-opensearch)

The k-NN plugin is not installed or enabled. Verify:

```
GET /_cat/plugins?v
```

```
# curl equivalent
curl -X GET 'http://localhost:9200/_cat/plugins?v'
```

If `opensearch-knn` is missing, install it (self-hosted) or use AWS OpenSearch Service which includes it by default.

### Dimension mismatch error

[](#dimension-mismatch-error)

This error means the **Embedding Dimension** config value does not match the actual output of the deployed model. The log message looks like:

```
Vector dimension mismatch. Expected: 768, Given: 384

```

**Step 1 — Find the correct dimension**

Check the [OpenSearch pretrained model catalog](https://docs.opensearch.org/latest/ml-commons-plugin/pretrained-models/) for the model you deployed. Alternatively, confirm the real dimension by running a test predict call against the deployed model and counting the floats in the response:

```
# local
curl -X POST http://localhost:9200/_plugins/_ml/models//predict \
  -H 'Content-Type: application/json' \
  -d '{"text_docs": ["test"]}' \
  | python3 -c "import sys,json; r=json.load(sys.stdin); print(len(r['inference_results'][0]['output'][0]['data']))"

# Docker Compose (service name: opensearch)
curl -X POST http://opensearch:9200/_plugins/_ml/models//predict \
  -H 'Content-Type: application/json' \
  -d '{"text_docs": ["test"]}' \
  | python3 -c "import sys,json; r=json.load(sys.stdin); print(len(r['inference_results'][0]['output'][0]['data']))"
```

**Step 2 — Update the config to match**

```
bin/magento config:set rivicore_semantiq/embedding/opensearch_ml_dimension
bin/magento cache:flush
```

**Step 3 — Full reindex**

The indexer detects the dimension change, automatically drops and recreates the OpenSearch index with the correct mapping, then re-embeds all documents:

```
bin/magento indexer:reindex rivicore_semantiq
```

No manual index deletion is required — the indexer handles it.

### Switching embedding providers

[](#switching-embedding-providers)

After changing the provider (or model), the existing vectors are incompatible. You must:

1. Set the correct **Embedding Dimension** for the new provider.
2. Disable SemantiQ (`General Settings → Enable SemantiQ → No`).
3. Delete the existing vector index (OpenSearch index, ChromaDB collection, or Bedrock KB documents).
4. Run a full reindex: `bin/magento indexer:reindex rivicore_semantiq`
5. Re-enable SemantiQ.

### AWS SDK not found (Bedrock)

[](#aws-sdk-not-found-bedrock)

```
composer require aws/aws-sdk-php
bin/magento setup:di:compile
bin/magento cache:flush
```

### Ollama connection refused

[](#ollama-connection-refused)

Ensure Ollama is running (`ollama serve`) and the model is pulled (`ollama pull nomic-embed-text`). If Magento runs in Docker, `localhost` in the config refers to the container — use the host machine's IP or Docker network hostname instead.

### Search falls back to Elasticsearch silently

[](#search-falls-back-to-elasticsearch-silently)

All errors in the vector search pipeline are caught and logged, and the request falls through to the standard Elasticsearch search. Check `var/log/system.log` for `SemantiQ:` prefixed error lines to identify the root cause.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance90

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

7

Last Release

46d ago

Major Versions

1.0.0 → 2.0.12026-06-17

### Community

Maintainers

![](https://www.gravatar.com/avatar/00ac5fea5a787b7d184f55b5632d8afe23d2fa420d186cc86f163a2b22d06930?d=identicon)[kavinga](/maintainers/kavinga)

---

Top Contributors

[![kavingas](https://avatars.githubusercontent.com/u/57118500?v=4)](https://github.com/kavingas "kavingas (17 commits)")

### Embed Badge

![Health badge](/badges/rivicore-module-semantiq/health.svg)

```
[![Health](https://phpackages.com/badges/rivicore-module-semantiq/health.svg)](https://phpackages.com/packages/rivicore-module-semantiq)
```

###  Alternatives

[run-as-root/magento2-prometheus-exporter

Magento2 Prometheus Exporter

69362.0k](/packages/run-as-root-magento2-prometheus-exporter)[mollie/magento2

Mollie Payment Module for Magento 2

1152.0M17](/packages/mollie-magento2)[mage-os/module-automatic-translation

Automatic AI content translation for Mage-OS.

3123.7k](/packages/mage-os-module-automatic-translation)[buckaroo/magento2

Buckaroo Magento 2 extension

32426.0k8](/packages/buckaroo-magento2)[doofinder/doofinder-magento2

Doofinder module for Magento 2

13256.9k1](/packages/doofinder-doofinder-magento2)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

293.1k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
