SQL + AI: 오늘 바로 사용할 수 있는 실무 데이터베이스 솔루션
요약
PostgreSQL과 AI를 결합하여 별도의 벡터 데이터베이스 없이도 임베딩 저장, RAG, NL2SQL, AI 에이전트를 구현하는 실무 패턴을 소개합니다. pgvector를 활용해 관계형 데이터와 벡터 데이터를 단일 쿼리로 처리하는 방법을 다룹니다.
핵심 포인트
- pgvector를 사용해 PostgreSQL 내에서 고차원 임베딩 저장 및 유사도 검색 가능
- 관계형 데이터와 벡터 데이터를 결합한 하이브리드 검색 구현
- RAG 파이프라인 및 Text-to-SQL 패턴을 통한 데이터베이스 활용 극대화
- SQL 기반 자율형 AI 에이전트를 위한 메모리 레이어로서의 DB 역할
📦 이 글의 모든 코드 예제는 GitHub에서 확인할 수 있습니다:
github.com/andre-carbajal/sql-ai-database-solutions
데이터베이스와 AI는 과거에 서로 분리된 세계에 존재했습니다. PostgreSQL 인스턴스는 구조화된 쿼리 (Structured Queries)를 처리했고, 머신러닝 (ML) 파이프라인은 완전히 다른 곳에서 실행되었습니다. 하지만 그 분리가 빠르게 사라지고 있습니다.
2025년에는 SQL 데이터베이스가 임베딩 (Embeddings)을 저장하고, 자연어 질문에 답하며, 시맨틱 검색 (Semantic Search)을 지원하고, 자율형 AI 에이전트 (Autonomous AI Agents)를 위한 메모리 레이어 (Memory Layer) 역할을 수행할 수 있습니다. 이 모든 것을 스택에 별도의 벡터 데이터베이스 (Vector Database)를 추가하지 않고도 가능합니다.
이 글에서는 작동하는 코드가 포함된 네 가지 실무 패턴을 살펴봅:
- pgvector — PostgreSQL에서 임베딩 (Embeddings) 저장 및 쿼리
- RAG 파이프라인 (RAG pipelines) — 자체 데이터베이스 콘텐츠로 LLM (Large Language Models) 강화
- NL2SQL / Text-to-SQL — 사용자가 일상적인 영어로 데이터베이스를 쿼리할 수 있도록 지원
- SQL 기반 AI 에이전트 (AI Agents over SQL) — 데이터에 대해 추론하고 행동하는 자율형 에이전트
사전 요구 사항 (Prerequisites)
pip install psycopg2-binary pgvector langchain langchain-openai openai sqlalchemy python-dotenv
# Docker: pgvector 지원을 포함하여 PostgreSQL 실행
docker run --name pgvector-demo \
-e POSTGRES_PASSWORD=secret \
...
환경 변수를 설정하세요:
# .env
OPENAI_API_KEY=sk-...
DATABASE_URL=postgresql://postgres:secret@localhost:5432/aidb
1. pgvector — PostgreSQL 내부의 시맨틱 검색 (Semantic Search)
pgvector는 네이티브 vector 데이터 타입을 추가하는 PostgreSQL 확장 기능 (Extension)으로, 고차원 임베딩 (High-dimensional Embeddings)을 저장하고 표준 SQL로 유사도 검색 (Similarity Searches)을 수행할 수 있게 해줍니다.
이것이 중요한 이유
별도의 벡터 데이터베이스 (Pinecone, Weaviate, Chroma)를 유지 관리하는 대신, 관계형 데이터 (Relational Data) 옆에 벡터를 함께 보관할 수 있습니다. 즉, 단일 쿼리 내에서 시맨틱 검색 (Semantic Search)과 SQL 필터 (Filters)를 결합할 수 있음을 의미합니다.
설정 (Setup)
-- 확장 기능 활성화
CREATE EXTENSION IF NOT EXISTS vector;
...
Python을 이용한 임베딩 (Embeddings) 삽입
Python을 이용한 임베딩 (Embeddings) 삽입
import os
import psycopg2
import numpy as np
...
질의(Querying): 하이브리드 의미론적 검색 + 구조화된 SQL
def semantic_search(query: str, max_price: float = None, category: str = None, limit: int = 5):
query_embedding = get_embedding(query)
...
출력:
[0.891] Ergonomic Office Chair ($449.00) — Lumbar support, adjustable arms
[0.832] Mechanical Keyboard ($129.00) — Cherry MX switches, RGB backlit
[0.801] Standing Desk ($599.00) — Electric height-adjustable desk
<=>연산자는 **코사인 거리(cosine distance)**를 계산합니다. pgvector는 또한<->(L2/유클리드) 및<#>(내적, inner product)도 지원합니다.
2. RAG 파이프라인 — 데이터베이스를 LLM 지식 기반으로 사용하기
검색 증강 생성(Retrieval-Augmented Generation, RAG)은 쿼리 시점에 사용자 자신의 데이터를 LLM의 컨텍스트에 주입할 수 있게 합니다. 미세 조정(fine-tuning) 대신, 데이터베이스에서 가장 관련성 높은 청크를 검색하여 컨텍스트로 전달합니다.
아키텍처
User Question
│
▼
...
LangChain + pgvector를 사용한 전체 RAG 파이프라인
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import PGVector
from langchain.text_splitter import RecursiveCharacterTextSplitter
...
다중 테넌트 RAG를 위한 메타데이터 필터 추가하기
# 테넌트 메타데이터와 함께 문서를 저장
vector_store = PGVector.from_documents(
documents=chunks,
...
3. NL2SQL — 자연어(Natural Language)를 SQL 질의로
NL2SQL (Text-to-SQL이라고도 함)은 사용자가 일반 영어로 데이터베이스에 질의할 수 있게 합니다. LLM이 스키마를 읽고 자연어 질문을 유효한 SQL 쿼리로 변환합니다.
단순 접근 방식: 직접적인 스키마 + 프롬프트
from openai import OpenAI
client = OpenAI()
...
출력:
--
```sql
--
sql|\n
```", "", sql).strip()
if not is_safe_sql(sql):
raise ValueError(f"Unsafe SQL rejected: {sql}")
...
정확도 향상을 위한 퓨샷 프롬프팅 (Few-shot prompting)
예시를 추가하면 복잡한 스키마 (schema)에서의 쿼리 정확도가 극적으로 향상됩니다:
FEW_SHOT_EXAMPLES = """
예시 1:
질문: 지난달에 주문된 주문 건수는 얼마인가요?
...
4. SQL 기반 AI 에이전트 — 자율적 데이터베이스 추론 (Autonomous Database Reasoning)
가장 강력한 패턴은 어떤 쿼리를 실행할지 자율적으로 결정하고, 결과를 검토하며, 복잡한 다단계 질문에 답하기 위해 반복(iterate)할 수 있는 AI 에이전트입니다.
LangChain + 커스텀 도구를 사용한 SQL 에이전트 구축
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.tools import tool
...
에이전트는 다음과 같은 작업을 자율적으로 수행합니다:
semantic_product_search("ergonomic office products")호출- 테이블을 이해하기 위해
get_schema()호출 - 독일 사무용 가구 구매자를 위한 SQL 쿼리 작성 및 실행
- 두 결과를 하나의 일관된 답변으로 합성
종합 정리: 아키텍처 개요 (Architecture Overview)
┌─────────────────────────────────────────────────────┐
│ PostgreSQL 데이터베이스 │
│ │
...
성능 최적화 팁 (Performance Tips)
pgvector를 위한 인덱스 전략 (Index strategy):
-- HNSW: 쿼리는 더 빠르지만 삽입은 더 느림 — 읽기 집약적인 프로덕션 워크로드에 최적
CREATE INDEX ON products USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
...
임베딩 배치 처리 (Batching embeddings):
# 임베딩 API를 한 번에 한 행씩 호출하지 마세요
texts = [f"{p['name']}: {p['description']}" for p in products]
...
반복되는 NL2SQL 쿼리 캐싱 (Caching):
import hashlib
import json
...
보안 체크리스트 (Security Checklist)
이러한 패턴들을 프로덕션 환경에 배포하기 전에:
- ✅ SELECT만 허용 (Allowlist only SELECT) — LLM이 생성한 SQL에서 DDL 및 DML 거부
- ✅ 사용자 제공 값을 사용하여 실행할 때 매개변수화된 쿼리 (Parameterized queries) 사용
- ✅ AI 레이어를 위한 읽기 전용 DB 사용자 (Read-only DB user) 생성
- ✅ 비용이 많이 드는 실수에 의한 전체 테이블 스캔 (Full-table scans)을 방지하기 위해 쿼리 타임아웃 (Query timeouts) 설정
- ✅ 에이전트 도구 호출 (Agent tool calls) 시 결과 집합 크기 (Result set sizes) 제한
- ✅ 감사를 위해 모든 LLM 생성 쿼리 로그 기록 (Log all LLM-generated queries)
- ✅ 가공되지 않은 에러 메시지 (Raw error messages)를 절대 노출하지 말 것 — 스키마 정보가 유출될 수 있음
-- AI 애플리케이션을 위한 제한된 역할(Role) 생성
CREATE ROLE ai_readonly;
GRANT CONNECT ON DATABASE aidb TO ai_readonly;
...
공개 저장소 (Public Repository)
Docker Compose 설정, 스키마 마이그레이션(Schema migrations), 즉시 실행 가능한 예제를 포함하여 이 기사의 모든 코드는 동반 저장소(Companion repository)에 있습니다:
저장소 구조:
sql-ai-database-solutions/
├── docker-compose.yml # PostgreSQL + pgvector, 즉시 사용 가능
├── schema/
...
다음 단계는? (What's Next?)
여기 소개된 패턴들은 시작일 뿐입니다. 탐구해 볼 만한 몇 가지 방향은 다음과 같습니다:
- DB-GPT — 오픈 소스 풀스택 AI 데이터베이스 프레임워크
- Vanna.AI — 자기 학습(Self-learning) 기능이 있는 RAG 기반 NL2SQL
- pgai — PostgreSQL 내부에서 직접 ML을 실행하기 위한 Timescale의 확장 기능
- 멀티 에이전트 SQL 워크플로우 (Multi-agent SQL workflows) — 여러 데이터베이스에 걸쳐 협업하는 에이전트들
"데이터베이스"와 "AI 시스템" 사이의 경계는 매달 점점 더 얇아지고 있습니다. 이미 PostgreSQL을 운영하고 있다면, 생각보다 훨씬 더 프로덕션 AI 스택에 가까이 와 있는 것입니다.
질문이 있거나 직접 구축한 것을 공유하고 싶으신가요? 아래에 댓글을 남기거나 저장소에 이슈(Issue)를 생성해 주세요!
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기