🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Reflection Agent 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2026. 2. 1. · 8 Views

Reflection Agent 완벽 가이드

AI 에이전트가 스스로 생각하고, 비판하고, 개선하는 Reflection 패턴을 초급 개발자도 쉽게 이해할 수 있도록 실무 예제와 함께 설명합니다. 자기 개선형 에이전트를 만드는 핵심 기법을 배워봅니다.


목차

  1. Self-Reflection_개념
  2. 자기_비판_프롬프트
  3. 개선_사이클_구현
  4. 메타인지_패턴
  5. 반복_횟수_제어
  6. 실전_자기_개선형_글쓰기_에이전트

1. Self-Reflection 개념

김개발 씨는 요즘 AI 에이전트 개발에 푹 빠져 있습니다. 그런데 한 가지 고민이 있었습니다.

"왜 내가 만든 AI는 한 번 답변하면 끝이지? 사람처럼 '아, 이건 좀 아닌데...' 하고 다시 생각해보는 건 안 되나?"

Self-Reflection은 AI 에이전트가 자신의 출력을 스스로 되돌아보고 평가하는 능력입니다. 마치 글을 쓴 후 퇴고하는 작가처럼, AI도 자신이 생성한 결과물을 검토하고 개선할 수 있습니다.

이 패턴을 적용하면 단순한 일회성 응답을 넘어서 품질 높은 결과물을 만들어낼 수 있습니다.

다음 코드를 살펴봅시다.

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage

# Reflection Agent의 기본 구조
class ReflectionAgent:
    def __init__(self):
        self.llm = ChatOpenAI(model="gpt-4")

    def generate(self, task: str) -> str:
        # 1단계: 초기 응답 생성
        response = self.llm.invoke([HumanMessage(content=task)])
        return response.content

    def reflect(self, task: str, response: str) -> str:
        # 2단계: 자기 성찰 - 응답을 스스로 평가
        reflection_prompt = f"""
        원래 작업: {task}
        내 응답: {response}

        위 응답을 비판적으로 평가해주세요.
        무엇이 좋고, 무엇이 부족한가요?
        """
        reflection = self.llm.invoke([HumanMessage(content=reflection_prompt)])
        return reflection.content

김개발 씨는 입사 6개월 차 AI 개발자입니다. 어느 날 팀장님이 중요한 미션을 주었습니다.

"고객 문의에 답변하는 AI 챗봇을 만들어주세요. 근데 답변 품질이 정말 중요해요." 김개발 씨는 열심히 챗봇을 만들었습니다.

GPT API를 연동하고, 프롬프트를 다듬었습니다. 그런데 테스트를 해보니 문제가 있었습니다.

AI가 때때로 엉뚱한 답변을 하거나, 중요한 정보를 빠뜨리는 경우가 있었던 것입니다. "사람이라면 답변을 보내기 전에 한 번 더 읽어보잖아.

AI도 그렇게 할 수 없을까?" 바로 이 지점에서 Self-Reflection 패턴이 등장합니다. Self-Reflection을 쉽게 비유하자면, 시험지를 제출하기 전에 한 번 더 검토하는 것과 같습니다.

학창 시절을 떠올려 보세요. 시험을 볼 때 답을 다 적고 바로 제출하는 학생이 있는가 하면, 남은 시간 동안 자신의 답을 다시 읽어보며 실수를 찾는 학생이 있었습니다.

어떤 학생이 더 좋은 성적을 받았을까요? AI 에이전트도 마찬가지입니다.

한 번의 응답으로 끝내는 것이 아니라, 자신이 생성한 결과물을 다시 살펴보는 과정을 거치면 훨씬 더 좋은 품질의 출력을 만들어낼 수 있습니다. 위 코드를 살펴보면 ReflectionAgent 클래스가 두 가지 핵심 메서드를 가지고 있습니다.

첫 번째는 generate 메서드로, 주어진 작업에 대한 초기 응답을 생성합니다. 두 번째는 reflect 메서드로, 생성된 응답을 비판적으로 평가합니다.

