Module: SwarmSDK::V3::Memory::Adapters::VectorUtils

Included in:
Loop::Executor, FilesystemAdapter, SqliteAdapter
Defined in:
lib/swarm_sdk/v3/memory/adapters/vector_utils.rb

Overview

Default in-memory vector math for adapters

Provides a pure-Ruby cosine similarity implementation that adapters can include when they don’t have a native vector engine. The FilesystemAdapter includes this module because its FAISS index only handles indexed top-k search — it cannot compute pairwise similarity between two arbitrary vectors.

**When to use this module:** Include it if your adapter stores embeddings as Ruby arrays and doesn’t have a native way to compute pairwise similarity. This is the common case for file-based, SQLite, or simple database adapters.

**When NOT to use this module:** If your storage backend has native vector operations, implement Base#similarity directly using the backend’s operator. Examples:

  • pgvector: ‘SELECT 1 - (a <=> b)` (cosine distance operator)

  • Qdrant/Pinecone: Use the client’s similarity API

  • **Redis with RediSearch**: ‘FT.SEARCH` with vector scoring

In those cases you skip this module entirely and write your own ‘similarity` method that delegates to the backend.

Examples:

Including in a custom adapter

class SqliteAdapter < SwarmSDK::V3::Memory::Adapters::Base
  include SwarmSDK::V3::Memory::Adapters::VectorUtils

  # similarity() is now available via VectorUtils
  # Override vector_search with your own indexed search
end

NOT including — pgvector adapter

class PgvectorAdapter < SwarmSDK::V3::Memory::Adapters::Base
  def similarity(embedding_a, embedding_b)
    # Compute server-side using pgvector's cosine distance
    result = @db.exec_params(
      "SELECT 1 - ($1::vector <=> $2::vector) AS sim",
      [embedding_a.to_s, embedding_b.to_s]
    )
    result[0]["sim"].to_f
  end
end

Instance Method Summary collapse

Instance Method Details

#similarity(embedding_a, embedding_b) ⇒ Float

Compute cosine similarity between two embedding vectors

This is a pure-Ruby implementation suitable for in-memory use. It computes: dot(a, b) / (||a|| * ||b||)

For production adapters with native vector engines, override this method to delegate to the backend instead.

Examples:

sim = adapter.similarity(card_a.embedding, card_b.embedding)
puts "Cards are duplicates" if sim > 0.92

Parameters:

  • embedding_a (Array<Float>)

    First embedding vector

  • embedding_b (Array<Float>)

    Second embedding vector

Returns:

  • (Float)

    Cosine similarity (-1.0 to 1.0)



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/swarm_sdk/v3/memory/adapters/vector_utils.rb', line 66

def similarity(embedding_a, embedding_b)
  dot = 0.0
  mag_a = 0.0
  mag_b = 0.0

  embedding_a.each_with_index do |va, i|
    vb = embedding_b[i]
    dot += va * vb
    mag_a += va * va
    mag_b += vb * vb
  end

  mag_a = Math.sqrt(mag_a)
  mag_b = Math.sqrt(mag_b)
  return 0.0 if mag_a.zero? || mag_b.zero?

  dot / (mag_a * mag_b)
end