Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
IT Security NachrichtenOnePlus/OxygenOS: Schad-App erhält Root-Zugriff ohne Berechtigungen(24.09.2026 um 23:38 Uhr)
•
IT Security NachrichtenRyuk Member Karen Vardanyan Sentenced to Two Years in U.S. Prison(24.09.2026 um 22:50 Uhr)
•••••
Hacking & PentestingRyuk Member Karen Vardanyan Sentenced to Two Years in U.S. Prison(24.09.2026 um 22:50 Uhr)
•
AI & KI NachrichtenWhy the U.N. Still Matters(24.09.2026 um 23:00 Uhr)
•••
IT Security NachrichtenOnePlus/OxygenOS: Schad-App erhält Root-Zugriff ohne Berechtigungen(24.09.2026 um 23:38 Uhr)
•
IT Security NachrichtenRyuk Member Karen Vardanyan Sentenced to Two Years in U.S. Prison(24.09.2026 um 22:50 Uhr)
•••••
Hacking & PentestingRyuk Member Karen Vardanyan Sentenced to Two Years in U.S. Prison(24.09.2026 um 22:50 Uhr)
•
AI & KI NachrichtenWhy the U.N. Still Matters(24.09.2026 um 23:00 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Embeddings & Vector Search in Rails — Semantic Search with pgvector

Streaming AI responses looks cool. But here's the problem: the AI doesn't know anything about your business. Ask it about your users, orders, or documents and it hallucinates. Embeddings fix this. They turn text into vectors — m…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Streaming AI responses looks cool. But here's the problem: the AI doesn't know anything about your business. Ask it about your users, orders, or documents and it hallucinates.



Embeddings fix this. They turn text into vectors — mathematical fingerprints that capture meaning. Similar ideas cluster together in vector space. Search stops being keyword matching and starts being concept matching.



This post adds semantic search to your Rails app using pgvector and the neighbor gem. By the end, you'll search your content by meaning, not keywords.






What We're Building



A document search where "cloud computing" finds articles about AWS, Azure, and deployment — even if they never use the words "cloud" or "computing".






Setup



First, get pgvector running. If you're on a VPS (which you should be):




# Ubuntu/Debian
sudo apt install postgresql-16-pgvector

# Or use the Docker image
# postgres:16 with pgvector extension






Enable the extension in your database:




CREATE EXTENSION IF NOT EXISTS vector;






Add the gems:




gem 'pgvector'
gem 'neighbor'
gem 'ruby-openai'






bundle install






The Document Model






bin/rails g model Document title:string content:text embedding:vector
bin/rails db:migrate






Your migration needs the vector type. Check that db/migrate/xxx_create_documents.rb looks like:




create_table :documents do |t|
t.string :title
t.text :content
t.vector :embedding, limit: 1536 # OpenAI's embedding dimension
t.timestamps
end









Generating Embeddings



When a document is saved, we automatically generate its embedding vector:




class Document < ApplicationRecord
has_neighbors :embedding

after_save :generate_embedding, if: :saved_change_to_content?

private

def generate_embedding
client = OpenAI::Client.new(
access_token: Rails.application.credentials.openai[:api_key]
)

response = client.embeddings(
parameters: {
model: "text-embedding-3-small",
input: "#{title}\n\n#{content}"
}
)

embedding = response.dig("data", 0, "embedding")
update_column(:embedding, embedding)
end
end






This runs async in production (wrap it in a job), but the logic is the same: text goes in, vector comes out.





Now the good part. Searching by meaning:




class DocumentsController < ApplicationController
def search
return render json: [] if params[:query].blank?

# Convert the query to an embedding
query_embedding = embed_query(params[:query])

# Find nearest neighbors using cosine similarity
@documents = Document.nearest_neighbors(
:embedding,
query_embedding,
distance: "cosine"
).limit(10)

render json: @documents.map { |d|
{
title: d.title,
content: d.content.truncate(200),
similarity: 1 - d.neighbor_distance # Convert distance to similarity
}
}
end

private

def embed_query(text)
client = OpenAI::Client.new(
access_token: Rails.application.credentials.openai[:api_key]
)

response = client.embeddings(
parameters: {
model: "text-embedding-3-small",
input: text
}
)

response.dig("data", 0, "embedding")
end
end






Add the route:




resources :documents do
collection do
get :search
end
end









How It Works





  1. Embedding generation — OpenAI converts text to a 1536-dimensional vector


  2. Storage — pgvector stores vectors efficiently with indexing


  3. Search — neighbor performs cosine similarity in SQL


  4. Results — Closest vectors = most semantically similar content



The magic is in the similarity calculation. Cosine similarity measures the angle between vectors. Two documents about deployment have similar vectors even if they use different words.






Building a Search UI






<%= form_with url: search_documents_path, method: :get, data: { turbo_frame: "results" } do |f| %>
<%= f.text_field :query, placeholder: "Search by meaning..." %>
<%= f.submit "Search" %>
<% end %>

<%= turbo_frame_tag "results" do %>
<% if @documents %>
<% @documents.each do |doc| %>
<div class="result">
<h3><%= doc.title %></h3>
<p><%= doc.content.truncate(200) %></p>
<small>Similarity: <%= (1 - doc.neighbor_distance).round(3) %></small>
</div>
<% end %>
<% end %>
<% end %>









Indexing for Performance



Without an index, vector search scans every row. Add an IVFFlat index:




class AddVectorIndexToDocuments < ActiveRecord::Migration[7.1]
def change
add_index :documents, :embedding, using: :ivfflat, opclass: :vector_cosine_ops, lists: 100
end
end






For datasets under 10k rows, you might skip this. For 100k+, it's essential.






Hybrid Search: Keywords + Vectors



Pure semantic search sometimes misses exact matches. Combine both:




def hybrid_search(query)
# Keyword search with trigram similarity
keyword_results = Document.where(
"content % ? OR title % ?", query, query
).order(Arel.sql("similarity(content, '#{query}') DESC")).limit(20)

# Semantic search
query_embedding = embed_query(query)
semantic_results = Document.nearest_neighbors(
:embedding, query_embedding, distance: "cosine"
).limit(20)

# Reciprocal Rank Fusion — combine both result sets
all_results = (keyword_results + semantic_results).uniq

# Simple RRF: score = 1 / (rank + k)
# Implementation left as exercise, or use a gem
all_results.first(10)
end









Production Considerations



Pre-compute embeddings for common queries — Cache embeddings for your top 100 search terms.



Batch embedding generation — OpenAI supports up to 2048 inputs per request:




def batch_embed(texts)
response = client.embeddings(
parameters: {
model: "text-embedding-3-small",
input: texts
}
)
response.dig("data").map { |d| d["embedding"] }
end






Monitor vector size — 1536 dimensions × 4 bytes = ~6KB per document. Plan storage accordingly.






Next Up



Now you can search by meaning. In the next post, we'll combine this with streaming responses to build a full RAG system — the AI will actually know your data.






Part of the Ruby for AI series. Building AI-powered Rails apps, one post at a time.

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - Embeddings & Vector Search in Rails — Semantic Search with pgvector
id: 1ba7309d-ccfe-4b6b-8c06-e4cc3d474c72
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "Embeddings & Vector Search in " ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Embeddings  Vector Search in Rails  Sema")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Embeddings  Vector Search in Rails  Sema*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Embeddings  Vector Search in Rails  Sema"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Embeddings &amp; Vector Search in Rails — Se.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Embeddings & Vector Search in Rails — Semantic Search with pgvector

Thematisch verwandte Begriffe: Embeddings, Vector, Search, Rails · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-82585 | The Botslab G980H dash camera firmware transmits sensitive information o…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel • Rechts: nächster Artikel • unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...
↗ Original-Quelle