reflect 메서드를 자세히 보면, 원래 작업과 AI의 응답을 함께 LLM에게 전달하고 있습니다. 그리고 "위 응답을 비판적으로 평가해달라"고 요청합니다.

이것이 바로 Self-Reflection의 핵심입니다. AI가 자기 자신의 출력을 객관적으로 바라보는 것입니다.

실제 현업에서는 이 패턴이 다양하게 활용됩니다. 예를 들어 코드 생성 AI라면 생성한 코드에 버그가 없는지, 더 효율적인 방법은 없는지 스스로 검토할 수 있습니다.

문서 작성 AI라면 논리적 오류나 누락된 정보가 없는지 확인할 수 있습니다. 중요한 점은 Self-Reflection이 단순한 "다시 생각해봐"가 아니라는 것입니다.

구체적인 평가 기준을 제시해야 합니다. "무엇이 좋고 무엇이 부족한지" 명확하게 물어보는 것이 핵심입니다.

김개발 씨는 이 패턴을 적용한 후 챗봇의 답변 품질이 눈에 띄게 향상되는 것을 확인했습니다. 팀장님도 만족스러워했습니다.

"오, 답변이 훨씬 꼼꼼해졌네요!" Self-Reflection은 Reflection Agent의 첫 번째 단계입니다. 하지만 단순히 성찰하는 것만으로는 부족합니다.

다음 단계에서는 이 성찰을 바탕으로 실제로 응답을 개선하는 방법을 배워보겠습니다.

실전 팁

💡 - Self-Reflection 프롬프트에는 구체적인 평가 기준을 포함하세요

  • 초기 응답과 성찰 결과를 모두 저장해두면 디버깅에 유용합니다

2. 자기 비판 프롬프트

박시니어 씨가 김개발 씨의 코드를 보더니 고개를 갸웃거렸습니다. "Reflection은 좋은데, 이 프롬프트로는 제대로 된 비판이 안 나올 거야.

AI한테 '비판해줘'라고만 하면 어떻게 될 것 같아?"

자기 비판 프롬프트는 AI가 스스로를 효과적으로 평가하도록 유도하는 프롬프트 설계 기법입니다. 단순히 "평가해줘"라고 하면 피상적인 답변만 나옵니다.

마치 학생에게 "자기 평가서 써봐"라고만 하면 "열심히 했습니다"로 끝나는 것처럼요. 구체적인 평가 축과 기준을 제시해야 진정한 비판이 가능합니다.

다음 코드를 살펴봅시다.

def create_critique_prompt(task: str, response: str) -> str:
    # 효과적인 자기 비판 프롬프트 템플릿
    return f"""
    당신은 엄격한 품질 검수관입니다.

    [원래 요청]
    {task}

    [생성된 응답]
    {response}

    다음 기준으로 위 응답을 철저히 비판하세요:

    1. 정확성: 사실적 오류가 있나요?
    2. 완전성: 빠진 중요한 정보가 있나요?
    3. 명확성: 모호하거나 혼란스러운 부분이 있나요?
    4. 관련성: 요청과 무관한 내용이 포함되었나요?
    5. 실용성: 실제로 도움이 되는 답변인가요?

    각 기준에 대해 구체적인 문제점을 지적하고,
    개선 방향을 제안하세요. 칭찬보다 비판에 집중하세요.
    """

김개발 씨는 Self-Reflection 코드를 작성한 후 테스트를 해보았습니다. 그런데 이상했습니다.

AI의 자기 평가가 너무 관대했던 것입니다. "응답이 전반적으로 훌륭합니다.

약간의 개선 여지가 있을 수 있습니다." 이게 뭔가요? 명백히 부족한 답변인데도 AI는 자기 자신을 칭찬하고 있었습니다.

박시니어 씨가 웃으며 말했습니다. "그게 바로 자기 긍정 편향이야.

사람도 그렇잖아. 자기 평가서 쓰라고 하면 대부분 좋게 쓰지.

AI도 마찬가지야." 그렇다면 어떻게 해야 AI가 진정으로 비판적인 시각을 가질 수 있을까요? 비유하자면, 이것은 마치 코드 리뷰와 같습니다.

