Skip to main content
Version: Next

Registering a Custom Embedding Usage

A usage is a named search capability — semantic_text_search, image_dedup, and so on — that usages.<name> in the configuration maps to a model. The bundle ships four usages; register your own when a bundle or app needs a capability of its own (e.g. a data-hub-simple-rest index owner adding a domain-specific search).

Implement the interface​

<?php
declare(strict_types=1);

namespace App\Embedding;

use Pimcore\Bundle\BackendPowerToolsBundle\Contracts\Embedding\EmbeddingUsageDefinitionInterface;

final readonly class ProductSimilarityUsage implements EmbeddingUsageDefinitionInterface
{
public function getName(): string
{
return 'product_similarity';
}

public function getElementTypes(): array
{
return ['object'];
}

public function getTranslationKey(): string
{
return 'embedding-configuration.usage.product_similarity';
}
}

No service tagging is needed: EmbeddingUsageDefinitionInterface carries #[AutoconfigureTag('pimcore.bpt.embedding_usage')], so any service implementing it is registered automatically as long as your bundle or app has autoconfiguration enabled (the Symfony default).

What each method controls​

  • getName() is the canonical, snake_case name — the exact string usages.<name> refers to in configuration, and what the Studio Usages tab lists once your definition is registered. Registration requires the name to match /^[a-z][a-z0-9_]*$/ (snake_case, no dashes); dashes are canonicalized to underscores only during lookups (has(), config validation).
  • getElementTypes() — 'asset', 'object', or both — decides which element types this usage is even considered for.
  • getTranslationKey() is the Studio UI label. Add the key to your bundle's translations/studio.*.yaml (or the app's, e.g. translations/studio.en.yaml) — a missing key falls back to the raw key text.

Consuming the mapped model​

Once usages.<name> maps your usage to a model, read it through EmbeddingModelRegistryInterface::getModelForUsage() (documents) and getQueryModelForUsage() (incoming queries) — the same seam the built-in usages use. Check hasUsage() first: an unmapped usage means the capability is switched off, not an error, so gate on it rather than catching the exception getModelForUsage() throws for an unmapped or unknown-model usage.

caution

Embeddings are an experimental feature. EmbeddingUsageDefinitionInterface is public API for this extension point, but may still change in breaking ways between releases.