AI가 스스로 배우고 자신을 개선한다 — self_apply.py 구축 삽질기
growth_log에 쌓인 인사이트를 LLM이 분류하고 실제 시스템에 자동 적용하는 파이프라인. 만들면서 겪은 삽질들.
아이디어
매일 JARVIS 시스템을 개선합니다. 그 과정에서 배운 것들을 growth_log.md에 씁니다.
# growth_log.md
## 2026-05-18
- devstral:24b 봇회의 타임아웃 문제 → gemma3:12b로 교체해야 함
- JSON 파싱 실패 시 재시도 로직 없음 → 추가 필요
- Ollama 모델 존재 확인 안 하고 pull 시도 → hub 확인 먼저 해야 함
이게 쌓이면 나중에 안 봅니다. 그냥 있습니다.
“이걸 AI가 읽고 자동으로 적용하면 어떨까?“
self_apply.py 동작 방식
매일 06:30 자동 실행:
1. growth_log.md 읽기 (최근 항목)
2. LLM에게 분류 요청
→ 카테고리: model_change / code_fix / config_update / skip
3. 카테고리별 처리
- model_change: Ollama hub에서 모델 존재 확인 → pull 시도
- code_fix: 해당 파일 수정 내용 생성 → 적용
- config_update: 설정 파일 갱신
4. 결과 Telegram 보고
핵심 코드 (핵심 부분만)
VALID_TYPES = ["model_change", "code_fix", "config_update", "skip"]
def _categorize_insight(insight_text: str) -> dict:
"""LLM에게 인사이트 분류 요청. JSON 파싱 실패 시 재시도."""
prompt = f"""
다음 인사이트를 분류하세요.
인사이트: {insight_text}
반드시 아래 JSON 형식으로만 응답하세요 (다른 텍스트 없이):
{{"type": "model_change|code_fix|config_update|skip", "action": "구체적 실행 내용"}}
"""
for attempt in range(3): # 최대 2회 재시도
response = ask_ollama(prompt)
try:
# 마크다운 코드블록 제거
cleaned = re.sub(r'```json?\n?|```', '', response).strip()
result = json.loads(cleaned)
if result.get("type") in VALID_TYPES:
return result
except (json.JSONDecodeError, KeyError):
pass
# 재시도 프롬프트 강화
prompt = prompt + "\n\n반드시 순수 JSON만. 마크다운 없이."
return {"type": "skip", "action": "파싱 실패"}
모델 존재 확인
Ollama 모델을 pull하기 전에 존재하는지 확인합니다.
def _hub_model_exists(model_name: str) -> bool:
"""ollama.com에서 모델 존재 여부 확인."""
# model_name 예: "gemma3:12b"
name_part = model_name.split(":")[0]
url = f"https://ollama.com/library/{name_part}"
try:
response = requests.head(url, timeout=10)
return response.status_code == 200
except Exception:
return False
처음엔 이 확인 없이 바로 pull을 시도했습니다. 존재하지 않는 모델명이 growth_log에 오타로 들어가면 pull이 한참 기다리다 실패했습니다.
겪었던 삽질들
삽질 1: JSON 파싱 실패율 30%
LLM(특히 소형 모델)이 JSON을 정확히 출력하는 비율이 낮았습니다.
출력 예:
# 이렇게 나옴
다음과 같이 분류됩니다:
```json
{
"type": "model_change",
"action": "devstral 대신 gemma3 사용"
}
코드블록으로 감싸거나, 앞에 설명 텍스트 붙이거나, 키 이름이 달라지거나.
해결: 정규식으로 코드블록 제거 + 2회 재시도 + 재시도 시 프롬프트 강화.
### 삽질 2: 타임아웃 60초
처음 debate 타임아웃이 60초였습니다. 14B 모델이 복잡한 분류 작업을 하면 60초 안에 못 끝냈습니다.
150초로 늘렸습니다.
### 삽질 3: code_fix 자동 적용의 위험성
LLM이 "이 파일 이렇게 수정하세요"라고 하면 그대로 적용했습니다.
문제: LLM이 잘못된 수정안을 제안하면 그대로 들어갑니다. 한 번은 import 구문을 잘못 수정해서 봇이 다운됐습니다.
해결: `code_fix` 타입은 자동 적용 중단. Telegram으로 수정 제안만 보내고 사람이 확인 후 적용.
```python
if insight["type"] == "code_fix":
# 자동 적용 안 함
send_telegram(f"코드 수정 제안:\n{insight['action']}\n\n직접 확인 후 적용 요망")
continue
삽질 4: devstral:24b → gemma3:12b 교체
자동화 분류 작업에 큰 모델이 필요할 것 같아서 devstral:24b를 썼습니다.
현실: 단순 분류에 24B 파라미터는 과함. 로딩 시간만 길어지고 결과는 비슷.
12B로 줄이니까 2배 빠르고 타임아웃도 없어졌습니다.
현재 상태
자동으로 처리하는 것:
model_change: Ollama 모델 교체 제안 → 사람이 확인 후 실행config_update: 설정값 변경 → 검토 후 적용skip: 그냥 넘김
자동 코드 수정은 중단했습니다. 제안만 받습니다.
결론
“AI가 스스로 개선한다”는 아이디어는 좋지만 완전 자동화는 위험합니다. 특히 코드 수정은.
현재는 “AI가 분석하고, 사람이 적용”하는 반자동 방식으로 씁니다. 이게 더 안전합니다.