Skip to content

Commit 7ea8648

Browse files
authored
Merge pull request #131 from #130
130 vectordb 유연성 개선 refactor
2 parents 5079c7f + 13298d6 commit 7ea8648

File tree

10 files changed

+292
-42
lines changed

10 files changed

+292
-42
lines changed

.env.example

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
###############################################
22
############## LLM API SELECTION ##############
33
###############################################
4+
LLM_PROVIDER=openai
5+
6+
OPENAI_API_KEY=sk-proj-
7+
LANGCHAIN_TRACING_V2=true
8+
LANGCHAIN_PROJECT=langgraph_tutorial
9+
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
10+
LANGCHAIN_API_KEY=lsv2_
11+
12+
413

514
# LLM_PROVIDER=openai
615
# OPEN_AI_KEY=sk-proj-----
7-
# OPEN_AI_LLM_MODEL=gpt-4.1
16+
OPEN_AI_LLM_MODEL=gpt-4.1
817

918
# LLM_PROVIDER=gemini
1019
# GEMINI_API_KEY=
1120
# GEMINI_LLM_MODEL=gemini-2.0-flash-lite
1221

13-
LLM_PROVIDER=azure
14-
AZURE_OPENAI_LLM_ENDPOINT=https://-------.openai.azure.com/
15-
AZURE_OPENAI_LLM_KEY=-
16-
AZURE_OPENAI_LLM_MODEL=gpt4o
17-
AZURE_OPENAI_LLM_API_VERSION=2024-07-01-preview
22+
# LLM_PROVIDER=azure
23+
# AZURE_OPENAI_LLM_ENDPOINT=https://-------.openai.azure.com/
24+
# AZURE_OPENAI_LLM_KEY=-
25+
# AZURE_OPENAI_LLM_MODEL=gpt4o
26+
# AZURE_OPENAI_LLM_API_VERSION=2024-07-01-preview
1827

1928
# LLM_PROVIDER=ollama
2029
# OLLAMA_LLM_BASE_URL=
@@ -36,8 +45,8 @@ AZURE_OPENAI_LLM_API_VERSION=2024-07-01-preview
3645
########### Embedding API SElECTION ###########
3746
###############################################
3847
# Only used if you are using an LLM that does not natively support embedding (openai or Azure)
39-
# EMBEDDING_PROVIDER='openai'
40-
# OPEN_AI_EMBEDDING_MODEL='text-embedding-ada-002'
48+
EMBEDDING_PROVIDER='openai'
49+
OPEN_AI_EMBEDDING_MODEL='text-embedding-ada-002'
4150

4251
# EMBEDDING_PROVIDER=azure
4352
# AZURE_OPENAI_EMBEDDING_ENDPOINT=https://-------.openai.azure.com/openai/deployments
@@ -50,11 +59,11 @@ AZURE_OPENAI_LLM_API_VERSION=2024-07-01-preview
5059
# EMBEDDING_MODEL='nomic-embed-text:latest'
5160
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
5261

53-
EMBEDDING_PROVIDER='bedrock'
54-
AWS_BEDROCK_EMBEDDING_ACCESS_KEY_ID=--
55-
AWS_BEDROCK_EMBEDDING_SECRET_ACCESS_KEY=-/-+-+-
56-
AWS_BEDROCK_EMBEDDING_REGION=us-west-2
57-
AWS_BEDROCK_EMBEDDING_MODEL=amazon.titan-embed-text-v2:0
62+
# EMBEDDING_PROVIDER='bedrock'
63+
# AWS_BEDROCK_EMBEDDING_ACCESS_KEY_ID=--
64+
# AWS_BEDROCK_EMBEDDING_SECRET_ACCESS_KEY=-/-+-+-
65+
# AWS_BEDROCK_EMBEDDING_REGION=us-west-2
66+
# AWS_BEDROCK_EMBEDDING_MODEL=amazon.titan-embed-text-v2:0
5867

5968
# EMBEDDING_PROVIDER='gemini'
6069
# GEMINI_EMBEDDING_API_KEY=
@@ -63,23 +72,22 @@ AWS_BEDROCK_EMBEDDING_MODEL=amazon.titan-embed-text-v2:0
6372
# EMBEDDING_PROVIDER='huggingface'
6473
# HUGGING_FACE_EMBEDDING_REPO_ID=
6574
# HUGGING_FACE_EMBEDDING_MODEL=
66-
6775
# HUGGING_FACE_EMBEDDING_API_TOKEN=
6876

