3 분 소요

이번 노트에서는 실제 프로덕션 환경에서 관찰된 에이전트형 시스템의 일반적인 패턴들을 살펴보자! 가장 기본이 되는 구성 요소인 확장된 LLM(augmented LLM)부터 시작하여, 점차 복잡도를 높여가며 단순한 조합형 워크플로우에서 자율적인 에이전트에 이르는 구조를 설명한다.

1. 빌딩 블록: 확장된 LLM

  • 에이전트형 시스템의 기본 단위는 검색(Retrieval), 도구(Tools), 메모리(Memory) 등의 기능이 추가된 LLM

  • 현재의 LLM들은 이 기능들을 능동적으로 활용
    • 자체적으로 검색 쿼리를 생성하고, 적절한 도구를 선택하며, 어떤 정보를 기억할지 판단하는 등의 작업을 수행할 수 있음

      그림1 - 확장된 LLM

  • 구현 시 두 가지 핵심 요소
    • 사용 사례에 맞게 기능을 조정하는 것
    • LLM이 쉽게 활용할 수 있도록 명확하고 문서화된 인터페이스를 제공하는 것
  • MCP(Model Context Protocol) -> 프로토콜을 사용하면 개발자가 간단한 클라이언트 구현만으로 다양한 서드파티 도구 생태계와 통합할 수 있음

  • 가정: 각 LLM 호출이 이러한 확장 기능에 접근할 수 있다고 가정

2. 워크플로우: 프롬프트 체이닝 (Prompt chaining)

  • 프롬프트 체이닝은 하나의 작업을 여러 단계로 나누고, 각 단계에서 LLM 호출이 이전 단계의 출력을 받아 처리하는 방식
    • 각 중간 단계에 대해 프로그래밍적인 검증(아래 다이어그램의 “게이트(gate)” 참고)을 추가할 수 있음
    • 프로그래밍적인 검증(게이트)을 통해 전체 프로세스가 올바른 방향으로 진행되고 있는지 확인할 수 있음
    • 작업을 명확하고 고정된 하위 작업들로 쉽게 분해할 수 있는 상황에서 적합
    • 그림2 - Prompt chaining
  • 프롬프트 체이닝 주요 목표
    • 각 LLM 호출이 더 단순한 작업을 처리하도록 분할함으로써, 지연 시간(latency)을 감수하고 정확도(accuracy)를 높이는 것
  • 프롬프트 체이닝이 유용한 예시
    • 마케팅 문구를 생성한 뒤, 이를 다른 언어로 번역하는 작업
    • 문서의 개요를 작성하고, 그 개요가 특정 기준을 충족하는지 검토한 후, 그 개요를 바탕으로 문서를 작성하는 작업

3. 워크플로우: 라우팅 (Routing)

그림3 - 라우팅

  • 라우팅(Routing)은 입력을 분류한 후, 해당 입력에 적합한 특화된 후속 작업으로 전달하는 워크플로우

    • 관심사의 분리(separation of concerns)를 가능하게 하고, 보다 전문화된 프롬프트 설계를 할 수 있도록 도와 줌
    • 워크플로우 없이 하나의 프롬프트로 모든 입력을 처리하려고 하면, 특정 입력 유형에 최적화하는 과정에서 다른 입력에 대한 성능이 저하될 수 있음
  • 라우팅의 사용 용도

    • 라우팅(Routing)은 복잡한 작업 중에서 명확히 구분되는 카테고리들이 존재하고, 이들을 각각 따로 처리하는 것이 더 효율적일 때 잘 작동함
    • 분류 작업은 LLM이나 전통적인 분류 모델/알고리즘을 통해 정확하게 수행 가능해야
  • 라우팅이 유용한 예시

    • 고객 문의를 일반 질문, 환불 요청, 기술 지원 등으로 구분하여, 각 유형에 맞는 후속 프로세스, 프롬프트, 도구로 전달하는 경우
    • 간단하거나 흔한 질문은 Claude 3.5 Haiku 같은 작은 모델로, 어렵거나 이례적인 질문은 Claude 3.5 Sonnet 같은 더 강력한 모델로 라우팅하여 비용과 응답 속도를 최적화하는 경우

4. 워크플로우: 병렬화(Parallelization)