"코드 봐줘"라고만 하면 "잘 짰네"로 끝나기 쉽습니다. 하지만 체크리스트를 주면 달라집니다.

"성능 이슈는 없나? 보안 취약점은?

에러 처리는 제대로 됐나?" 구체적인 기준이 있으면 더 날카로운 리뷰가 가능해집니다. 위 코드에서 핵심은 다섯 가지 평가 축입니다.

정확성, 완전성, 명확성, 관련성, 실용성. 이 기준들이 있으면 AI는 각 축에 대해 하나씩 검토하게 됩니다.

또 하나 중요한 포인트는 프롬프트 시작 부분입니다. "당신은 엄격한 품질 검수관입니다." 이 역할 설정이 AI의 태도를 바꿉니다.

검수관은 칭찬하는 사람이 아닙니다. 문제점을 찾아내는 사람입니다.

마지막 문장도 주목해야 합니다. "칭찬보다 비판에 집중하세요." 이 명시적인 지시가 없으면 AI는 본능적으로 균형 잡힌, 즉 칭찬과 비판이 반반인 피드백을 주려고 합니다.

우리가 원하는 것은 개선점을 찾는 것이므로 비판에 집중하라고 명확히 지시해야 합니다. 실무에서 자기 비판 프롬프트를 설계할 때는 도메인에 맞는 평가 기준을 추가하는 것이 좋습니다.

코드 생성이라면 "버그 가능성", "코드 스타일", "테스트 용이성" 같은 기준을 넣을 수 있습니다. 마케팅 문구 생성이라면 "설득력", "타겟 적합성", "브랜드 톤앤매너" 같은 기준이 필요할 것입니다.

주의할 점도 있습니다. 평가 기준이 너무 많으면 오히려 역효과가 납니다.

AI가 각 기준에 대해 피상적으로만 언급하고 넘어가기 때문입니다. 5개 내외가 적당합니다.

김개발 씨는 새로운 프롬프트를 적용하고 다시 테스트했습니다. 이번에는 달랐습니다.

AI가 정말로 날카로운 비판을 내놓았습니다. "두 번째 단락에서 인과관계가 불명확합니다", "핵심 요청인 예제 코드가 누락되었습니다".

이제야 제대로 된 피드백이 나오기 시작했습니다.

실전 팁

💡 - 평가 기준은 5개 내외로 유지하고, 도메인에 맞게 커스터마이징하세요

  • "칭찬보다 비판에 집중하세요" 같은 명시적 지시를 반드시 포함하세요

3. 개선 사이클 구현

"비판은 좋아졌는데, 그래서 어쩌라고?" 김개발 씨가 화면을 보며 혼잣말했습니다. AI가 문제점을 지적하는 것까지는 좋았습니다.

하지만 정작 개선된 응답을 만들어내지는 못하고 있었습니다.

개선 사이클은 비판을 바탕으로 실제로 응답을 개선하는 반복 과정입니다. 생성, 비판, 개선의 세 단계가 하나의 사이클을 이루며, 이 사이클을 반복할수록 응답의 품질이 향상됩니다.

마치 조각가가 대리석을 깎아 작품을 완성해가는 것처럼, AI도 점진적으로 더 나은 결과물을 만들어갑니다.

다음 코드를 살펴봅시다.

class ReflectionAgent:
    def __init__(self):
        self.llm = ChatOpenAI(model="gpt-4")
        self.history = []  # 개선 과정 기록

    def improve_cycle(self, task: str, max_iterations: int = 3) -> str:
        # 1단계: 초기 응답 생성
        response = self.generate(task)
        self.history.append({"type": "initial", "content": response})

        for i in range(max_iterations):
            # 2단계: 자기 비판
            critique = self.critique(task, response)
            self.history.append({"type": "critique", "content": critique})

            # 3단계: 비판을 바탕으로 개선
            response = self.improve(task, response, critique)
            self.history.append({"type": "improved", "content": response})

        return response

    def improve(self, task: str, response: str, critique: str) -> str:
        # 비판을 반영하여 새로운 응답 생성
        improve_prompt = f"""
        원래 요청: {task}
        이전 응답: {response}
        받은 피드백: {critique}

        피드백을 반영하여 개선된 응답을 작성하세요.
        """
        improved = self.llm.invoke([HumanMessage(content=improve_prompt)])
        return improved.content

