8000 Lang2SQL/interface at master Β· ContinuousAnalysis/Lang2SQL Β· GitHub
[go: up one dir, main page]

Skip to content

Latest commit

Β 

History

History
Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

README.md

interface

Streamlit 기반 Lang2SQL 데이터 뢄석 λ„κ΅¬μ˜ μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€ λ ˆμ΄μ–΄μž…λ‹ˆλ‹€.

디렉토리 ꡬ쑰

interface/
β”œβ”€β”€ app_pages/                    # Streamlit νŽ˜μ΄μ§€λ“€
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ chatbot.py                # AI ChatBot νŽ˜μ΄μ§€
β”‚   β”œβ”€β”€ graph_builder.py          # LangGraph ꡬ성 νŽ˜μ΄μ§€
β”‚   β”œβ”€β”€ home.py                   # ν™ˆ νŽ˜μ΄μ§€
β”‚   β”œβ”€β”€ lang2sql.py               # Lang2SQL 메인 νŽ˜μ΄μ§€
β”‚   β”œβ”€β”€ settings.py               # μ„€μ • νŽ˜μ΄μ§€ (νƒ­ ꡬ성)
β”‚   β”œβ”€β”€ sidebar_components/       # μ‚¬μ΄λ“œλ°” UI μ»΄ν¬λ„ŒνŠΈ
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ chatbot_session_controller.py
β”‚   β”‚   β”œβ”€β”€ data_source_selector.py
β”‚   β”‚   β”œβ”€β”€ db_selector.py
β”‚   β”‚   β”œβ”€β”€ embedding_selector.py
β”‚   β”‚   β”œβ”€β”€ llm_selector.py
β”‚   β”‚   └── README.md
β”‚   └── settings_sections/        # μ„€μ • νŽ˜μ΄μ§€ μ„Ήμ…˜λ“€
β”‚       β”œβ”€β”€ __init__.py
β”‚       β”œβ”€β”€ data_source_section.py
β”‚       β”œβ”€β”€ db_section.py
β”‚       β”œβ”€β”€ llm_section.py
β”‚       └── README.md
β”œβ”€β”€ core/                         # 핡심 μΈν„°νŽ˜μ΄μŠ€ 둜직
β”‚   β”œβ”€β”€ config/                   # μ„€μ • 관리
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ models.py             # μ„€μ • 데이터 λͺ¨λΈ
β”‚   β”‚   β”œβ”€β”€ paths.py              # 파일 경둜 관리
β”‚   β”‚   β”œβ”€β”€ persist.py            # λ””μŠ€ν¬ μ €μž₯/λ‘œλ“œ
β”‚   β”‚   β”œβ”€β”€ registry_data_sources.py
β”‚   β”‚   β”œβ”€β”€ registry_db.py
β”‚   β”‚   β”œβ”€β”€ registry_llm.py
β”‚   β”‚   └── settings.py           # μ„€μ • μ—…λ°μ΄νŠΈ API
β”‚   β”œβ”€β”€ dialects.py               # SQL λ‹€μ΄μ–Όλ ‰νŠΈ 프리셋
β”‚   β”œβ”€β”€ lang2sql_runner.py        # Lang2SQL μ‹€ν–‰ 래퍼
β”‚   β”œβ”€β”€ result_renderer.py        # κ²°κ³Ό μ‹œκ°ν™”
β”‚   └── session_utils.py          # μ„Έμ…˜ 관리
β”œβ”€β”€ pages_config.py               # νŽ˜μ΄μ§€ ꡬ성
└── streamlit_app.py              # 메인 μ§„μž…μ 

μ•„ν‚€ν…μ²˜ κ°œμš”

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        streamlit_app.py                         β”‚
β”‚                    (메인 μ§„μž…μ , νŽ˜μ΄μ§€ λ„€λΉ„κ²Œμ΄μ…˜)                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  pages_config.py β”‚
                    β”‚   (νŽ˜μ΄μ§€ μ„€μ •)    β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                    β”‚                    β”‚
        β–Ό                    β–Ό                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   home.py     β”‚   β”‚ lang2sql.py   β”‚   β”‚  chatbot.py   β”‚
β”‚  (ν™ˆ/μ†Œκ°œ)     β”‚   β”‚ (메인 κΈ°λŠ₯)    β”‚   β”‚  (AI μ±„νŒ…)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                   β”‚
        β”‚          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚          β”‚                 β”‚
        β–Ό          β–Ό                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚graph_builder.pyβ”‚ β”‚ settings.py   β”‚ β”‚sidebar_componentsβ”‚
β”‚  (κ·Έλž˜ν”„ ꡬ성) β”‚ β”‚ (μ„€μ •)        β”‚ β”‚   (μ‚¬μ΄λ“œλ°”)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚                 β”‚
                          β–Ό                 β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚settings_sectionsβ”‚  β”‚ core/config/   β”‚
                  β”‚ (μ„€μ • UI)      β”‚  β”‚ (μ„€μ • 관리)    β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
                                               β–Ό
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚ core/            β”‚
                                    β”‚ - dialects.py    β”‚
                                    β”‚ - lang2sql_runnerβ”‚
                                    β”‚ - result_rendererβ”‚
                                    β”‚ - session_utils  β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” μ»΄ν¬λ„ŒνŠΈ