그림4 - 병렬화

  • 병렬화 워크플로우: LLM은 때때로 하나의 작업을 동시에 여러 개 처리하고, 그 결과를 프로그래밍 방식으로 통합(aggregate)할 수 있음
    • 섹셔닝(Sectioning): 작업을 서로 독립적인 하위 작업들로 분할하여, 동시에 실행하는 방식
    • 투표(Voting): 동일한 작업을 여러 번 실행하여 다양한 출력 결과를 생성하고, 그 중에서 가장 적절한 결과를 선택하거나 통합하는 방식
  • 사용 시기
    • 병렬화(Parallelization)하위 작업을 병렬로 처리하여 속도를 높일 수 있거나,여러 관점이나 시도가 필요한 경우에 효과적
    • 복잡한 작업에서 여러 가지 고려사항이 있을 경우, 각 고려사항을 별도의 LLM 호출로 처리하면 더 나은 성능을 보이며, 이를 통해 각각의 특정 측면에 집중할 수 있음
  • 병렬화가 유용한 예시
    • 섹셔닝(Sectioning):
      • 가드레일(guardrails) 구현: 한 모델 인스턴스가 사용자 질문을 처리하고, 다른 모델이 이를 부적절한 내용이나 요청이 있는지 검토하는 방식. 같은 LLM 호출이 두 가지 작업을 처리하는 것보다 성능이 더 좋음
      • LLM 성능 평가 자동화: 각 LLM 호출이 주어진 프롬프트에서 모델 성능의 다른 측면을 평가하는 방식.
    • 투표(Voting):
      • 코드의 취약점 검토: 여러 개의 다른 프롬프트가 코드를 리뷰하고, 문제를 발견하면 플래그를 지정하는 방식.
      • 콘텐츠의 부적절성 평가: 여러 프롬프트가 다양한 측면을 평가하거나 다른 투표 기준을 요구하여 허위 긍정(false positives)과 허위 부정(false negatives)을 균형 있게 조정하는 방식.

5. 워크플로우: 오케스트레이터-워커(Orchestrator-workers)

그림5 - Orchestrator-workers

  • synthesize: 오케스트레이터-워커(Orchestrator-Workers) 워크플로우에서는 중앙 LLM이 작업을 동적으로 분해하고, 이를 워커 LLM들에게 할당한 뒤, 그 결과를 synthesize함.
  • 오케스트레이터-워커 사용 용도
    • 필요한 하위 작업을 사전에 예측할 수 없는 복잡한 작업에 적합함
    • 코딩 작업의 경우, 수정해야 할 파일의 수나 각 파일에서의 변경 내용은 작업마다 달라질 수 있음
    • 병렬화와 겉보기에는 유사하지만, 핵심적인 차이점은 유연성에 있음
    • 병렬화에서는 하위 작업이 사전에 정의되어 있는 반면, 오케스트레이터-워커 방식에서는 입력에 따라 오케스트레이터가 동적으로 하위 작업을 결정함.
  • 오케스트레이터-워커 방식이 유용한 예시:
    • 여러 파일에 복잡한 변경을 반복적으로 수행하는 코딩 프로덕트
    • 다양한 출처에서 정보를 수집하고 분석해, 관련 내용을 도출해야 하는 검색 작업

6. 워크플로우: Evaluator-Optimizer

그림6 - Evaluator-Optimizer

  • Evaluator-Optimizer 워크플로우: 하나의 LLM 호출이 응답을 생성하고, 다른 LLM 호출이 이를 평가하고 피드백을 제공하는 과정을 반복(loop)하며 진행함
  • Evaluator-Optimizer 사용 용도
    • 명확한 평가 기준이 있고,반복적인 개선(iterative refinement)측정 가능한 가치를 제공할 때 특히 효과적
    • 사람이 완성도 높은 글을 작성하기 위해 여러 번 다듬는 과정
  • 워크플로우가 잘 맞는 두 가지 징후
    • 사람이 피드백을 제공하면 LLM 응답이 실제로 개선되는 경우
    • LLM 스스로도 유의미한 피드백을 생성할 수 있는 경우
  • Evaluator-Optimizer가 유용한 예시:
  • 문학 번역: 번역 LLM이 처음에는 담아내지 못한 미묘한 뉘앙스를 평가자 역할의 LLM이 유용한 비평이나 개선 제안으로 보완하는 경우
  • 복잡한 정보 검색 작업: 포괄적인 정보를 수집하기 위해 여러 번의 검색과 분석이 필요한 경우, 평가 LLM이 추가 검색이 필요한지 여부를 판단하여 검색 방향을 조정하는 방식

댓글남기기