LLM 시스템 설계 패턴: 아키텍처와 모듈화 원칙 이해하기

LLM을 활용하는 시스템을 구축할 때 필요한 핵심 아키텍처와 모듈화 원칙을 배웁니다. 프롬프트 관리, 데이터 검색, 외부 도구 연동 등 각 구성 요소의 역할을 이해하고 시스템을 설계하는 방법을 제시합니다.

이 글의 목차

LLM을 활용한 시스템을 개발할 때, 단순히 LLM API를 호출하는 것만으로는 원하는 수준의 성능을 얻기 어렵습니다. 복잡한 비즈니스 로직이나 외부 데이터가 필요한 작업을 처리하려면, LLM 자체의 추론 능력 외에 추가적인 구성 요소가 필요합니다. 개발자들은 어떤 모듈을 어디에 배치하고, 이 모듈들이 어떻게 상호작용해야 하는지 설계하는 과정에서 어려움을 겪습니다.

성능을 극대화하는 시스템은 하나의 거대한 모델이 아니라, 여러 전문 모듈이 결합된 아키텍처로 이루어집니다. 이 모듈들은 데이터 검색, 외부 시스템 호출, 특정 행동 수행 등 각자의 역할을 분담합니다. 시스템의 성공 여부는 이 개별 모듈들이 얼마나 유기적으로 연결되고, 모듈 간의 데이터가 어떤 흐름을 따라 전달되는지를 정의하는 데 달려 있습니다.

따라서 시스템 설계 패턴을 이해하는 것이 필수적입니다. 이 글에서는 RAG와 같은 데이터 검색 원리부터 외부 도구 연동, 그리고 추론과 행동을 결합하는 ReAct 패턴까지 핵심 아키텍처 원리를 설명합니다. 또한, 모듈 간의 데이터 흐름을 체계적으로 정의하는 방법을 제시합니다.

시스템 구성 요소의 이해

LLM 시스템은 단순히 대규모 언어 모델(LLM) 하나를 호출하는 것 이상의 복합적인 아키텍처입니다. 시스템의 목적에 따라 여러 개의 모듈이 결합하여 작동하며, 각 모듈은 독립적인 기능을 수행하여 전체 시스템의 완성도를 높입니다. 이러한 모듈식 설계 덕분에 시스템은 특정 기능에 대한 확장성과 안정성을 확보할 수 있습니다.

시스템을 구성하는 핵심 요소로는 입력 지시를 구조화하는 프롬프트 관리(Prompt Management)가 있습니다. 프롬프트는 모델에게 어떤 역할을 부여하고 어떤 형식으로 답변을 유도할지 정의하는 역할을 합니다. 또한, 모델이 학습하지 않은 최신 또는 특정 도메인의 지식을 활용하기 위해 데이터 검색 증강 생성(Retrieval-Augmented Generation, RAG) 파이프라인을 구성합니다. RAG는 외부 지식 저장소에서 관련 정보를 가져와 모델의 입력 컨텍스트로 제공하는 방식을 사용합니다.

더불어, LLM이 외부 환경과 상호작용할 수 있도록 외부 도구 연동(Tool Use) 모듈이 필요합니다. 도구 사용은 모델이 단순히 텍스트를 생성하는 것을 넘어, 계산기 사용, 데이터베이스 조회, 또는 API 호출과 같은 구체적인 행동을 할 수 있게 만듭니다. 이러한 모듈들은 각자 명확한 경계를 가지고 작동하며, 전체 시스템의 흐름을 정의하는 오케스트레이션 계층을 통해 연결됩니다.

시스템의 작동 원리를 이해하는 것은 개발 단계에서 필수적입니다. 개발자는 각 구성 요소가 어떤 역할을 하며, 어떤 데이터를 주고받는지 명확히 정의해야 합니다. 예를 들어, 사용자 질문이 들어오면, 먼저 프롬프트 모듈이 요청을 분석하고, 필요한 경우 RAG 모듈을 통해 관련 지식을 검색합니다. 이 검색된 지식과 원래의 질문이 결합된 컨텍스트가 최종적으로 LLM에 전달되어 답변을 생성하게 됩니다. 이러한 모듈 간의 데이터 흐름을 정의하는 것이 시스템 설계의 핵심 원칙입니다.