1. streamlit_app.py

Streamlit μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 메인 μ§„μž…μ μž…λ‹ˆλ‹€.

μ—­ν• :

  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ—­ μ„€μ • μ΄ˆκΈ°ν™” (제λͺ©, μ•„μ΄μ½˜, λ ˆμ΄μ•„μ›ƒ)
  • νŽ˜μ΄μ§€ λ„€λΉ„κ²Œμ΄μ…˜ ꡬ성 및 μ‹€ν–‰

μ£Όμš” ν•¨μˆ˜:

  • configure_app(): Streamlit μ „μ—­ μ„€μ •
  • main(): μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ§„μž…μ 

μ‚¬μš© μ˜ˆμ‹œ:

# streamlit run interface/streamlit_app.py

μ˜μ‘΄μ„±:

  • interface.pages_config.PAGES: νŽ˜μ΄μ§€ λͺ©λ‘

2. pages_config.py

Streamlit νŽ˜μ΄μ§€ ꡬ성 μ •μ˜ λͺ¨λ“ˆμž…λ‹ˆλ‹€.

μ—­ν• :

  • 각 νŽ˜μ΄μ§€μ˜ κ²½λ‘œμ™€ 제λͺ© μ •μ˜
  • λ„€λΉ„κ²Œμ΄μ…˜μ— μ‚¬μš©λ˜λŠ” νŽ˜μ΄μ§€ 리슀트 제곡

λ‚΄μš©:

  • PAGES: 5개 νŽ˜μ΄μ§€ μ •μ˜
    • ν™ˆ (home.py)
    • Lang2SQL (lang2sql.py)
    • κ·Έλž˜ν”„ λΉŒλ” (graph_builder.py)
    • ChatBot (chatbot.py)
    • μ„€μ • (settings.py)

μ‚¬μš©μ²˜:

  • streamlit_app.py (line 9, 37)

3. app_pages/

Streamlit μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 각 νŽ˜μ΄μ§€ λͺ¨λ“ˆλ“€μž…λ‹ˆλ‹€.

3.1. home.py

ν™ˆ νŽ˜μ΄μ§€λ‘œ Lang2SQL 도ꡬ μ†Œκ°œ 및 μ‚¬μš© 방법 μ•ˆλ‚΄λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

μ£Όμš” λ‚΄μš©:

  • 도ꡬ μ†Œκ°œ 및 ν™˜μ˜ λ©”μ‹œμ§€
  • μ‚¬μš© 방법 κ°€μ΄λ“œ
  • μ£Όμš” κΈ°λŠ₯ 링크 μ•ˆλ‚΄

μ‚¬μš©μ²˜:

  • pages_config.py (line 18)

3.2. lang2sql.py

Lang2SQL 메인 νŽ˜μ΄μ§€λ‘œ μžμ—°μ–΄ 질의λ₯Ό SQL 쿼리둜 λ³€ν™˜ν•˜κ³  κ²°κ³Όλ₯Ό μ‹œκ°ν™”ν•©λ‹ˆλ‹€.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        πŸ” Lang2SQL                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   Sidebar        β”‚            β”‚    Main Area          β”‚ β”‚
β”‚  β”‚                  β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚            β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚ β”‚Data Source   β”‚ β”‚            β”‚ │쿼리 μž…λ ₯ μ˜μ—­        β”‚ β”‚ β”‚
β”‚  β”‚ β”‚Selector      β”‚ β”‚            β”‚ β”‚                   β”‚ β”‚ β”‚
β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚            β”‚ β”‚"고객 데이터λ₯Ό..."    β”‚ β”‚ β”‚
β”‚  β”‚ ──────────────── β”‚            β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ β”‚LLM Selector  β”‚ β”‚            β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚            β”‚ β”‚DB 선택 및 관리      β”‚ β”‚ β”‚
β”‚  β”‚ ──────────────── β”‚            β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ β”‚Embedding Sel.β”‚ β”‚            β”‚ [검색기 μœ ν˜•]          β”‚ β”‚
β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚            β”‚ [Top-N 개수]          β”‚ β”‚
β”‚  β”‚ ──────────────── β”‚            β”‚ [λͺ¨λΈ μ‹€ν–‰ μž₯치]        β”‚ β”‚
β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ β”‚DB Selector   β”‚ β”‚            β”‚   [쿼리 μ‹€ν–‰]         β”‚ β”‚
β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ ──────────────── β”‚            β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚ Output Settings  β”‚            β”‚ β”‚  κ²°κ³Ό ν‘œμ‹œ μ˜μ—­     β”‚ β”‚ β”‚
β”‚  β”‚ β–‘ Token Usage    β”‚            β”‚ β”‚  - SQL 쿼리        β”‚ β”‚ β”‚
β”‚  β”‚ β–‘ Result Desc    β”‚            β”‚ β”‚  - κ²°κ³Ό ν…Œμ΄λΈ”      β”‚ β”‚ β”‚
β”‚  β”‚ β–‘ Show SQL       β”‚            β”‚ β”‚  - 차트           β”‚ β”‚ β”‚
β”‚  β”‚ ...              β”‚            β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β”‚ ──────────────── β”‚            β”‚                       β”‚ β”‚
β”‚  β”‚ μ›Œν¬ν”Œλ‘œμš° 선택     β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚  β”‚ β—‹ κΈ°λ³Έ            β”‚                                      β”‚
β”‚  β”‚ β—‹ ν™•μž₯            β”‚                                      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” κΈ°λŠ₯:

  • μ‚¬μ΄λ“œλ°” μ„€μ •: 데이터 μ†ŒμŠ€, LLM, Embedding, DB 선택
  • 좜λ ₯ μ˜΅μ…˜ μ„€μ • (토큰 μ‚¬μš©λŸ‰, SQL ν‘œμ‹œ, 차트 λ“±)
  • μ›Œν¬ν”Œλ‘œμš° 선택 (κΈ°λ³Έ/ν™•μž₯)
  • μžμ—°μ–΄ 질의 μž…λ ₯ 및 SQL λ³€ν™˜ μ‹€ν–‰
  • DB λ‹€μ΄μ–Όλ ‰νŠΈ 선택 및 νŽΈμ§‘
  • 검색기 μœ ν˜• 및 Top-N μ„€μ •
  • κ²°κ³Ό μ‹œκ°ν™” (ν…Œμ΄λΈ”, 차트)

