← All posts

Geek Out Time: Play with LangChain 3 — Simulate Full RAG Locally with word2vec and Gemma

Apr 2024·~800 words in full

Geek Out Time: Play with LangChain 3 — Simulate RAG Fully Locally with word2vec and Gemma

With the Apple researchers’ unveiling of ReALM, following Gemma from Google, Llama from Meta, and a couple of others from Microsoft, running LLM applications fully locally is attracting more and more attention. I tried running Langchain with Gemma locally in “ Geek Out Time: Play with LangChain 2- locally with Gemma ”. The missing piece was the embedding. To run the entire RAG simulation locally, I added the word2vec embedding in the code below.

import json import numpy as np from gensim.models import KeyedVectors from langchain_community.llms import Ollama import logging # Configure basic logging logging.basicConfig(level=logging.INFO) # Function to compute embeddings using a pre-trained Word2Vec model def compute_embeddings ( text, embedding_model ): words = [word for word in text.split() if word in embedding_model.key_to_index] if words: return np.mean([embedding_model[word] for word in words], axis= 0 ) else : return np.zeros(embedding_model.vector_size) # Load the pre-trained Word2Vec embeddings try : model_path = 'GoogleNews-vectors-negative300.bin' # Correct path to your downloaded model embedding_model = KeyedVectors.load_word2vec_format(model_path, binary= True ) except Exception as e: logging.error( f"Failed to load Word2Vec model: {e} " ) # Load data from JSON try : with open ( 'my_data.json' , 'r' ) as file: data = json.load(file) except Exception as e: logging.error( f"Error loading JSON data: {e} " ) data = [] def simulate_rag ( data, prompt ): matches = [] threshold = 0.4 # Example threshold for cosine similarity prompt_embedding = compute_embeddings(prompt, embedding_model) for passage in data: combined_text = f" {passage[ 'title' ]} {passage[ 'content' ]} " .lower() passage_embedding = compute_embeddings(combined_text, embedding_model) similarity = np.dot(prompt_embedding, passage_embedding) / (np.linalg.norm(prompt_embedding) * np.linalg.norm(passage_embedding)) print ( f"passage: {passage} " ) print ( f"Similarity: {similarity} " ) if similarity > threshold: matches.append(passage) return matches[: 2 ] # Return top 2 retrieved passages prompt = "What does Nedved Yang like to eat? Can you suggest any place in Singapore for him to eat? " # Retrieve relevant passages from local data retrieved_passages = simulate_rag(data, prompt) print ( f"**retrieved_passages:**\n {retrieved_passages} " ) # Construct the prompt for the LLM llm_prompt = f"User Query: {prompt} \n\nRetrieved Information:\n" for passage in retrieved_passages: llm_prompt += f"- {passage[ 'title' ]} :\n - {passage[ 'content' ]} \n - Source: {passage[ 'source' ]} \n" print ( f"**LLM Prompt:**\n {llm_prompt} " ) llm = Ollama(model= "gemma:2b" ) llm_response = llm.invoke(llm_prompt) # Replace with your LLM interaction method final_response = f"**LLM Response:**\n {llm_response} " # Print the final response print (final_response) My_data.json is copied below.

This is an excerpt — the full article continues on Medium.

Read the full article on Medium →

© 2026 Nedved Yang

Vibe-coded with AI + Next.js + Tailwind CSS

Singapore