69-
DATAHUB_SERVER = 'http://-.-.-.-:-'
77+
DATAHUB_SERVER = 'http://localhost:8080'
7078

7179

7280
###############################################
7381
######## Database Connector SELECTION #########
7482
###############################################
7583

7684
# clickhouse
77-
# DB_TYPE=clickhouse
78-
# CLICKHOUSE_HOST=_._._._
79-
# CLICKHOUSE_PORT=9000
80-
# CLICKHOUSE_USER=_
81-
# CLICKHOUSE_PASSWORD=_
82-
# CLICKHOUSE_DATABASE=_
85+
DB_TYPE=clickhouse
86+
CLICKHOUSE_HOST=localhost
87+
CLICKHOUSE_PORT=9001
88+
CLICKHOUSE_USER=clickhouse
89+
CLICKHOUSE_PASSWORD=clickhouse
90+
CLICKHOUSE_DATABASE=default
8391

8492
# databricks
8593
# DB_TYPE=databricks
@@ -134,3 +142,14 @@ DATAHUB_SERVER = 'http://-.-.-.-:-'
134142
# DB_TYPE=sqlite
135143
# SQLITE_PATH=./data/sqlite.db
136144

145+
146+
# pgvector 설정 (VECTORDB_TYPE=pgvector일 때 사용)
147+
PGVECTOR_HOST=localhost
148+
PGVECTOR_PORT=5432
149+
PGVECTOR_USER=postgres
150+
PGVECTOR_PASSWORD=postgres
151+
PGVECTOR_DATABASE=postgres
152+
PGVECTOR_COLLECTION=table_info_db
153+
154+
# VectorDB 설정
155+
VECTORDB_TYPE=faiss # faiss 또는 pgvector

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Lang2SQL은 자연어 쿼리를 최적화된 SQL 문으로 변환하는 오픈
3434
- **🔍 스키마 인식**: DataHub 메타데이터를 활용한 정확한 컬럼 매핑
3535
- **🛠️ 웹 인터페이스**: 대화형 Streamlit 앱을 통한 사용
3636
- **📈 시각화**: 생성된 SQL 쿼리 결과를 다양한 차트와 그래프로 시각화하여 데이터 인사이트를 직관적으로 파악
37+
- **🗄️ 유연한 VectorDB**: FAISS(로컬)와 pgvector(PostgreSQL) 중 선택 가능한 벡터 데이터베이스 지원
3738

3839
### 🤔 해결하는 문제
3940