μ£Όμš” ν•¨μˆ˜:

  • νŽ˜μ΄μ§€ λ ˆλ²¨μ—μ„œ 직접 μ‹€ν–‰λ˜λŠ” Streamlit UI μ½”λ“œ

μ‚¬μš© λͺ¨λ“ˆ:

  • interface.core.dialects: λ‹€μ΄μ–Όλ ‰νŠΈ 프리셋
  • interface.core.lang2sql_runner: Lang2SQL μ‹€ν–‰
  • interface.core.result_renderer: κ²°κ³Ό μ‹œκ°ν™”
  • interface.core.session_utils: κ·Έλž˜ν”„ μ΄ˆκΈ°ν™”
  • interface.app_pages.sidebar_components: μ‚¬μ΄λ“œλ°” μ»΄ν¬λ„ŒνŠΈ

μ˜μ‘΄μ„±:

  • engine.query_executor.execute_query: μ‹€μ œ 쿼리 μ‹€ν–‰

3.3. graph_builder.py

LangGraph μ›Œν¬ν”Œλ‘œμš°λ₯Ό κ΅¬μ„±ν•˜κ³  μ„Έμ…˜μ— μ μš©ν•˜λŠ” νŽ˜μ΄μ§€μž…λ‹ˆλ‹€.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   LangGraph ꡬ성 UI                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  프리셋 선택:  β—‹ κΈ°λ³Έ  β—‹ ν™•μž₯  β—‹ μ»€μŠ€ν…€                    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  μ»€μŠ€ν…€ μ˜΅μ…˜:                                           β”‚ β”‚
β”‚  β”‚  β˜‘ PROFILE_EXTRACTION 포함                              β”‚ β”‚
β”‚  β”‚  β˜‘ CONTEXT_ENRICHMENT 포함                              β”‚ β”‚
β”‚  β”‚  β˜‘ QUERY_MAKER 포함                                     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  GET_TABLE_INFO μ„€μ •:                                   β”‚ β”‚
β”‚  β”‚  - ν…Œμ΄λΈ” 검색기: [벑터 검색 (κΈ°λ³Έ) β–Ό]                   β”‚ β”‚
β”‚  β”‚  - 검색할 ν…Œμ΄λΈ” 정보 개수: [====●====] 5               β”‚ β”‚
β”‚  β”‚  - λͺ¨λΈ μ‹€ν–‰ μž₯치: [cpu β–Ό]                             β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  μ‹€ν–‰ μˆœμ„œ:                                             β”‚ β”‚
β”‚  β”‚  GET_TABLE_INFO β†’ PROFILE_EXTRACTION β†’ ...             β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  κ·Έλž˜ν”„ 생성:                                           β”‚ β”‚
β”‚  β”‚  ℹ️ κ·Έλž˜ν”„κ°€ μ„Έμ…˜μ— μ μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.                       β”‚ β”‚
β”‚  β”‚  [μ„Έμ…˜ κ·Έλž˜ν”„ μƒˆλ‘œκ³ μΉ¨]                                 β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  ν˜„μž¬ μ„Έμ…˜ κ·Έλž˜ν”„ μ„€μ • (expander)                        β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” κΈ°λŠ₯:

  • 프리셋 선택: κΈ°λ³Έ, ν™•μž₯, μ»€μŠ€ν…€
  • λ…Έλ“œ μ‹œν€€μŠ€ ꡬ성 (GET_TABLE_INFO β†’ PROFILE β†’ CONTEXT β†’ QUERY_MAKER)
  • GET_TABLE_INFO μ„€μ • (검색기, Top-N, μž₯치)
  • κ·Έλž˜ν”„ μ„Έμ…˜μ— 적용 및 μƒˆλ‘œκ³ μΉ¨
  • ν˜„μž¬ κ·Έλž˜ν”„ μ„€μ • 확인

