메인 콘텐츠로 건너뛰기

10장 LLM 에이전트의 추론·계획·평가를 위한 프롬프트 엔지니어링

로버트
로버트
조회수 14

생성형 AI 도구를 활용하여 작성 및 편집된 노트입니다.

다시 보는 AI Agents in Action
요약

개요

이 노트는 LLM(대규모 언어 모델) 기반 에이전트가 어떻게 "생각하고, 계획하고, 스스로를 평가"하게 만드는지에 초점을 맞춘다. 특히 에이전트 구성 요소 중에서 핵심인 계획(planning)이 어떤 역할을 하고, 추론·이해·평가·피드백과 어떻게 연결되는지 정리한다.

Generated Image

또한 가장 기본적인 직접 해답 요청(direct solution prompting)에서 시작해, 질문-응답(question-and-answer) 프롬프트, Prompt Flow를 활용한 질의·응답·평가 파이프라인, 임베딩 기반 평가 기법, 그리고 Semantic Kernel을 활용한 다양한 계획 기법과 프롬프트 전략의 큰 흐름을 한 번에 이해할 수 있도록 구성한다.

에이전트에서 '계획(Planning)'의 역할

에이전트에서 계획은 단순히 "앞으로 무엇을 할지 정하는 기능"을 넘어서, 추론(reasoning), 이해(understanding), 평가(evaluation), 피드백(feedback)을 묶어주는 허브 역할을 한다. 사용자의 목표(예: "프로젝트 계획 세워줘")가 들어오면, 에이전트는 문제를 이해하고, 필요한 정보를 추론해 나누고, 각 단계를 실행한 뒤, 결과를 평가하고 수정하는 전체 흐름을 설계·조정하는 것이 바로 계획이다.

추론은 "이 문제를 어떻게 쪼개고, 어떤 순서로 풀어야 합리적인가?"를 생각하는 과정이고, 이해는 "사용자가 무엇을 원하고, 현재 무엇을 알고 있는지"를 파악하는 과정이다. 계획은 이 둘을 연결해 "추론을 단계별로 정리된 실행 계획"으로 바꾸며, 각 단계를 수행한 뒤 결과를 다시 평가하고 피드백을 반영해 계획을 조정한다.

평가는 계획의 품질을 유지하고 개선하는 안전장치처럼 동작한다. 예를 들어, 에이전트가 단계별로 글을 작성했다면, 최종 결과가 요구사항에 맞는지, 논리적으로 자연스러운지, 누락된 부분은 없는지 스스로 평가할 수 있다. 이렇게 평가 결과를 다시 계획 단계로 되돌려 피드백을 반영하면, 에이전트는 반복적으로 질을 높이는 자기 개선 루프를 형성한다.

결국 잘 설계된 에이전트는 "입력 → 계획 수립 → 단계별 추론·실행 → 평가 → 계획 수정"이라는 루프를 수행하며, 이 전 과정을 뒷받침하는 핵심이 바로 계획(planning)과 그에 맞는 프롬프트 엔지니어링이다.

직접 해답 요청(Direct Solution Prompting)의 개념과 특징

직접 해답 요청(direct solution prompting)은 가장 단순하면서도 가장 자주 사용되는 프롬프트 방식이다. 사용자가 질문을 던지고, LLM이 바로 최종 답을 생성하는 방식이다. 예를 들어, "영화 '백 투 더 퓨처(1985)'에서 마티는 얼마나 과거로 여행했나?"라고 묻고, LLM이 "30년 전으로 여행했다"라고 답하는 패턴이다.

이 방식의 장점은 요청과 응답이 간단하고 빠르다는 점이다. 별도의 단계 쪼개기나 복잡한 구조 없이, 단일 프롬프트로 많은 일을 처리할 수 있다. 초기 프로토타입, 간단한 정보 질의, 설명 요청, 요약 등에는 이 접근법이 충분히 유용하다.

하지만 직접 해답 요청은 몇 가지 한계가 있다. 첫째, 모델이 "어떻게" 생각했는지, 어떤 단계와 근거를 거쳤는지 드러나지 않는다. 둘째, 복잡한 문제에서는 중간 추론이 꼬이거나 일부 조건을 놓쳐도 바로 최종 답만 나오기 때문에, 오류를 찾고 수정하기 어렵다. 셋째, 에이전트 구조로 확장할 때, 계획과 평가를 끼워 넣기 어렵다. 따라서 실제 에이전트 환경에서는 직접 해답 요청을 기본으로 하되, 추론을 드러내거나 단계별 계획을 세우는 추가 전략을 함께 쓰는 경우가 많다.

