LLM 시대, LangChain(랭체인)으로 배우는 AI 소프트웨어 개발
Reflexion은 LLM을 이용한 에이전트를 프롬프트의 반복적인 개선으로 성능을 향ㅅ상시키는 학습기법입니다. 여기서 말하는 학습은 LLM의 파라미터 업데이트와 함께 파인튜닝과 같은 Transformer의 파라미터 업데이트와 관련된 학습이 아닙니다. LLM자체가 작업을 시도한 결과를 분석하고 언어 피드백을 생성하여 자체 개선을 의미합니다. 언어적인 피드백을 다음에 시도할 때의 프롬프트에 컨텍스트로서 포함하기 때문에 일종의 문맥내 학습이라고도 할 수 있습니다.
Reflexion은 언어 피드백을 경험을호 장기 기억으로 저장하고 다음 시도에서 참조하여 에이전트 성능을 향상시킵니다. 반면에 각 시도에 필요한 정보는 단기 기억으로 저장됩니다.
Reflexion의 에이전트는 아래 그림과 같이 Actor, Evaluator, Self-Reflection의 3가지 구성요소를 사용하여 주어진 작업을 수행합니다. 이러한 구성요소는 각각 LLM을 사용하여 각 역할을 수행합니다. 추론시, 액터는 단기기억에 저장한 궤적(Trajectory)과 장기기억에서 추출한 중요한 경험을 컨텏스트로서 프롬프트에 내장 LLM에 전달합니다. 여기의 궤적은 에이전트가 과거에 한 추론과 행동(프롬프트 및 LLM출력) 및 관측 순서를 나타냅니다. 앞서 소개한 ReAct의 일련의 프로세스는 궤적에 해당합니다. Actor가 환경과 상호작용하는 경우 ReAct와 같은 메커니즘이 사용됩니다.
각 구성요소의 작동은 다음과 같습니다.
Actor: 주어진 작업을 시도합니다. 현재의 시도에서의 궤적(추론이나 행동과 관측의 순서)을 단기기억으로서 유지합니다. 또한, 과거 시도에서 얻은 Self-Reflection의 피드백을 장기기억으로 참조합니다.
Evaluator: 단기기억에 저장된 Actor의 시도 결과인 궤적을 평가합니다.
Self-Reflection: 현재 시험의 궤적과 Evaluator평가결과를 입력으로 받아 언어 피드백을 생성합니다. 이 피드백은 장기기억에 추가됩니다.
단기기억은 태스크의 시도마다 완결되고, 시도가 종료하면 파기됩니다. 한편 장기기억은 여러 시도를 거쳐 축적되어 갑니다. 이 설계를 통해 각 에이전트는 자신의 역할에 특화된 정보를 처리할 수 있습니다. 또한, 장기기억을 통해 Actor가 과거의 경험에서 학습함으로써 유사한 작업을 반복하는 동안 성능이 향상됩니다.
② Reflextion 처리 절차
하나의 태스크가 주어졌을 때의 Reflexion의 처리 순서는 다음과 같습니다.
1.Actor가 초기 궤적을 생성
2. Evaluator가 궤적을 평가
3. Evaluator가 합격판정을 내거나 시험횟수가 상한에 도달할 때까지 다음 내용을 반복합니다.
① Self-Reflection이 평가결과로부터 피드백을 생성
② 피드백을 장기 기억에 추가
이 작업을 통한 경험은 장기기억에 남기 때문에 Actor의 다음 작업에도 활용됩니다.
③ Reflexion을 이용한 코드 생성의 예시
예를 들어, Reflexion을 코드 생성 태스크에 적용한 경우를 소개합니다. 여기서는 파이썬 함수 시그니처과 문서를 입력으로 사용하고 함수를 구현하는 코드생성 작업을 가정합니다.
먼저 다음 함수 시그니처와 문서를 제공하여 함수 본문을 생성하는 작업을 생각해 보겠습니다.
여기서 함수문서는 Python의 docstring형식으로 제공됩니다. '두 개의 정수 a와 b를 받고 그 합을 반환한다'라는 설명은 함수문서입니다.
시작하기 전에 Actor는 초기 궤적을 생성합니다. 궤적 생성은 LLM에 프롬프트를 제공하고 출력을 얻음으로써 수행됩니다. 사용할 프롬프트는 다음과 같습니다.
여기서는 함수의 시그니처와 문서가 주어져 그 함수를 구현하는 코드를 생성하도록 지시하고 있습니다. 또한, Python의 코드블록에서 답변하도록 Few-Shot(One-Shot)프롬프트에서 답변을 보여줍니다.
LLM은 이 프롬프트에 대해 다음과 유사한 코드를 생성합니다.
함수 본문에는 두 개의 인수 a와 b를 더하여 반환하는 코드가 생성됩니다. 그런 다음 Evaluator가 생성된 코드를 평가합니다. Evaluator는 LLM에 다음과 같은 프롬프트를 제공하여 코드를 평가하는 테스트를 생성합니다.
여기에서는 함수의 시그니처와 문서가 주어지고 함수에 대한 단위테스트를 생성하도록 지시합니다. 또한, 이전 프롬프트와 마찬가지로 Few-Shot(One-Shot) 프롬프트를 사용하여 생성되는 단위 테스트를 보여줍니다.
Evaluator LLM은 이 프롬프트에 대해 다음과 같은 단위 테스트를 생성합니다.
Evaluator는 생성된 단위 테스트를 수행하고 Actor가 생성한 코드를 평가합니다. 그 결과, Actor가 생성한 코드가 모든 테스트를 합격하면 에이전트의 처리를 종료합니다. 반면에 테스트에 실패하면 Self-Refection은 언어피드백을 생성하고 Actor가 사용하는 장기기억에 추가합니다.
여기서는 Actor가 생성한 코드가 다음과 같이 잘못되었을 경우를 가정해 Self-Reflection의 동작을 설명합니다.
이 코드는 2개의 인수 a와 b의 합이 아닌 차이를 반환합니다. 이 때문에 Evaluator가 생성한 유닛테스트에 대해서는 다음과 같이 대부분의 테스트가 실패합니다.
Test failed: 부분에는 불합격의 테스트 케이스에 대한 기대되는 출력과 실제 출력을 기재하고 있습니다.
Self-Refelection은 언어 피드백을 얻기 위해 생성된 코드와 테스트 결과를 사용하여 LLM에 다음과 같은 프롬프트를 제공합니다.
LLM은 이 프롬프트에 대해 다음과 같은 피드백을 생성합니다.
이 피드백은 2개의 정수를 올바르게 합산하려면 -연산자를 +연산자로 바꾸는 것이 필요하다는 것을 언급합니다. Self-Reflection은 이 피드백을 Actor의 장기기억에 추가합니다.
그리고 이 피드백은 Actor 다음 시도에서 코드 생성에 활용됩니다. 장기기억이 다음 시도에서 어떻게 활용되는지 살펴보겠습니다. Actor 두번째 시도에서는 LLM에 다음과 같은 프롬프트를 제공하여 생성된 코드를 LLM에 업데이트합니다.
두번째 시도는 첫번째 결과와 Self-Reflection의 피드백을 제공합니다. 구체적으로 [previous impl]은 첫번째 시도에서 생성된 코드를 [reflection on previous Impl]은 Self-Reflection 피드백을 제공합니다.
Actor는 이 프롬프트에 대해 다음과 같은 코드를 생성합니다.
여기에서 Actor는 Self-Reflection의 피드백을 활용하여 두개의 정수 a와 b를 올바르게 합산하는 코드를 생성합니다.
이런 식으로 Reflexion은 언어피드백을 통해 Actor의 성능을 반복적으로 향상시킵니다. 장기기억은 작업시도를 통해 축적되어 Actor의 의사결정에 영향을 미칩니다. 각 작업 시도에 대해 Actor는 단기기억을 구축하지만 장기기억에 축적된 피드백을 참조할 수 있습니다. 이를 통해 과거 경험에서 학습하고 다음 작업 시행에 활용할 수 있습니다.
LLM에 특정 역할과 개인을 설정하면 모델 성능과 응답 품질을 향상시킬 수 있습니다. 역할과 페르소나 설정은 프롬프트 엔지니어링의 중요한 기술중 하나이며 다양한 응용이 가능합니다. 예를 들어, 역할과 개인 설정은 에이전트 구현에도 적용됩니다. 에이전트 프레임워크인 CrewAI 및 AutoGen을 사용하면 API의 일부에서 에이전트 역할과 페르소나를 지정할 수 있습니다.
전문적인 역할을 LLM으로 설정하면 특정 영역에서 LLM성능을 향상시킬 수 있습니다. (Role-play Prompting). Kong et. al, 2024은 '수학교사'의 역할을 LLM으로 설정하여 산술문제의 성능을 향상 시켰음을 보고 했습니다. 예를 들어, 다음과 같은 문장을 프롬프트에 추가하여 LLM에 '수학교사'의 역할을 설정할 수 있습니다.
이러한 프롬프트를 Zero-Shot CoT프롬프트와 결합함으로써 LLM은 수학분야에 특화된 상세한 추론 과정을 생성할 수 있게 되었습니다. 그 결과 응답 정확가 향상되는 것 같습니다.
② 역할 설정 한계
역할 설정은 CoT 추론의 성능을 향상시킬 수 있는 것으로 알려져 있지만, 성능향상은 작업에 따라 달라진 것을 알고 있습니다. Zheng et al, 2024논문에서 지식을 묻는 문제의 경우 특정 역할이 성능을 크게 향상시키지 않는다는 것을 보여줍니다. 또한, 남성 또는 여성 역할을 설정하면 성별 중립 역할 때보다 약간 성능이 나빠지는 것이 유의한 차이로 보고 되었습니다. 논문에서는 이러한 성별에 따른 성능차이에 대해 사회적 성별 스테레오타입에서 유래한 모델의 바이어스가 원인일 가능성이 시사되고 있습니다.
③ 페르소나 설정
Jiang et al, 2024논문에서는 빅파이브 모델(Big Five Model)에 기초한 성격특성을 LLM으로 설정함으로써 LLM이 그 성격특성에 맞는 언어적 특징을 나타내게 되어 인간다운 대화가 가능하게 된다고 합니다.
빅파이브 모델은 인간 심리학에서 가장 널리 받아 들여지는 성격 특성의 분류법 중 하나입니다. 이 모델은 인간의 성격을 다음 다섯가지 특성(특성척도)으로 분류합니다.
외향성(Extraversion): 사교적, 활발, 적극적, 자기주장이 강한 등의 특징을 나타냅니다.
협조성(Agreeableness): 사려깊은, 상냥한, 협력적, 관용등의 특징을 나타냅니다.
성실성(Conscientiousness): 책임감이 강한 조직적, 근면, 계획적인 어느 특징을 나타냅니다.
신경증 경향(Neuroticism): 불안해지기 쉬운, 감정적으로 불안정, 스트레에 약한 등의 특징을 나타냅니다.
개방성(Openness to Experience): 지적 호기심이 강한, 창조적, 상상력이 풍부하고 새로운 경험에 개방적인 어느 특징을 나타냅니다.
예를 들어, 다음과 같은 프롬프트를 사용하여 LLM에 '사교적으로 개방적인 성격'의 페르소나를 설정할 수 있습니다.
이러한 문장을 프롬프트에 추가하면 설정한 페르소나와 일치하는 답변을 할 것으로 기대됩니다.
©2024-2025 GAEBAL AI, Hand-crafted & made with Damon Jaewoo Kim.
GAEBAL AI 개발사: https://gaebalai.com
AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5