μν°λλ© μ κ· μ μ¬μμ 3κ°μ μ¨λ³΄λ© κ²½νμ AI μ±λ΄κ³Όμ λνλ₯Ό ν΅ν΄ μμ§νκ³ λΆμνλ μμ€ν μ λλ€. μμ°μ€λ¬μ΄ λνν μΈν°νμ΄μ€λ‘ νΌλλ°±μ λ°μ λΆμ 리ν¬νΈλ₯Ό μλ μμ±νκ³ μ΄λ©μΌλ‘ λ°μ‘ν©λλ€. νΌννμ΄ μ μ μ¬μμ μ¨λ³΄λ© κ²½νμ 체κ³μ μΌλ‘ νμ νκ³ κ°μ μ μ λμΆνλ λ° νμ©λ©λλ€.
chatbot-onboarding/
βββ main.py # Streamlit μ ν리μΌμ΄μ
μ§μ
μ
βββ pyproject.toml # Python νλ‘μ νΈ μμ‘΄μ± κ΄λ¦¬
βββ Makefile # νλ‘μ νΈ μ€ν λͺ
λ Ήμ΄ λͺ¨μ
βββ .env # νκ²½λ³μ (API ν€, μ΄λ©μΌ μ€μ )
βββ .env.example # νκ²½λ³μ μμ νμΌ
β
βββ src/
β βββ app.py # μ±λ΄ ν΅μ¬ λ‘μ§ (OnboardingChatbot ν΄λμ€)
β βββ config.py # μ€μ νμΌ λ‘λ
β βββ report_generator.py # λΆμ 리ν¬νΈ HTML μμ±
β βββ conversation_exporter.py # λν λ΄μ HTML μμ±
β βββ email_sender.py # 리ν¬νΈ μμ± λ° μ΄λ©μΌ λ°μ‘ μ€μΌμ€νΈλ μ΄μ
β β
β βββ ui/
β β βββ intro_page.py # μμ νμ΄μ§ (μ΄λ¦/μ΄λ©μΌ μ
λ ₯)
β β βββ chat_page.py # μ±ν
μΈν°νμ΄μ€ νμ΄μ§
β β
β βββ utils/
β βββ email_service.py # SMTP μ΄λ©μΌ λ°μ‘ μλΉμ€
β βββ emotion.py # κ°μ λΆμ (GPT-4 κΈ°λ°)
β βββ logger.py # λ‘κΉ
μ€μ
β
βββ config/
β βββ questions.json # μ€λ¬Έ μ§λ¬Έ μ μ (11κ° μ§λ¬Έ)
β βββ llm_config.json # LLM λͺ¨λΈ μ€μ (GPT-4o)
β βββ system_prompt.md # μ±λ΄ νλ₯΄μλ λ° λν κ·μΉ
β βββ report_analysis_prompt.md # 리ν¬νΈ λΆμ ν둬ννΈ
β
βββ data/
β βββ reports/ # μμ±λ HTML 리ν¬νΈ μ μ₯μ
β βββ responses/ # μ¬μ©μ μλ΅ JSON μ μ₯μ
β
βββ assets/
βββ images/ # Wanted λ‘κ³ λ° μ΄λ―Έμ§
| νμΌ | μν |
|---|---|
src/app.py |
μ±λ΄ λν νλ¦ κ΄λ¦¬, μ§λ¬Έ μμ μ μ΄, μλ΅ κ²μ¦ |
src/report_generator.py |
GPT-4λ‘ λν λΆμ ν HTML 리ν¬νΈ μμ± |
src/email_sender.py |
리ν¬νΈ/λν HTML μμ± β μ΄λ©μΌ λ°μ‘ ν΅ν© κ΄λ¦¬ |
src/utils/email_service.py |
Gmail SMTPλ₯Ό ν΅ν μ΄λ©μΌ μ μ‘ |
config/system_prompt.md |
μ±λ΄μ μ±κ²©, λν μ€νμΌ, μ§λ¬Έ λ°©μ μ μ |
config/report_analysis_prompt.md |
리ν¬νΈ λΆμ κΈ°μ€ λ° νμ μ μ |
| λΌμ΄λΈλ¬λ¦¬ | λ²μ | μ©λ |
|---|---|---|
| langchain | >=0.1.0 | LLM μ€μΌμ€νΈλ μ΄μ νλ μμν¬ |
| langchain-openai | >=0.1.0 | OpenAI GPT-4 ν΅ν© (ChatOpenAI ν΄λμ€) |
| streamlit | >=1.28.0 | μΉ κΈ°λ° λνν UI νλ μμν¬ |
| python-dotenv | >=1.0.0 | νκ²½λ³μ κ΄λ¦¬ (.env νμΌ) |
| pydantic | >=2.0.0 | LangChain λ΄λΆ λ°μ΄ν° κ²μ¦μ© (μμ‘΄μ±) |
| markdown | >=3.5.0 | λ§ν¬λ€μ΄ ν μ€νΈ μ²λ¦¬ |
| λꡬ | μ©λ |
|---|---|
| black | μ½λ μλ ν¬λ§·ν |
| ruff | λ¦°ν λ° μ½λ μ€νμΌ κ²μ¬ |
- Python 3.11 μ΄μ
- UV ν¨ν€μ§ λ§€λμ (κΆμ₯)
- OpenAI API ν€ (GPT-4o μ κ·Ό κΆν)
- Gmail κ³μ (μ΄λ©μΌ λ°μ‘μ©)
curl -LsSf https://astral.sh/uv/install.sh | sh# νλ‘μ νΈ ν΄λ‘
git clone <repository-url>
cd chatbot-onboarding
# μμ‘΄μ± μ€μΉ
make install
# λλ
uv sync# .env.exampleμ 볡μ¬νμ¬ .env νμΌ μμ±
cp .env.example .env.env νμΌ μμ:
# OpenAI API Configuration
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxx # μ€μ OpenAI API ν€ μ
λ ₯
OPENAI_MODEL=gpt-4o
# Application Settings
DEBUG=false
LOG_LEVEL=INFO
# Email Configuration
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=true
EMAIL_SENDER=[email protected] # λ°μ‘μ Gmail μ£Όμ
EMAIL_PASSWORD=abcd1234efgh5678 # Gmail μ± λΉλ°λ²νΈ (16μ리)
EMAIL_RECIPIENTS=[email protected],[email protected] # μμ μ (μΌν ꡬλΆ)make run
# λλ
uv run streamlit run main.pymake dev
# λλ
uv run streamlit run main.py --logger.level=debugmake help # μ¬μ© κ°λ₯ν λͺ
λ Ήμ΄ νμΈ
make clean # μΊμ λ° μμ νμΌ μ 리
make lint # μ½λ μ€νμΌ κ²μ¬
make format # μ½λ μλ ν¬λ§·ν
API ν€ λ°κΈ:
- OpenAI Platform μ μ
- API Keys λ©λ΄μμ μ ν€ μμ±
- μμ±λ ν€λ₯Ό
.envνμΌμOPENAI_API_KEYμ μ λ ₯
μ£Όμμ¬ν:
- API ν€λ μ λ μ½λμ νλμ½λ©νμ§ μκΈ°
.envνμΌμ.gitignoreμ ν¬ν¨λμ΄ μμ΄ Gitμ μ λ‘λλμ§ μμ- GPT-4o λͺ¨λΈ μ κ·Ό κΆν νμ
νμΌ μμΉ: config/system_prompt.md
μ±λ΄μ μ±κ²©, λν μ€νμΌ, μ§λ¬Έ λ°©μμ μ μν©λλ€.
μμ κ°λ₯ν νλͺ©:
- μ±λ΄ νλ₯΄μλ (μΉκ·Όν¨, μ λ¬Έμ± μμ€)
- κΈμ§ νλ (κ°μΈμ 보 μμ§, λΆμ μ ν μ£Όμ )
- λν κ·μΉ (μ§λ¬Έ μμ, μ¬μ§λ¬Έ 쑰건)
- λ§λ¬΄λ¦¬ λ©νΈ
μμ:
## μν (Role)
λΉμ μ μν°λλ© νΌνν μμμ μΉκ·Όνκ³ λ°λ»ν AI μ±λ΄μ
λλ€.
μ κ· μ
μ¬μμ 3κ°μ μ¨λ³΄λ© κ²½νμ λν΄ μμ°μ€λ½κ² λννλ©° νΌλλ°±μ μμ§ν©λλ€.
...νμΌ μμΉ: config/report_analysis_prompt.md
GPT-4κ° λν λ΄μ©μ λΆμνμ¬ λ¦¬ν¬νΈλ₯Ό μμ±ν λ μ¬μ©νλ μ§μΉ¨μ λλ€.
μμ κ°λ₯ν νλͺ©:
- λΆμ κΈ°μ€ (μ μ λΆμ¬ λ‘μ§)
- 리ν¬νΈ μΉμ ꡬμ±
- νκ° νλͺ© (μ 무 μ ν©λ, μ‘°μ§λ¬Έν μ μλ λ±)
- λ§ν¬λ€μ΄ νμ κ·μΉ
μμ:
## μ€μ μμΉ
1. **μλ―Έ μλ λ΅λ³**μ΄ λ§μ κ²½μ° β κ° νλͺ© **20-40μ λ²μ**
2. **ꡬ체μ μ¬λ‘ μμ΄ μΌλ°μ νν**λ§ μ¬μ©ν κ²½μ° β **40-55μ λ²μ**
3. **ꡬ체μ μ¬λ‘ 1-2κ° + κΈμ μ νλ** β **55-70μ λ²μ**
...νμΌ μμΉ: config/questions.json
μ±λ΄μ΄ μμλλ‘ μ§λ¬Έν λ΄μ©μ μ μν©λλ€.
JSON ꡬ쑰:
{
"survey_questions": [
{
"id": 1,
"question": "μ§λ 3κ°μ κ°μ μν°λ μνμ λμλ΄€μ λ, κ°μ₯ λ¨Όμ λ μ€λ₯΄λ λ¨μ΄λ ννμ μμ λ‘κ² λ§ν΄ μ£ΌμΈμ."
},
{
"id": 2,
"question": "μ
μ¬ ν 3κ°μμ μ¨λ³΄λ© κΈ°κ°λμ κ°μ₯ κΈ°μ΅μ λ¨λ κ²½νμ΄λ μνΌμλλ₯Ό λ€λ €μ£ΌμΈμ."
},
{
"id": 11,
"question": "μ 체μ μΌλ‘ νΌνν μ£Όκ΄ μ¨λ³΄λ© νλ‘κ·Έλ¨μ λ§μ‘±λλ₯Ό μλ €μ£ΌμΈμ. (1~10μ )",
"scale": {
"min": 1,
"max": 10,
"labels": ["λ§€μ° λΆλ§μ‘±", "λΆλ§μ‘±", "보ν΅", "λ§μ‘±", "λ§€μ° λ§μ‘±"]
}
}
]
}μ£Όμμ¬ν:
idλ 1λΆν° μμ°¨μ μΌλ‘ μ¦κ°- μ μ κΈ°λ° μ§λ¬Έμλ
scaleκ°μ²΄ μΆκ° κ°λ₯ (min, max, labels) - μ§λ¬Έ κ°μ λ³κ²½ μ
src/app.pyμmeaningful_answers_countλ‘μ§λ νμΈ νμ
λ¬Έμ: [email protected]