질문-응답(Question-and-Answer) 프롬프트 흐름

질문-응답(question-and-answer) 프롬프트는 "주어진 컨텍스트에 대해 질문하고 답하게 만드는" 구조의 대표적인 패턴이다. 다음과 같은 형태로 구성된다.

  • 시스템 메시지: "아래 컨텍스트를 기반으로 질문에 답하라. 모르면 '정확히 알 수 없음'이라고 답하라. 답변은 짧고 간결하게."

  • 컨텍스트(context): LLM이 참고해야 하는 텍스트(예: 영화 줄거리, 문서, 지식 베이스 일부).

  • 사용자 질문(question): 컨텍스트에 기반해 답해야 하는 구체적인 질문.

예를 들어, 컨텍스트에 "Back to the Future (1985)..." 줄거리를 넣고, 질문으로 "마티는 영화에서 과거로 얼마나 돌아갔는가?"를 전달하면, 모델은 컨텍스트를 읽고 해당 정보를 찾아 답하게 된다. 이 방식은 RAG(Retrieval-Augmented Generation) 패턴과 유사하며, 외부 지식이나 문서에 대한 질의·응답 시스템을 만들 때 기본 빌딩 블록이 된다.

핵심은 "모르는 것은 모른다고 말하게 하는 규칙"을 시스템 메시지에 명시하는 것이다. 이렇게 해야 모델이 자신이 모르는 내용을 상상해서 지어내는(환각) 경향을 줄이고, 실제 컨텍스트에 기반해 답하도록 유도할 수 있다. 또한 답변을 짧고 간결하게 제한함으로써, 후속 평가나 파이프라인 연결 시 처리가 더 쉬워진다.

Prompt Flow로 구성하는 질의·응답·평가 파이프라인

Prompt Flow(예: VS Code용 Prompt Flow)는 LLM과 관련된 여러 컴포넌트를 한 흐름(flow)으로 시각적으로 구성하고 실행해 볼 수 있는 도구이다. 이를 이용하면 "질문-응답 → 임베딩 생성 → 유사도 평가"와 같은 완전한 파이프라인을 간단하게 구현해 볼 수 있다.

질문-응답 프롬프트를 이용한 예시 플로우는 대략 다음과 같은 구조를 가진다.

  1. 입력(Inputs)

    • context: 질문의 대상이 되는 콘텐츠(문서, 줄거리 등).

    • question: 컨텍스트에 대해 묻고 싶은 질문.

    • expected: 사람이 미리 정한 "기대 정답".

  2. LLM 노드: question_answer

    • 입력: context, question

    • 출력: predicted (모델이 생성한 답변)

  3. 임베딩 노드(Embedding_predicted, Embedding_expected)

    • Embedding_predicted: predicted 답변을 임베딩 벡터로 변환.

    • Embedding_expected: expected(기대 정답)를 임베딩 벡터로 변환.

  4. Python 노드: evaluation

    • 입력: 두 임베딩 벡터

    • 출력: evaluation_score (예측 답변과 기대 정답의 의미적 유사도 점수)

  5. 최종 출력(Outputs)

    • context, question, expected, predicted, evaluation_score

이 흐름을 실행하면, 예를 들어 evaluation_score가 0.95처럼 높게 나온다면, 모델이 생성한 답변이 기대 정답과 의미적으로 매우 비슷하다는 뜻이 된다. 이 파이프라인 구조는 "LLM이 얼마나 잘 답하는지"를 자동으로 평가하는 실험 환경으로 사용할 수 있고, 다양한 프롬프트 전략을 바꾸어 가며 품질 차이를 비교하는데도 유용하다.

임베딩을 이용한 예측 답변 평가 방식

임베딩(embedding)은 텍스트를 고차원 벡터(숫자 배열)로 변환한 표현이다. 의미가 비슷한 문장들은 임베딩 공간에서 서로 가까운 위치에 놓이도록 학습되어 있다. 이 성질을 활용하면, 두 문장이 같은 의미인지 아닌지, 어느 정도 비슷한지를 수치로 계산할 수 있다.

