현대의 웹 애플리케이션에서는 빠르고 정확한 검색 기능이 필수적입니다. 특히 이미지와 텍스트의 유사성을 기반으로 한 검색 기능은 사용자 경험을 크게 향상시킬 수 있습니다. 이 글에서는 DataStax Astra DB와 벡터 검색을 활용하여 NodeJS 애플리케이션을 개발하는 방법을 소개하고자 합니다. Astra DB는 높은 성능과 확장성을 자랑하는 데이터베이스로, 스타게이트-몽구스와 JSON API를 통해 쉽게 데이터를 처리할 수 있습니다. 벡터 검색은 AI 모델을 활용하여 텍스트와 이미지의 유사성을 분석해 가장 관련성이 높은 결과를 찾아주는 기능입니다.
이번 프로젝트에서는 OpenAI의 텍스트 임베딩 API와 Google MediaPipe를 사용하여 텍스트와 이미지의 임베딩 벡터를 생성하고, 이를 기반으로 벡터 유사성 검색을 구현할 것입니다. 또한, Express 프레임워크를 사용해 NodeJS 애플리케이션을 개발하고, Astra DB를 통해 데이터를 저장하고 불러오는 과정을 상세히 설명할 것입니다.
다음 섹션에서는 데이터 모델링부터 API 호출, 그리고 벡터 검색 구현까지의 과정을 단계별로 살펴보겠습니다.
AI와 벡터 검색을 활용한 NodeJS 앱 개발하기
데이터 모델링
NodeJS 애플리케이션을 개발하기 위해 먼저 데이터 모델을 정의해야 합니다. Mongoose를 사용하여 데이터 스키마를 작성하고, 이를 통해 사진 데이터를 Astra DB에 저장할 수 있습니다. 아래는 사진 데이터 모델의 예시입니다.
const mongoose = require('mongoose');
const photoSchema = new mongoose.Schema({
name: String,
description: String,
category: String,
image: String,
"$vector": Array
});
const Photo = mongoose.model('Photo', photoSchema);
이 스키마는 사진의 이름, 설명, 카테고리, 이미지 파일명, 그리고 벡터 데이터를 포함합니다.
데이터 저장 및 불러오기
사진을 추가할 때는 사용자로부터 입력받은 데이터를 기반으로 새로운 Photo 객체를 생성하고, 이를 Astra DB에 저장합니다. 예를 들어, 사용자가 "Add Photo" 버튼을 클릭하면 아래와 같은 코드가 실행됩니다.
const newPhoto = new Photo({
name: req.body.name,
description: req.body.description,
category: req.body.category,
image: newImageName,
"$vector": description_embedding
});
await newPhoto.save();
데이터를 불러올 때는 카테고리별로 사진을 조회하거나, 특정 사진의 상세 정보를 가져올 수 있습니다.
const photosOfCategory = await Photo.find({ 'category': categoryName }).limit(limitNumber);
const photo = await Photo.findById(photoId);
텍스트 유사성 검색
텍스트 유사성 검색은 사용자가 입력한 텍스트와 유사한 설명을 가진 사진을 찾는 기능입니다. 이를 위해 OpenAI의 텍스트 임베딩 API를 사용하여 텍스트 임베딩 벡터를 생성합니다. 사진을 추가할 때와 검색할 때 모두 이 임베딩 벡터를 사용합니다.
사진을 추가할 때는 아래와 같이 설명 텍스트의 임베딩 벡터를 생성합니다.
const description_embedding = await getTextEmbedding(req.body.description);
검색할 때는 사용자가 입력한 검색어에 대한 임베딩 벡터를 생성한 후, 유사한 벡터를 가진 사진을 찾습니다.
const search_embedding = await getTextEmbedding(searchTerm);
const photos = await Photo.find({}).sort({ $vector: { $meta: search_embedding } }).limit(3);
예를 들어, 사용자가 "초원에서 풀을 뜯는 소"라는 문구로 검색하면, 초원과 관련된 사진을 반환할 수 있습니다.
이미지 유사성 검색
이미지 유사성 검색은 사용자가 업로드한 이미지와 유사한 이미지를 찾는 기능입니다. 이를 위해 Google MediaPipe를 사용하여 이미지 임베딩 벡터를 생성합니다. NodeJS 환경에서 Python 스크립트를 실행하여 이 임베딩 벡터를 생성할 수 있습니다.
const photo_embedding = await getPhotoEmbedding(image);
const photos = await Photo.find({}).sort({ $vector: { $meta: photo_embedding } }).limit(3);
예를 들어, 사용자가 "해질녘의 자동차" 이미지를 업로드하면, 유사한 색조와 구성의 이미지를 반환할 수 있습니다.
Express 서버 설정
NodeJS 애플리케이션의 기본 구조는 Express 프레임워크를 사용하여 설정합니다. Express는 라우팅, 미들웨어, 요청 처리 등을 간편하게 할 수 있도록 도와줍니다.
const express = require('express');
const mongoose = require('mongoose');
const app = express();
mongoose.connect('your-astra-db-connection-string', { useNewUrlParser: true, useUnifiedTopology: true });
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post('/add-photo', async (req, res) => {
const description_embedding = await getTextEmbedding(req.body.description);
const newPhoto = new Photo({
name: req.body.name,
description: req.body.description,
category: req.body.category,
image: req.body.image,
"$vector": description_embedding
});
await newPhoto.save();
res.send('Photo added successfully');
});
app.get('/search-text', async (req, res) => {
const search_embedding = await getTextEmbedding(req.query.searchTerm);
const photos = await Photo.find({}).sort({ $vector: { $meta: search_embedding } }).limit(3);
res.send(photos);
});
app.get('/search-image', async (req, res) => {
const photo_embedding = await getPhotoEmbedding(req.query.image);
const photos = await Photo.find({}).sort({ $vector: { $meta: photo_embedding } }).limit(3);
res.send(photos);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
이 코드는 사진 추가, 텍스트 검색, 이미지 검색을 위한 API 엔드포인트를 제공합니다. 각 엔드포인트는 클라이언트의 요청을 받아서 적절한 처리를 수행한 후, 결과를 반환합니다.
텍스트 임베딩 API 호출
OpenAI 텍스트 임베딩 API를 사용하여 텍스트 임베딩 벡터를 생성하는 함수는 아래와 같습니다.
const axios = require('axios');
async function getTextEmbedding(text) {
const response = await axios.post('https://api.openai.com/v1/embeddings', {
input: text,
model: 'text-embedding-ada-002'
}, {
headers: {
'Authorization': `Bearer YOUR_OPENAI_API_KEY`
}
});
return response.data.data[0].embedding;
}
이미지 임베딩 생성
이미지 임베딩 벡터를 생성하기 위해 Python 스크립트를 실행하는 NodeJS 코드는 다음과 같습니다.
const { PythonShell } = require('python-shell');
async function getPhotoEmbedding(imagePath) {
return new Promise((resolve, reject) => {
PythonShell.run('generate_embedding.py', { args: [imagePath] }, (err, results) => {
if (err) reject(err);
resolve(JSON.parse(results[0]));
});
});
}
generate_embedding.py는 Google MediaPipe를 사용하여 이미지 임베딩 벡터를 생성하는 Python 스크립트입니다.
import sys
import json
import mediapipe as mp
import numpy as np
def generate_embedding(image_path):
# MediaPipe 및 MobileNetV3를 사용하여 임베딩 벡터 생성 코드
pass
if __name__ == '__main__':
image_path = sys.argv[1]
embedding = generate_embedding(image_path)
print(json.dumps(embedding.tolist()))
이렇게 해서 텍스트와 이미지의 유사성을 기반으로 검색할 수 있는 NodeJS 애플리케이션을 완성할 수 있습니다. 다음 섹션에서는 이 애플리케이션의 결론을 다루겠습니다.
이번 포스팅에서는 DataStax Astra DB와 벡터 검색을 활용하여 AI 기반의 NodeJS 애플리케이션을 개발하는 과정을 상세히 다루었습니다. 이를 통해 사진 데이터의 저장, 텍스트와 이미지의 유사성 검색 기능을 구현할 수 있었습니다. 벡터 검색은 사용자의 검색 의도를 보다 정확하게 파악하여 관련성 높은 결과를 제공하는 데 매우 유용합니다.
주요 내용 요약
데이터 모델링: Mongoose를 사용하여 사진 데이터를 Astra DB에 저장하기 위한 스키마를 정의했습니다.
데이터 저장 및 불러오기: 사용자가 사진을 추가할 때 데이터베이스에 저장하고, 필요할 때 카테고리별 또는 개별 사진을 불러오는 방법을 설명했습니다.
텍스트 유사성 검색: OpenAI의 텍스트 임베딩 API를 활용하여 텍스트 임베딩 벡터를 생성하고, 이를 기반으로 유사한 설명을 가진 사진을 검색하는 기능을 구현했습니다.
이미지 유사성 검색: Google MediaPipe를 사용하여 이미지 임베딩 벡터를 생성하고, 유사한 이미지를 검색하는 기능을 NodeJS와 Python을 연동하여 구현했습니다.
Express 서버 설정: Express 프레임워크를 사용하여 API 엔드포인트를 설정하고, 클라이언트 요청을 처리하는 방법을 다루었습니다.
벡터 검색의 장점
벡터 검색은 AI 모델의 강력한 기능을 활용하여 기존의 키워드 기반 검색보다 더 정교하고 정확한 검색 결과를 제공합니다. 텍스트와 이미지의 임베딩 벡터를 사용함으로써, 사용자가 입력한 검색어 또는 업로드한 이미지와 가장 유사한 데이터를 찾아낼 수 있습니다. 이는 특히 대량의 이미지 또는 텍스트 데이터를 관리하고 검색해야 하는 애플리케이션에서 매우 유용합니다.
실용적인 활용 사례
이러한 기술은 다양한 분야에서 활용될 수 있습니다. 예를 들어, 전자 상거래 사이트에서는 사용자가 원하는 제품과 유사한 다른 제품을 추천할 수 있습니다. 또한, 사진 갤러리나 소셜 미디어 플랫폼에서는 사용자가 업로드한 사진과 유사한 다른 사용자들의 사진을 쉽게 찾아볼 수 있습니다. 교육 분야에서는 학습 자료나 논문 등의 유사성을 분석하여 관련 자료를 추천하는 데 활용될 수 있습니다.
향후 발전 방향
앞으로 벡터 검색 기술은 더욱 발전할 것으로 예상됩니다. 특히, AI와 머신러닝 모델이 계속해서 개선됨에 따라, 더 정교한 임베딩 벡터를 생성하고 이를 활용한 검색 기능이 더욱 강력해질 것입니다. 또한, 다양한 도메인에서 벡터 검색을 통합하여 보다 스마트한 검색 솔루션을 제공할 수 있을 것입니다.
결론
NodeJS와 DataStax Astra DB를 활용한 벡터 검색 애플리케이션 개발은 비교적 간단한 과정이지만, 그 결과는 매우 강력합니다. 이번 프로젝트를 통해 텍스트와 이미지의 유사성을 기반으로 한 검색 기능을 성공적으로 구현할 수 있었습니다. 이러한 기술은 사용자 경험을 향상시키고, 다양한 분야에서 실질적인 가치를 제공할 수 있는 잠재력을 가지고 있습니다.
앞으로도 지속적인 학습과 개발을 통해 벡터 검색 기술을 더욱 향상시키고, 이를 실무에 적용하는 다양한 방법을 모색해 나가길 바랍니다. 여러분도 이 튜토리얼을 따라하며 자신의 프로젝트에 벡터 검색 기능을 추가해보세요. 더 나은 검색 경험을 제공하는 AI 애플리케이션을 만들어가는 데 큰 도움이 될 것입니다.
'SW > 인공지능' 카테고리의 다른 글
AI 주도 디지털 전략과 애자일 제품 개발의 융합 (0) | 2024.05.23 |
---|---|
생성 AI 시대: 소프트웨어 엔지니어를 위한 MLOps와 LLM 배포 전략 (0) | 2024.05.21 |
데이터 분석의 혁명: 생성적 AI의 힘을 활용하다 (0) | 2024.05.08 |
데이터에서 통찰까지: 생성적 AI를 활용한 데이터 분석 혁신 (0) | 2024.05.07 |
AI 기반 글쓰기로 블로그 트래픽을 높이는 법 (0) | 2024.05.05 |