jongkwan.dev
개발 · Essay №034

Reflexion

실패를 언어로 분석하고 메모리에 저장하여 같은 실수를 반복하지 않는 자기 개선 기법

이종관2026년 1월 30일7 min read
Contents

실패를 언어로 분석해 메모리에 남기고, 다음 시도에서 그 교훈을 참조해 같은 실수를 피하는 기법이다.

개념

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

동작 구조

  1. 1차 시도 후 실패한다
  2. 반성 -- "왜 실패했는가?"를 언어로 분석한다
  3. 메모리에 교훈 저장 -- 반성 내용을 텍스트로 기록한다
  4. 2차 시도 -- 메모리를 참조하여 같은 실수를 피하고 성공한다

예시

python
# [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 변수의 타입 검증이 필요하다. 사용자가 문자열이나 다른 타입을 전달할 수 있다."

메모리에 저장

python
# [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)
 
# 결과: 성공

핵심 특징

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

성능

벤치마크기존 state-of-the-art(SOTA) GPT-4Reflexion
HumanEval (코딩, pass@1)80%91%

Reflexion 논문(arXiv:2303.11366) 보고 기준으로, HumanEval pass@1는 80%에서 91%로 올라 당시 SOTA였던 GPT-4(80%)를 11%p 앞섰다.

단순 재시도와의 차이

  • 단순 재시도: 1차 실패 -- 2차 실패(같은 실수 반복) -- 3차 실패(또 같은 실수). 피드백 없이 반복하므로 개선되지 않는다.
  • Reflexion: 1차 실패 후 "타입 검증이 없었다"라고 반성하고, 2차에서 타입 검증을 추가하여 성공한다. 실패 원인을 분석하므로 빠르게 개선된다.

메모리 구조

python
# 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글쓰기, 요약

동작 알고리즘

python
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

load_memory는 이전 시도에서 쌓인 교훈을 불러오고, execute_with_memory는 그 메모리를 참조해 작업을 실행한다. 실패하면 reflect_on_failure가 오류와 코드를 받아 실패 원인을 언어로 정리하고, memory.append로 그 반성을 다음 시도에 쓸 수 있게 누적한다.

적용 시나리오

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

한계

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

정리

Reflexion은 실패한 시도를 언어로 분석하고 텍스트 메모리에 남겨, 다음 시도에서 같은 실수를 피하는 기법이다. 모델 가중치를 바꾸지 않고 메모리만 갱신하므로 재학습 없이 누적 학습이 가능하다. 다만 성공과 실패가 명확히 갈리는 작업에서만 효과가 분명하고, 관련 경험을 메모리에서 찾지 못하면 개선이 일어나지 않는다. 코딩이나 테스트가 있는 문제처럼 실패 신호가 뚜렷한 영역에 잘 맞고, 창작처럼 기준이 모호한 작업에는 Self-Refine이 더 적합하다.

관련 개념

  • Self-Refine: 지속적 개선 (실패 없이도)
  • CRITIC: 외부 도구 검증
  • ReAct: 기반 프레임워크
  • Self-Debug (arXiv 2304.05128): 코드 실행 트레이스를 읽어 스스로 디버깅하는 자기수정 계열