|
| 1 | +## llm_utils 개요 |
| 2 | + |
| 3 | +Lang2SQL 파이프라인에서 LLM, 검색(RAG), 그래프 워크플로우, DB 실행, 시각화 등 보조 유틸리티를 모아둔 패키지입니다. 이 문서는 depth(계층)별로 기능과 통합 흐름을 정리합니다. |
| 4 | + |
| 5 | +### Depth 0: 최상위 유틸리티 |
| 6 | + |
| 7 | +- (Moved) `engine/query_executor.py`: Lang2SQL 그래프 선택/컴파일/실행 진입점. |
| 8 | +- (Moved) `viz/display_chart.py`: LLM 활용 Plotly 시각화 유틸. |
| 9 | +- (Moved) `infra/monitoring/check_server.py`: GMS 헬스체크. |
| 10 | +- (Moved) `infra/db/connect_db.py`: ClickHouse 연결/실행. |
| 11 | +- **`token_utils.py`**: LLM 메시지의 `usage_metadata` 합산 토큰 집계. |
| 12 | +- **`llm_response_parser.py`**: LLM 응답에서 `<SQL>`, `<해석>` 블록 추출. |
| 13 | +- **`prompts_class.py`**: LangChain SQL 프롬프트를 로컬 YAML로 오버라이드. |
| 14 | +- **`utils.py`**: `profile_to_text(profile)` 등 소형 유틸. |
| 15 | + |
| 16 | +### Depth 1: LLM/임베딩/검색 |
| 17 | + |
| 18 | +- **`llm_factory.py`**: 환경변수로 LLM/임베딩 공급자 선택 팩토리. |
| 19 | + - LLM: `openai`, `azure`, `bedrock`, `gemini`, `ollama`, `huggingface` |
| 20 | + - Embeddings: `openai`, `azure`, `bedrock`, `gemini`, `ollama`, `huggingface` |
| 21 | + - 사용처: 체인/그래프 전반 및 `vectordb` 인덱싱/검색. |
| 22 | +- **`retrieval.py`**: 테이블 메타 검색 및 재순위화. |
| 23 | + - `search_tables(query, retriever_name, top_n, device)` |
| 24 | + - 기본: FAISS/pgvector에서 similarity_search. |
| 25 | + - `Reranker`: ko-reranker(CrossEncoder)로 재순위. |
| 26 | + |
| 27 | +### Depth 1.5: 벡터DB |
| 28 | + |
| 29 | +- **`vectordb/factory.py` → `get_vector_db()`**: `VECTORDB_TYPE`(`faiss`|`pgvector`)에 따라 인스턴스 반환. |
| 30 | +- **`vectordb/faiss_db.py`**: 로컬 디스크 `table_info_db` 로드/없으면 `tools.get_info_from_db()`로 빌드 후 저장. |
| 31 | +- **`vectordb/pgvector_db.py`**: PGVector 컬렉션 연결, 없거나 비면 `from_documents`로 재구성. |
| 32 | + |
| 33 | +### Depth 2: 데이터 소스/메타 수집 |
| 34 | + |
| 35 | +- **`tools.py`**: DataHub 기반 메타데이터 수집. |
| 36 | + - `set_gms_server(gms_server)`로 GMS 설정. |
| 37 | + - `get_info_from_db()` → `langchain.schema.Document` 리스트: 테이블 설명, 컬럼, 예시 쿼리, 용어집을 포맷. |
| 38 | + - `get_metadata_from_db()` → 풍부한 전체 메타데이터(dict) 목록. |
| 39 | + |
| 40 | +### Depth 2.5: 체인(Chains) |
| 41 | + |
| 42 | +- **`chains.py`**: LangChain ChatPromptTemplate로 구성된 체인. |
| 43 | + - `create_query_refiner_chain`, `create_query_maker_chain`, `create_profile_extraction_chain`, `create_query_refiner_with_profile_chain`, `create_query_enrichment_chain` |
| 44 | + - `QuestionProfile` Pydantic 모델로 질의 특성 구조화 추출. |
| 45 | + |
| 46 | +### Depth 3: 그래프(Graph) 워크플로우 |
| 47 | + |
| 48 | +- **`graph_utils/base.py`**: 공통 상태(`QueryMakerState`)와 노드 함수 집합. |
| 49 | + - 노드: `get_table_info_node`(RAG), `profile_extraction_node`, `query_refiner_node`/`query_refiner_with_profile_node`, `context_enrichment_node`, `query_maker_node`, `query_maker_node_without_refiner`. |
| 50 | + - 각 노드는 `chains.py`와 `retrieval.py`, `utils.profile_to_text` 등을 호출하며 상태를 갱신. |
| 51 | +- **`graph_utils/basic_graph.py`**: GET_TABLE_INFO → QUERY_REFINER → QUERY_MAKER → END |
| 52 | +- **`graph_utils/enriched_graph.py`**: GET_TABLE_INFO → PROFILE_EXTRACTION → QUERY_REFINER(with profile) → CONTEXT_ENRICHMENT → QUERY_MAKER → END |
| 53 | +- **`graph_utils/simplified_graph.py`**: GET_TABLE_INFO → PROFILE_EXTRACTION → CONTEXT_ENRICHMENT → QUERY_MAKER(without refiner) → END |
| 54 | + |
| 55 | +### 통합 흐름(End-to-End) |
| 56 | + |
| 57 | +1) 사용자가 자연어 질문 입력 → `query_executor.execute_query()` 호출 |
| 58 | +2) 그래프 선택(`basic`/`enriched`/`simplified`) 및 컴파일 |
| 59 | +3) `GET_TABLE_INFO`에서 `retrieval.search_tables()`로 관련 테이블/컬럼/예시쿼리/용어집 수집 |
| 60 | +4) `PROFILE_EXTRACTION`(선택)에서 `chains.profile_extraction_chain`으로 질문 특성 추출 → `utils.profile_to_text` |
| 61 | +5) `QUERY_REFINER`(선택) 또는 `CONTEXT_ENRICHMENT`로 질문을 정교화/보강 |
| 62 | +6) `QUERY_MAKER`에서 DB 가이드/메타를 바탕으로 SQL 생성 (`<SQL>` 코드블록 포함 권장) |
| 63 | +7) 반환 `messages`에서 `llm_response_parser.extract_sql()`로 SQL 추출 |
| 64 | +8) 필요 시 `connect_db.run_sql()`로 실행, `display_chart`로 결과 시각화 |
| 65 | + |
| 66 | +### 환경 변수 요약 |
| 67 | + |
| 68 | +- **LLM 관련**: `LLM_PROVIDER`, `OPEN_AI_KEY`, `OPEN_AI_LLM_MODEL`, `AZURE_*`, `AWS_BEDROCK_*`, `GEMINI_*`, `OLLAMA_*`, `HUGGING_FACE_*` |
| 69 | +- **임베딩 관련**: `EMBEDDING_PROVIDER`, 각 공급자별 키/모델 |
| 70 | +- **VectorDB**: `VECTORDB_TYPE`(faiss|pgvector), `VECTORDB_LOCATION`, `PGVECTOR_*` |
| 71 | +- **DataHub**: `DATAHUB_SERVER` |
| 72 | +- **ClickHouse**: `CLICKHOUSE_HOST`, `CLICKHOUSE_PORT`, `CLICKHOUSE_DATABASE`, `CLICKHOUSE_USER`, `CLICKHOUSE_PASSWORD` |
| 73 | + |
| 74 | +### 핵심 사용 예시 |
| 75 | + |
| 76 | +```python |
| 77 | +from engine.query_executor import execute_query, extract_sql_from_result |
| 78 | + |
| 79 | +res = execute_query( |
| 80 | + query="지난달 매출 추이 보여줘", |
| 81 | + database_env="postgres", |
| 82 | + retriever_name="Reranker", |
| 83 | + top_n=5, |
| 84 | + device="cpu", |
| 85 | + use_enriched_graph=True, |
| 86 | +) |
| 87 | + |
| 88 | +sql = extract_sql_from_result(res) |
| 89 | +``` |
| 90 | + |
| 91 | +```python |
| 92 | +from viz.display_chart import DisplayChart |
| 93 | + |
| 94 | +chart = DisplayChart(question="지난달 매출 추이", sql=sql, df_metadata=str(df.dtypes)) |
| 95 | +code = chart.generate_plotly_code() |
| 96 | +fig = chart.get_plotly_figure(code, df) |
| 97 | +``` |
| 98 | + |
| 99 | +### 파일간 의존 관계(요약) |
| 100 | + |
| 101 | +- `query_executor.py` → `graph_utils/*` → `chains.py`, `retrieval.py`, `llm_factory.py`, `utils.py` |
| 102 | +- `retrieval.py` → `vectordb/*` → `llm_factory.get_embeddings()`, `tools.get_info_from_db()` |
| 103 | +- `display_chart.py` → OpenAI LLM(선택적)로 코드 생성 → Plotly 실행 |
| 104 | +- `connect_db.py` → ClickHouse 클라이언트로 SQL 실행 |
| 105 | +- `llm_response_parser.py` → 결과 파서 |
| 106 | + |
| 107 | + |
0 commit comments