μ£Όμš” ν•¨μˆ˜:

  • build_selected_sequence(): 프리셋에 λ”°λ₯Έ λ…Έλ“œ μ‹œν€€μŠ€ 생성
  • build_state_graph(): StateGraph λΉŒλ” 생성
  • render_sequence(): μ‹œν€€μŠ€λ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜

μ‚¬μš© λͺ¨λ“ˆ:

  • utils.llm.graph_utils.base: λ…Έλ“œ μ •μ˜ 및 κ·Έλž˜ν”„ μœ ν‹Έ

3.4. chatbot.py

AI ChatBot νŽ˜μ΄μ§€λ‘œ LangGraph 기반 λŒ€ν™”ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     πŸ€– AI ChatBot                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Sidebar                  β”‚  Chat Area                       β”‚
β”‚                           β”‚                                  β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚Data Source Selector   β”‚ β”‚ β”‚ μ•ˆλ…•ν•˜μ„Έμš”! 무엇을... πŸ€–      β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ ───────────────────────── β”‚                                 β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚LLM Selector           β”‚ β”‚ β”‚ μ‚¬μš©μž: λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”... β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ ───────────────────────── β”‚                                 β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚Embedding Selector     β”‚ β”‚ β”‚ Assistant: κ΄€λ ¨ ν…Œμ΄λΈ”μ€...  β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ πŸ€– λͺ¨λΈ: gpt-4o-mini         β”‚ β”‚
β”‚ ───────────────────────── β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                                 β”‚
β”‚ β”‚DB Selector            β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ μ‚¬μš©μž: [μž…λ ₯ 쀑...]         β”‚ β”‚
β”‚ ───────────────────────── β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ πŸ€– ChatBot μ„€μ •           β”‚                                 β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                                 β”‚
β”‚ β”‚ Thread ID: uuid...    β”‚ β”‚                                 β”‚
β”‚ β”‚ [μƒˆ μ„Έμ…˜ μ‹œμž‘]         β”‚ β”‚                                 β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚                                 β”‚
β”‚ ───────────────────────── β”‚                                 β”‚
β”‚ λŒ€ν™” 기둝:                β”‚                                 β”‚
β”‚ - Thread ID              β”‚                                 β”‚
β”‚ - λ©”μ‹œμ§€ λͺ©λ‘ (JSON)       β”‚                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” κΈ°λŠ₯:

  • OpenAI 기반 λŒ€ν™”ν˜• AI μ±„νŒ…
  • μ‚¬μ΄λ“œλ°” μ„€μ •: 데이터 μ†ŒμŠ€, LLM, Embedding, DB
  • Thread ID 기반 μ„Έμ…˜ 관리
  • λŒ€ν™” 기둝 ν‘œμ‹œ 및 관리
  • μ‹ κ·œ μ„Έμ…˜ μ‹œμž‘ κΈ°λŠ₯

μ£Όμš” ν•¨μˆ˜:

  • initialize_session_state(): μ„Έμ…˜ μƒνƒœ μ΄ˆκΈ°ν™” 및 ChatBot μΈμŠ€ν„΄μŠ€ 생성

μ‚¬μš© λͺ¨λ“ˆ:

  • utils.llm.chatbot.ChatBot: ChatBot 핡심 둜직
  • interface.app_pages.sidebar_components: μ‚¬μ΄λ“œλ°” μ»΄ν¬λ„ŒνŠΈ
  • interface.core.config.load_config: μ„€μ • λ‘œλ“œ

μ œμ•½μ‚¬ν•­:

  • ν˜„μž¬ OpenAI만 지원
  • OpenAI API ν‚€ ν•„μˆ˜

3.5. settings.py

μ„€μ • νŽ˜μ΄μ§€λ‘œ 데이터 μ†ŒμŠ€, LLM, DB 섀정을 νƒ­μœΌλ‘œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        βš™οΈ μ„€μ •                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”‚
β”‚  │데이터 μ†ŒμŠ€ β”‚  LLM     β”‚   DB     β”‚                         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        
8000
                 β”‚
β”‚                                                              β”‚
β”‚  [μ„ νƒλœ νƒ­ λ‚΄μš© ν‘œμ‹œ]                                        β”‚
β”‚                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” κΈ°λŠ₯:

  • 3개 νƒ­μœΌλ‘œ ꡬ성: 데이터 μ†ŒμŠ€, LLM, DB
  • 각 탭은 settings_sections λͺ¨λ“ˆ μ‚¬μš©
  • μ„Έμ…˜ μš°μ„  μ„€μ • 반영

μ‚¬μš© λͺ¨λ“ˆ:

  • interface.app_pages.settings_sections: 각 μ„€μ • μ„Ήμ…˜

3.6. sidebar_components/