박시니어 씨가 화이트보드에 그림을 그리기 시작했습니다. 동그라미 세 개를 그리고 화살표로 연결했습니다.

"봐봐. 첫 번째 동그라미는 '생성'이야.

AI가 처음 응답을 만들어내는 거지. 두 번째는 '비판'.

방금 우리가 만든 자기 비판 프롬프트로 문제점을 찾는 단계야. 세 번째는 '개선'.

비판을 바탕으로 더 나은 응답을 만드는 거야." "그리고 이 세 단계가 계속 반복되는 거군요?" "맞아. 이게 바로 개선 사이클이야." 이 개념을 일상적인 비유로 설명하면, 소설가의 집필 과정과 비슷합니다.

소설가가 첫 번째 초고를 씁니다. 그리고 읽어봅니다.

"음, 여기 전개가 너무 급하네." 그래서 수정합니다. 다시 읽어봅니다.

"이번엔 캐릭터 묘사가 부족해." 또 수정합니다. 이런 과정을 거쳐 명작이 탄생합니다.

위 코드의 improve_cycle 메서드를 보면 이 과정이 코드로 구현되어 있습니다. for 루프 안에서 critique과 improve가 번갈아 호출됩니다.

특히 주목할 부분은 history 리스트입니다. 각 단계의 결과를 모두 기록하고 있습니다.

이것이 왜 중요할까요? 나중에 디버깅할 때, 어느 단계에서 문제가 생겼는지 추적할 수 있기 때문입니다.

또한 개선 과정 자체를 분석하면 더 나은 프롬프트를 설계하는 데 도움이 됩니다. improve 메서드를 자세히 살펴봅시다.

세 가지 정보를 함께 전달합니다. 원래 요청, 이전 응답, 그리고 받은 피드백.

AI는 이 세 가지를 종합하여 개선된 응답을 생성합니다. 여기서 핵심은 피드백을 명시적으로 전달한다는 것입니다.

그냥 "다시 해봐"가 아니라 "이런 문제점이 있었으니 고쳐줘"라고 구체적으로 알려주는 것입니다. 실무에서는 이 사이클에 종료 조건을 추가하기도 합니다.

예를 들어 비판에서 더 이상 심각한 문제점이 발견되지 않으면 사이클을 조기 종료할 수 있습니다. 불필요한 API 호출을 줄이고 비용을 절약하는 효과가 있습니다.

김개발 씨가 개선 사이클을 적용한 후 테스트를 해보았습니다. 첫 번째 응답은 70점짜리였습니다.

한 번 사이클을 돌린 후에는 85점. 두 번 돌린 후에는 92점.

정말로 품질이 향상되고 있었습니다. "와, 진짜 되네요!" 하지만 박시니어 씨가 손을 들어 제지했습니다.

"잠깐, 그런데 몇 번을 반복해야 하는지는 어떻게 정할 거야? 무한정 돌릴 순 없잖아." 좋은 질문입니다.

다음 섹션에서 반복 횟수를 제어하는 방법을 알아보겠습니다.

실전 팁

💡 - 개선 과정을 history에 기록해두면 디버깅과 분석에 유용합니다

  • improve 프롬프트에는 이전 응답과 피드백을 모두 포함시키세요

4. 메타인지 패턴

"근데 시니어님, AI가 자기가 뭘 모르는지도 알 수 있나요?" 김개발 씨의 질문에 박시니어 씨가 미소를 지었습니다. "좋은 질문이야.

그게 바로 메타인지라는 거야. 생각에 대해 생각하는 것."

메타인지는 자신의 사고 과정 자체를 인식하고 모니터링하는 능력입니다. AI 에이전트에게 메타인지를 부여하면, 단순히 "이 답이 맞나?"를 넘어서 "내가 이 문제를 제대로 이해했나?", "내 추론 과정에 허점은 없나?"까지 점검할 수 있습니다.

