AI Study

Migrating from Python FAISS to Node.js LangChain: A Real-World RAG Integration Experience

jimmmy_jin 2025. 6. 5. 16:09

 

Building a personalized AI chatbot for my portfolio site, I aimed to integrate a Retrieval-Augmented Generation (RAG) system using vector embeddings stored in FAISS. However, this journey turned out to be more complex than expected — especially when trying to align Python-based tools with a Node.js environment.

 

 

🧩 Problem Overview

 

I initially built the RAG logic in Python using langchain, FAISS, and OpenAI. It worked well locally. But when trying to deploy or port the logic into my Vercel-hosted Next.js project, I hit several major roadblocks:

 

 

⚠️ Key Issues

 

  • faiss-node is not actively maintained and fails to install on modern Node.js versions (like Node 20+), especially on ARM-based Macs like the M2.
  • FAISS requires low-level binary compilation, making it problematic for serverless environments like Vercel or Netlify.
  • Keeping a consistent vector index updated across frontend and backend becomes messy without a unified architecture.

 


 

🔁 My Approach & Attempts

 

  1. Initial Setup in Python (Success)
    • Built a RAG PDF chatbot using langchain, PyPDFLoader, and FAISS.
    • Deployed it locally as a script using OpenAI API.
  2.  
  3. Attempted to Port FAISS to Node (faiss-node)
    • Received EINVALIDTAGNAME and compilation errors due to deprecated url.parse() and incompatibility with Node 20.
    • Even after forcing builds, it remained unstable.
  4.  
  5. Switched to MemoryVectorStore in LangChain.js
    • Replaced FAISS with MemoryVectorStore to keep everything in-memory.
    • This allowed me to test the frontend chatbot while avoiding binary issues.
  6.  

 


 

✅ What Finally Worked

import { MemoryVectorStore } from "langchain/vectorstores/memory";
// (Replaces FAISS in vectorStore.ts)

const vectorStore = await MemoryVectorStore.fromDocuments(docs, embeddings);

Additionally, I fixed a critical runtime bug:

chat_history: string[] // ❌ WRONG
chat_history: { role: "user" | "assistant"; content: string }[] // ✅ CORRECT

ConversationalRetrievalQAChain requires full role-based message objects, not just strings. Without this, .map() errors like _getType is not a function will occur.

 


 

🧠 Lessons Learned

 

  • Don’t mix native-compiled libraries (like FAISS) with modern JS unless you’re in full control of your server.
  • For serverless deployments, prefer MemoryVectorStore, Supabase, or Pinecone for vector storage.
  • RAG is powerful, but it depends on proper input/output formatting, especially for conversational context.

 


 

📌 Next Steps

 

  • Use Python only as a backend vector service (with Flask or FastAPI) if FAISS is a must.
  • Otherwise, adopt hosted vector DBs or stay in-memory for simpler needs.
  • Continue refining the chatbot prompt and responses using LangChain’s system prompt and contextual prioritization (MyProfile.md, README.md, etc.).

 


 

🇰🇷 한글 요약

 

🧪 문제 요약:

Python에서 FAISS를 이용해 구축한 RAG 챗봇을 Next.js 기반 포트폴리오에 통합하려 했으나, faiss-node가 최신 Node + M2 환경에서 작동하지 않아 실패.

 

🛠️ 해결 방법:

 

  • FAISS 대신 LangChain.js의 MemoryVectorStore로 전환
  • chat_history를 단순 string 배열이 아닌 { role, content } 객체 배열로 전달
  • 시스템 프롬프트를 통해 정확도와 문맥 유지 개선

 

📌 향후 계획:

 

  • Python 기반 백엔드로 FAISS API 구축하거나
  • Supabase, Pinecone 등의 클라우드 벡터 DB 활용 고려
  • 챗봇 Prompt 및 응답 방식 지속 개선

 

Demo Link: https://jinleedev.vercel.app/