μ‚¬μ΄λ“œλ°”μ—μ„œ μ‚¬μš©λ˜λŠ” μ„€μ • 선택 μ»΄ν¬λ„ŒνŠΈλ“€μž…λ‹ˆλ‹€.

λͺ¨λ“ˆ ꡬ쑰:

  • data_source_selector.py: 데이터 μ†ŒμŠ€ 선택 (DataHub/VectorDB)
  • llm_selector.py: LLM ν”„λ‘œνŒŒμΌ 선택
  • embedding_selector.py: Embedding ν”„λ‘œνŒŒμΌ 선택
  • db_selector.py: DB ν”„λ‘œνŒŒμΌ 선택
  • chatbot_session_controller.py: ChatBot μ„Έμ…˜ 관리

μ‚¬μš©μ²˜:

  • lang2sql.py: 메인 νŽ˜μ΄μ§€ μ‚¬μ΄λ“œλ°”
  • chatbot.py: ChatBot νŽ˜μ΄μ§€ μ‚¬μ΄λ“œλ°”

μžμ„Έν•œ λ‚΄μš©: sidebar_components/README.md μ°Έκ³ 


3.7. settings_sections/

μ„€μ • νŽ˜μ΄μ§€μ˜ 각 μ„Ήμ…˜ UI λͺ¨λ“ˆλ“€μž…λ‹ˆλ‹€.

λͺ¨λ“ˆ ꡬ쑰:

  • data_source_section.py: DataHub/VectorDB 관리
  • llm_section.py: LLM 및 Embedding μ„€μ •
  • db_section.py: DB μ—°κ²° μ„€μ •

μ‚¬μš©μ²˜:

  • settings.py: μ„€μ • νŽ˜μ΄μ§€ νƒ­ λ‚΄μš©

μžμ„Έν•œ λ‚΄μš©: settings_sections/README.md μ°Έκ³ 


4. core/

핡심 μΈν„°νŽ˜μ΄μŠ€ λ‘œμ§μ„ λ‹΄λ‹Ήν•˜λŠ” λͺ¨λ“ˆλ“€μž…λ‹ˆλ‹€.

4.1. dialects.py

SQL λ‹€μ΄μ–Όλ ‰νŠΈ 프리셋 μ •μ˜ 및 관리 λͺ¨λ“ˆμž…λ‹ˆλ‹€.

μ£Όμš” λ‚΄μš©:

  • DialectOption: SQL μ—”μ§„ νŠΉμ„± λ°μ΄ν„°ν΄λž˜μŠ€
    • name: μ—”μ§„ ν‘œμ‹œ 이름
    • supports_ilike: ILIKE 지원 μ—¬λΆ€
    • hints: 자주 μ“°μ΄λŠ” ν•¨μˆ˜ λͺ©λ‘
  • PRESET_DIALECTS: 9개 SQL μ—”μ§„ 프리셋
    • PostgreSQL, ClickHouse, Trino, Snowflake, Redshift
    • BigQuery, MSSQL, Oracle, DuckDB

μ‚¬μš©μ²˜:

  • lang2sql.py (line 19, 85-124): DB 선택 및 νŽΈμ§‘ UI

4.2. lang2sql_runner.py

Lang2SQL μ‹€ν–‰ 래퍼 λͺ¨λ“ˆμž…λ‹ˆλ‹€.

μ£Όμš” ν•¨μˆ˜:

  • run_lang2sql(): μžμ—°μ–΄ 질의λ₯Ό SQL둜 λ³€ν™˜ ν›„ μ‹€ν–‰

νŒŒλΌλ―Έν„°:

  • query: μžμ—°μ–΄ 질문
  • database_env: λ°μ΄ν„°λ² μ΄μŠ€ ν™˜κ²½ 이름
  • retriever_name: 검색기 μœ ν˜•
  • top_n: 검색할 ν…Œμ΄λΈ” 정보 개수
  • device: λͺ¨λΈ μ‹€ν–‰ μž₯치

μ‚¬μš©μ²˜:

  • lang2sql.py (line 139-145): 쿼리 μ‹€ν–‰

μ˜μ‘΄μ„±:

  • engine.query_executor.execute_query: μ‹€μ œ μ‹€ν–‰ 둜직

4.3. result_renderer.py

Lang2SQL μ‹€ν–‰ κ²°κ³Ό μ‹œκ°ν™” λͺ¨λ“ˆμž…λ‹ˆλ‹€.

μ£Όμš” ν•¨μˆ˜:

  • display_result(): Streamlit UI둜 κ²°κ³Ό 좜λ ₯

ν‘œμ‹œ ν•­λͺ©:

  • Question Gate κ²°κ³Ό
  • λ¬Έμ„œ 적합성 평가
  • 토큰 μ‚¬μš©λŸ‰
  • SQL 쿼리 및 해석
  • κ²°κ³Ό μ„€λͺ…
  • μž¬ν•΄μ„λœ 질문
  • μ°Έκ³  ν…Œμ΄λΈ” λͺ©λ‘
  • 쿼리 μ‹€ν–‰ κ²°κ³Ό ν…Œμ΄λΈ”
  • κ²°κ³Ό 차트 (Plotly)