@@ -85,6 +86,28 @@ lang2sql run-streamlit
8586
lang2sql --datahub_server http://your-datahub-server:8080 run-streamlit -p 8888
8687
```
8788

89+
### VectorDB 선택
90+
91+
FAISS(로컬) 또는 pgvector(PostgreSQL) 중 선택:
92+
93+
```bash
94+
# FAISS 사용 (기본값)
95+
lang2sql --vectordb-type faiss run-streamlit
96+
97+
# pgvector 사용
98+
lang2sql --vectordb-type pgvector run-streamlit
99+
```
100+
101+
### 자연어 쿼리 실행
102+
103+
```bash
104+
# 기본 FAISS 사용
105+
lang2sql query "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리"
106+
107+
# pgvector 사용
108+
lang2sql query "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리" --vectordb-type pgvector --vectordb-location "postgresql://postgres:postgres@localhost:5432/postgres"
109+
```
110+
88111
### 환경 설정
89112

90113
- 현재는 pip 패키지 설치로 프로젝트 시작이 어려운 상황입니다.

cli/__init__.py

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,31 @@
6464
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True),
6565
help="프롬프트 템플릿(.md 파일)이 저장된 디렉토리 경로를 지정합니다. 지정하지 않으면 기본 경로를 사용합니다.",
6666
)
67+
@click.option(
68+
"--vectordb-type",
69+
type=click.Choice(["faiss", "pgvector"]),
70+
default="faiss",
71+
help="사용할 벡터 데이터베이스 타입 (기본값: faiss)",
72+
)
73+
@click.option(
74+
"--vectordb-location",
75+
help=(
76+
"VectorDB 위치 설정\n"
77+
"- FAISS: 디렉토리 경로 (예: ./my_vectordb)\n"
78+
"- pgvector: 연결 문자열 (예: postgresql://user:pass@host:port/db)\n"
79+
"기본값: FAISS는 './table_info_db', pgvector는 환경변수 사용"
80+
),
81+
)
6782
# pylint: disable=redefined-outer-name
6883
def cli(
6984
ctx: click.Context,
7085
datahub_server: str,
7186
run_streamlit: bool,
7287
port: int,
73-
env_file_path: str = None,
74-
prompt_dir_path: str = None,
88+
env_file_path: str | None = None,
89+
prompt_dir_path: str | None = None,
90+
vectordb_type: str = "faiss",
91+
vectordb_location: str = None,
7592
) -> None:
7693
"""
7794
Datahub GMS 서버 URL을 설정하고, Streamlit 애플리케이션을 실행할 수 있는 CLI 명령 그룹입니다.
@@ -117,6 +134,23 @@ def cli(
117134
click.secho(f"프롬프트 디렉토리 환경변수 설정 실패: {str(e)}", fg="red")
118135
ctx.exit(1)
119136

137+
# VectorDB 타입을 환경 변수로 설정
138+
try:
139+
os.environ["VECTORDB_TYPE"] = vectordb_type
140+
click.secho(f"VectorDB 타입 설정됨: {vectordb_type}", fg="green")
141+
except Exception as e:
142+
click.secho(f"VectorDB 타입 설정 실패: {str(e)}", fg="red")
143+
ctx.exit(1)
144+
145+
# VectorDB 경로를 환경 변수로 설정
146+
if vectordb_location:
147+
try:
148+
os.environ["VECTORDB_LOCATION"] = vectordb_location
149+
click.secho(f"VectorDB 경로 설정됨: {vectordb_location}", fg="green")
150+
except Exception as e:
151+
click.secho(f"VectorDB 경로 설정 실패: {str(e)}", fg="red")
152+
ctx.exit(1)
153+
120154
logger.info(
121155
"Initialization started: GMS server = %s, run_streamlit = %s, port = %d",
122156
datahub_server,
@@ -129,7 +163,7 @@ def cli(
129163
logger.info("GMS server URL successfully set: %s", datahub_server)
130164
else:
131165
logger.error("GMS server health check failed. URL: %s", datahub_server)
132-
ctx.exit(1)
166+
# ctx.exit(1)
133167

134168
if run_streamlit:
135169
run_streamlit_command(port)
@@ -234,6 +268,21 @@ def run_streamlit_cli_command(port: int) -> None:
234268
is_flag=True,
235269
help="단순화된 그래프(QUERY_REFINER 제거) 사용 여부",
236270
)
271+
@click.option(
272+
"--vectordb-type",
273+
type=click.Choice(["faiss", "pgvector"]),
274+
default="faiss",
275+
help="사용할 벡터 데이터베이스 타입 (기본값: faiss)",
276+
)
277+
@click.option(
278+
"--vectordb-location",
279+
help=(
280+
"VectorDB 위치 설정\n"
281+
"- FAISS: 디렉토리 경로 (예: ./my_vectordb)\n"
282+
"- pgvector: 연결 문자열 (예: postgresql://user:pass@host:port/db)\n"
283+
"기본값: FAISS는 './table_info_db', pgvector는 환경변수 사용"
284+
),
285+
)
237286
def query_command(
238287
question: str,
239288
database_env: str,
@@ -242,6 +291,8 @@ def query_command(
242291
device: str,
243292
use_enriched_graph: bool,
244293
use_simplified_graph: bool,
294+
vectordb_type: str = "faiss",
295+
vectordb_location: str = None,
245296
) -> None:
246297
"""
247298
자연어 질문을 SQL 쿼리로 변환하여 출력하는 명령어입니다.
@@ -260,11 +311,19 @@ def query_command(
260311
예시:
261312
lang2sql query "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리"
262313
lang2sql query "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리" --use-enriched-graph
314+
lang2sql query "고객 데이터를 기반으로 유니크한 유저 수를 카운트하는 쿼리" --vectordb-type pgvector
263315
"""
264316

265317
try:
266318
from llm_utils.query_executor import execute_query, extract_sql_from_result
267319

320+
# VectorDB 타입을 환경 변수로 설정
321+
os.environ["VECTORDB_TYPE"] = vectordb_type
322+
323+
# VectorDB 위치를 환경 변수로 설정
324+
if vectordb_location:
325+
os.environ["VECTORDB_LOCATION"] = vectordb_location
326+
268327
# 공용 함수를 사용하여 쿼리 실행
269328
res = execute_query(
270329
query=question,

llm_utils/retrieval.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,7 @@
88

99
from .tools import get_info_from_db
1010
from .llm_factory import get_embeddings
11-
12-
13-
def get_vector_db():
14-
"""벡터 데이터베이스를 로드하거나 생성합니다."""
15-
embeddings = get_embeddings()
16-
try:
17-
db = FAISS.load_local(
18-
os.getcwd() + "/table_info_db",
19-
embeddings,
20-
allow_dangerous_deserialization=True,
21-
)
22-
except:
23-
documents = get_info_from_db()
24-
db = FAISS.from_documents(documents, embeddings)
25-
db.save_local(os.getcwd() + "/table_info_db")
26-
print("table_info_db not found")
27-
return db
11+
from .vectordb import get_vector_db
2812

2913

3014
def load_reranker_model(device: str = "cpu"):

llm_utils/vectordb/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
VectorDB 모듈 - FAISS와 pgvector를 지원하는 벡터 데이터베이스 추상화
3+
"""
4+
5+
from .factory import get_vector_db
6+
7+
__all__ = ["get_vector_db"]

llm_utils/vectordb/factory.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
VectorDB 팩토리 모듈 - 환경 변수에 따라 적절한 VectorDB 인스턴스를 생성
3+
"""
4+
5+
import os
6+
from typing import Optional
7+
8+
from llm_utils.vectordb.faiss_db import get_faiss_vector_db
9+
from llm_utils.vectordb.pgvector_db import get_pgvector_db
10+
11+
12+
def get_vector_db(
13+
vectordb_type: Optional[str] = None, vectordb_location: Optional[str] = None
14+
):
15+
"""
16+
VectorDB 타입과 위치에 따라 적절한 VectorDB 인스턴스를 반환합니다.
17+
18+
Args:
19+
vectordb_type: VectorDB 타입 ("faiss" 또는 "pgvector"). None인 경우 환경 변수에서 읽음.
20+
vectordb_location: VectorDB 위치 (FAISS: 디렉토리 경로, pgvector: 연결 문자열). None인 경우 환경 변수에서 읽음.
21+
22+
Returns:
23+
VectorDB 인스턴스 (FAISS 또는 PGVector)
24+
"""
25+
if vectordb_type is None:
26+
vectordb_type = os.getenv("VECTORDB_TYPE", "faiss").lower()
27+
28+
if vectordb_location is None:
29+
vectordb_location = os.getenv("VECTORDB_LOCATION")
30+
31+
if vectordb_type == "faiss":
32+
return get_faiss_vector_db(vectordb_location)
33+
elif vectordb_type == "pgvector":
34+
return get_pgvector_db(vectordb_location)
35+
else:
36+
raise ValueError(
37+
f"지원하지 않는 VectorDB 타입: {vectordb_type}. 'faiss' 또는 'pgvector'를 사용하세요."
38+
)

llm_utils/vectordb/faiss_db.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
FAISS VectorDB 구현
3+
"""
4+
5+
import os
6+
from langchain_community.vectorstores import FAISS
7+
from typing import Optional
8+
9+
from llm_utils.tools import get_info_from_db
10+
from llm_utils.llm_factory import get_embeddings
11+
12+
13+
def get_faiss_vector_db(vectordb_path: Optional[str] = None):
14+
"""FAISS 벡터 데이터베이스를 로드하거나 생성합니다."""
15+
embeddings = get_embeddings()
16+
17+
# 기본 경로 설정
18+
if vectordb_path is None:
19+
vectordb_path = os.path.join(os.getcwd(), "table_info_db")
20+
21+
try:
22+
db = FAISS.load_local(
23+
vectordb_path,
24+
embeddings,
25+
allow_dangerous_deserialization=True,
26+
)
27+
except:
28+
documents = get_info_from_db()
29+
db = FAISS.from_documents(documents, embeddings)
30+
db.save_local(vectordb_path)
31+
print(f"VectorDB를 새로 생성했습니다: {vectordb_path}")
32+
return db

0 commit comments

Comments
 (0)