이러한 시스템적 접근 방식은 단순히 모델의 성능을 높이는 것을 넘어, 신뢰성과 예측 가능성을 확보하는 기반이 됩니다. LLM API 기초와 같은 구조를 이해하면, 모델을 하나의 블랙박스가 아닌, 여러 기능을 가진 컴포넌트들의 조합으로 바라볼 수 있습니다.

데이터 검색(RAG)의 원리

LLM이 특정 배경 지식을 활용하여 답변을 생성하려면 외부 데이터 접근이 필수적입니다. LLM은 학습된 지식의 범위를 넘어서는 최신 정보나 기업 내부의 전문 지식을 다루기 어렵기 때문입니다. 따라서 검색 증강 생성(Retrieval-Augmented Generation, RAG)은 LLM의 지식 기반을 확장하는 핵심 아키텍처 패턴입니다.

전통적인 RAG 시스템은 방대한 문서를 작은 단위의 텍스트 조각(chunk)으로 분할하여 정보를 검색합니다. 이 방식은 검색 과정의 효율성을 높이지만, 문서를 분할하는 과정에서 원래 문맥 정보가 손실될 위험이 있습니다. 따라서 검색된 정보가 충분한 근거를 갖추지 못할 수 있습니다.

이러한 한계를 극복한 것이 Contextual Retrieval입니다. 이 기법은 단순히 청크 단위의 정보만 가져오는 것이 아니라, 해당 청크가 속한 주변 문맥 정보를 함께 활용합니다. 이러한 문맥 보강은 검색된 정보의 정확도를 높여 LLM이 오해 없이 근거를 파악하도록 돕습니다. Contextual Retrieval은 청크별 임베딩과 BM25(Best Match 25)와 같은 검색 기법을 결합하여 검색의 신뢰성을 높입니다.

결과적으로 RAG 시스템은 단순한 키워드 검색을 넘어, 문맥을 이해하고 근거를 제시하는 방식으로 진화하고 있습니다. 이 과정은 데이터를 어떻게 분할하고, 어떤 문맥 정보를 추가할지 설계하는 RAG 파이프라인 설계와 같은 체계적인 접근이 필요합니다.

외부 도구 연동(Tool Use)의 원리

외부 도구 연동(Tool Use)은 대규모 언어 모델(LLM)이 외부의 기능이나 서비스에 접근하여 작업을 수행하는 방식입니다. LLM이 스스로의 추론 능력만으로는 해결할 수 없는 실시간 정보 검색이나 계산, 데이터 조작 등의 작업을 가능하게 합니다. 이 과정에서 LLM은 미리 정의된 함수나 API를 호출하는 형태로 작동합니다.

도구 사용은 요청과 응답이 주고받는 왕복 과정(round trip)을 거칩니다. 사용자의 질문을 받으면 LLM은 내부적으로 어떤 도구가 필요한지 판단합니다. 이후 해당 도구의 이름과 필요한 매개변수(parameter)를 포함한 호출을 생성합니다. 시스템은 이 호출을 받아 실제 코드를 실행하고, 그 결과를 다시 LLM에게 전달합니다. LLM은 이 결과를 바탕으로 최종적인 답변을 구성하게 됩니다.

도구는 코드가 실행되는 위치에 따라 종류가 구분됩니다. 코드가 사용자 환경이나 클라이언트 측에서 실행되는 도구와, 서버 측에서 실행되는 도구로 나뉩니다. 서버 측 도구는 복잡한 백엔드 로직이나 데이터베이스 접근이 필요할 때 사용됩니다. 도구의 실행 위치에 따라 처리 방식과 추가적인 사용 비용이 발생할 수 있습니다.

이러한 도구 연동의 개념은 LLM을 단순한 텍스트 생성기가 아닌, 외부 환경과 상호작용하는 에이전트(agent)로 확장하는 핵심 원리입니다. LLM의 추론 능력과 외부 시스템의 실행력을 결합하여 실제 비즈니스 문제를 해결하는 아키텍처를 구축합니다. 이러한 구조는 AI 개발자를 위한 구조화 출력과 함수 호출 설계 가이드와 같은 패턴을 통해 구현됩니다.

추론과 행동의 결합 (ReAct)

LLM의 추론 능력과 외부 행동 능력을 결합하는 접근 방식이 중요합니다. 단순히 언어 이해에 그치지 않고, 실제로 환경과 상호작용하며 문제를 해결하는 것이 목표입니다. ReAct(Reasoning and Acting)는 이러한 추론 과정과 작업별 행동을 번갈아 사용하며 두 능력을 결합합니다.