μ‚¬μš© λͺ¨λ“ˆ:

  • infra.observability.token_usage.TokenUtils: 토큰 μ‚¬μš©λŸ‰
  • utils.databases.DatabaseFactory: DB 컀λ„₯ν„°
  • utils.llm.llm_response_parser.LLMResponseParser: SQL νŒŒμ‹±
  • utils.visualization.display_chart.DisplayChart: 차트 생성

μ‚¬μš©μ²˜:

  • lang2sql.py (line 146): κ²°κ³Ό ν‘œμ‹œ

4.4. session_utils.py

Streamlit μ„Έμ…˜ μƒνƒœμ—μ„œ κ·Έλž˜ν”„ λΉŒλ”λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” λͺ¨λ“ˆμž…λ‹ˆλ‹€.

μ£Όμš” ν•¨μˆ˜:

  • init_graph(): κ·Έλž˜ν”„ μ΄ˆκΈ°ν™” 및 μ„Έμ…˜ μƒνƒœ κ°±μ‹ 

νŒŒλΌλ―Έν„°:

  • use_enriched: ν™•μž₯ κ·Έλž˜ν”„ μ‚¬μš© μ—¬λΆ€

λ°˜ν™˜κ°’:

  • κ·Έλž˜ν”„ μœ ν˜• λ¬Έμžμ—΄ ("ν™•μž₯된" λ˜λŠ” "κΈ°λ³Έ")

μ‚¬μš©μ²˜:

  • lang2sql.py (line 72, 76): κ·Έλž˜ν”„ μ΄ˆκΈ°ν™”

μ˜μ‘΄μ„±:

  • utils.llm.graph_utils.enriched_graph: ν™•μž₯ κ·Έλž˜ν”„
  • utils.llm.graph_utils.basic_graph: κΈ°λ³Έ κ·Έλž˜ν”„

4.5. config/

μ„€μ • 관리 νŒ¨ν‚€μ§€λ‘œ 데이터 μ†ŒμŠ€, DB, LLM, Embedding 섀정을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.

μ•„ν‚€ν…μ²˜:

