11장 — 목표 설정과 모니터링

AI 에이전트가 진정으로 효과적이고 의미 있게 작동하려면 정보를 처리하거나 도구를 사용하는 능력만으로는 부족합니다. 명확한 방향 감각과 함께 자신이 정말로 성공하고 있는지 판단할 수단이 필요합니다.

이 패턴은 에이전트에게 달성해야 할 구체적인 목표를 부여하고, 그 목표를 향한 진행 상황을 추적하며, 목표 달성 여부를 판별할 수단을 갖추게 하는 것이다.

패턴 개요

여행 계획을 세운다고 생각해 보자. 순간이동 하듯 목적지에 갑자기 나타나는 사람은 없다. 어디로 갈지(목표 상태) 정하고, 지금 어디에 있는지(초기 상태) 파악하고, 이용 가능한 선택지(교통수단, 경로, 예산)를 고려한 다음, 일련의 단계를 짠다.

AI 에이전트 맥락에서 계획 수립이란, 에이전트가 상위 수준 목표를 받아 자율적으로 또는 반자율적으로 일련의 중간 단계나 하위 목표를 생성하는 과정을 가리킵니다. 이렇게 생성된 단계는 순차적으로 실행될 수도 있고, 도구 사용·라우팅·멀티 에이전트 협업 같은 다른 패턴과 결합해 더 복잡한 흐름을 이룰 수도 있습니다.

계획 수립 메커니즘에는 정교한 탐색 알고리즘이나 논리적 추론이 활용되며, 최근에는 대규모 언어 모델이 학습 데이터와 작업 이해를 바탕으로 타당하고 효과적인 계획을 만들어 내는 방식이 점점 늘고 있습니다.

계획 수립 능력이 뛰어나면 단순한 단일 단계 질의로는 해결할 수 없는 문제에도 대응할 수 있다. 다면적인 요청을 처리하고, 상황이 바뀌면 재계획을 통해 적응하며, 복잡한 워크플로를 오케스트레이션할 수 있게 된다. 이 패턴은 많은 고급 에이전틱 행동의 기반이 되며, 단순한 반응형 시스템을 정해진 목표를 향해 주도적으로 작업하는 시스템으로 바꿔 놓는다.

실제 적용과 활용 사례

사례 목표 무엇을 모니터링하나
고객 지원 자동화 “고객의 요금 청구 문의 해결” 대화를 모니터링하고 DB 항목을 확인하며 도구로 요금을 조정한다. 요금 변경이 실제로 반영되었는지, 고객이 긍정적 피드백을 남겼는지 확인하고, 해결되지 않으면 상위 팀으로 이관한다
개인화 학습 시스템 “학생의 대수학 이해도 향상” 연습 문제 진행 상황을 보며 정답률과 풀이 시간 같은 지표를 추적하고, 학생이 어려움을 겪으면 교재와 접근 방식을 바꾼다
프로젝트 관리 도우미 “프로젝트 마일스톤 X를 Y 날짜까지 완료” 작업 상태·팀 커뮤니케이션·가용 자원을 모니터링하면서 지연을 경고하고 목표 달성이 위험해지면 시정 조치를 제안한다
자동 매매 봇 “위험 허용 범위 내에서 수익 극대화” 시장 데이터·포트폴리오 가치·위험 지표를 지속 모니터링하고, 위험 한도를 초과하면 전략을 조정한다
로봇 공학과 자율주행 차량 “승객을 A에서 B까지 안전하게 수송” 주변 환경(다른 차량·보행자·교통 신호), 자체 상태(속도·연료), 계획된 경로상의 진행 상황
콘텐츠 모더레이션 “플랫폼 X에서 유해 콘텐츠를 식별하고 제거” 오탐(false positive)과 미탐(false negative) 을 추적해 필터링 기준을 조정하거나, 모호한 사례는 사람 검토자에게 이관한다

이 패턴은 에이전트가 안정적으로 작동하고, 구체적인 성과를 내며, 변화하는 조건에 적응해야 하는 상황에서 근본적으로 중요하다. 지능적 자기 관리에 필요한 프레임워크를 제공하기 때문이다.

실습 — 스스로 평가하며 코드를 고치는 에이전트

LangChain과 오픈AI API로 파이썬 코드를 생성하고 개선하는 자율 AI 에이전트를 만듭니다. 핵심은 지정된 문제를 풀면서 사용자가 정의한 품질 기준을 충족하는지 확인하는 것입니다.

