LLM Agent 직접 만들어보기 03
환경
window
4070 super
32G 메모리
Self Improvements
AI 가 자신의 출력을 스스로 평가하고 개선하는 능력을 말합니다.
기본 프로세스:
- 초기 답변 생성
- 자기 평가 (“이 답변이 좋은가?”)
- 문제점 식별
- 개선된 답변 재생성
- 반복…
rok 을 써보면 이 과정을 투명하게 보여줘서, 어떤 흐름을 거쳐서 최종적인 답변이 완성되는지를 알 수 있습니다. 이 개선 과정에 있어서는 크게 3가지 방법론이 적용될 수 있습니다.
Human-guided 방법론
RLHF (Reinforcement Learning from Human Feedback) 모델의 응답 결과를 사람이 직접 평가해서 응답을 개선하는 방법입니다. 인간이 선호하는 ‘좋은’ 답변을 학습할 수 있지만, 평가자마자 주관적 차이가 있고 대량 학습이 어렵다는 단점이 있습니다.
AI-guided 방법론
Self-Rewarding 과 같은 방법이 있고, AI 가 스스로 평가하고 개선할 수 있기 때문에 비용이 효율적입니다. 그러나 인간 가치에서 벗어날 위험이 있습니다. 보상 중심의 방법의 경우엔, 실제 목표를 달성하는 것이 아니라 해킹을 통한 보상 점수를 높이려 할 수 있습니다.
이를 보완하고자 AI-as-a-Judge 와 같은 방법을 통해서 AI 가 다른 AI 의 답변을 평가하는 방법도 존재하지만, 평가 모델의 품질이 매우 중요하다는 단점이 있습니다.
하이브리드 방법론
Human-guided 와 AI-guided 를 모두 사용하는 방법입니다. 실제로 claude, gpt 는 모두 하이브리드 방법을 사용하고 있습니다.
Self reflection
로컬 머신의 한계로, 간단히 self-reflection 을 통해서 self improvements 를 실행해보겠습니다.
전체 코드는 여기를 참고해주세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
async def perform_self_reflection(
self,
response: str,
original_request: str,
language: str,
framework: Optional[str],
session_id: Optional[str] = None
) -> ReflectionResult:
"""Self-reflection을 통한 응답 평가 (컨텍스트 고려)"""
# 컨텍스트 정보 수집
context_guidance = ""
if session_id:
context_info = context_manager.get_context_for_llm(session_id)
if context_info:
context_guidance = f"""
**프로젝트 컨텍스트:**
{context_info}
**컨텍스트 일관성 평가 포함:**
- 기존 코드 스타일과의 일치성
- 사용된 라이브러리의 일관성
- 아키텍처 패턴의 연속성
- 네이밍 컨벤션의 일치성
"""
reflection_prompt = f"""
다음 코드를 종합적으로 평가해주세요:
**원본 요청:** {original_request}
**언어:** {language}
**프레임워크:** {framework or "없음"}
{context_guidance}
**생성된 코드:**
```{language}
{response}
```
다음 기준으로 평가하고 JSON 형식으로 답변해주세요:
score,
"completeness": score,
"context_consistency": score,
"best_practices": score,
"error_handling": score,
"overall_issues": ["전체적인 문제점1", "전체적인 문제점2", "전체적인 문제점3"],
"improvement_suggestions": ["개선 제안1", "개선 제안2", "개선 제안3"],
"overall_assessment": "전체적인 평가 및 요약"
}}
평가 기준:
- 9-10: 뛰어남 (production-ready, 컨텍스트 완벽 일치)
- 7-8: 좋음 (minor improvements needed)
- 5-6: 보통 (moderate improvements needed)
- 3-4: 나쁨 (major improvements needed)
- 0-2: 매우 나쁨 (complete rewrite needed)
"""
try:
reflection_response = self.llm.invoke(reflection_prompt)
try:
reflection_data = json.loads(reflection_response)
except json.JSONDecodeError:
reflection_data = self._extract_reflection_from_text(reflection_response)
issues = reflection_data.get("overall_issues", [])
suggestions = reflection_data.get("improvement_suggestions", [])
return ReflectionResult(
score=float(reflection_data.get("score", 5.0)),
issues=issues,
suggestions=suggestions,
overall_assessment=reflection_data.get("overall_assessment", "평가를 완료했습니다.")
)
except Exception as e:
logger.error(f"Self-reflection 실패: {e}")
return ReflectionResult(
score=5.0,
issues=["평가 중 오류 발생"],
suggestions=["재평가 필요"],
overall_assessment="평가를 완료하지 못했습니다."
)
간단히 코드의 품질을 평가해달라고 했습니다. 다만, judge 모델이 생성 모델과 동일하다보니, 대체로 평가가 후한(?)점은 어쩔 수 없는 것 같습니다.
실행 결과는 다음과 같습니다.
1
2
3
4
5
6
7
🤖 코드 생성 요청 (세션: f837de6d...): 구글맵으로부터 서울의 인기 맛집들을 크롤링해오는 크롤러를 만들어줘...
2025-06-18 22:28:39,500 - app.services.ollama_service - INFO - 🔄 Self-improvement 반복 1/3
2025-06-18 22:28:43,677 - watchfiles.main - INFO - 1 change detected
2025-06-18 22:29:11,099 - app.services.ollama_service - INFO - ✅ 만족스러운 품질 달성 (점수: 7.5)
✅ 코드 생성 완료: python_app_20250618_222911.py (41.1초)
질문이 너무 쉬웠을까요? 이번엔 어려운 요청을 던져봤습니다.(본인도 뭔지 모름) 그리고 최소 통과 기준을 7.5 점에서 9점으로 올렸습니다. 이렇게 하면 열일할 수 밖에! 🔥🔥
1
2
3
4
5
6
7
8
9
10
11
12
🤖 코드 생성 요청 (세션: f0232e0d...): 시계열 데이터에서 실시간 이상값을 탐지하는 시스템을 만들어줘. 통계적 방법, 머신러닝, 딥...
2025-06-18 22:57:10,679 - watchfiles.main - INFO - 1 change detected
2025-06-18 22:57:25,875 - app.services.ollama_service - INFO - 🔄 Self-improvement 반복 1/3
2025-06-18 22:58:23,141 - app.services.ollama_service - INFO - ✅ 현재 품질 (점수: 8.5)
2025-06-18 22:58:39,245 - app.services.ollama_service - INFO - 📈 반복 1 완료 - 점수: 8.5
2025-06-18 22:58:39,245 - app.services.ollama_service - INFO - 🔄 Self-improvement 반복 2/3
2025-06-18 22:59:22,646 - app.services.ollama_service - INFO - ✅ 현재 품질 (점수: 8.5)
2025-06-18 22:59:42,829 - app.services.ollama_service - INFO - 📈 반복 2 완료 - 점수: 8.5
2025-06-18 22:59:42,829 - app.services.ollama_service - INFO - 🔄 Self-improvement 반복 3/3
2025-06-18 23:00:16,384 - app.services.ollama_service - INFO - ✅ 현재 품질 (점수: 8.5)
통과하지 못하고 결국 한계로 지정한 3번의 사이클을 모두 완수했습니다. 코드를 살펴보니 머신 러닝을 적용하는 부분을 결국 구현하지 못했습니다. 아무래도 모델의 크기가 작다보니 한계에 도달한 것 같네요.
다음
오늘은 self improvements 를 통해서 모델이 스스로의 응답을 한계까지 개선하도록 해봤습니다. 다음번엔 LoRA 를 적용해서 fine tuning 을 해보고 싶지만.. 파인튜닝을 하기엔 제 로컬 머신의 한계가 있습니다. 🥲 그러므로, RAG 를 적용해 외부 소스로부터 응답에 필요한 항목을 조회할 수 있도록 해보겠습니다.