config/
β”œβ”€β”€ models.py                    # 데이터 λͺ¨λΈ μ •μ˜
β”‚   β”œβ”€β”€ Config                   # μ „μ—­ μ„€μ •
β”‚   β”œβ”€β”€ DataHubSource           # DataHub μ†ŒμŠ€
β”‚   β”œβ”€β”€ VectorDBSource          # VectorDB μ†ŒμŠ€
β”‚   β”œβ”€β”€ DataSourcesRegistry     # 데이터 μ†ŒμŠ€ λ ˆμ§€μŠ€νŠΈλ¦¬
β”‚   β”œβ”€β”€ DBConnectionProfile     # DB ν”„λ‘œνŒŒμΌ
β”‚   β”œβ”€β”€ DBConnectionsRegistry   # DB λ ˆμ§€μŠ€νŠΈλ¦¬
β”‚   β”œβ”€β”€ LLMProfile              # LLM ν”„λ‘œνŒŒμΌ
β”‚   β”œβ”€β”€ LLMRegistry             # LLM λ ˆμ§€μŠ€νŠΈλ¦¬
β”‚   β”œβ”€β”€ EmbeddingProfile        # Embedding ν”„λ‘œνŒŒμΌ
β”‚   └── EmbeddingRegistry       # Embedding λ ˆμ§€μŠ€νŠΈλ¦¬
β”‚
β”œβ”€β”€ paths.py                     # 파일 경둜 관리
β”‚   β”œβ”€β”€ get_registry_file_path()      # 데이터 μ†ŒμŠ€ λ ˆμ§€μŠ€νŠΈλ¦¬ 경둜
β”‚   β”œβ”€β”€ get_db_registry_file_path()   # DB λ ˆμ§€μŠ€νŠΈλ¦¬ 경둜
β”‚   β”œβ”€β”€ get_llm_registry_file_path()  # LLM λ ˆμ§€μŠ€νŠΈλ¦¬ 경둜
β”‚   └── get_embedding_registry_file_path()  # Embedding λ ˆμ§€μŠ€νŠΈλ¦¬ 경둜
β”‚
β”œβ”€β”€ persist.py                   # λ””μŠ€ν¬ μ €μž₯/λ‘œλ“œ
β”‚   β”œβ”€β”€ save_registry_to_disk()       # 데이터 μ†ŒμŠ€ μ €μž₯
β”‚   β”œβ”€β”€ load_registry_from_disk()     # 데이터 μ†ŒμŠ€ λ‘œλ“œ
β”‚   β”œβ”€β”€ save_db_registry_to_disk()    # DB μ €μž₯
β”‚   β”œβ”€β”€ load_db_registry_from_disk()  # DB λ‘œλ“œ
β”‚   β”œβ”€β”€ save_llm_registry_to_disk()   # LLM μ €μž₯
β”‚   β”œβ”€β”€ load_llm_registry_from_disk() # LLM λ‘œλ“œ
β”‚   β”œβ”€β”€ save_embedding_registry_to_disk()   # Embedding μ €μž₯
β”‚   └── load_embedding_registry_from_disk() # Embedding λ‘œλ“œ
β”‚
β”œβ”€β”€ settings.py                  # μ„€μ • μ—…λ°μ΄νŠΈ API
β”‚   β”œβ”€β”€ load_config()                   # μ„€μ • λ‘œλ“œ
β”‚   β”œβ”€β”€ update_datahub_server()        # DataHub μ„œλ²„ μ—…λ°μ΄νŠΈ
β”‚   β”œβ”€β”€ update_data_source_mode()      # 데이터 μ†ŒμŠ€ λͺ¨λ“œ μ—…λ°μ΄νŠΈ
β”‚   β”œβ”€β”€ update_vectordb_settings()     # VectorDB μ„€μ • μ—…λ°μ΄νŠΈ
β”‚   β”œβ”€β”€ update_llm_settings()          # LLM μ„€μ • μ—…λ°μ΄νŠΈ
β”‚   β”œβ”€β”€ update_embedding_settings()    # Embedding μ„€μ • μ—…λ°μ΄νŠΈ
β”‚   └── update_db_settings()           # DB μ„€μ • μ—…λ°μ΄νŠΈ
β”‚
β”œβ”€β”€ registry_data_sources.py     # 데이터 μ†ŒμŠ€ λ ˆμ§€μŠ€νŠΈλ¦¬ 관리
β”‚   β”œβ”€β”€ get_data_sources_registry()    # λ ˆμ§€μŠ€νŠΈλ¦¬ 쑰회
β”‚   β”œβ”€β”€ add_datahub_source()           # DataHub μΆ”κ°€
β”‚   β”œβ”€β”€ update_datahub_source()        # DataHub μ—…λ°μ΄νŠΈ
β”‚   β”œβ”€β”€ delete_datahub_source()        # DataHub μ‚­μ œ
β”‚   β”œβ”€β”€ add_vectordb_source()          # VectorDB μΆ”κ°€
β”‚   β”œβ”€β”€ update_vectordb_source()       # VectorDB μ—…λ°μ΄νŠΈ
β”‚   └── delete_vectordb_source()       # VectorDB μ‚­μ œ
β”‚
β”œβ”€β”€ registry_db.py               # DB λ ˆμ§€μŠ€νŠΈλ¦¬ 관리
β”‚   β”œβ”€β”€ get_db_connections_registry()  # λ ˆμ§€μŠ€νŠΈλ¦¬ 쑰회
β”‚   β”œβ”€β”€ add_db_connection()            # DB μΆ”κ°€
β”‚   β”œβ”€β”€ update_db_connection()         # DB μ—…λ°μ΄νŠΈ
β”‚   └── delete_db_connection()         # DB μ‚­μ œ
β”‚
β”œβ”€β”€ registry_llm.py              # LLM/Embedding λ ˆμ§€μŠ€νŠΈλ¦¬ 관리
β”‚   β”œβ”€β”€ get_llm_registry()             # LLM λ ˆμ§€μŠ€νŠΈλ¦¬ 쑰회
β”‚   β”œβ”€β”€ save_llm_profile()             # LLM ν”„λ‘œνŒŒμΌ μ €μž₯
β”‚   β”œβ”€β”€ get_embedding_registry()       # Embedding λ ˆμ§€μŠ€νŠΈλ¦¬ 쑰회
β”‚   └── save_embedding_profile()       # Embedding ν”„λ‘œνŒŒμΌ μ €μž₯
β”‚
└── __init__.py                  # νŒ¨ν‚€μ§€ 곡개 API

μ„€μ • μš°μ„ μˆœμœ„:

  1. μ„Έμ…˜ μƒνƒœ (st.session_state)
  2. ν™˜κ²½ λ³€μˆ˜ (os.getenv)
  3. κΈ°λ³Έκ°’

μ €μž₯ μœ„μΉ˜:

  • κΈ°λ³Έ: ./config/ 디렉토리
  • ν™˜κ²½ λ³€μˆ˜λ‘œ μ˜€λ²„λΌμ΄λ“œ κ°€λŠ₯:
    • LANG2SQL_REGISTRY_PATH
    • LANG2SQL_DB_REGISTRY_PATH
    • LANG2SQL_LLM_REGISTRY_PATH
    • LANG2SQL_EMBEDDING_REGISTRY_PATH

μ‚¬μš© μ˜ˆμ‹œ:

from interface.core.config import load_config, get_data_sources_registry

# μ„€μ • λ‘œλ“œ
config = load_config()

# λ ˆμ§€μŠ€νŠΈλ¦¬ 쑰회
registry = get_data_sources_registry()

# DataHub μΆ”κ°€
from interface.core.config import add_datahub_source
add_datahub_source(
    name="Production",
    url="http://datahub.prod:8080",
    faiss_path="./prod/faiss",
    note="ν”„λ‘œλ•μ…˜ DataHub"
)

