02. Reflection Agents
왜 리플렉션(Reflection)이 중요한가
인간이 실수를 하면 "왜 틀렸지?"라고 생각하고 같은 실수를 반복하지 않으려 합니다. 하지만 기본 LLM은 상태가 없어서(stateless) 이전 시도를 기억하지 못하고 종종 같은 잘못된 답을 내놓습니다.
Reflection Agents는 자신의 작업을 비평하고 그 비평을 사용해 개선합니다. 작가가 초안을 쓰고 계속 수정하는 과정과 같습니다.
Generator-Reflector 패턴
가장 간단한 리플렉션 패턴은 역할을 둘로 나눕니다:
| 역할 | 책임 |
|---|---|
| Generator | 초기 출력 생성 또는 피드백 기반 수정 |
| Reflector | 출력을 비평하고 개선 제안 제공 |
Generator 구현
def generator(topic: str, previous_draft: str = None, critique: str = None) -> str:
"""
초안을 생성하거나 비평을 기반으로 수정합니다.
"""
if previous_draft and critique:
prompt = f"""주제: {topic}
이전 초안:
{previous_draft}
비평/피드백:
{critique}
위의 비평을 반영하여 초안을 다시 작성하세요.
"""
else:
prompt = f"주제: {topic}\n주제에 대한 짧은 에세이 초안을 작성하세요."
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.contentReflector 구현
def reflector(draft: str) -> str:
"""
초안을 읽고 건설적인 비평을 제공합니다.
"""
prompt = f"""다음 초안을 읽고 건설적인 비평을 제공하세요.
논리, 명확성, 스타일을 평가하세요. 개선이 필요한 영역을 최대 3개까지 지적하세요.
칭찬보다는 수정이 필요한 부분에 집중하세요.
초안:
{draft}
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.contentReflexion 루프
Generator와 Reflector를 반복 루프로 결합:
루프 실행
# Step 1: 첫 번째 초안
print("✍️ 초안 V1 작성 중...")
draft_v1 = generator(topic)
# Step 2: 리플렉션
print("🤔 성찰 중...")
critique_v1 = reflector(draft_v1)
# Step 3: 개선
print("✍️ 초안 V2 작성 (개선)...")
draft_v2 = generator(topic, previous_draft=draft_v1, critique=critique_v1)예시: 에세이 개선
주제: "AI가 인간의 창의성을 대체할 수 있는가?"
초안 V1:
"AI가 인간의 창의성을 대체할 수 있는지에 대한 질문은 복잡합니다..."
비평 V1:
- 논증 구조 명확화 필요
- 구체적인 예시 추가 필요
- 문체 흐름 개선 필요
초안 V2 (리플렉션 후):
"AI는 창의적 산출물을 생성할 수 있지만, 인간 창의성의 감정적, 맥락적 기반을 완전히 복제할 수 없습니다. 머신러닝과 같은 기술은 패턴을 분석하지만, 이는 감정과 문화에 뿌리를 둔 인간의 창의적 경험과 다릅니다..."
핵심 인사이트: 각 리플렉션 사이클은 Reflector가 식별한 특정 약점을 해결하여 측정 가능하게 더 나은 출력을 생성합니다.
자동화된 Reflexion Agent
중지 조건이 충족될 때까지 루프 자동화:
class ReflexionAgent:
def __init__(self, max_iterations: int = 3):
self.max_iterations = max_iterations
def run(self, topic: str):
current_draft = generator(topic)
print(f"📝 초기 초안:\n{current_draft}\n")
for i in range(self.max_iterations):
print(f"--- 반복 {i+1} ---")
# 1. 비평
critique = reflector(current_draft)
print(f"🔍 비평:\n{critique}\n")
# 2. 중지 조건 확인
if "개선 필요 없음" in critique.lower():
print("✨ Reflector가 만족합니다. 중지.")
break
# 3. 개선
current_draft = generator(
topic,
previous_draft=current_draft,
critique=critique
)
print(f"✍️ 개선된 초안:\n{current_draft}\n")
return current_draft자가 디버깅 코드 에이전트
리플렉션은 코딩 작업에 특히 강력합니다:
구현
def code_generator(prompt: str, error_msg: str = None, previous_code: str = None) -> str:
if error_msg:
full_prompt = f"""다음 코드에서 에러가 발생했습니다.
코드:
{previous_code}
에러:
{error_msg}
코드를 수정하세요. 코드만 반환하세요.
"""
else:
full_prompt = f"다음을 수행하는 Python 코드를 작성하세요: {prompt}. 코드만 반환하세요."
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": full_prompt}]
)
return clean_code(response.choices[0].message.content)
def execute_code(code: str):
"""실행하고 (성공 여부, 출력/에러) 반환"""
try:
exec_globals = {}
exec(code, exec_globals)
return True, "성공"
except Exception as e:
return False, str(e)
# 자가 수정 루프
code = code_generator(problem)
success, output = execute_code(code)
if not success:
print("⚠️ 에러 감지! 자가 수정 중...")
fixed_code = code_generator(problem, error_msg=output, previous_code=code)고급 중지 조건
고정된 반복 대신 점수 기반 피드백 사용:
def scored_reflector(draft: str) -> tuple[str, int]:
"""(비평, 1-5 점수) 반환"""
prompt = f"""초안을 1-5점으로 평가하고 비평을 제공하세요.
형식: 점수: X\n비평: ...
초안:
{draft}
"""
response = client.chat.completions.create(...)
# 응답에서 점수와 비평 파싱
return critique, score
# 루프에서:
critique, score = scored_reflector(current_draft)
if score >= 4:
print("✅ 품질 임계값 도달!")
break리플렉션 vs 다른 패턴
| 패턴 | 접근 방식 | 적합한 경우 |
|---|---|---|
| ReAct | 번갈아 추론 | 대화형 탐색 |
| Plan-Execute | 먼저 계획, 그 다음 행동 | 다단계 워크플로우 |
| Reflection | 생성, 비평, 개선 | 품질 향상 |
| Debate | 여러 에이전트가 논쟁 | 논쟁적 주제 처리 |
실습 내용
노트북에서 다음을 수행합니다:
Generator & Reflector 구축
에세이 작성을 위한 두 역할 패턴 구현
Reflexion 루프 실행
여러 반복을 통해 에세이가 개선되는 것 관찰
자가 디버깅 에이전트 생성
자체 오류를 수정하는 코드 에이전트 구축
중지 조건 실험
점수 기반 루프 종료 구현
핵심 요점
- 자기 비평이 품질을 향상 - LLM은 자신의 출력을 효과적으로 비평할 수 있음
- 관심사 분리 - Generator와 Reflector 역할은 구분되어야 함
- 반복이 일회성보다 나음 - 여러 개선 사이클이 일관되게 결과를 향상
- 중지 조건이 중요 - 반복 횟수만이 아니라 점수나 품질 임계값 사용
참고 자료 & 추가 학습
학술 논문
-
"Reflexion: Language Agents with Verbal Reinforcement Learning" - Shinn et al., 2023
- arXiv:2303.11366 (opens in a new tab)
- 에이전트의 언어적 자기 성찰 기초
-
"Self-Refine: Iterative Refinement with Self-Feedback" - Madaan et al., 2023
- arXiv:2303.17651 (opens in a new tab)
- 반복적 자기 피드백이 다양한 작업에서 생성을 개선함을 보임
-
"Constitutional AI: Harmlessness from AI Feedback" - Anthropic, 2022
- arXiv:2212.08073 (opens in a new tab)
- AI를 사용하여 AI 응답을 비평하고 개선
-
"Language Models can Solve Computer Tasks" - Kim et al., 2023
- arXiv:2303.17491 (opens in a new tab)
- 코드 생성을 위한 자가 디버깅 접근법
관련 개념
- Critique Models: LLM Critics (opens in a new tab)
- Self-Consistency: 샘플링 기반 자가 검증 (opens in a new tab)
다음 단계
리플렉션을 이해했으니, Structured Reasoning으로 이동하여 고급 분해와 Tree of Thoughts를 배워보세요!