이 스크립트는 “목표 설정과 모니터링” 패턴을 활용하여 코드를 한 번만 생성하는 데 그치지 않고, 생성 → 자체 평가 → 개선을 반복한다. 에이전트의 성공 여부는 생성된 코드가 처음 설정한 목표를 충족하는지를 AI가 스스로 판단해 측정한다.

흐름은 이렇습니다.

사용자 → 프롬프트 → 코드 생성 → [자기 검토 + 품질 체크리스트] → 양호한가?
                       ↑                                    │참        │거짓
                       └────────────────────────────────────┘          ↓
                                                                     출력
pip install langchain_openai openai python-dotenv
# .env 파일에 OPENAI_API_KEY 준비

핵심 함수들

llm = ChatOpenAI(
    model="gpt-4o",      # gpt-4o에 접근할 수 없으면 다른 오픈AI LLM을 사용한다
    temperature=0.3,
    openai_api_key=OPENAI_API_KEY,
)

def generate_prompt(use_case: str, goals: list[str],
                    previous_code: str = "", feedback: str = "") -> str:
    base_prompt = f"""
You are an AI coding agent. Your job is to write Python code
based on the following use case:

Use Case: {use_case}

Your goals are:
{chr(10).join(f"- {g.strip()}" for g in goals)}
"""
    if previous_code:
        base_prompt += f"\nPreviously generated code:\n{previous_code}"
    if feedback:
        base_prompt += f"\nFeedback on previous version:\n{feedback}\n"
    base_prompt += "\nPlease return only the revised Python code. Do not include comments or explanations outside the code."
    return base_prompt

평가는 두 단계로 나뉩니다. 비평을 생성하는 함수그 비평을 보고 목표 충족 여부를 불리언으로 판정하는 함수입니다.

def get_code_feedback(code: str, goals: list[str]) -> str:
    feedback_prompt = f"""
You are a Python code reviewer. A code snippet is shown below.
Based on the following goals:
{chr(10).join(f"- {g.strip()}" for g in goals)}
Please critique this code and identify if the goals are met.
Mention if improvements are needed for clarity, simplicity,
correctness, edge case handling, or test coverage.
Code:
{code}
"""
    return llm.invoke(feedback_prompt)


def goals_met(feedback_text: str, goals: list[str]) -> bool:
    """피드백 텍스트를 바탕으로 LLM을 사용해 목표 충족 여부를 평가한다.
    LLM 출력에서 파싱한 True 또는 False를 반환한다."""
    review_prompt = f"""
You are an AI reviewer.
Here are the goals:
{chr(10).join(f"- {g.strip()}" for g in goals)}
Here is the feedback on the code:
{feedback_text}

Based on the feedback above, have the goals been met?
Respond with only one word: True or False.
"""
    response = llm.invoke(review_prompt).content.strip().lower()
    return response == "true"

“True 또는 False 한 단어로만 응답하라” 고 강제하는 것이 반복 종료를 쉽게 결정하는 열쇠입니다. 랭체인 책 21장의 LLM Judge가 CORRECT/INCORRECT만 답하게 한 것과 같은 설계입니다.

메인 루프

def run_code_agent(use_case: str, goals_input: str, max_iterations: int = 5) -> str:
    goals = [g.strip() for g in goals_input.split(",")]
    previous_code = ""
    feedback = ""

    for i in range(max_iterations):
        print(f"\n=== Iteration {i + 1} of {max_iterations} ===")
        prompt = generate_prompt(use_case, goals, previous_code,
                                 feedback if isinstance(feedback, str) else feedback.content)
        code_response = llm.invoke(prompt)
        code = clean_code_block(code_response.content.strip())

        feedback = get_code_feedback(code, goals)
        feedback_text = feedback.content.strip()

        if goals_met(feedback_text, goals):
            print("LLM confirms goals are met. Stopping iteration.")
            break

        print("Goals not fully met. Preparing for next iteration...")
        previous_code = code

    final_code = add_comment_header(code, use_case)
    return save_code_to_file(final_code, use_case)

최종 코드는 헤더 주석을 붙여 저장하는데, 파일명도 LLM에게 요약을 맡겨 만듭니다.