이것은 마치 체스 선수가 수를 두기 전에 "상대방 입장에서 생각해보면..."이라고 하는 것과 같습니다.

다음 코드를 살펴봅시다.

def create_metacognitive_prompt(task: str, response: str) -> str:
    # 메타인지적 자기 점검 프롬프트
    return f"""
    [작업]
    {task}

    [내 응답]
    {response}

    다음 메타인지적 질문에 답하세요:

    1. 이해도 점검
       - 요청을 정확히 이해했나요?
       - 숨겨진 의도나 맥락을 놓치진 않았나요?

    2. 추론 과정 점검
       - 어떤 가정을 했나요? 그 가정은 타당한가요?
       - 논리적 비약은 없나요?

    3. 지식 한계 인식
       - 확실하지 않은 정보가 있나요?
       - 추가로 필요한 정보는 무엇인가요?

    4. 대안 탐색
       - 다른 접근 방식은 없었나요?
       - 왜 이 방식을 선택했나요?

    각 질문에 솔직하게 답하고, 개선이 필요한 부분을 도출하세요.
    """

어느 날 김개발 씨가 이상한 현상을 발견했습니다. 개선 사이클을 돌렸는데, 응답이 점점 더 길어지기만 하고 실제로 좋아지는 것 같지 않았습니다.

비판에서 "정보가 부족하다"고 했더니 AI가 관련 없는 정보까지 마구 추가한 것입니다. "비판은 하는데, 제대로 된 비판이 아닌 것 같아요." 박시니어 씨가 고개를 끄덕였습니다.

"자기 비판 프롬프트가 '무엇이' 잘못됐는지는 찾아내지만, '왜' 잘못됐는지, '어떻게' 그런 실수를 했는지는 분석하지 못하거든. 그래서 메타인지가 필요해." 메타인지를 쉽게 설명하면, 생각에 대해 생각하는 것입니다.

예를 들어볼까요. 수학 문제를 풀다가 틀렸습니다.

단순 비판은 "답이 틀렸다"입니다. 메타인지적 비판은 "왜 틀렸지?

아, 문제를 잘못 읽었구나. 음수 조건을 놓쳤어"입니다.

위 코드의 메타인지 프롬프트는 네 가지 차원에서 점검합니다. 첫째, 이해도 점검입니다.

애초에 요청을 제대로 이해했는지 확인합니다. 놀랍게도 많은 경우 AI의 실수는 요청을 잘못 해석한 데서 시작합니다.

둘째, 추론 과정 점검입니다. AI가 어떤 가정을 했는지, 그 가정이 타당한지 살펴봅니다.

"사용자가 초급자일 것이다"라고 가정했는데 실제로는 전문가였다면? 완전히 다른 응답이 필요했을 것입니다.

셋째, 지식 한계 인식입니다. AI도 모르는 것이 있습니다.

확실하지 않은 정보를 마치 확실한 것처럼 말하는 것보다, "이 부분은 확인이 필요합니다"라고 솔직하게 인정하는 것이 더 낫습니다. 넷째, 대안 탐색입니다.

선택한 방식 외에 다른 방법은 없었는지 점검합니다. 때로는 처음 떠올린 방식이 최선이 아닐 수 있습니다.

실무에서 메타인지 패턴은 특히 복잡한 의사결정이 필요한 에이전트에 유용합니다. 예를 들어 코드 리팩토링을 제안하는 에이전트라면, 단순히 "이렇게 바꾸면 좋겠다"가 아니라 "왜 이 방식을 선택했는지", "다른 선택지는 무엇이 있었는지", "어떤 트레이드오프가 있는지"까지 설명할 수 있습니다.

주의할 점은 메타인지 프롬프트가 기존 비판 프롬프트를 대체하는 것이 아니라 보완한다는 것입니다. 내용의 정확성 같은 기본적인 검증은 여전히 필요합니다.