ReAct 패턴은 모델이 생각하는 과정(Reasoning Trace)과 외부 자원을 사용하는 행동(Action)을 순차적으로 교차하며 수행합니다. 추론 과정은 모델이 계획을 수립하고, 진행 상황을 추적하며, 예외 상황을 처리하는 데 도움을 줍니다. 반면, 행동은 지식 기반이나 외부 환경과 상호작용하여 추가 정보를 수집하는 역할을 합니다.

이러한 결합은 모델이 단지 추론에 의존할 때 발생하는 환각이나 오류 전파 문제를 극복합니다. 외부 API와 같은 실제 자원과 상호작용함으로써, 모델은 얻은 정보를 바탕으로 더욱 해석 가능하고 신뢰할 수 있는 문제 해결 경로를 생성합니다.

이러한 에이전트적 시스템은 복잡한 목표를 달성하기 위해 계획을 세우고, 실행 단계별로 결과를 확인하며, 필요에 따라 계획을 수정하는 과정을 거칩니다. 이러한 아키텍처는 단순한 지식 검색을 넘어, 실제 업무 흐름을 자동화하는 기반이 됩니다.

시스템 설계 패턴의 발전 단계

시스템의 복잡도가 높아짐에 따라 아키텍처 패턴도 발전합니다. 초기 단계는 여러 독립적인 구성 요소들을 단순히 연결하는 조합적(compositional) 워크플로우를 형성합니다. 이 단계에서는 각 모듈이 정해진 순서대로 기능을 수행하며 전체 시스템을 구성합니다.

다음 단계는 예측 가능성과 일관성이 중요한 경우에 사용되는 워크플로우(Workflows)입니다. 워크플로우는 LLM과 외부 도구(Tools)가 사전에 정의된 코드 경로를 따라 작동합니다. 이 방식은 작업의 흐름이 명확하고 예측 가능한 결과를 원할 때 적합합니다. 예를 들어, 특정 순서로 데이터를 처리하고 검증해야 하는 업무에 활용할 수 있습니다.

더 높은 수준의 복잡성을 요구할 때는 에이전트 시스템(Agentic Systems)으로 발전합니다. 에이전트 시스템은 모델 자체의 의사 결정 능력을 활용하여 스스로 계획을 세우고 목표를 달성하는 방식입니다. 이 단계에서는 모델이 주어진 환경을 인식하고, 필요한 도구를 선택하며, 결과를 바탕으로 다음 행동을 결정하는 자율적인 루프가 작동합니다.

이러한 설계 패턴의 발전은 본질적으로 예측 가능성(Predictability)과 유연성(Flexibility) 사이의 균형을 맞추는 과정입니다.

패턴 작동 방식 장점 적합한 상황
조합적 워크플로우 모듈을 정해진 순서로 연결 구조적이고 예측 가능합니다. 명확한 단계와 규칙이 필요한 경우입니다.
에이전트 시스템 모델이 스스로 계획하고 행동을 결정 높은 유연성과 자율성이 필요합니다. 복잡하고 변수가 많은 문제 해결이 필요합니다.

에이전트 시스템을 구축할 때는 모델이 추론(Reasoning)한 내용을 바탕으로 외부 행동(Acting)을 수행하는 과정이 반복됩니다. 이러한 추론과 행동의 결합은 모델이 계획을 수정하고 예외 상황을 처리하게 합니다.

따라서 시스템을 설계할 때는 해결하려는 문제의 성격과 요구되는 안정성을 판단해야 합니다. 작업 흐름이 매우 정밀하게 통제되어야 한다면 워크플로우를, 환경 변화에 대응하며 자율적인 문제 해결 능력이 필요하다면 에이전트 시스템을 고려합니다. AI 에이전트 개발 가이드에서 에이전트 시스템에 대한 심화 내용을 확인하실 수 있습니다.

모듈 간의 데이터 흐름 정의

시스템 설계에서 모듈 간의 데이터 흐름을 명확히 정의하는 과정은 시스템의 신뢰성을 결정하는 핵심 단계입니다. 단순히 기능을 나열하는 것을 넘어, 한 모듈의 출력이 다음 모듈의 입력으로 어떻게 사용될지 구체적으로 정의해야 합니다. 이 과정은 시스템의 예측 가능성을 높이는 가장 기본적인 원칙입니다.

