diff --git a/README.md b/README.md index dc53629..e0e2d00 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ ## ๐Ÿš€ Lang2SQL์ด๋ž€? -Lang2SQL์€ ์ž์—ฐ์–ด ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”๋œ SQL ๋ฌธ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. LangGraph์™€ DataHub ํ†ตํ•ฉ์œผ๋กœ ๊ตฌ์ถ•๋˜์–ด, ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•œ ๊นŠ์€ ์ง€์‹ ์—†์ด๋„ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ์ž๋“ค์ด ํšจ์œจ์ ์ธ SQL ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. +Lang2SQL์€ ์ž์—ฐ์–ด๋ฅผ SQL๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. **define-by-run** ์ฒ ํ•™์— ๊ธฐ๋ฐ˜ํ•œ ๋ชจ๋“ˆ๋Ÿฌ ์•„ํ‚คํ…์ฒ˜๋กœ, ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•œ ๊นŠ์€ ์ง€์‹ ์—†์ด๋„ ํšจ์œจ์ ์ธ SQL ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ### ๐ŸŽฏ ์ฃผ์š” ๊ธฐ๋Šฅ - **๐Ÿ—ฃ๏ธ ์ž์—ฐ์–ด๋ฅผ SQL๋กœ ๋ณ€ํ™˜**: ์ผ์ƒ ์–ธ์–ด๋ฅผ ์ •ํ™•ํ•œ SQL ์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜ -- **๐Ÿ“Š ์Šค๋งˆํŠธ ํ…Œ์ด๋ธ” ๋ฐœ๊ฒฌ**: ์˜๋ฏธ๋ก ์  ๊ฒ€์ƒ‰์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ จ ํ…Œ์ด๋ธ”์„ ์ž๋™์œผ๋กœ ์ฐพ๊ธฐ -- **๐Ÿ” ์Šคํ‚ค๋งˆ ์ธ์‹**: DataHub ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์ •ํ™•ํ•œ ์ปฌ๋Ÿผ ๋งคํ•‘ -- **๐Ÿ› ๏ธ ์›น ์ธํ„ฐํŽ˜์ด์Šค**: ๋Œ€ํ™”ํ˜• Streamlit ์•ฑ์„ ํ†ตํ•œ ์‚ฌ์šฉ -- **๐Ÿ“ˆ ์‹œ๊ฐํ™”**: ์ƒ์„ฑ๋œ SQL ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์–‘ํ•œ ์ฐจํŠธ์™€ ๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™”ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ํŒŒ์•… -- **๐Ÿ—„๏ธ ์œ ์—ฐํ•œ VectorDB**: FAISS(๋กœ์ปฌ)์™€ pgvector(PostgreSQL) ์ค‘ ์„ ํƒ ๊ฐ€๋Šฅํ•œ ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ง€์› +- **๐Ÿ“Š ์Šค๋งˆํŠธ ํ…Œ์ด๋ธ” ๋ฐœ๊ฒฌ**: BM25 ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰๊ณผ ๋ฒกํ„ฐ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰์„ ๊ฒฐํ•ฉํ•œ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰ +- **๐Ÿ”Œ Port ๊ธฐ๋ฐ˜ ํ™•์žฅ**: LLM, DB, ์ž„๋ฒ ๋”ฉ, ๋ฒกํ„ฐ์Šคํ† ์–ด๋ฅผ Protocol ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ž์œ ๋กญ๊ฒŒ ๊ต์ฒด +- **๐Ÿ› ๏ธ ์›น ์ธํ„ฐํŽ˜์ด์Šค**: Streamlit ๊ธฐ๋ฐ˜ ๋Œ€ํ™”ํ˜• ์•ฑ (์ฟผ๋ฆฌ ์ƒ์„ฑ + ์ฑ—๋ด‡) +- **๐Ÿ“ˆ ์‹œ๊ฐํ™”**: SQL ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฐจํŠธ์™€ ๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™” +- **๐Ÿ—„๏ธ ์œ ์—ฐํ•œ VectorDB**: InMemory, FAISS(๋กœ์ปฌ), pgvector(PostgreSQL) ์ค‘ ์„ ํƒ ### ๐Ÿค” ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ์ œ @@ -59,7 +59,7 @@ Lang2SQL์€ ์ž์—ฐ์–ด ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”๋œ SQL ๋ฌธ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์˜คํ”ˆ # pip pip install lang2sql -# uv +# uv (๊ถŒ์žฅ) uv venv --python 3.11 source .venv/bin/activate uv add lang2sql @@ -68,17 +68,15 @@ uv add lang2sql ### ์†Œ์Šค์—์„œ ์„ค์น˜ ```bash -# ์†Œ์Šค ํด๋ก  git clone https://github.com/CausalInferenceLab/lang2sql.git cd lang2sql -# (๊ถŒ์žฅ) uv ์‚ฌ์šฉ -# uv ์„ค์น˜๊ฐ€ ๋˜์–ด ์žˆ๋‹ค๋ฉด ์•„๋ž˜ ๋‘ ์ค„๋กœ ๊ฐœ๋ฐœ ๋ชจ๋“œ ์„ค์น˜ +# uv (๊ถŒ์žฅ) uv venv --python 3.11 source .venv/bin/activate -uv pip install -e . +uv sync -# (๋Œ€์•ˆ) pip ์‚ฌ์šฉ +# pip python -m venv .venv source .venv/bin/activate pip install -e . @@ -86,58 +84,97 @@ pip install -e . --- -## ๐Ÿ› ๏ธ ์‚ฌ์šฉ๋ฒ• +## โšก ๋น ๋ฅธ ์‹œ์ž‘ (Python API) + +```python +from lang2sql import BaselineNL2SQL +from lang2sql.integrations.db import SQLAlchemyDB +from lang2sql.integrations.llm import OpenAILLM + +catalog = [ + { + "name": "orders", + "description": "๊ณ ๊ฐ ์ฃผ๋ฌธ ์ •๋ณด", + "columns": { + "order_id": "์ฃผ๋ฌธ ๊ณ ์œ  ID", + "customer_id": "๊ณ ๊ฐ ID", + "order_date": "์ฃผ๋ฌธ ์ผ์‹œ", + "amount": "์ฃผ๋ฌธ ๊ธˆ์•ก", + "status": "์ฃผ๋ฌธ ์ƒํƒœ", + }, + }, + { + "name": "customers", + "description": "๊ณ ๊ฐ ๋งˆ์Šคํ„ฐ", + "columns": { + "customer_id": "๊ณ ๊ฐ ID", + "name": "๊ณ ๊ฐ ์ด๋ฆ„", + "grade": "๊ณ ๊ฐ ๋“ฑ๊ธ‰: bronze / silver / gold", + }, + }, +] + +pipeline = BaselineNL2SQL( + catalog=catalog, + llm=OpenAILLM(model="gpt-4o-mini"), + db=SQLAlchemyDB("sqlite:///sample.db"), + db_dialect="sqlite", +) + +rows = pipeline.run("์ง€๋‚œ๋‹ฌ ์ฃผ๋ฌธ ๊ฑด์ˆ˜๋ฅผ ์•Œ๋ ค์ค˜") +print(rows) +``` -### ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค +### ํŒŒ์ดํ”„๋ผ์ธ ์„ ํƒ ๊ฐ€์ด๋“œ -Streamlit ์›น ์ธํ„ฐํŽ˜์ด์Šค ์‹คํ–‰: +| ํŒŒ์ดํ”„๋ผ์ธ | ๊ฒ€์ƒ‰ ๋ฐฉ์‹ | ์ ํ•ฉํ•œ ์ƒํ™ฉ | +|---|---|---| +| `BaselineNL2SQL` | BM25 ํ‚ค์›Œ๋“œ | ๋น ๋ฅธ ์‹œ์ž‘, ์นดํƒˆ๋กœ๊ทธ ๊ทœ๋ชจ ์†Œ~์ค‘๊ฐ„ | +| `HybridNL2SQL` | BM25 + Vector | ๊ฒ€์ƒ‰ ํ’ˆ์งˆ ์šฐ์„ , ๋น„์ฆˆ๋‹ˆ์Šค ๋ฌธ์„œ ํ™œ์šฉ | +| `EnrichedNL2SQL` | BM25 + Vector + Gate | ์šด์˜ ํ™˜๊ฒฝ, ๋ถ€์ ํ•ฉ ์งˆ๋ฌธ ํ•„ํ„ฐ๋ง ํ•„์š” | -```bash -lang2sql run-streamlit -``` +๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ [ํŠœํ† ๋ฆฌ์–ผ](docs/tutorials/01-quickstart.md)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. -์‚ฌ์šฉ์ž ์ •์˜ ํฌํŠธ๋กœ ์‹คํ–‰: +--- -```bash -lang2sql run-streamlit -p 8888 -``` +## ๐Ÿ› ๏ธ ์‚ฌ์šฉ๋ฒ• -**์ฐธ๊ณ **: -- Streamlit ์„œ๋ฒ„๋Š” `0.0.0.0` ์œผ๋กœ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์™ธ๋ถ€์—์„œ ์ ‘์† ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. -- `--datahub_server` ์˜ต์…˜์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(deprecated). DataHub ์„ค์ •์€ UI์˜ ์„ค์ • > ๋ฐ์ดํ„ฐ ์†Œ์Šค ํƒญ์—์„œ ๊ด€๋ฆฌํ•˜์„ธ์š”. +### CLI -### Graph Builder ํŽ˜์ด์ง€ +```bash +# Streamlit ์›น ์ธํ„ฐํŽ˜์ด์Šค ์‹คํ–‰ +lang2sql run-streamlit +lang2sql run-streamlit -p 8888 # ํฌํŠธ ์ง€์ • -Streamlit ์•ฑ์€ ๋ฉ€ํ‹ฐ ํŽ˜์ด์ง€ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ขŒ์ธก ๋„ค๋น„๊ฒŒ์ด์…˜์—์„œ "Graph Builder" ํŽ˜์ด์ง€๋ฅผ ์—ด์–ด LangGraph ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +# ์ž์—ฐ์–ด ์ฟผ๋ฆฌ ์‹คํ–‰ +lang2sql query "์ง€๋‚œ๋‹ฌ ์ฃผ๋ฌธ ๊ฑด์ˆ˜๋ฅผ ์ง‘๊ณ„ํ•ด์ค˜" -- ํ”„๋ฆฌ์…‹ ์„ ํƒ: "๊ธฐ๋ณธ" ๋˜๋Š” "ํ™•์žฅ" -- ์ปค์Šคํ…€ ์˜ต์…˜: `PROFILE_EXTRACTION`, `CONTEXT_ENRICHMENT`, `QUERY_MAKER` ํฌํ•จ ์—ฌ๋ถ€ ํ† ๊ธ€ -- ์„ ํƒ์ด ๋ฐ”๋€Œ๋ฉด ๊ทธ๋ž˜ํ”„๊ฐ€ ์ฆ‰์‹œ ์ปดํŒŒ์ผ๋˜์–ด ์„ธ์…˜์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค -- "์„ธ์…˜ ๊ทธ๋ž˜ํ”„ ์ƒˆ๋กœ๊ณ ์นจ" ๋ฒ„ํŠผ์œผ๋กœ ์ˆ˜๋™ ์žฌ์ ์šฉ ๊ฐ€๋Šฅ -- `QUERY_MAKER`๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด ํ…Œ์ด๋ธ” ๊ฒ€์ƒ‰ ์ •๋ณด๋งŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค +# enriched ํ”Œ๋กœ์šฐ (์งˆ๋ฌธ ๊ฒ€์ฆ + ํ”„๋กœํŒŒ์ผ๋ง + ์ปจํ…์ŠคํŠธ ๋ณด๊ฐ•) +lang2sql query "์ด๋ฒˆ ๋‹ฌ ์ˆœ๋งค์ถœ ํ•ฉ๊ณ„" --flow enriched --dialect sqlite --top-n 5 -### VectorDB ์„ ํƒ +# QuestionGate ๋น„ํ™œ์„ฑํ™” (enriched ์ „์šฉ) +lang2sql query "์ด๋ฒˆ ๋‹ฌ ์ˆœ๋งค์ถœ ํ•ฉ๊ณ„" --flow enriched --no-gate +``` -**์ฐธ๊ณ **: CLI ๋ ˆ๋ฒจ์˜ `--vectordb-type` ๋ฐ `--vectordb-location` ์˜ต์…˜์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(deprecated). Streamlit ์‹คํ–‰ ์‹œ VectorDB ์„ค์ •์€ UI์˜ ์„ค์ • > ๋ฐ์ดํ„ฐ ์†Œ์Šค ํƒญ์—์„œ ๊ด€๋ฆฌํ•˜์„ธ์š”. +**CLI ์˜ต์…˜:** -`query` ๋ช…๋ น์–ด์—์„œ๋Š” VectorDB ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +| ์˜ต์…˜ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… | +|------|--------|------| +| `--flow` | `baseline` | `baseline` ๋˜๋Š” `enriched` | +| `--dialect` | `None` | SQL ๋ฐฉ์–ธ (sqlite, postgresql, mysql, bigquery, duckdb) | +| `--top-n` | `5` | ๊ฒ€์ƒ‰ํ•  ์ตœ๋Œ€ ํ…Œ์ด๋ธ” ์ˆ˜ | +| `--no-gate` | `False` | QuestionGate ๋น„ํ™œ์„ฑํ™” (enriched ์ „์šฉ) | -```bash -# FAISS ์‚ฌ์šฉ (๊ธฐ๋ณธ๊ฐ’) -lang2sql query "์งˆ๋ฌธ" --vectordb-type faiss +> CLI๋Š” `.env` ํŒŒ์ผ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜(`LLM_PROVIDER`, `DB_TYPE` ๋“ฑ)๋ฅผ ์ฝ์–ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. `.env.example`์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. -# pgvector ์‚ฌ์šฉ -lang2sql query "์งˆ๋ฌธ" --vectordb-type pgvector +### Streamlit ์›น UI -# ์œ„์น˜ ์ง€์ • ์˜ˆ์‹œ -# FAISS: ์ธ๋ฑ์Šค ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์ง€์ • -lang2sql query "์งˆ๋ฌธ" --vectordb-type faiss --vectordb-location ./dev/table_info_db +Streamlit ์•ฑ์€ ๋ฉ€ํ‹ฐ ํŽ˜์ด์ง€ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค: -# pgvector: ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด ์ง€์ • -lang2sql query "์งˆ๋ฌธ" --vectordb-type pgvector --vectordb-location "postgresql://user:pass@host:5432/db" -``` - -์ฐธ๊ณ : DataHub ์—†์ด๋„ ๋ฏธ๋ฆฌ ์ค€๋น„๋œ VectorDB(FAISS ํŒŒ์ผ ํ˜น์€ pgvector ์ปฌ๋ ‰์…˜)๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ค€๋น„ ๋ฐฉ๋ฒ•์€ [๋ฒกํ„ฐ ๊ฒ€์ƒ‰ ํŠœํ† ๋ฆฌ์–ผ](docs/tutorials/03-vector-search.md)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. +- **๐Ÿ  ํ™ˆ** โ€” ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ +- **๐Ÿ” Lang2SQL** โ€” ์ž์—ฐ์–ด ์ฟผ๋ฆฌ โ†’ SQL ์ƒ์„ฑ ๋ฐ ์‹คํ–‰ +- **๐Ÿค– ChatBot** โ€” ๋ฉ€ํ‹ฐํ„ด ๋Œ€ํ™” ๊ธฐ๋ฐ˜ SQL ์ƒ์„ฑ +- **โš™๏ธ ์„ค์ •** โ€” LLM, DB, ์ž„๋ฒ ๋”ฉ, ๋ฐ์ดํ„ฐ ์†Œ์Šค ์„ค์ • ### ์ฒ˜์Œ ์‹œ์ž‘ํ•˜๊ธฐ @@ -146,120 +183,115 @@ lang2sql query "์งˆ๋ฌธ" --vectordb-type pgvector --vectordb-location "postgresql | ๋ฒˆํ˜ธ | ๋ฌธ์„œ | ๋‚ด์šฉ | |------|------|------| | 01 | [๋น ๋ฅธ ์‹œ์ž‘](docs/tutorials/01-quickstart.md) | 5๋ถ„ ์•ˆ์— NL2SQL ์‹คํ–‰ | -| 02 | [Baseline ํŒŒ์ดํ”„๋ผ์ธ](docs/tutorials/02-baseline.md) | ์‹ค์ œ DB ์—ฐ๊ฒฐ, DB Explorer | +| 02 | [Baseline ํŒŒ์ดํ”„๋ผ์ธ](docs/tutorials/02-baseline.md) | ์‹ค์ œ DB ์—ฐ๊ฒฐ, DB Explorer, Factory ํ•จ์ˆ˜ | | 03 | [๋ฒกํ„ฐ ๊ฒ€์ƒ‰](docs/tutorials/03-vector-search.md) | FAISS/pgvector ์ธ๋ฑ์‹ฑ | | 04 | [ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰](docs/tutorials/04-hybrid.md) | BM25 + Vector, EnrichedNL2SQL | -| 05 | [๊ณ ๊ธ‰](docs/tutorials/05-advanced.md) | ์ˆ˜๋™ ์กฐํ•ฉ, ์ปค์Šคํ…€ ์–ด๋Œ‘ํ„ฐ, Hook | - -### ์ž์—ฐ์–ด ์ฟผ๋ฆฌ ์‹คํ–‰ - -```bash -# ๊ธฐ๋ณธ ์‚ฌ์šฉ (FAISS, clickhouse, ๊ธฐ๋ณธ ๊ฒ€์ƒ‰๊ธฐ) -lang2sql query "๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์œ ๋‹ˆํฌํ•œ ์œ ์ € ์ˆ˜๋ฅผ ์นด์šดํŠธํ•˜๋Š” ์ฟผ๋ฆฌ" - -# ์˜ต์…˜ ์‚ฌ์šฉ ์˜ˆ์‹œ -lang2sql query "๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์œ ๋‹ˆํฌํ•œ ์œ ์ € ์ˆ˜๋ฅผ ์นด์šดํŠธํ•˜๋Š” ์ฟผ๋ฆฌ" \ - --database-env clickhouse \ - --retriever-name ๊ธฐ๋ณธ \ - --top-n 5 \ - --device cpu \ - --use-enriched-graph \ - --vectordb-type faiss \ - --vectordb-location ./dev/table_info_db - -# pgvector ์‚ฌ์šฉ ์˜ˆ์‹œ -lang2sql query "๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์œ ๋‹ˆํฌํ•œ ์œ ์ € ์ˆ˜๋ฅผ ์นด์šดํŠธํ•˜๋Š” ์ฟผ๋ฆฌ" \ - --vectordb-type pgvector \ - --vectordb-location "postgresql://postgres:postgres@localhost:5432/postgres" -``` - -**์ฃผ์š” ์˜ต์…˜ ์„ค๋ช…:** -- `--database-env`: ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ™˜๊ฒฝ (๊ธฐ๋ณธ๊ฐ’: clickhouse) -- `--retriever-name`: ํ…Œ์ด๋ธ” ๊ฒ€์ƒ‰๊ธฐ ์ด๋ฆ„ (๊ธฐ๋ณธ๊ฐ’: ๊ธฐ๋ณธ) -- `--top-n`: ๊ฒ€์ƒ‰๋œ ์ƒ์œ„ ํ…Œ์ด๋ธ” ์ˆ˜ ์ œํ•œ (๊ธฐ๋ณธ๊ฐ’: 5) -- `--device`: LLM ์‹คํ–‰์— ์‚ฌ์šฉํ•  ๋””๋ฐ”์ด์Šค (๊ธฐ๋ณธ๊ฐ’: cpu) -- `--use-enriched-graph`: ํ™•์žฅ๋œ ๊ทธ๋ž˜ํ”„(ํ”„๋กœํŒŒ์ผ ์ถ”์ถœ + ์ปจํ…์ŠคํŠธ ๋ณด๊ฐ•) ์‚ฌ์šฉ ์—ฌ๋ถ€ -- `--vectordb-type`: ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํƒ€์ž… ("faiss" ๋˜๋Š” "pgvector", ๊ธฐ๋ณธ๊ฐ’: faiss) -- `--vectordb-location`: VectorDB ์œ„์น˜ (FAISS: ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ, pgvector: ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด) - -### ํ™˜๊ฒฝ ์„ค์ • +| 05 | [๊ณ ๊ธ‰](docs/tutorials/05-advanced.md) | ์ˆ˜๋™ ์กฐํ•ฉ, ์ปค์Šคํ…€ ์–ด๋Œ‘ํ„ฐ, Port ๋ ˆํผ๋Ÿฐ์Šค, Hook | -- `.env` ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ์„ค์ •์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ์‹œ ํŒŒ์ผ์ด ์žˆ๋‹ค๋ฉด ์ฐธ์กฐ) -- ๋˜๋Š” CLI ์˜ต์…˜์œผ๋กœ ํ™˜๊ฒฝ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: - - `--env-file-path`: ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ ๊ฒฝ๋กœ ์ง€์ • - - `--prompt-dir-path`: ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ(.md) ๋””๋ ‰ํ† ๋ฆฌ ์ง€์ • - - `--datahub_server`: [Deprecated] DataHub GMS ์„œ๋ฒ„ URL ์ง€์ •. ์ด์ œ๋Š” UI์˜ ์„ค์ • > ๋ฐ์ดํ„ฐ ์†Œ์Šค ํƒญ์—์„œ ๊ด€๋ฆฌํ•˜์„ธ์š”. +--- ## ๐Ÿ—๏ธ ์•„ํ‚คํ…์ฒ˜ -Lang2SQL์€ LangGraph๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค๋‹จ๊ณ„ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค: - -1. **๐Ÿ“ ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ**: ์‚ฌ์šฉ์ž ์˜๋„ ํŒŒ์‹ฑ ๋ฐ ํ•ต์‹ฌ ์—”ํ‹ฐํ‹ฐ ์ถ”์ถœ -2. **๐Ÿ” ํ…Œ์ด๋ธ” ๊ฒ€์ƒ‰**: ์˜๋ฏธ๋ก ์  ์œ ์‚ฌ์„ฑ์„ ์‚ฌ์šฉํ•œ ๊ด€๋ จ ํ…Œ์ด๋ธ” ์ฐพ๊ธฐ (Vector Search) -3. **โš™๏ธ SQL ์ƒ์„ฑ**: ์ตœ์ ํ™”๋œ SQL ์ฟผ๋ฆฌ ์ƒ์„ฑ -4. **๐Ÿš€ ์ฟผ๋ฆฌ ์‹œ๊ฐํ™”**: ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์‹œ๊ฐํ™” ํ•ฉ๋‹ˆ๋‹ค. +Lang2SQL v2๋Š” **define-by-run** ์ฒ ํ•™์„ ๋”ฐ๋ฅด๋Š” ๋ชจ๋“ˆ๋Ÿฌ ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ ์ œ์–ด๋Š” ํ”„๋ ˆ์ž„์›Œํฌ DSL์ด ์•„๋‹Œ ์ˆœ์ˆ˜ Python ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ---- +``` +src/lang2sql/ +โ”œโ”€โ”€ core/ # ์™ธ๋ถ€ ์˜์กด์„ฑ 0% โ€” ์ ˆ๋Œ€ third-party import ๊ธˆ์ง€ +โ”‚ โ”œโ”€โ”€ base.py # BaseComponent, BaseFlow +โ”‚ โ”œโ”€โ”€ catalog.py # CatalogEntry, TextDocument, IndexedChunk +โ”‚ โ”œโ”€โ”€ ports.py # LLMPort, DBPort, EmbeddingPort ๋“ฑ Protocol ์ธํ„ฐํŽ˜์ด์Šค +โ”‚ โ”œโ”€โ”€ hooks.py # TraceHook, MemoryHook (๊ด€์ธก์„ฑ) +โ”‚ โ””โ”€โ”€ exceptions.py +โ”‚ +โ”œโ”€โ”€ components/ # ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ถ€ํ’ˆ +โ”‚ โ”œโ”€โ”€ retrieval/ # KeywordRetriever, VectorRetriever, HybridRetriever +โ”‚ โ”œโ”€โ”€ generation/ # SQLGenerator (dialect๋ณ„ ํ”„๋กฌํ”„ํŠธ) +โ”‚ โ”œโ”€โ”€ execution/ # SQLExecutor +โ”‚ โ”œโ”€โ”€ gate/ # QuestionGate, TableSuitabilityEvaluator +โ”‚ โ”œโ”€โ”€ enrichment/ # QuestionProfiler, ContextEnricher +โ”‚ โ””โ”€โ”€ loaders/ # MarkdownLoader, PlainTextLoader, DirectoryLoader +โ”‚ +โ”œโ”€โ”€ flows/ # ํ”„๋ฆฌ์…‹ ํŒŒ์ดํ”„๋ผ์ธ +โ”‚ โ”œโ”€โ”€ nl2sql.py # BaselineNL2SQL (Keyword โ†’ SQL โ†’ Execute) +โ”‚ โ”œโ”€โ”€ hybrid.py # HybridNL2SQL (BM25 + Vector) +โ”‚ โ””โ”€โ”€ enriched_nl2sql.py # EnrichedNL2SQL (Gate + Profile + Enrich) +โ”‚ +โ””โ”€โ”€ integrations/ # ์™ธ๋ถ€ ์˜์กด์„ฑ ๊ตฌํ˜„์ฒด + โ”œโ”€โ”€ llm/ # OpenAI, Anthropic, Azure, Gemini, Bedrock, Ollama, HuggingFace + โ”œโ”€โ”€ embedding/ # OpenAI, Azure, Gemini, Bedrock, Ollama, HuggingFace + โ”œโ”€โ”€ db/ # SQLAlchemyDB, SQLAlchemyExplorer + โ”œโ”€โ”€ vectorstore/ # InMemory, FAISS, pgvector + โ”œโ”€โ”€ catalog/ # DataHubCatalogLoader + โ”œโ”€โ”€ loaders/ # PDFLoader + โ””โ”€โ”€ chunking/ # SemanticChunker +``` -## ๐Ÿง‘โ€๐Ÿ’ป ๊ธฐ์ˆ  ์Šคํƒ +### ์„ค๊ณ„ ์›์น™ -- **[LangGraph](https://github.com/langchain-ai/langgraph)**: LLM ์›Œํฌํ”Œ๋กœ์šฐ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ -- **[DataHub](https://datahubproject.io/)**: ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ ๋ฐ ํ™œ์šฉ -- **[Streamlit](https://streamlit.io/)**: ๋Œ€ํ™”ํ˜• ์›น ์ธํ„ฐํŽ˜์ด์Šค +- **`core/`๋Š” ์™ธ๋ถ€ ์˜์กด์„ฑ 0%**: ๋ชจ๋“  third-party ์—ฐ๋™์€ `integrations/`์—์„œ ๊ตฌํ˜„ +- **Port Protocol**: `LLMPort`, `DBPort`, `EmbeddingPort` ๋“ฑ ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋งŒ ๋งž์ถ”๋ฉด ์–ด๋–ค ๊ตฌํ˜„์ฒด๋“  ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ +- **Hook ๊ธฐ๋ฐ˜ ๊ด€์ธก์„ฑ**: `MemoryHook`์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ณ„ ์‹คํ–‰ ์‹œ๊ฐ„, ์—๋Ÿฌ๋ฅผ ์ถ”์  --- -## ๐ŸŒŸ ๊ธฐ์—ฌ๊ฐ€ ํ•„์š”ํ•œ ์˜์—ญ (Help!) - -### Containerization - -- Docker๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜๊ณ , `pip install lang2sql` ์„ค์น˜ ํ›„ ๋‹จ์ผ ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค. -- CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ• ๋ฐ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ๊นŒ์ง€ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. +## ๐Ÿง‘โ€๐Ÿ’ป ์ง€์› ํ™˜๊ฒฝ -### Agentic ์•„ํ‚คํ…์ฒ˜ ๊ฐœ๋ฐœ +### LLM -- ์ฟผ๋ฆฌ ์ƒ์„ฑ ๊ณผ์ •์„ ์—์ด์ „ํ‹ฑํ•˜๊ฒŒ ๊ฐœ์„ ํ•˜์—ฌ ๋”์šฑ ์ง€๋Šฅ์ ์ด๊ณ  ์ž์œจ์ ์ธ SQL ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค. -- ๋ฐ์ดํ„ฐ ๋””์Šค์ปค๋ฒ„๋ฆฌ ๊ธฐ๋Šฅ์„ ๊ฐ•ํ™”ํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ๊ณผ์ ์œผ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +| ํ”„๋กœ๋ฐ”์ด๋” | ํ™˜๊ฒฝ๋ณ€์ˆ˜ `LLM_PROVIDER` | +|---|---| +| OpenAI | `openai` | +| Anthropic | `anthropic` | +| Azure OpenAI | `azure` | +| Google Gemini | `gemini` | +| AWS Bedrock | `bedrock` | +| Ollama | `ollama` | +| HuggingFace | `huggingface` | -### Datahub ํ†ตํ•ฉ ๊ฐ•ํ™” +### ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค -- ํ˜„์žฌ Datahub์˜ Glossary์™€ ์ฟผ๋ฆฌ ์˜ˆ์‹œ๋ฅผ ์ฝ”๋“œ๋กœ ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -- ์ด๋Ÿฌํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌ ์ƒ์„ฑ ๊ณผ์ •์— ๋”์šฑ ๊ธด๋ฐ€ํ•˜๊ฒŒ ํ†ตํ•ฉํ•˜์—ฌ ์ปจํ…์ŠคํŠธ ๊ธฐ๋ฐ˜์˜ ์ •ํ™•ํ•œ SQL ์ƒ์„ฑ์„ ์ง€์›ํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. +SQLite, PostgreSQL, MySQL, MariaDB, DuckDB, ClickHouse, Snowflake, Oracle, BigQuery, Trino, Hive, Crate -### VectorDB ์œ ์—ฐ์„ฑ ๊ฐœ์„  +### VectorDB -- ํ˜„์žฌ๋Š” Datahub๋ฅผ ํ†ตํ•ด ๋กœ์ปฌ์— FAISS VectorDB๋ฅผ ์ƒ์„ฑํ•ด์•ผ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. -- ์ด ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถฐ์„œ Datahub ์—†์ด๋„ ๊ธฐ์กด์— ์ค€๋น„๋œ VectorDB๋งŒ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. +| ๋ฐฑ์—”๋“œ | ์˜์†์„ฑ | ๊ถŒ์žฅ ๊ทœ๋ชจ | +|---|---|---| +| `InMemoryVectorStore` | ์—†์Œ | < 50k chunks | +| `FAISSVectorStore` | ๋กœ์ปฌ ํŒŒ์ผ | < 500k chunks | +| `PGVectorStore` | PostgreSQL | 500k+ chunks | -### ๋ชจ๋‹ˆํ„ฐ๋ง / ๋กœ๊น… ๊ฐ•ํ™” - -- ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ ํŒจํ„ด๊ณผ ์„ฑ๋Šฅ์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ , ์ƒ์„ธํ•œ ๋กœ๊น… ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค. -- ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ ์ˆ˜์ง‘ ๋ฐ ๋ถ„์„ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ†ตํ•ด ์ง€์†์ ์ธ ๊ฐœ์„ ์ด ๊ฐ€๋Šฅํ•œ ๊ธฐ๋ฐ˜์„ ๋งˆ๋ จํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. +--- -### ๋ฌธ์„œํ™” ๊ฐ•ํ™” +## ๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ -- ํ”„๋กœ์ ํŠธ ๊ธฐ์—ฌ ์žฅ๋ฒฝ์„ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•œ ํฌ๊ด„์ ์ธ ๋ฌธ์„œํ™” ์ž‘์—…์ž…๋‹ˆ๋‹ค. -- ๊ฐœ๋ฐœ์ž ๊ฐ€์ด๋“œ, ํŠœํ† ๋ฆฌ์–ผ ๋“ฑ์„ ์ฒด๊ณ„์ ์œผ๋กœ ์ •๋ฆฌํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ธฐ์—ฌ์ž๋“ค์ด ์‰ฝ๊ฒŒ ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์กฐ์„ฑํ•ฉ๋‹ˆ๋‹ค. +์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! -### LLM ํ”„๋ก ํŠธ์—์„œ ๋ถ„๋ฆฌํ•˜๊ธฐ +### ๐Ÿ”ง ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • -ํ”„๋ŸฐํŠธ์—์„œ๋Š” LLM ํ˜ธ์ถœยทํ‚ค๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋‚ด๋ถ€ ๋ฐฑ์—”๋“œ API๋กœ ์œ„์ž„ํ•ด ๋ณด์•ˆยท๊ถŒํ•œยท๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ค‘์•™ํ™”ํ•ฉ๋‹ˆ๋‹ค. +```bash +# 1. ์ €์žฅ์†Œ ํฌํฌ & ํด๋ก  +git clone https://github.com/YOUR_USERNAME/lang2sql.git +cd lang2sql ---- +# 2. ์˜์กด์„ฑ ์„ค์น˜ +uv venv --python 3.11 +source .venv/bin/activate +uv sync --group dev -## ๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ +# 3. ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ (๋„ค์ด๋ฐ: feature/์ด์Šˆ๋ฒˆํ˜ธ-์ž‘์—…๋‚ด์šฉ) +git checkout -b feature/42-amazing-feature -์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ์—ฌ๋Ÿฌ๋ถ„์ด ๋„์šธ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•๋“ค: +# 4. ์ž‘์—… ํ›„ ์ปค๋ฐ‹ & PR +git commit -m "feat: add amazing feature" +git push origin feature/42-amazing-feature +``` -### ๐Ÿ”ง ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • +### ๐Ÿ“‹ ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ผ์ธ -1. ์ €์žฅ์†Œ ํฌํฌํ•˜๊ธฐ -2. ํฌํฌ ํด๋ก : `git clone https://github.com/YOUR_USERNAME/lang2sql.git` -3. ์˜์กด์„ฑ ์„ค์น˜: `pip install -r requirements.txt` -4. ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ: `git checkout -b feature/amazing-feature` -5. ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ปค๋ฐ‹: `git commit -m 'Add amazing feature'` -6. ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œ: `git push origin feature/amazing-feature` -7. Pull Request ์—ด๊ธฐ +- `pre-commit run --all-files`๋กœ ํฌ๋งทํŒ… ํ™•์ธ +- ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ (`tests/test__.py`) +- PR์€ `master` ๋ธŒ๋žœ์น˜ ๋Œ€์ƒ, ์ตœ์†Œ 2๋ช… ๋ฆฌ๋ทฐ์–ด ์Šน์ธ ํ•„์š” +- ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€: `feat:`, `fix:`, `docs:`, `refactor:` ๋“ฑ prefix ์‚ฌ์šฉ ### ๐Ÿ› ์ด์Šˆ ์‹ ๊ณ  @@ -269,13 +301,6 @@ Lang2SQL์€ LangGraph๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค๋‹จ๊ณ„ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค: - ์˜ˆ์ƒ ๋™์ž‘ vs ์‹ค์ œ ๋™์ž‘ - ํ™˜๊ฒฝ ์„ธ๋ถ€์‚ฌํ•ญ -### ๐Ÿ“‹ ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ผ์ธ - -- pre-commit ํ™œ์„ฑํ™” -- ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ -- ํ•„์š”์‹œ ๋ฌธ์„œ ์—…๋ฐ์ดํŠธ -- ์›์ž์ ์ด๊ณ  ์ž˜ ์„ค๋ช…๋œ ์ปค๋ฐ‹ ์œ ์ง€ - --- ## ๐ŸŽ“ ํ•™์Šต ์ž๋ฃŒ @@ -304,41 +329,30 @@ Lang2SQL์€ LangGraph๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค๋‹จ๊ณ„ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค: | **Data Engineer** | ํ™์ง€์˜ | ![Python](https://img.shields.io/badge/Python-Expert-3776AB) | LLM, Data Engineering | | **Data Operator** | ์ดํ™”๋ฆผ | ![Python](https://img.shields.io/badge/Python-Expert-3776AB) | LLM, Data Engineering | - - ## ๐Ÿš€ ๋ฐฐํฌ ๋ฐ ๋ฆด๋ฆฌ์Šค -### ์ˆ˜๋™ ๋นŒ๋“œ - -```bash -uv build -UV_PUBLISH_TOKEN=$PYPI_API_TOKEN uv publish --token $UV_PUBLISH_TOKEN -``` - ### ์ž๋™ ๋ฐฐํฌ(GitHub Actions) -์‚ฌ์ „ ์ค€๋น„: GitHub Secrets์— `PYPI_API_TOKEN` ๋“ฑ๋ก +`v*` ํƒœ๊ทธ ํ‘ธ์‹œ ์‹œ `.github/workflows/pypi-release.yml`์ด ์‹คํ–‰๋˜์–ด PyPI์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ```bash -# 1) ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ -# - ๋ฒ„์ „ ํŒŒ์ผ: version.py ์˜ __version__ = "X.Y.Z" +# 1) ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ (version.py) git add version.py git commit -m "chore: bump version to X.Y.Z" -# 2) ํƒœ๊ทธ ์ƒ์„ฑ/ํ‘ธ์‹œ (v* ํ˜•์‹์ด ํŠธ๋ฆฌ๊ฑฐ) +# 2) ํƒœ๊ทธ ์ƒ์„ฑ/ํ‘ธ์‹œ git tag vX.Y.Z git push origin HEAD git push origin vX.Y.Z ``` -์„ค๋ช…: `v*` ํƒœ๊ทธ๊ฐ€ ํ‘ธ์‹œ๋˜๋ฉด `.github/workflows/pypi-release.yml`์ด ์‹คํ–‰๋˜์–ด uv๋กœ ๋นŒ๋“œ/๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. +์‚ฌ์ „ ์ค€๋น„: GitHub Secrets์— `PYPI_API_TOKEN` ๋“ฑ๋ก -### TestPyPI๋กœ ์‚ฌ์ „ ๊ฒ€์ฆ(์„ ํƒ) +### ์ˆ˜๋™ ๋นŒ๋“œ ```bash uv build -UV_PUBLISH_TOKEN=$TEST_PYPI_API_TOKEN \ - uv publish --repository-url https://test.pypi.org/legacy/ --token $UV_PUBLISH_TOKEN +UV_PUBLISH_TOKEN=$PYPI_API_TOKEN uv publish --token $UV_PUBLISH_TOKEN ``` ---