summary_prompt = (
    f"Summarize the following use case into a single lowercase word or phrase, "
    f"no more than 10 characters, suitable for a Python filename:\n\n{use_case}"
)
raw_summary = llm.invoke(summary_prompt).content.strip()
short_name = re.sub(r"[^a-zA-Z0-9_]", "", raw_summary.replace(" ", "_").lower())[:10]
filename = f"{short_name}_{random.randint(1000, 9999)}.py"

실행 예시는 이렇습니다.

use_case_input = "Write code to find BinaryGap of a given positive integer"
goals_input = ("Code simple to understand, Functionally correct, "
               "Handles comprehensive edge cases, Takes positive integer input only, "
               "prints the results with few examples")
run_code_agent(use_case_input, goals_input)

이 과정을 사람의 언어로

이 기획서와 함께 엄격한 품질 체크리스트도 제공하는데, 이 체크리스트가 최종 코드가 충족해야 할 목표에 해당한다. “해법이 단순해야 한다”, “기능적으로 정확해야 한다”, “예상치 못한 엣지 케이스까지 처리해야 한다” 같은 기준이다.

이 과제를 받은 AI 프로그래머는 코드 초안을 작성한다. 그러나 초안을 곧바로 제출하지 않고 한 가지 핵심 단계를 수행한다. 바로 엄격한 자체 검토다. AI는 자신이 작성한 코드를 품질 체크리스트의 모든 항목과 꼼꼼히 비교하며, 스스로 품질 검사관 역할을 한다. 모든 기준을 충족하면 “True”, 미달이면 “False”다.

판정이 “False”라면 AI는 포기하지 않는다. 자체 비평에서 얻은 통찰을 바탕으로 약점을 정확히 짚어내고, 코드를 지능적으로 다시 작성하는 수정 단계에 돌입한다. 초안 작성 → 자기 검토 → 개선이라는 이 순환은 반복될 때마다 목표에 한 발짝 더 다가간다.

주의 사항 — 스스로를 평가한다는 것의 한계

이 장에서 가장 값진 대목입니다.

이 코드는 패턴을 설명하기 위한 예시이며, 실제 운영 환경에 바로 투입할 수 있는 수준이 아니라는 점을 유의해야 한다.

세 가지 함정을 짚습니다.

  1. LLM이 목표의 의도를 완전히 파악하지 못해 실제로는 실패한 결과를 성공으로 잘못 평가할 수 있다. 아니면 목표를 잘 이해하더라도 환각이 발생할 수도 있다.
  2. 코드를 작성하는 LLM과 품질을 판단하는 LLM이 동일하면, 방향이 틀어졌을 때 스스로 알아차리기가 더 어려울 수 있다.
  3. LLM이 마법처럼 완벽한 코드를 만들어 내는 것은 아니므로 생성된 코드를 직접 실행하고 테스트해야 한다. 더구나 이 예제에서 “모니터링”은 기초적인 수준에 머물러 프로세스가 끝없이 돌아갈 위험도 있다.

두 번째가 핵심입니다. 자기 자신을 채점하는 시험의 구조적 맹점이고, 20장에서 다룰 평가 설계로 이어지는 문제이기도 합니다.

책은 더 나은 리뷰어 프롬프트의 예시를 보여 줍니다.

당신은 깔끔하고, 정확하며, 간결한 코드를 작성하는 데 확고한 의지를 가진 전문 코드 리뷰어입니다. 당신의 핵심 임무는 모든 제안이 실제 동작과 모범 사례에 기반하도록 하여 코드 “환각”을 제거하는 것입니다. 내가 코드 스니펫을 제공하면, 다음을 수행하세요:

  • 오류 식별 및 수정: 논리적 결함, 버그, 잠재적 런타임 오류를 찾아내세요.
  • 단순화 및 리팩터링: 정확성을 유지하면서 가독성, 효율성, 유지보수성을 높이는 변경 사항을 제안하세요.
  • 명확한 설명 제공: 모든 변경 제안에 대해, 클린 코드 원칙·성능·보안 관점에서 왜 개선인지 설명하세요.
  • 수정된 코드 제시: 변경 전과 변경 후를 함께 보여주어 개선 사항이 명확히 드러나도록 하세요.

더 견고한 접근 — 역할을 나눈 에이전트 팀