실제 평가 흐름은 다음과 같다.

  1. 예측 답변(predicted)과 기대 정답(expected)을 각각 임베딩 모델에 넣어 벡터로 변환한다.

  2. 두 벡터의 유사도를 코사인 유사도(cosine similarity) 등으로 계산한다.

  3. 결과는 0~1 사이의 값(혹은 -1~1)을 가지며, 값이 클수록 의미적으로 더 비슷하다.

예를 들어,

  • expected: "마티는 30년 전으로 시간 여행했다."

  • predicted: "마티는 1985년에서 1955년으로, 즉 30년 과거로 돌아갔다." 와 같이 표현만 조금 다를 뿐 의미는 사실상 같은 경우, 텍스트를 그대로 비교하면 "일치하지 않는다"고 보이지만, 임베딩 유사도는 0.95 이상의 높은 점수를 줄 수 있다.

이 방식의 장점은 다음과 같다.

  • 표현 방식이 달라도 의미가 같으면 높은 점수를 줄 수 있다.

  • 자동화된 대량 평가에 적합하다.

  • 여러 프롬프트 전략, 모델 버전 간 비교 지표로 활용할 수 있다.

다만, 임베딩 유사도는 "형식적 요구사항(예: 반드시 '예/아니오'로 답할 것)"이나 "세부 규칙 준수 여부(예: 특정 키워드를 포함해야 함)"를 직접적으로 평가하지는 못한다. 이런 경우에는 임베딩 기반 평가에 더해, 별도의 규칙 기반 체크나 추가 LLM 평가 프롬프트를 결합하는 것이 좋다.

Few-shot 프롬프트와 계획에의 확장

Few-shot 프롬프트는 "예제를 몇 개 보여주고, 그 패턴을 따라 답하게 만드는" 방식이다. 질문-응답 프롬프트가 주로 컨텍스트(사실, 문서)를 기반으로 답을 구하게 만드는 것이라면, few-shot은 예시 패턴을 통해 모델의 행동을 조정한다.

예를 들어, "sunner"라는 가짜 단어를 정의하고, "sunner를 문장에 사용해 달라"라고 요청할 수 있다.

  • statement(입력): "sunner는 캐나다에서 해 질 무렵 먹는 식사이다. 이 단어를 문장에 사용해줘."

  • expected: "우리는 sunner를 먹으며 저무는 해를 바라보았다." (기대 정답)

  • LLM 출력(predicted): "긴 하이킹 후, 우리는 호숫가에 앉아 sunner를 즐기며 붉게 물드는 하늘을 바라보았다."

이때도 마찬가지로 expected와 predicted를 임베딩으로 변환해 평가할 수 있다. 중요한 점은 "sunner"가 실제로 존재하지 않는 단어임에도, 프롬프트를 통해 모델이 이 단어를 자연스럽고 일관되게 사용하도록 유도할 수 있다는 것이다.

이런 기술은 에이전트의 계획과 연결했을 때, 다음과 같은 응용이 가능하다.

  • 새로운 도메인 용어, 내부 용어(사내 약어, 코드명 등)를 빠르게 학습시켜 사용하게 만들기

  • 특정 스타일, 톤, 포맷에 따른 응답 패턴을 학습시켜, 계획 단계에서 "어떤 스타일로 진행할지"를 유연하게 바꾸기

  • 가상의 규칙이나 약속을 정의해, 시뮬레이션(가상 게임, 가상 시스템 설계)에서 일관된 세계관을 유지하도록 하기

즉 few-shot 프롬프트는 "에이전트가 어떤 세계관과 규칙을 전제로 계획·추론할지"를 조정하는 도구로 사용할 수 있다.

Semantic Kernel 기반 계획 기법 개요

Semantic Kernel(SK)은 LLM을 "함수와 플러그인 묶음"처럼 다루고, 계획을 자동으로 생성·수정·실행할 수 있게 돕는 프레임워크(라이브러리)이다. 이 장에서는 세부 코드보다 개념적 구조와 프롬프트 전략 관점에서만 정리한다.

