
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
rag_embeddings is a native Ruby library for efficient storage and comparison of AI-generated embedding vectors (float arrays) using high-performance C extensions. It is designed for seamless integration with external LLMs (Ollama, OpenAI, Mistral, etc) and works perfectly for RAG (Retrieval-Augmented Generation) applications.
langchainrb
(for embedding)ollama
is used as LLM so it must be active and working, although there are some workaroundssqlite3
(for storage)Requires a working C compiler in order to build the native extension
gem install rag_embeddings
If you'd rather install it using bundler, add a line for it in your Gemfile (but set the require option to false, as it is a standalone tool):
gem "rag_embeddings", require: false
require "rag_embeddings"
embedding = RagEmbeddings.embed("Hello world, this is RAG!")
# embedding is a float array
The default model is llama3.2 but you can set another one (reload the console as the llm is memoized):
embedding = RagEmbeddings.embed("Hello world, this is RAG!", model: 'qwen3:0.6b')
c_embedding = RagEmbeddings::Embedding.from_array(embedding)
puts "Dimension: #{c_embedding.dim}"
# Dimension: 1024 # qwen3:0.6b
# Dimension: 3072 # llama3.2
puts "Ruby array: #{c_embedding.to_a.inspect}"
emb1 = RagEmbeddings.embed("Hello world!")
emb2 = RagEmbeddings.embed("Hi universe!")
obj1 = RagEmbeddings::Embedding.from_array(emb1)
obj2 = RagEmbeddings::Embedding.from_array(emb2)
sim = obj1.cosine_similarity(obj2)
puts "Cosine similarity: #{sim}" # Value between -1 and 1
db = RagEmbeddings::Database.new("embeddings.db")
db.insert("Hello world!", RagEmbeddings.embed("Hello world!"))
db.insert("Completely different sentence", RagEmbeddings.embed("Completely different sentence"))
# Find the most similar text to a query
result = db.top_k_similar("Hello!", k: 1)
puts "Most similar text: #{result.first[1]}, score: #{result.first[2]}"
# load all .txt files
files = Dir["./docs/*.txt"].map { |f| [File.basename(f), File.read(f)] }
db = RagEmbeddings::Database.new("knowledge_base.db")
files.each do |name, text|
vector = RagEmbeddings.embed(text)
db.insert(name, vector)
end
puts "Indexed #{files.size} documents."
require "openai" # or your favorite LLM client
# 1) build or open your vector store
db = RagEmbeddings::Database.new("knowledge_base.db")
# 2) embed your user question
client = OpenAI::Client.new(api_key: ENV.fetch("OPENAI_API_KEY"))
q_embedding = client.embeddings(
parameters: {
model: "text-embedding-ada-002",
input: "What are the benefits of retrieval-augmented generation?"
}
).dig("data", 0, "embedding")
# 3) retrieve top-3 relevant passages
results = db.top_k_similar(q_embedding, k: 3)
# 4) build a prompt for your LLM
context = results.map { |id, text, score| text }.join("\n\n---\n\n")
prompt = <<~PROMPT
You are an expert.
Use the following context to answer the question:
CONTEXT:
#{context}
QUESTION:
What are the benefits of retrieval-augmented generation?
PROMPT
# 5) call the LLM for final answer
response = client.chat(
parameters: {
model: "gpt-4o",
messages: [{ role: "user", content: prompt }]
}
)
puts response.dig("choices", 0, "message", "content")
# use SQLite :memory: for ephemeral experiments
db = RagEmbeddings::Database.new(":memory:")
# insert & search exactly as with a file-backed DB
db.insert("Quick test", RagEmbeddings.embed("Quick test"))
db.top_k_similar("Test", k: 1)
rag_embeddings combines the simplicity of Ruby with the performance of C to deliver fast vector operations for RAG applications.
The library uses a hybrid memory-storage approach:
C Extension (embedding.c
)
Ruby Interface
SQLite Storage
:memory:
) databasesEmbedding.from_array()
Performance: Critical operations run in optimized C code, delivering significant speed improvements over pure Ruby implementations.
Memory Efficiency: While embeddings are stored in SQLite, all vector computations happen in memory, avoiding I/O bottlenecks during similarity calculations.
Simplicity: SQLite eliminates the need for complex vector database setups while maintaining good performance for moderate-scale applications.
Portability: The entire knowledge base fits in a single SQLite file, making deployment and backup trivial.
For applications requiring millions of vectors, consider specialized vector databases (Faiss, sqlite-vss) while using this library for prototyping and smaller-scale production use.
If you need to customize the c part (ext/rag_embeddings/embedding.c
), recompile it with:
rake compile
To run all specs (RSpec required):
bundle exec rspec
bundle exec rspec spec/performance_spec.rb
You'll get something like this in random order:
Performance test with embedding size: 768
Embedding creation (10000 times): 19 ms
Cosine similarity (10000 times): 27 ms
RSS: 132.3 MB
Memory usage test with embedding size: 768
Memory usage delta: 3.72 MB for 10000 embeddings
Performance test with embedding size: 2048
Embedding creation (10000 times): 69 ms
Cosine similarity (10000 times): 73 ms
RSS: 170.08 MB
Memory usage test with embedding size: 2048
Memory usage delta: 25.11 MB for 10000 embeddings
Performance test with embedding size: 3072
Embedding creation (10000 times): 98 ms
Cosine similarity (10000 times): 112 ms
RSS: 232.97 MB
Memory usage test with embedding size: 3072
Memory usage delta: 60.5 MB for 10000 embeddings
Performance test with embedding size: 4096
Embedding creation (10000 times): 96 ms
Cosine similarity (10000 times): 140 ms
RSS: 275.2 MB
Memory usage test with embedding size: 4096
Memory usage delta: 92.41 MB for 10000 embeddings
Open an issue or contact the maintainer for questions, suggestions, or bugs.
Happy RAG! ๐
FAQs
Unknown package
We found that rag_embeddings demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.