전체 데이터 흐름

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     μ‚¬μš©μž μž…λ ₯                              β”‚
β”‚              (μžμ—°μ–΄ 질의, μ„€μ • λ³€κ²½ λ“±)                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Streamlit UI Layer                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚ app_pages/  β”‚  β”‚  core/      β”‚  β”‚   config/   β”‚        β”‚
β”‚  β”‚ - lang2sql  β”‚  β”‚ - runner    β”‚  β”‚ - settings  β”‚        β”‚
β”‚  β”‚ - chatbot   β”‚  β”‚ - renderer  β”‚  β”‚ - registry  β”‚        β”‚
β”‚  β”‚ - settings  β”‚  β”‚ - dialects  β”‚  β”‚ - persist   β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Business Logic Layer                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚  engine/    β”‚  β”‚ utils/llm/  β”‚  β”‚ utils/data/ β”‚        β”‚
β”‚  β”‚ - executor  β”‚  β”‚ - graph     β”‚  β”‚ - databases β”‚        β”‚
β”‚  β”‚             β”‚  β”‚ - factory   β”‚  β”‚ - hub       β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                Data & External Services                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚ DataHub     β”‚  β”‚  Database   β”‚  β”‚  LLM APIs   β”‚        β”‚
β”‚  β”‚ VectorDB    β”‚  β”‚  (DBs)      β”‚  β”‚  (OpenAI,   β”‚        β”‚
β”‚  β”‚             β”‚  β”‚             β”‚  β”‚   AWS, etc) β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     κ²°κ³Ό λ°˜ν™˜                               β”‚
β”‚              (SQL, ν…Œμ΄λΈ”, 차트, μ„€λͺ… λ“±)                      β”‚
└──────────────
4D9A
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” μ„€μ • 파일

섀정은 JSON 파일둜 ./config/ 디렉토리에 μ €μž₯λ©λ‹ˆλ‹€.

  • data_sources.json: DataHub/VectorDB λ ˆμ§€μŠ€νŠΈλ¦¬
  • db_connections.json: DB ν”„λ‘œνŒŒμΌ λ ˆμ§€μŠ€νŠΈλ¦¬
  • llm_profiles.json: LLM ν”„λ‘œνŒŒμΌ λ ˆμ§€μŠ€νŠΈλ¦¬
  • embedding_profiles.json: Embedding ν”„λ‘œνŒŒμΌ λ ˆμ§€μŠ€νŠΈλ¦¬

μ˜ˆμ‹œ: data_sources.json

{
  "datahub": [
    {
      "name": "Local DataHub",
      "url": "http://localhost:8080",
      "faiss_path": "./dev/table_info_db",
      "note": "둜컬 개발 ν™˜κ²½"
    }
  ],
  "vectordb": [
    {
      "name": "Local FAISS",
      "type": "faiss",
      "location": "./dev/faiss_db",
      "collection_prefix": null,
      "note": "둜컬 벑터 DB"
    }
  ]
}

μ‚¬μš© 방법

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰

# 메인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰
streamlit run interface/streamlit_app.py

# λ˜λŠ”
python -m interface.streamlit_app

μ„€μ • 관리

from interface.core.config import (
    load_config,
    get_data_sources_registry,
    add_datahub_source,
    update_db_settings,
)

# μ„€μ • λ‘œλ“œ
config = load_config()

# DataHub μΆ”κ°€
add_datahub_source(
    name="Production",
    url="http://datahub.prod:8080",
    faiss_path="./prod/faiss"
)

# DB μ„€μ • μ—…λ°μ΄νŠΈ
update_db_settings(
    db_type="postgresql",
    values={"host": "localhost", "port": "5432", "user": "admin"},
    secrets={"password": "secret"}
)

μ˜μ‘΄μ„±

μ£Όμš” νŒ¨ν‚€μ§€:

  • streamlit: UI ν”„λ ˆμž„μ›Œν¬
  • pandas: 데이터 처리
  • plotly: 차트 μ‹œκ°ν™”
  • langchain_core: LLM λ©”μ‹œμ§€ 처리

ν”„λ‘œμ νŠΈ λ‚΄λΆ€ λͺ¨λ“ˆ:

  • engine.query_executor: 쿼리 μ‹€ν–‰
  • utils.llm: LLM κ΄€λ ¨ μœ ν‹Έλ¦¬ν‹°
  • utils.data: 데이터 κ΄€λ ¨ μœ ν‹Έλ¦¬ν‹°
  • utils.databases: λ°μ΄ν„°λ² μ΄μŠ€ μœ ν‹Έλ¦¬ν‹°
  • infra.observability: λͺ¨λ‹ˆν„°λ§ 및 κ΄€μ°°μ„±

μ°Έκ³  λ¬Έμ„œ

  • app_pages/sidebar_components/README.md: μ‚¬μ΄λ“œλ°” μ»΄ν¬λ„ŒνŠΈ 상세
  • app_pages/settings_sections/README.md: μ„€μ • μ„Ήμ…˜ 상세
  • README_UPDATE_CONDITION.md: λ¬Έμ„œ μ—…λ°μ΄νŠΈ κ°€μ΄λ“œ
0