๐ ๊ฐ์
์ด ๊ธ์์๋ FastAPI + PostgreSQL + pgvector๋ฅผ ํ์ฉํ์ฌ ๋ฒกํฐ ๊ฒ์ API๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค.
โ pgvector๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒกํฐ ๋ฐ์ดํฐ ์ ์ฅ
โ FastAPI๋ฅผ ์ด์ฉํด REST API๋ก ๋ฒกํฐ ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ
โ AI ๋ชจ๋ธ์ ํ์ฉํ์ฌ ํ ์คํธ ์๋ฒ ๋ฉ์ ๋ฒกํฐ๋ก ๋ณํ ํ ์ ์ฅ
๐ 1. FastAPI ํ๋ก์ ํธ ์ค์
๋จผ์ , FastAPI ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
1๏ธโฃ FastAPI ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ ์์ฑ
mkdir fastapi-vector-search
cd fastapi-vector-search
2๏ธโฃ Python ๊ฐ์ํ๊ฒฝ ์ค์ (์ ํ)
python3 -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
3๏ธโฃ FastAPI ๋ฐ PostgreSQL ํด๋ผ์ด์ธํธ ์ค์น
pip install fastapi uvicorn psycopg2 sqlalchemy numpy
๐ 2. PostgreSQL ํ ์ด๋ธ ์์ฑ
FastAPI์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๋๋ก pgvector๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ด๋ธ์ ์์ฑํฉ๋๋ค.
1๏ธโฃ PostgreSQL ์ ์
kubectl exec -it $(kubectl get pod -n database -l app.kubernetes.io/name=postgresql -o jsonpath="{.items[0].metadata.name}") -n database -- psql -U postgres -d ragdb
2๏ธโฃ ๋ฒกํฐ ํ ์ด๋ธ ์์ฑ
CREATE TABLE IF NOT EXISTS embeddings (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(3) -- 3์ฐจ์ ๋ฒกํฐ ์ ์ฅ (์ค์ ์ฌ์ฉ ์ 1536์ฐจ์ ๋ฑ ์กฐ์ ๊ฐ๋ฅ)
);
โ ํ ์ด๋ธ ์์ฑ ํ์ธ
\dt
List of relations
Schema | Name | Type | Owner
--------+-----------+-------+---------
public | embeddings | table | postgres
๐ 3. FastAPI์์ PostgreSQL ์ฐ๊ฒฐ
์ด์ FastAPI๋ฅผ ์ฌ์ฉํ์ฌ PostgreSQL๊ณผ ์ฐ๋ํฉ๋๋ค.
๐ main.py ์์ฑ
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import psycopg2
import numpy as np
from typing import List
app = FastAPI()
# PostgreSQL ์ฐ๊ฒฐ ์ ๋ณด
DB_HOST = "localhost"
DB_PORT = "5432"
DB_NAME = "ragdb"
DB_USER = "postgres"
DB_PASSWORD = "postgresql"
# PostgreSQL ์ฐ๊ฒฐ
def get_db_connection():
return psycopg2.connect(
host=DB_HOST, port=DB_PORT,
database=DB_NAME, user=DB_USER, password=DB_PASSWORD
)
# ๋ฐ์ดํฐ ๋ชจ๋ธ ์ ์
class VectorData(BaseModel):
content: str
embedding: List[float]
# ๋ฐ์ดํฐ ์ฝ์
API
@app.post("/add_vector/")
def add_vector(data: VectorData):
conn = get_db_connection()
cur = conn.cursor()
try:
# ๋ฒกํฐ๋ฅผ PostgreSQL์ ์ฝ์
cur.execute(
"INSERT INTO embeddings (content, embedding) VALUES (%s, %s) RETURNING id;",
(data.content, np.array(data.embedding).tolist())
)
conn.commit()
return {"message": "Vector added successfully", "id": cur.fetchone()[0]}
except Exception as e:
conn.rollback()
raise HTTPException(status_code=500, detail=str(e))
finally:
cur.close()
conn.close()
# ์ต๊ทผ์ ์ด์ ๊ฒ์ API
@app.get("/search/")
def search_vector(query_vector: List[float]):
conn = get_db_connection()
cur = conn.cursor()
try:
cur.execute(
"SELECT content, embedding <-> %s AS distance FROM embeddings ORDER BY distance LIMIT 1;",
(np.array(query_vector).tolist(),)
)
result = cur.fetchone()
return {"content": result[0], "distance": result[1]}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
cur.close()
conn.close()
๐ 4. FastAPI ์คํ ๋ฐ ํ ์คํธ
1๏ธโฃ FastAPI ์คํ
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
โ ์คํ ํ http://localhost:8000/docs ์ ์ ์ํ๋ฉด Swagger UI๋ฅผ ํตํด API๋ฅผ ํ ์คํธํ ์ ์์ต๋๋ค.
2๏ธโฃ ๋ฒกํฐ ๋ฐ์ดํฐ ์ถ๊ฐ ํ ์คํธ
POST /add_vector/ API ํ ์คํธ
{
"content": "Hello, world!",
"embedding": [0.1, 0.2, 0.3]
}
โ ์๋ต ์์
{
"message": "Vector added successfully",
"id": 1
}
3๏ธโฃ ๋ฒกํฐ ๊ฒ์ ํ ์คํธ
GET /search/?query_vector=[0.2,0.2,0.2]
โ ์๋ต ์์
{
"content": "Hello, world!",
"distance": 0.141421
}
๐ 5. AI ๋ชจ๋ธ์ ์ฌ์ฉํ ๋ฒกํฐ ์์ฑ
์ผ๋ฐ์ ์ผ๋ก ๋ฒกํฐ ๋ฐ์ดํฐ๋ AI ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์์ฑํฉ๋๋ค.
์๋ฅผ ๋ค์ด, OpenAI์ text-embedding-ada-002 ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ํ ์คํธ๋ฅผ ๋ฒกํฐ๋ก ๋ณํํ ์ ์์ต๋๋ค.
1๏ธโฃ OpenAI API ํค ์ค์
pip install openai
๐ ๋ฒกํฐ ์์ฑ ํจ์ ์ถ๊ฐ (main.py ์์ )
import openai
openai.api_key = "your-openai-api-key"
def get_embedding(text: str):
response = openai.Embedding.create(
input=text,
model="text-embedding-ada-002"
)
return response['data'][0]['embedding']
@app.post("/add_text/")
def add_text(content: str):
embedding = get_embedding(content)
return add_vector(VectorData(content=content, embedding=embedding))
๐ 6. ์ต์ข ์ ๋ฆฌ
โ FastAPI + PostgreSQL + pgvector๋ฅผ ํ์ฉํ ๋ฒกํฐ ๊ฒ์ API ๊ตฌ์ถ
โ ๋ฒกํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ API ๊ตฌํ
โ OpenAI API๋ฅผ ํ์ฉํ์ฌ ๋ฌธ์ฅ์ ๋ฒกํฐ๋ก ๋ณํ ํ ์ ์ฅ
โ Swagger UI(http://localhost:8000/docs)๋ฅผ ์ด์ฉํ API ํ ์คํธ ๊ฐ๋ฅ