좀 더 견고한 접근 방식은 이러한 관심사를 분리해 여러 에이전트에게 각각 고유한 역할을 맡기는 것이다.

저자가 제미나이로 구축한 개인용 AI 에이전트 팀은 이렇습니다.

에이전트 역할
피어 프로그래머(Peer Programmer) 코드 작성과 아이디어 구상을 돕는다
코드 리뷰어(Code Reviewer) 오류를 잡아내고 개선점을 제안한다
문서 작성자(Documenter) 명확하고 간결한 문서를 만든다
테스트 작성자(Test Writer) 포괄적인 단위 테스트를 작성한다
프롬프트 개선자(Prompt Refiner) AI와의 상호작용을 최적화한다

이 멀티 에이전트 시스템에서 코드 리뷰어는 프로그래머 에이전트와 독립된 존재로 활동하며, 예제의 심사자와 유사한 프롬프트를 사용하므로 객관적 평가가 크게 향상된다. 이러한 구조는 자연스럽게 더 나은 실천 방식으로 이어지는데, 테스트 작성자 에이전트가 피어 프로그래머가 만든 코드를 검증하는 단위 테스트를 작성할 수 있기 때문이다.

7장의 멀티 에이전트 협업이 평가의 독립성을 확보하는 수단으로 다시 등장하는 셈입니다.

정리

목표 설정과 모니터링이란 무엇인가

AI 에이전트에는 명확한 방향이 부족한 경우가 많아, 단순한 반응형 작업을 넘어 목적의식을 갖고 행동하기 어렵습니다. 목표가 명확히 정의되지 않으면 에이전트는 복잡한 다단계 문제를 독립적으로 해결하거나 정교한 워크플로를 오케스트레이션할 수 없습니다. 게다가 자신의 행동이 성공적인 결과로 이어지는지 판단할 내재적 메커니즘도 없습니다.

왜 사용하는가?

이 패턴은 에이전틱 시스템에 목적의식과 자기 평가 역량을 심어 넣는 표준화된 해법입니다. 먼저 명확하고 측정 가능한 목표를 명시적으로 정의하는 데서 출발하고, 동시에 진행 상황과 환경 상태를 목표에 비추어 지속적으로 추적하는 모니터링 메커니즘을 갖춥니다. 그 결과 핵심적인 피드백 순환 구조가 형성되어, 에이전트는 자신의 성과를 평가하고, 경로를 교정하며, 성공 경로에서 벗어나면 계획을 수정할 수 있습니다.

언제 사용해야 하는가?

AI 에이전트가 사람의 지속적인 개입 없이 다단계 작업을 자율적으로 실행하고, 변화하는 조건에 적응하며, 구체적인 상위 수준 목표를 안정적으로 달성해야 할 때 이 패턴을 사용한다.

핵심 정리

  • 목표 설정과 모니터링은 에이전트에게 목적의식과 진행 상황 추적 메커니즘을 부여한다.
  • 목표는 구체적이고, 측정 가능하며, 달성 가능하고, 관련성 있으며, 기한이 정해져야 한다(SMART).
  • 효과적으로 모니터링하려면 지표와 성공 기준을 명확히 정의해야 한다.
  • 모니터링이란 에이전트의 동작, 환경 상태, 도구 출력을 관찰하는 일이다.
  • 모니터링을 통해 형성된 순환 구조 덕분에 에이전트는 적응하고, 계획을 수정하거나, 문제를 이관할 수 있다.
  • 구글 ADK에서 목표는 주로 에이전트 지시를 통해 전달되며, 모니터링은 상태 관리와 도구 상호작용을 통해 이루어진다.

마치며

이 패턴은 AI 에이전트를 단순한 반응형 시스템에서 주도적이고 목표 지향적인 존재로 전환하는 핵심적인 역할을 합니다. 고객 서비스부터 로봇 공학까지 다양한 도메인에서 안정적인 자율 운영을 뒷받침합니다.

궁극적으로, 에이전트에게 목표를 설정하고 감독하는 역량을 갖추게 하는 것은 진정으로 지능적이고 책임감 있는 AI 시스템을 구축하기 위한 핵심 발판이다.

다만 이 장이 솔직하게 짚듯, 스스로를 평가하는 구조에는 맹점이 있습니다. 작성자와 평가자를 분리하는 것이 그 맹점을 줄이는 현실적인 방법입니다.

참고 문헌