이종관
Back to Posts

Reflexion: 실패로부터 배우는 에이전트

실패한 시도를 언어로 분석하고 메모리에 저장하여, 다음 시도에서 같은 실수를 반복하지 않습니다

2026년 2월 1일·5 min read·
ai
ai-agent
llm
reflexion
self-reflection
learning

언어적 자기 성찰을 통한 학습

개념

Reflexion은 실패한 시도를 언어로 분석하고 메모리에 저장하여, 다음 시도에서 같은 실수를 반복하지 않도록 하는 기법입니다.

동작 구조

1차 시도 → 실패
    ↓
반성: "왜 실패했는가?"
    ↓
메모리에 교훈 저장
    ↓
2차 시도 (메모리 참조) → 성공

예시

# [1차 시도]
def book_hotel(name, dates, room_type):
    reservation = {
        "name": name,
        "dates": dates,
        "room": room_type
    }
    return confirm_booking(reservation)

# 결과: RuntimeError - 'dates' must be a list
# [반성]
"dates 변수의 타입 검증이 필요하다.
 사용자가 문자열이나 다른 타입을 전달할 수 있다."
→ 메모리에 저장
# [2차 시도] - 메모리 참조
def book_hotel(name, dates, room_type):
    # 메모리에서 학습: 타입 검증 필요
    if not isinstance(dates, list):
        raise ValueError("dates must be a list")

    reservation = {
        "name": name,
        "dates": dates,
        "room": room_type
    }
    return confirm_booking(reservation)

# 결과: 성공!

핵심 특징

특징설명
가중치 변경 없음모델 재학습 불필요
텍스트 기반 메모리효율적이고 해석 가능
누적 학습경험이 쌓일수록 개선

성능

벤치마크기존Reflexion
HumanEval (코딩)48%91%

**HumanEval 48% → 91%**는 약 2배의 성능 향상입니다.

단순 재시도와의 차이

[단순 재시도]
1차: 실패
2차: 실패 (같은 실수 반복)
3차: 실패 (또 같은 실수)

[Reflexion]
1차: 실패
   → 반성: "타입 검증이 없었다"
2차: 타입 검증 추가 → 성공!

메모리 구조

# Reflexion 메모리 예시
memory = [
    {
        "task": "book_hotel 함수 구현",
        "failure": "TypeError: dates must be a list",
        "reflection": "입력 타입 검증이 필요하다",
        "solution": "isinstance() 체크 추가"
    },
    {
        "task": "API 호출 함수",
        "failure": "ConnectionError",
        "reflection": "네트워크 에러 처리가 필요하다",
        "solution": "try-except와 재시도 로직 추가"
    }
]

메모리 활용

[새로운 작업] "결제 API 함수 구현"

[메모리 검색]
→ 관련 경험: "API 호출 함수" - 네트워크 에러 처리 필요

[적용]
처음부터 try-except와 재시도 로직 포함
→ 1차 시도에서 성공!

Self-Refine과의 차이

ReflexionSelf-Refine
트리거실패 후 반성지속적 개선
실패 신호명확한 실패 필요실패 없이도 개선
메모리장기 메모리에 저장즉시 반영
적용 분야코딩, QA글쓰기, 요약

동작 알고리즘

def reflexion_loop(task, max_attempts=3):
    memory = load_memory()

    for attempt in range(max_attempts):
        # 메모리 참조하여 시도
        result = execute_with_memory(task, memory)

        if result.success:
            return result

        # 실패 시 반성
        reflection = reflect_on_failure(
            task=task,
            error=result.error,
            code=result.code
        )

        # 메모리에 저장
        memory.append({
            "task": task,
            "failure": result.error,
            "reflection": reflection
        })

    return result

적용 시나리오

시나리오적합 여부
코딩 문제 (테스트 있음)매우 적합
명확한 성공/실패 기준적합
팩트 기반 QA적합 (CRITIC과 결합)
창작 글쓰기덜 적합 (Self-Refine 권장)

한계

  1. 명확한 실패 신호 필요: 성공/실패가 불분명한 작업에는 부적합
  2. 메모리 검색 품질: 관련 경험을 찾지 못할 수 있음
  3. 일반화: 비슷한 상황을 인식하지 못할 수 있음

관련 개념

  • Self-Refine: 지속적 개선 (실패 없이도)
  • CRITIC: 외부 도구 검증
  • ReAct: 기반 프레임워크