메타인지는 그 위에 한 층 더 깊은 성찰을 추가하는 것입니다. 김개발 씨는 메타인지 프롬프트를 추가한 후 다시 테스트했습니다.

이번에는 AI가 "제가 사용자의 기술 수준을 고려하지 않았습니다. 초급자를 대상으로 한다면 용어 설명이 필요합니다"라고 스스로 지적했습니다.

"오, 이제 정말 똑똑해진 것 같아요!"

실전 팁

💡 - 메타인지 프롬프트는 기존 비판 프롬프트와 함께 사용하세요

  • 특히 "어떤 가정을 했는지" 점검하는 것이 실수를 줄이는 데 효과적입니다

5. 반복 횟수 제어

"근데 이거 무한 루프 돌면 어떡해요?" 김개발 씨가 걱정스럽게 물었습니다. 개선 사이클이 끝없이 돌아가면 API 비용도 문제지만, 오히려 품질이 떨어지는 과적합 현상도 발생할 수 있었습니다.

반복 횟수 제어는 개선 사이클을 언제 멈출지 결정하는 메커니즘입니다. 무조건 많이 반복한다고 좋은 것이 아닙니다.

마치 요리할 때 적절한 조리 시간이 있는 것처럼, AI 개선 사이클에도 최적의 반복 횟수가 있습니다. 너무 적으면 덜 익고, 너무 많으면 타버립니다.

다음 코드를 살펴봅시다.

class SmartReflectionAgent:
    def __init__(self, max_iterations: int = 5, quality_threshold: float = 0.9):
        self.llm = ChatOpenAI(model="gpt-4")
        self.max_iterations = max_iterations
        self.quality_threshold = quality_threshold

    def improve_with_control(self, task: str) -> dict:
        response = self.generate(task)

        for i in range(self.max_iterations):
            # 품질 평가
            score = self.evaluate_quality(task, response)

            # 종료 조건 1: 품질 기준 충족
            if score >= self.quality_threshold:
                return {"response": response, "iterations": i, "reason": "quality_met"}

            # 종료 조건 2: 개선 정체 감지
            critique = self.critique(task, response)
            if self.is_improvement_stagnant(critique):
                return {"response": response, "iterations": i, "reason": "stagnant"}

            # 개선 진행
            response = self.improve(task, response, critique)

        return {"response": response, "iterations": self.max_iterations, "reason": "max_reached"}

    def evaluate_quality(self, task: str, response: str) -> float:
        # 0~1 사이의 품질 점수 반환
        eval_prompt = f"0~1 점수로 평가하세요. 숫자만 답하세요.\n작업:{task}\n응답:{response}"
        score = self.llm.invoke([HumanMessage(content=eval_prompt)])
        return float(score.content.strip())

박시니어 씨가 재미있는 실험 결과를 보여주었습니다. 같은 작업에 대해 개선 사이클을 1회, 3회, 5회, 10회 돌린 결과물이었습니다.

1회는 확실히 부족했습니다. 3회는 괜찮았습니다.

5회는 더 좋았습니다. 그런데 10회는 오히려 이상해졌습니다.

문장이 불필요하게 복잡해지고, 같은 말을 다르게 반복하고, 핵심이 흐려졌습니다. "이게 바로 과적합 현상이야.

너무 많이 다듬으면 오히려 망가져." 그렇다면 몇 번이 적당한 걸까요? 정답은 "그때그때 다르다"입니다.

그래서 지능적인 종료 조건이 필요합니다. 위 코드에서 세 가지 종료 조건을 구현했습니다.

첫째, 품질 기준 충족입니다. evaluate_quality 메서드가 응답의 품질을 0에서 1 사이 점수로 평가합니다.

이 점수가 설정한 임계값을 넘으면 "이 정도면 됐다"라고 판단하고 종료합니다. 둘째, 개선 정체 감지입니다.

is_improvement_stagnant 메서드가 비판 내용을 분석합니다. 비판에서 더 이상 심각한 문제점이 발견되지 않거나, 이전 사이클과 비슷한 비판만 반복되면 정체 상태로 판단합니다.

