Spaces:
Running
Running
| # 07. ํธ๋ฌ๋ธ์ํ | |
| ์ด ๋ฌธ์๋ ๊ฐ๋ฐ ์ค ์์ฃผ ๋ง๋ ์ ์๋ ๋ฌธ์ ์ ํ์ธ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค. | |
| ## Docker๊ฐ ์คํ๋์ง ์์ ๋ | |
| ### ์ฆ์ | |
| `docker compose up --build` ์คํ ์ Docker daemon ๊ด๋ จ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| Docker Desktop์ด ์คํ ์ค์ธ์ง ํ์ธํฉ๋๋ค. | |
| ```bash | |
| docker info | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - Docker Desktop์ ์คํํ๋ค. | |
| - Docker๊ฐ ์์ ํ ์์๋ ๋ค ๋ค์ ๋ช ๋ น์ ์คํํ๋ค. | |
| - ๊ธฐ์กด ์ปจํ ์ด๋๊ฐ ๊ผฌ์์ผ๋ฉด `docker compose down` ํ ๋ค์ ์คํํ๋ค. | |
| ## Streamlit ์ฑ์ ์ ์๋์ง ์์ ๋ | |
| ### ์ฆ์ | |
| `http://localhost:8501`์ ์ ์ํด๋ ํ๋ฉด์ด ์ด๋ฆฌ์ง ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| ์ปจํ ์ด๋๊ฐ ์คํ ์ค์ธ์ง ํ์ธํฉ๋๋ค. | |
| ```bash | |
| docker compose ps | |
| ``` | |
| ๋ก๊ทธ๋ฅผ ํ์ธํฉ๋๋ค. | |
| ```bash | |
| docker compose logs cert-study-app | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ์ฑ ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋์๋์ง ํ์ธํ๋ค. | |
| - 8501 ํฌํธ๋ฅผ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด ์ฌ์ฉ ์ค์ธ์ง ํ์ธํ๋ค. | |
| - ํ์ํ๋ฉด `http://127.0.0.1:8501`๋ก๋ ์ ์ํด ๋ณธ๋ค. | |
| ๋ก์ปฌ ๊ฐ์ํ๊ฒฝ์ `streamlit` ์คํ ํ์ผ์ด ์์ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์๋์ฒ๋ผ Python ๋ชจ๋ ๋ฐฉ์์ผ๋ก ์คํํฉ๋๋ค. | |
| ```bash | |
| python -m streamlit run streamlit_app.py | |
| ``` | |
| ## PostgreSQL ์ฐ๊ฒฐ ์ค๋ฅ | |
| ### ์ฆ์ | |
| ์ฑ ์คํ ์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| PostgreSQL ์ปจํ ์ด๋ ์ํ๋ฅผ ํ์ธํฉ๋๋ค. | |
| ```bash | |
| docker compose ps postgres | |
| ``` | |
| ๋ก๊ทธ๋ฅผ ํ์ธํฉ๋๋ค. | |
| ```bash | |
| docker compose logs postgres | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - `postgres` ์ปจํ ์ด๋๊ฐ healthy ์ํ์ธ์ง ํ์ธํ๋ค. | |
| - `DATABASE_URL`์ด Docker Compose ์ค์ ๊ณผ ์ผ์นํ๋์ง ํ์ธํ๋ค. | |
| - ๋ก์ปฌ์์ ์ง์ ์คํํ ๋๋ host๊ฐ `postgres`๊ฐ ์๋๋ผ `localhost`์ฌ์ผ ํ ์ ์๋ค. | |
| ## SQLite fallback ๊ด๋ จ ํผ๋ | |
| ### ์ฆ์ | |
| PostgreSQL์ ์ฐ๋ ค๊ณ ํ๋๋ฐ SQLite ํ์ผ์ด ์๊ธฐ๊ฑฐ๋, ๋ฐ๋๋ก SQLite fallback์ด ๋์ง ์์ต๋๋ค. | |
| ### ์ค๋ช | |
| ํ์ฌ ํ๋ก์ ํธ๋ PostgreSQL ์ฌ์ฉ์ ๊ธฐ๋ณธ์ผ๋ก ํฉ๋๋ค. SQLite๋ ๊ฐ๋ฐ ์ค ์์ fallback ์ฉ๋์ ๋๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| PostgreSQL์ ์ฌ์ฉํ ๋: | |
| ```env | |
| DATABASE_URL=postgresql+pg8000://cert_study:cert_study@postgres:5432/cert_study | |
| ``` | |
| SQLite fallback์ ๊ผญ ํ์ฉํด์ผ ํ ๋: | |
| ```env | |
| CERT_STUDY_DB_FALLBACK=1 | |
| ``` | |
| ์ด์ ๋๋ ๋ฐฐํฌ ํ๊ฒฝ์์๋ PostgreSQL์ ๊ธฐ์ค์ผ๋ก ๋ง์ถ๋ ๊ฒ์ด ์ข์ต๋๋ค. | |
| ### `attempt to write a readonly database` ์ค๋ฅ๊ฐ ๋ ๋ | |
| ๊ธฐ์กด SQLite ํ์ผ ๊ถํ ๋๋ฌธ์ seed ๊ฐฑ์ ์ด ์คํจํ ์ ์์ต๋๋ค. | |
| ๋น ๋ฅด๊ฒ ํ๋ฉด๋ง ํ์ธํ๋ ค๋ฉด ์ ์์ DB๋ฅผ ์ง์ ํฉ๋๋ค. | |
| ```bash | |
| DATABASE_URL=sqlite:////tmp/cert-study-local-check.db \ | |
| python -m streamlit run streamlit_app.py | |
| ``` | |
| ๊ธฐ์กด DB๋ฅผ ๊ณ์ ์ฐ๋ ค๋ฉด `data/questions.db` ํ์ผ ๊ถํ๊ณผ ์์ ์๋ฅผ ํ์ธํฉ๋๋ค. | |
| ## Airflow ํ๋ฉด์ ์ ์๋์ง ์์ ๋ | |
| ### ์ฆ์ | |
| `http://localhost:8080`์ ์ ์ํด๋ Airflow ํ๋ฉด์ด ์ด๋ฆฌ์ง ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| ```bash | |
| docker compose ps airflow-webserver airflow-scheduler | |
| ``` | |
| ```bash | |
| docker compose logs airflow-webserver | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - `airflow-init`์ด ๋จผ์ ์คํ๋์๋์ง ํ์ธํ๋ค. | |
| - 8080 ํฌํธ๋ฅผ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด ์ฌ์ฉ ์ค์ธ์ง ํ์ธํ๋ค. | |
| - Airflow DB ๋ง์ด๊ทธ๋ ์ด์ ์ค๋ฅ๊ฐ ์๋์ง ๋ก๊ทธ๋ฅผ ํ์ธํ๋ค. | |
| ## PDF ์ฒ๋ฆฌ ์์ ์ด ๋ฉ์ถ ๊ฒ์ฒ๋ผ ๋ณด์ผ ๋ | |
| ### ์ฆ์ | |
| PDF ์ ๋ก๋ ํ ์ฒ๋ฆฌ ํํฉ์ด ์ค๋ ๋ฐ๋์ง ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| - Airflow DAG๊ฐ ์คํ ์ค์ธ์ง ํ์ธํ๋ค. | |
| - `ingestion_jobs`์ `stage`, `message`, `current`, `total` ๊ฐ์ด ๋ฐ๋๋์ง ํ์ธํ๋ค. | |
| - Airflow ๋ก๊ทธ์์ ์คํจ ๋จ๊ณ๊ฐ ์๋์ง ํ์ธํ๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ํฐ PDF๋ ํ์ฑ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ์ ์๋ค. | |
| - LLM ๋๋ ์ด๋ฏธ์ง ๋ถ์์ ์ผ๋ฉด ๋ ๋๋ ค์ง ์ ์๋ค. | |
| - ์คํจํ ๊ฒฝ์ฐ ํด๋น ์์ ์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋จผ์ ํ์ธํ๋ค. | |
| ## ๋ฌธ์ ํ์ฑ ๊ฒฐ๊ณผ๊ฐ ์ด์ํ ๋ | |
| ### ์ฆ์ | |
| ๋ฌธ์ ๋ณธ๋ฌธ์ด ์๋ฆฌ๊ฑฐ๋, ๋ณด๊ธฐ๊ฐ ๋น ์ง๊ฑฐ๋, ์ ๋ต์ด ๋น์ด ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| - ํ์ง ๋ฆฌํฌํธ๊ฐ ์์ฑ๋์๋์ง ํ์ธํ๋ค. | |
| - `quality_score`, `quality_status`, `quality_issues` ๊ฐ์ ํ์ธํ๋ค. | |
| - ์๋ณธ PDF ํ ์คํธ ์ถ์ถ์ด ๊ฐ๋ฅํ PDF์ธ์ง ํ์ธํ๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ํ์ฑ ๊ท์น์ ๊ฐ์ ํ๋ค. | |
| - OCR์ด ํ์ํ PDF์ธ์ง ํ์ธํ๋ค. | |
| - ๋ฌธ์ ๋ฒํธ ํจํด๊ณผ ๋ณด๊ธฐ ํจํด์ ๋ ๋ช ํํ ์ฒ๋ฆฌํ๋ค. | |
| - ๋ชจ๋ ๋ฌธ์ ๋ฅผ LLM์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ๋ณด๋ค, ์คํจ ๊ฐ๋ฅ์ฑ์ด ๋์ ๋ฌธ์ ๋ง ๋ณด์ ํ๋ ๋ฐฉํฅ์ด ์ข๋ค. | |
| ## ๊ณตํต ์ง๋ฌธ์ด ๋ณด์ด์ง ์์ ๋ | |
| ### ์ฆ์ | |
| ์ผ์ด์ค ์คํฐ๋ ๋ฌธ์ ์ธ๋ฐ `๊ณตํต ์ง๋ฌธ ๋ณด๊ธฐ`๊ฐ ๋ํ๋์ง ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| - `questions_seed.json`์ `parent_stem`์ด ๋ค์ด ์๋์ง ํ์ธํ๋ค. | |
| - ์ฑ์ด ์ค๋๋ DB๋ฅผ ๋ณด๊ณ ์์ง ์์์ง ํ์ธํ๋ค. | |
| - seed refresh๊ฐ DB์ ์ธ ์ ์๋ ์ํ์ธ์ง ํ์ธํ๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - Space ๋๋ ๋ก์ปฌ ์ฑ์ ์ฌ์์ํ๋ค. | |
| - ๋ก์ปฌ์์๋ ์์ SQLite DB๋ก ๋ค์ ์คํํด seed ์์ฒด๊ฐ ์ ์์ธ์ง ํ์ธํ๋ค. | |
| - ๊ธฐ์กด DB๊ฐ ์ฝ๊ธฐ ์ ์ฉ์ด๋ฉด ๊ถํ์ ์์ ํ๊ฑฐ๋ ์ DB๋ฅผ ์ฌ์ฉํ๋ค. | |
| ## Yes/No ๋ฌธ์ ๊ฐ ๊ฐ๊ด์์ฒ๋ผ ๋ณด์ผ ๋ | |
| ### ์ฆ์ | |
| `๋ค์ ๊ฐ ์ง์ ์ ๋ํด ์/์๋์ค๋ฅผ ์ ํ`ํ๋ ๋ฌธ์ ๊ฐ A/B/C ๋ณด๊ธฐ์ฒ๋ผ ํ์๋ฉ๋๋ค. | |
| ### ์ค๋ช | |
| Yes/No ์ง์ ํ ๋ฌธ์ ๋ ์ผ๋ฐ ๊ฐ๊ด์๊ณผ ๋ค๋ฅด๊ฒ ์ง์ ๋ณ `์ / ์๋์ค` ์ ๋ ฅ UI๊ฐ ํ์ํฉ๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| - `question_type`์ด `Hotspot (True/False)` ๋๋ ์ ์ฌํ ๊ฐ์ธ์ง ํ์ธํ๋ค. | |
| - ์ ๋ต์ด `Y,N,Y` ๋๋ `[{key, value}]` ํํ๋ก ์ ๊ทํ๋๋์ง ํ์ธํ๋ค. | |
| - `1-A / 1-B / 2-A / 2-B` ํ์์ ํญ๋ชฉ๋ณ ์ ํ UI๋ก ํ์๋์ด์ผ ํ๋ค. | |
| ### ํ์ธ ๋ช ๋ น | |
| ๋ฌธ์ ์ ํ alias์ ์ ๋ต ์ ๊ทํ ํ ์คํธ๋ฅผ ๋จผ์ ์คํํ๋ค. | |
| ```bash | |
| python -m pytest tests/test_answer_normalizer.py tests/test_question_type_metadata_service.py | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ์ ๋ฌธ์ ์ ํ ๋ฌธ์์ด์ด ์ถ๊ฐ๋๋ฉด `question_type_metadata_service.py`์ alias์ ๋จผ์ ๋ฑ๋กํ๋ค. | |
| - ์ฑ์ ์ด ์ด์ํ๋ฉด ํ๋ฉด ์ฝ๋๋ณด๋ค `answer_normalizer.py`์์ `chosen`๊ณผ `answer`๊ฐ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ ๊ทํ๋๋์ง ํ์ธํ๋ค. | |
| - Yes/No๋ ์ผ๋ฐ ๊ฐ๊ด์ A/B/C๊ฐ ์๋๋ผ `Y,N,Y`์ฒ๋ผ ํ๋ณ ๋ต์์ผ๋ก ๋น๊ตํ๋ ๊ฒ์ด ๊ธฐ์ค์ด๋ค. | |
| ## ๋ชจ๋ฐ์ผ ํ๋ฉด์ด ๋ณต์กํ๊ฒ ๋ณด์ผ ๋ | |
| ### ์ฆ์ | |
| ํด๋ํฐ์์ ๋ฉ๋ด๊ฐ ๋๋ฌด ๋ง๊ฑฐ๋, ๋ต์ ์ ํ ์์ญ์ด ์์ ๋ณด์ ๋๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ํ ํ๋ฉด์ ๋ฌธ์ ํ์ด, ์ค๋ต/๋ณต์ต, ๊ฐ๋ ์ ๋ฆฌ ๊ฐ์ ํ์ต ๊ธฐ๋ฅ์ ๋จผ์ ๋ณด์ฌ์ค๋ค. | |
| - PDF ์ ๋ก๋, ์ฒ๋ฆฌ ํํฉ, AI ์์ธ์ `์ ๋ก๋/๊ด๋ฆฌ` ์์ญ์ผ๋ก ๋ฌถ๋๋ค. | |
| - ๋ต์ ์ ํ UI๋ ์ต์ 44px ์ด์์ ํฐ์น ์์ญ์ ์ ์งํ๋ค. | |
| - ๋ฌธ์ ์ ํ๋ณ๋ก radio, checkbox, selectbox, Yes/No matrix๋ฅผ ๊ตฌ๋ถํด์ ์ฌ์ฉํ๋ค. | |
| ## Chroma ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์ด์ํ ๋ | |
| ### ์ฆ์ | |
| ์ ์ฌ ๋ฌธ์ ๊ฐ ์ ๋์ค์ง ์๊ฑฐ๋, ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋น์ด ์์ต๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| - ๋ฌธ์ ๊ฐ Chroma์ ์์ธ๋์๋์ง ํ์ธํ๋ค. | |
| - ์ฌ์ฉ ์ค์ธ ์๋ฒ ๋ฉ ๋ชจ๋ธ์ด ์์ธํ ๋์ ๋ชจ๋ธ๊ณผ ๊ฐ์์ง ํ์ธํ๋ค. | |
| - `chroma_db` ๋๋ ํฐ๋ฆฌ๊ฐ ์ ์ง๋๊ณ ์๋์ง ํ์ธํ๋ค. | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ๊ฐ์ ์๋ฒ ๋ฉ ๋ชจ๋ธ๋ก ๋ค์ ์์ธํ๋ค. | |
| - ์๋ฒ ๋ฉ ๋ชจ๋ธ๋ณ๋ก ์ปฌ๋ ์ ์ ๋ถ๋ฆฌํ๋ค. | |
| - PostgreSQL์๋ ๋ฌธ์ ๊ฐ ์๋๋ฐ Chroma์๋ง ์๋ค๋ฉด ์์ธ ์์ ์ ๋ค์ ์คํํ๋ค. | |
| ## AI ์ง๋ฌธ ๊ธฐ๋ฅ์์ ํ๋ฉด์ด ๊นจ์ง ๋ (2026-07-04 ์ถ๊ฐ) | |
| ### ์ฆ์ | |
| ๋ฌธ์ ํ์ด ์ค "์ง๋ฌธํ๊ธฐ" ๋ฒํผ์ ๋๋ฅด๋ฉด ํ์ด์ง ์ ์ฒด๊ฐ ์๋ฌ๋ก ๊นจ์ง๋๋ค. | |
| ### ์์ธ๊ณผ ํ์ธ | |
| **โ ๋ฌธ์ ์์ธ(ChromaDB)์ด ๋น์ด ์์ ๋** | |
| ํ ๋ฒ๋ AI ์์ธ์ ์คํํ์ง ์์ ์ํ์์ ๊ฒ์ํ๋ฉด `n_results > n_documents` ์ค๋ฅ๊ฐ ๋ฉ๋๋ค. | |
| **โก Ollama๊ฐ ์๋ตํ์ง ์์ ๋** | |
| ๋ชจ๋ธ ๋ฏธ์ค์น ๋๋ ์๋ฒ ์ค์ง ์ํ์์ ์คํธ๋ฆฌ๋ฐ ์ค๋ฅ๊ฐ ๋ฉ๋๋ค. | |
| ```bash | |
| curl http://localhost:11434/api/tags | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - AI ์์ธ ๋ฉ๋ด์์ ๋จผ์ ์์ธ์ ์คํํ๋ค. | |
| - Ollama ์คํ ์ํ์ ๋ชจ๋ธ ์ค์น๋ฅผ ํ์ธํ๋ค. | |
| - ์ฑ์ด ์๋ฌ ๋ฉ์์ง๋ฅผ ํ์ํ๋ฉด ํ๋ฉด์์ URLยท๋ชจ๋ธ๋ช ํํธ๋ฅผ ํ์ธํ๋ค. | |
| > 2026-07-04 ์์ : ์ด์ ๋น ์ปฌ๋ ์ ์ด๊ฑฐ๋ Ollama ์ค๋ฅ๊ฐ ๋๋ ํ์ด์ง๊ฐ ๊นจ์ง์ง ์๊ณ ์๋ฌ ๋ฉ์์ง๋ง ํ์๋ฉ๋๋ค. | |
| ## Ollama ๋๋ LLM ๊ด๋ จ ์ค๋ฅ | |
| ### ์ฆ์ | |
| LLM ํ์ฑ, ์ค๋ช ์์ฑ, ์ด๋ฏธ์ง ๋ถ์ ๋จ๊ณ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. | |
| ### ํ์ธํ ๊ฒ | |
| ```bash | |
| ollama list | |
| ``` | |
| ### ํด๊ฒฐ ๋ฐฉํฅ | |
| - ํ์ํ ๋ชจ๋ธ์ด ์ค์น๋์ด ์๋์ง ํ์ธํ๋ค. | |
| - Docker ์ปจํ ์ด๋์์ ์ ๊ทผํ๋ `OLLAMA_BASE_URL`์ด ๋ง๋์ง ํ์ธํ๋ค. | |
| - LLM์ ๋๊ณ ๊ท์น ๊ธฐ๋ฐ ํ์ฑ๋ง์ผ๋ก ๋จผ์ ์คํํด ๋ณธ๋ค. | |
| ## Git์ ์ฌ๋ฆฌ๋ฉด ์ ๋๋ ๋ฐ์ดํฐ | |
| ๋ค์ ๋ฐ์ดํฐ๋ ์คํ ์ค ์์ฑ๋๋ ๋ฐํ์ ๋ฐ์ดํฐ์ด๋ฏ๋ก ๋ณดํต Git์ ์ฌ๋ฆฌ์ง ์์ต๋๋ค. | |
| - ์ ๋ก๋ PDF | |
| - ํ์ฑ ๊ฒฐ๊ณผ JSON | |
| - Chroma ์ธ๋ฑ์ค | |
| - PostgreSQL ๋ฐ์ดํฐ ๋ณผ๋ฅจ | |
| - Airflow ๋ก๊ทธ | |
| - Airflow DB | |
| - ๊ฐ์ธ `.env` ํ์ผ | |
| GitHub์๋ ์ฝ๋์ ๋ฌธ์, ์ค์ ์์ ์ค์ฌ์ผ๋ก ์ฌ๋ฆฌ๋ ๊ฒ์ด ์ข์ต๋๋ค. | |