γ……γ…Žγ…‡
Add CodeWeaver Gradio app
515f392
---
title: CodeWeaver
emoji: πŸ€–
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: "4.44.1"
app_file: ui/app.py
pinned: false
license: mit
---
# CodeWeaver
LangGraph 기반의 **개발자 Q&A μ—μ΄μ „νŠΈ**μž…λ‹ˆλ‹€. μ§ˆλ¬Έμ„ λΆ„μ„ν•˜κ³ (후속/독립), **μΊμ‹œ(Qdrant)**λ₯Ό μš°μ„  ν™•μΈν•œ λ’€ μΊμ‹œ 미슀일 λ•Œ **3개 μ†ŒμŠ€(Stack Overflow / GitHub / 곡식 λ¬Έμ„œ(Tavily))λ₯Ό 병렬 검색**ν•΄ 닡변을 μƒμ„±ν•©λ‹ˆλ‹€. μ„œλ‘œ 독립적인 질문이 2개 λ“€μ–΄μ˜€λ©΄ **λ™μ μœΌλ‘œ 2개 νŒŒμ΄ν”„λΌμΈμ„ 병렬 μ‹€ν–‰**ν•΄ 톡합 닡변을 μ œκ³΅ν•©λ‹ˆλ‹€.
## 핡심 κΈ°λŠ₯(ν˜„μž¬ μ½”λ“œ κΈ°μ€€)
- **질문 개수 감지**: 1개(단일 주제) / 2개(독립 질문 2개) / 3개 이상(거절 μ•ˆλ‚΄)
- **질문 νƒ€μž… 뢄석**: `clarification`이면 검색/μΊμ‹œ 없이 **λŒ€ν™” νžˆμŠ€ν† λ¦¬ 기반 λ‹΅λ³€**
- **의미적 캐싱**: Qdrant에 질문-닡변을 μ €μž₯ν•˜κ³  μœ μ‚¬ μ§ˆλ¬Έμ„ λΉ λ₯΄κ²Œ μž¬μ‚¬μš©(μž„κ³„κ°’ 0.85)
- **병렬 검색**: Stack Overflow / GitHub / Tavily(곡식 λ¬Έμ„œ 도메인 μ œν•œ) λ™μ‹œ 검색
- **검색 ν’ˆμ§ˆ 보정**: κ²°κ³Όκ°€ λΆ€μ‘±ν•˜λ©΄ **쿼리 κ°œμ„ μ„ μ΅œλŒ€ 1회** μˆ˜ν–‰
- **μ„œλΈŒκ·Έλž˜ν”„ 처리**: 검색 κ²°κ³Όλ₯Ό 필터링/μ μˆ˜ν™” ν›„ μš”μ•½ β†’ μ΅œμ’… λ‹΅λ³€ 생성
## λ¬Έμ„œ
- μ•„ν‚€ν…μ²˜/λ™μž‘ 원리: `../ARCHITECTURE.md`
- 닀쀑 질문 병렬 처리 섀계(λ°°κ²½ μ„€λͺ…): `../DYNAMIC_PARALLEL_SEARCH.md`
## λΉ λ₯Έ μ‹œμž‘
### 1) μ„€μΉ˜
μ•„λž˜λŠ” μ €μž₯μ†Œ λ£¨νŠΈκ°€ μ•„λ‹ˆλΌ **`CodeWeaver/` 디렉터리 κΈ°μ€€** μ˜ˆμ‹œμž…λ‹ˆλ‹€.
```bash
cd CodeWeaver
# uv μ‚¬μš©(ꢌμž₯)
uv sync
# λ˜λŠ” pip μ‚¬μš©
pip install -r requirements.txt
```
> `sentence-transformers`κ°€ 졜초 μ‹€ν–‰ μ‹œ `BAAI/bge-m3` λͺ¨λΈμ„ λ‹€μš΄λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€(λ„€νŠΈμ›Œν¬ ν•„μš”).
### 2) ν™˜κ²½ λ³€μˆ˜ μ„€μ •(.env)
`CodeWeaver/.env` νŒŒμΌμ„ λ§Œλ“€κ³  μ•„λž˜λ₯Ό μ„€μ •ν•˜μ„Έμš”(ν•„μˆ˜/선택 ꡬ뢄).
```bash
# ν•„μˆ˜: Gemini (LLM)
GOOGLE_API_KEY=your_google_api_key
# ν•„μˆ˜: Tavily (곡식 λ¬Έμ„œ 검색)
TAVILY_API_KEY=your_tavily_api_key
# ν•„μˆ˜: Qdrant Cloud (μΊμ‹œ)
QDRANT_URL=https://xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.us-east-1-0.aws.cloud.qdrant.io
QDRANT_API_KEY=your_qdrant_api_key
# 선택: GitHub API rate limit μ™„ν™”
GITHUB_TOKEN=your_github_token
# 선택: LangSmith νŠΈλ ˆμ΄μ‹±
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your_langsmith_api_key
```
### 3) μ‹€ν–‰(Gradio UI)
```bash
cd CodeWeaver
python ui/app.py
```
κΈ°λ³Έ μ£Όμ†Œ: `http://localhost:7860`
## ν˜„μž¬ 폴더 ꡬ쑰
```
CodeWeaver/
β”œβ”€β”€ main.py
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ agent/
β”‚ β”‚ β”œβ”€β”€ graph.py # LangGraph 메인 κ·Έλž˜ν”„(λΌμš°νŒ…/병렬화)
β”‚ β”‚ β”œβ”€β”€ nodes.py # 각 λ…Έλ“œ κ΅¬ν˜„
β”‚ β”‚ └── state.py # AgentState + reducer μ •μ˜
β”‚ β”œβ”€β”€ tools/
β”‚ β”‚ └── search_tools.py # StackOverflow/GitHub/Tavily 검색
β”‚ β”œβ”€β”€ utils/
β”‚ β”‚ └── tracing.py # trace_node λ°μ½”λ ˆμ΄ν„°(LangSmith 연동)
β”‚ └── vector_db/
β”‚ β”œβ”€β”€ qdrant_client.py # Qdrant μΊμ‹œ 관리
β”‚ └── local_embeddings.py # bge-m3 둜컬 μž„λ² λ”©
└── ui/
└── app.py # Gradio UI (μ‹€μ œ μ—”νŠΈλ¦¬)
```
## λ™μž‘ 흐름(μš”μ•½)
- `START β†’ create_plan`
- **3개 이상**이면 μ•ˆλ‚΄ λ©”μ‹œμ§€ λ°˜ν™˜
- **2개**λ©΄ 각 μ§ˆλ¬Έμ„ workerμ—μ„œ 단일 νŒŒμ΄ν”„λΌμΈμœΌλ‘œ μ‹€ν–‰ ν›„ κ²°ν•©
- **1개**λ©΄ μ•„λž˜ 단일 νŒŒμ΄ν”„λΌμΈ μˆ˜ν–‰
- 단일 νŒŒμ΄ν”„λΌμΈ:
- `analyze_question`
- `clarification`이면 `generate_with_history`둜 μ¦‰μ‹œ λ‹΅λ³€
- κ·Έ μ™Έ: `check_cache` β†’ hitλ©΄ λ°˜ν™˜, missλ©΄ `classify_intent`
- `classify_intent` β†’ 3μ†ŒμŠ€ 병렬 검색 β†’ `collect_results` β†’ `evaluate_results`
- ν•„μš” μ‹œ `refine_search` 1회 β†’ μž¬κ²€μƒ‰
- `filter_and_score β†’ summarize_results β†’ generate_answer`(+쑰건뢀 μΊμ‹œ μ €μž₯)
μžμ„Έν•œ μ›λ¦¬λŠ” `../ARCHITECTURE.md`λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.