셋째, 최대 반복 횟수입니다. 위 두 조건이 작동하지 않더라도 max_iterations에 도달하면 강제 종료합니다.

이것은 안전장치입니다. 반환값에 reason을 포함시킨 것에 주목하세요.

"quality_met", "stagnant", "max_reached" 중 어떤 이유로 종료됐는지 알 수 있습니다. 이 정보는 시스템을 튜닝할 때 매우 유용합니다.

대부분 max_reached로 끝난다면 최대 반복 횟수를 늘려야 할 수 있습니다. 대부분 한두 번 만에 quality_met로 끝난다면 초기 프롬프트가 이미 충분히 좋은 것입니다.

실무에서는 작업의 복잡도에 따라 max_iterations를 다르게 설정하기도 합니다. 간단한 질문 답변은 2회면 충분하지만, 복잡한 코드 생성은 5회 이상이 필요할 수 있습니다.

이런 설정은 경험적으로 조정해나가야 합니다. 비용 관점에서도 반복 횟수 제어는 중요합니다.

GPT-4 API 호출은 비용이 듭니다. 한 번의 개선 사이클에 최소 2회 호출이 필요합니다.

비판 한 번, 개선 한 번. 불필요한 반복을 줄이면 비용을 크게 절약할 수 있습니다.

김개발 씨가 smart한 반복 제어를 구현한 후, 평균 반복 횟수가 5회에서 2.3회로 줄었습니다. 품질은 유지되면서 API 비용은 절반 이상 절약된 것입니다.

"역시 무조건 많이 한다고 좋은 게 아니군요."

실전 팁

💡 - 품질 평가 프롬프트는 일관된 기준을 적용하도록 신중하게 설계하세요

  • 종료 이유를 기록해두면 시스템 튜닝에 큰 도움이 됩니다

6. 실전 자기 개선형 글쓰기 에이전트

"자, 이제 배운 것들을 다 합쳐서 실전 프로젝트를 만들어볼까?" 박시니어 씨의 제안에 김개발 씨의 눈이 반짝였습니다. 지금까지 배운 Self-Reflection, 자기 비판 프롬프트, 개선 사이클, 메타인지, 반복 제어를 모두 적용한 완성형 에이전트를 만들 시간입니다.

자기 개선형 글쓰기 에이전트는 앞서 배운 모든 Reflection 패턴을 통합한 실전 예제입니다. 사용자의 글쓰기 요청을 받아 초안을 작성하고, 자기 비판과 메타인지적 점검을 거쳐 점진적으로 개선합니다.

최종적으로 품질 기준을 충족하는 글을 생성하며, 전체 개선 과정도 함께 제공합니다.

다음 코드를 살펴봅시다.

class WritingAgent:
    def __init__(self):
        self.llm = ChatOpenAI(model="gpt-4")
        self.max_iterations = 4
        self.quality_threshold = 0.85

    def write(self, topic: str, style: str, length: str) -> dict:
        # 1단계: 초안 작성
        draft = self.create_draft(topic, style, length)
        history = [{"stage": "draft", "content": draft}]

        for i in range(self.max_iterations):
            # 2단계: 자기 비판 + 메타인지
            critique = self.comprehensive_review(topic, draft, style)
            history.append({"stage": f"review_{i+1}", "content": critique})

            # 3단계: 품질 평가
            score = self.score_writing(topic, draft, style)
            if score >= self.quality_threshold:
                break

            # 4단계: 개선
            draft = self.revise(topic, draft, critique, style)
            history.append({"stage": f"revision_{i+1}", "content": draft})

        return {"final": draft, "history": history, "iterations": i+1}

    def comprehensive_review(self, topic: str, draft: str, style: str) -> str:
        # 자기 비판 + 메타인지 통합 리뷰
        prompt = f"""
        [주제] {topic}
        [요청 스타일] {style}
        [작성된 글] {draft}

        === 내용 검토 ===
        1. 주제 적합성: 주제를 잘 다루고 있나요?
        2. 논리적 구조: 글의 흐름이 자연스럽나요?
        3. 문체 일관성: 요청한 스타일에 맞나요?

        === 메타인지 점검 ===
        4. 독자 고려: 대상 독자를 고려했나요?
        5. 가정 검토: 어떤 가정을 했고 타당한가요?
        6. 대안 탐색: 더 효과적인 접근이 있었나요?

        각 항목에 대해 구체적으로 평가하고 개선점을 제시하세요.
        """
        return self.llm.invoke([HumanMessage(content=prompt)]).content