데이터 흐름 정의는 각 모듈이 주고받는 데이터의 형식과 구조를 확립하는 작업입니다. 각 모듈의 인터페이스(Interface)는 일종의 '계약'과 같습니다. 이 계약은 모듈이 어떤 종류의 입력(Input)을 받아야 하는지, 그리고 어떤 형태의 출력(Output)을 생성할 것인지를 명시합니다. 예를 들어, 검색 모듈(RAG)의 출력은 다음 추론 모듈(LLM)이 처리할 수 있는 구조화된 텍스트 형태여야 합니다.

이러한 명확한 정의는 데이터의 무결성(Data Integrity)을 유지하는 데 필수적입니다. 만약 데이터의 흐름이 불분명하면, 한 모듈에서 발생한 사소한 형식 오류가 전체 시스템의 오작동으로 이어질 수 있습니다. 따라서 모든 데이터 교환 지점에서는 데이터 스키마(Data Schema)를 정의하고 이를 준수하도록 설계하는 것이 중요합니다.

데이터 흐름의 정의는 다음과 같이 입력과 출력을 기준으로 모듈 간의 관계를 명확히 합니다.

모듈 입력 데이터 (Input) 출력 데이터 (Output)
검색 모듈 (RAG) 사용자 질의 (Query) 관련 문서 청크 목록 (Context Chunks)
추론 모듈 (LLM) 질의 + Context Chunks 최종 답변 초안 (Draft Answer)
도구 사용 모듈 (Tool Use) 초안 답변 + 필요한 도구 이름 실행된 도구 결과 (Tool Result)

이처럼 각 단계의 입출력을 구조화된 형태로 정의하면, 시스템의 동작 과정을 추적하기가 용이합니다. 특히 LLM이 외부 도구를 호출하거나 구조화된 데이터를 생성할 때는 AI 개발자를 위한 구조화 출력과 함수 호출 설계 가이드와 같은 원칙을 적용하여 데이터의 형식을 강제해야 합니다.

모듈 간의 데이터 흐름을 체계적으로 정의하는 것은 시스템을 단순한 기능의 나열이 아닌, 예측 가능한 파이프라인(Pipeline)으로 만듭니다. 이는 시스템 복잡도가 증가하더라도 안정성을 유지하는 기반이 됩니다. 개발자는 이 데이터 흐름을 통해 시스템의 병목 지점(Bottleneck)을 파악하고, 각 모듈의 최적화 포인트를 찾아낼 수 있습니다.

흔한 오해

"LLM 시스템은 프롬프트 엔지니어링만으로 충분합니다." 모델의 성능을 높이려면 프롬프트 외에 데이터 검색이나 외부 도구 연동 같은 모듈 결합이 필요합니다. 이러한 결합은 시스템에 필요한 배경 지식을 제공하거나 특정 작업을 수행할 수 있게 합니다.

"RAG는 단순히 문서를 잘게 쪼개서 검색하는 것입니다." 전통적인 RAG는 문서를 작은 조각으로 나누어 검색합니다. Contextual Retrieval은 조각별 정보를 추가하여 검색의 정확도를 높이는 방식으로 작동합니다. 이 방식은 검색 과정에서 더 풍부한 맥락을 활용합니다.

"에이전트는 항상 워크플로우보다 우월합니다." 작업에 예측 가능성과 일관성이 필요할 때는 워크플로우가 적합합니다. 반면, 유연한 결정 과정이나 모델 기반의 의사결정이 필요할 때 에이전트가 더 효과적입니다. 두 방식은 각각 다른 상황에 강점을 가집니다.

정리

  • LLM 시스템은 단순한 API 호출을 넘어선 복합적인 아키텍처로 구성됩니다.
  • 데이터 검색은 Contextual Retrieval과 같은 방법을 통해 정확도를 높일 수 있습니다.
  • 외부 도구 연동은 LLM이 정의된 함수를 호출하며 왕복 과정을 거칩니다.
  • 시스템의 복잡도에 따라 워크플로우와 에이전트 중 적절한 패턴을 선택해야 합니다.
  • 모듈 간의 데이터 흐름을 명확히 정의하는 것이 시스템 설계의 핵심입니다.

참고 자료

  • #LLM 아키텍처
  • #시스템 설계
  • #RAG
  • #에이전트