Semantic Kernel의 계획(Planning) 기능은 대략 다음과 같은 흐름을 가진다.

  1. 목표 설정 사용자가 "블로그 글을 써줘", "회의 요약하고 액션 아이템 정리해줘"처럼 고수준 목표를 입력한다.

  2. 계획 생성 LLM이 제공된 스킬(플러그인, 함수) 목록과 목표를 바탕으로, 목표를 달성하기 위한 단계별 계획을 생성한다.

    • 예: "정보 검색 → 구조 설계 → 초안 작성 → 요약 및 검토"처럼 단계들을 자동으로 나열.

  3. 계획 실행 각 단계마다 적절한 스킬을 호출하거나, LLM 프롬프트를 실행해 중간 결과를 생성한다.

  4. 평가와 피드백 적용 각 단계 또는 최종 결과에 대해 평가 프롬프트나 임베딩 기반 평가를 적용하고, 필요하면 계획을 수정하거나 재실행한다.

Semantic Kernel은 여러 계획 기법(예: 단일 단계 계획, 단계별 계획, 재귀적 계획)을 지원하며, 이를 통해 에이전트가 복잡한 작업을 "스스로 계획하고 실행하는 시스템"을 구성할 수 있다. 이때 프롬프트 엔지니어링의 핵심 포인트는 다음과 같다.

  • 목표를 명확하고 제약 조건(길이, 포맷, 스타일 등)을 포함하여 설명하기.

  • 사용할 수 있는 스킬(도구, 함수)의 목록과 역할을 LLM에 명시적으로 알려주기.

  • 계획을 생성할 때, "단계별로 나눠서 써라", "각 단계에 필요한 입력과 출력 형태를 써라"와 같은 구조적 요구사항을 포함하기.

  • 평가 및 피드백 단계에서, 계획을 개선할 수 있도록 "무엇이 부족했는지, 어떻게 수정해야 하는지"를 서술하도록 유도하기.

추론·계획 프롬프트 전략의 큰 그림

LLM 에이전트의 추론과 계획을 강화하는 대표적인 프롬프트 전략들은 다음과 같은 계층 구조를 가진다고 볼 수 있다.

  1. 직접 해답 요청(Direct Solution Prompting)

    • 단일 질문 → 단일 답변.

    • 간단한 작업, 빠른 응답, 프로토타입용.

  2. 질문-응답(RAG 스타일) 프롬프트

    • "컨텍스트 + 질문" 구조.

    • 문서 질의·응답, 지식 기반 검색, 사실 기반 질문에 적합.

  3. Few-shot 프롬프트

    • 몇 개의 예시를 통해 새로운 패턴, 용어, 스타일을 학습.

    • 새로운 도메인 적응, 특정 행동 패턴 유도.

  4. 사고 과정을 드러내는 추론 프롬프트 (체인 오브 소트, 트리 오브 소트 등)

    • "단계별로 생각하라", "여러 가능한 가설을 나열하고 가장 좋은 것을 선택하라" 등의 형태.

    • 복잡한 추론, 다단계 문제 해결에 적합.

  5. 계획 중심 프롬프트 (Semantic Kernel 등과 결합)

    • "목표를 단계별 계획으로 분해하라", "필요한 도구를 나열하고 실행 순서를 제안하라" 등.

    • 에이전트가 스스로 작업을 설계·실행·평가하도록 만드는 핵심.

이 전체 흐름 속에서, Prompt Flow와 임베딩 기반 평가는 "다양한 프롬프트 전략이 실제로 얼마나 잘 작동하는지"를 실험·검증하는 실험장 역할을 한다. 즉,

  • 다양한 프롬프트 버전을 만들어 플로우에 연결하고,

  • 많은 테스트 케이스에 대해 답변을 생성한 후,

  • 임베딩 기반 유사도나 별도의 평가 프롬프트로 품질을 점수화하여,

  • 어떤 전략이 더 좋은 결과를 내는지 데이터 기반으로 비교할 수 있다.

이러한 구조를 잘 이해하고 활용하면, 단순히 "한 번에 좋은 프롬프트를 찾는 것"을 넘어서, "계획·추론·평가를 갖춘 LLM 에이전트 전체를 설계하고 개선하는" 수준으로 나아갈 수 있다.

#LLM 에이전트#계획(Planning)#프롬프트 전략#질문-응답(RAG)#임베딩 평가

이 노트는 요약·비평·학습 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.