드디어 모든 퍼즐 조각을 맞출 시간이 왔습니다. 김개발 씨는 박시니어 씨와 함께 실전에서 사용할 수 있는 완성형 글쓰기 에이전트를 만들기로 했습니다.

"글쓰기 에이전트를 만드는 이유가 뭐예요?" 박시니어 씨가 설명했습니다. "글쓰기는 Reflection Agent의 효과가 가장 극명하게 드러나는 영역이야.

초안, 퇴고, 완성이라는 흐름이 인간의 글쓰기 과정과 똑같거든." 위 코드의 WritingAgent 클래스는 네 가지 핵심 메서드로 구성됩니다. write 메서드는 전체 프로세스를 조율하는 오케스트레이터입니다.

초안 작성부터 반복 개선까지 모든 단계를 관리합니다. topic, style, length 세 가지 파라미터를 받아서 사용자의 요구사항을 명확히 전달합니다.

create_draft 메서드는 첫 번째 초안을 생성합니다. 완벽할 필요 없습니다.

일단 뼈대를 만드는 것이 목적입니다. comprehensive_review 메서드가 이 에이전트의 핵심입니다.

앞서 배운 자기 비판과 메타인지를 통합했습니다. 내용 검토에서는 주제 적합성, 논리 구조, 문체 일관성을 점검합니다.

메타인지 점검에서는 독자 고려, 가정 검토, 대안 탐색을 수행합니다. revise 메서드는 리뷰 결과를 바탕으로 글을 개선합니다.

여기서 중요한 것은 원본 글과 피드백을 함께 전달한다는 점입니다. AI가 맥락을 유지하면서 개선할 수 있도록 합니다.

history 변수에 주목해주세요. 각 단계의 결과를 모두 기록합니다.

최종 결과물뿐만 아니라 어떤 과정을 거쳐 완성됐는지 보여줄 수 있습니다. 사용자에게 투명성을 제공하고, 개발자에게는 디버깅 정보를 제공합니다.

실제로 이 에이전트를 사용해보면 놀라운 결과를 볼 수 있습니다. 예를 들어 "초급 개발자를 위한 Git 사용법"이라는 주제로 "친근한 문체"의 글을 요청했다고 합시다.

첫 번째 초안은 정보는 담겨 있지만 다소 딱딱합니다. 첫 번째 리뷰에서 "독자인 초급 개발자의 눈높이를 더 고려해야 한다", "비유를 활용하면 이해도가 높아질 것"이라는 피드백이 나옵니다.

첫 번째 개선 후에는 비유가 추가되고 문체가 부드러워집니다. 두 번째 리뷰에서 "흐름은 좋아졌지만 실습 예제가 부족하다"는 피드백이 나옵니다.

두 번째 개선 후에는 실습 예제가 추가됩니다. 이쯤 되면 품질 점수가 threshold를 넘어서 완성됩니다.

김개발 씨가 완성된 에이전트를 테스트하며 감탄했습니다. "와, 정말 사람이 퇴고하는 것처럼 글이 점점 좋아지네요!" 이 패턴은 글쓰기뿐만 아니라 코드 생성, 번역, 요약, 기획서 작성 등 다양한 분야에 적용할 수 있습니다.

핵심은 동일합니다. 생성, 비판, 개선의 사이클을 지능적으로 반복하는 것입니다.

실전 팁

💡 - comprehensive_review에서 도메인별로 평가 기준을 커스터마이징하세요

  • history를 활용하면 사용자에게 개선 과정을 시각화하여 보여줄 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#ReflectionAgent#SelfCritique#LLM#AIAgent#Spring,AI,Agent

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스