Module: Legion::Guardrails::EmbeddingSimilarity

Defined in:
lib/legion/guardrails.rb

Class Method Summary collapse

Class Method Details

.check(input, safe_embeddings:, threshold: 0.3) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/legion/guardrails.rb', line 9

def check(input, safe_embeddings:, threshold: 0.3)
  return { safe: true, reason: 'no embeddings service' } unless defined?(Legion::LLM) && Legion::LLM.respond_to?(:embed)

  input_vec = Legion::LLM.embed(input)
  return { safe: true, reason: 'embedding failed' } unless input_vec

  min_dist = safe_embeddings.map { |se| cosine_distance(input_vec, se) }.min || 1.0
  safe = min_dist <= threshold
  if !safe && defined?(Legion::Logging)
    Legion::Logging.warn "[Guardrails] EmbeddingSimilarity rejected input: distance=#{min_dist.round(4)} threshold=#{threshold}"
  end
  { safe: safe, distance: min_dist.round(4), threshold: threshold }
end

.cosine_distance(vec_a, vec_b) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/legion/guardrails.rb', line 23

def cosine_distance(vec_a, vec_b)
  return 1.0 if vec_a.nil? || vec_b.nil? || vec_a.empty? || vec_b.empty?

  dot = vec_a.zip(vec_b).sum { |x, y| (x || 0) * (y || 0) }
  mag_a = Math.sqrt(vec_a.sum { |x| x**2 })
  mag_b = Math.sqrt(vec_b.sum { |x| x**2 })
  return 1.0 if mag_a.zero? || mag_b.zero?

  1.0 - (dot / (mag_a * mag_b))
end