Search by

illuma-law / laravel-semantic-deduper

miguelenes

Blazing-fast, generic semantic deduplication for Laravel collections and arrays.

Package info

github.com/eloquage/laravel-semantic-deduper

pkg:composer/illuma-law/laravel-semantic-deduper

Statistics

Installs: 64

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 2

v0.1.5 2026-10-23 14:04 UTC

README

Laravel Semantic Deduper vector clusters

Group and deduplicate Laravel search or RAG results using cosine similarity of their embedding vectors. Also includes fuzzy string deduplication and text chunking utilities.

Tests Latest Version License

Requires PHP 8.3+ and Laravel 11, 12, or 13.

Install

composer require illuma-law/laravel-semantic-deduper
php artisan vendor:publish --tag=semantic-deduper-config

Cluster results

Pass items with an embedding vector and a group key. The clusterer removes near-duplicates, limits each group, and returns the retained items as DTOs.

use IllumaLaw\SemanticDeduper\SemanticClusterer;

$results = [
    ['id' => 1, 'source' => 'web', 'embedding' => [0.1, 0.2, 0.3]],
    ['id' => 2, 'source' => 'web', 'embedding' => [0.11, 0.19, 0.31]],
    ['id' => 3, 'source' => 'docs', 'embedding' => [0.8, 0.3, -0.2]],
];

$grouped = SemanticClusterer::make()
    ->groupBy('source')
    ->threshold(0.95)
    ->maxPerGroup(3)
    ->cluster($results);

$items = $grouped->allItems();
$ids = $grouped->collectIdentifiers();

Defaults for the threshold and result limits are in config/semantic-deduper.php. Use embeddingKey() or idKey() if your input uses different field names.

Utilities

Laravel collections include the dedupeFuzzy macro after package discovery:

$unique = collect(['Laravel', 'Laraval', 'Symfony'])
    ->dedupeFuzzy(fn (string $name) => $name, threshold: 85);

Split text into overlapping character-based chunks:

use IllumaLaw\SemanticDeduper\Utils\TextChunker;

$chunks = TextChunker::chunk($text, chunkSize: 1200, overlap: 150);

Test

composer test
composer analyse
vendor/bin/pint --test

MIT licensed. See LICENSE.