1장 — 프롬프트 체이닝

패턴 개요

프롬프트 체이닝(Prompt Chaining)은 파이프라인 패턴(Pipeline pattern) 이라고도 불립니다. LLM이 복잡한 문제를 거대한 단일 단계에서 한 번에 풀어내기를 기대하는 대신, 문제를 나누어 해결하는 분할 정복(divide-and-conquer) 전략을 지향합니다.

핵심 아이디어는 난해한 원래 문제를 더 작고 관리 가능한 하위 문제의 연속으로 분해하는 것입니다. 각 하위 문제는 목적에 맞게 설계된 프롬프트로 개별적으로 다루고, 한 프롬프트가 생성한 출력은 다음 프롬프트의 입력으로 전달됩니다. ‘체이닝’이라는 이름이 붙은 이유가 여기에 있습니다. 이 정보 전달이 이전 연산의 맥락과 결과가 이후 처리를 이끄는 의존성 사슬을 형성합니다.

이 방식이 주는 이점은 두 가지입니다.

  • 모듈성과 명확성 — 각 단계를 이해하고 디버깅하기 쉬워져 전체 프로세스가 더 견고해지고 해석하기도 좋아집니다.
  • 단계별 최적화 — 각 단계를 더 큰 문제의 특정 측면에만 집중하도록 세밀하게 설계할 수 있어, 더 정확하고 초점이 분명한 출력을 얻습니다.

나아가 프롬프트 체이닝은 단순한 문제 분해에 그치지 않고 외부 시스템, API, 데이터베이스와의 통합 지점이 됩니다. 각 단계에서 LLM이 외부 지식과 도구에 접근하도록 지시할 수 있고, 이를 통해 내부 학습 데이터의 한계를 넘어섭니다. LLM이 고립된 모델에 머무르지 않고 지능형 시스템의 핵심 구성 요소가 되게 하는 능력입니다.

단일 프롬프트의 한계

다층적인 작업에 단 하나의 복잡한 프롬프트를 쓰면 모델이 제약과 지시를 동시에 처리하는 데 어려움을 겪습니다. 책이 꼽는 대표적인 실패 양상은 다음과 같습니다.

실패 양상 설명
지시 누락 프롬프트의 일부 지시를 놓칩니다
맥락 표류 초기 맥락을 잃어버립니다
오류 전파 초기 오류가 이후 단계에서 증폭됩니다
컨텍스트 윈도 부족 충분한 정보를 입력받으려면 더 긴 컨텍스트 윈도가 필요합니다
환각(hallucination) 인지 부하가 커지며 잘못된 정보를 만들어냅니다

예를 들어 “시장 조사 보고서를 분석하고, 트렌드를 식별하고, 결과를 요약하고, 데이터 포인트를 포함해 이메일을 작성하라”는 단일 질의는 실패할 위험이 큽니다. 모델이 요약은 잘 수행하더라도 데이터 추출이나 이메일 작성에는 제대로 대응하지 못할 수 있기 때문입니다.

순차적 분해를 통한 신뢰성 향상

같은 작업을 파이프라인으로 재구성하면 이렇게 됩니다.

  1. 초기 프롬프트(요약) — “다음 시장 조사 보고서의 핵심 결과를 요약하라: [텍스트].” 모델이 요약에만 집중하므로 이 단계의 정확성이 높아집니다.
  2. 두 번째 프롬프트(트렌드 식별) — “요약을 바탕으로 세 가지 신흥 트렌드를 식별하고, 각 트렌드를 뒷받침하는 구체적인 데이터 포인트를 추출하라: [1단계 출력].” 앞 단계보다 더 강하게 제약되어 있고, 이미 검증된 출력 위에서 작업합니다.
  3. 세 번째 프롬프트(이메일 작성) — “다음 트렌드와 이를 뒷받침하는 데이터를 정리하여 마케팅 팀에 보낼 간결한 이메일을 작성하라: [2단계 출력].”

각 단계는 더 단순하고 모호성이 적어 모델의 인지 부하를 줄입니다. 각 함수가 특정 연산을 수행한 뒤 결과를 다음 단계로 넘기는 계산 파이프라인과 유사한 모듈성입니다.

한 가지 실무 팁으로, 단계별로 모델에 서로 다른 역할을 부여할 수 있습니다. 첫 번째 프롬프트에는 “시장 분석가”, 다음에는 “트렌드 분석가”, 마지막에는 “전문 문서 작성자” 같은 식입니다.

구조화된 출력의 역할

체인의 신뢰성은 단계 사이에 전달되는 데이터가 얼마나 온전하게 유지되느냐에 크게 좌우됩니다. 한 프롬프트의 출력이 모호하거나 형식이 불량하면, 잘못된 입력 때문에 다음 프롬프트가 실패합니다.

그래서 JSON이나 XML 같은 구조화된 출력 형식을 지정하는 것이 중요합니다. 앞선 트렌드 식별 단계의 출력은 이렇게 만들 수 있습니다.

{
  "trends": [
    {
      "trend_name": "AI 기반 개인화",
      "supporting_data": "소비자의 73%는 개인 정보를 활용하여 쇼핑 경험을 개선하는 브랜드와 거래하는 것을 선호한다."
    },
    {
      "trend_name": "지속가능하고 윤리적인 브랜드",
      "supporting_data": "ESG 관련 주장을 담은 제품의 매출은 지난 5년간 28% 성장한 반면, 그렇지 않은 제품은 20% 성장에 그쳤다."
    }
  ]
}

구조화된 형식을 쓰면 데이터가 기계가 읽을 수 있는 형태가 되어 정확하게 파싱되고, 어떠한 모호함도 없이 다음 프롬프트에 안정적으로 삽입됩니다. 자연어 해석에서 발생할 수 있는 오류를 최소화하는, 견고한 다단계 LLM 시스템의 핵심 요소입니다.

실제 적용 및 활용 사례

정보 처리 워크플로

문서를 요약하고, 핵심 개체를 추출한 뒤, 이를 활용해 데이터베이스를 검색하거나 보고서를 생성하는 흐름입니다.

  • 프롬프트 1: 주어진 URL 또는 문서에서 텍스트 콘텐츠를 추출한다.
  • 프롬프트 2: 정제된 텍스트를 요약한다.
  • 프롬프트 3: 요약 또는 원문에서 특정 개체(이름, 날짜, 위치)를 추출한다.
  • 프롬프트 4: 추출한 개체로 내부 지식 베이스를 검색한다.
  • 프롬프트 5: 요약, 개체, 검색 결과를 통합한 최종 보고서를 생성한다.

복잡한 쿼리에 대한 답변

“1929년 주식시장 붕괴의 주요 원인은 무엇이었으며, 이에 대해 정부는 어떤 정책으로 대응했는가?” 같은 질의는 다단계 추론과 정보 검색이 함께 필요합니다.

  • 프롬프트 1: 사용자의 질의에서 핵심 하위 질문을 식별한다(붕괴 원인, 정부 대응).
  • 프롬프트 2: 1929년 붕괴 원인에 대한 정보를 조사·검색한다.
  • 프롬프트 3: 정부 정책 대응을 조사·검색한다.
  • 프롬프트 4: 2단계와 3단계의 정보를 종합해 일관된 답변을 생성한다.

병렬 처리와의 조합 — 자동화된 리서치 에이전트는 하이브리드 워크플로를 따릅니다. 관련 기사를 다수 검색한 뒤, 각 기사에서 핵심 정보를 추출하는 작업은 출처별로 독립적이므로 병렬 처리합니다. 그러나 추출 결과를 취합해 초안으로 종합하고 최종 보고서를 다듬는 후반 단계는 앞 단계가 끝나야 진행할 수 있는 의존적 작업이고, 이곳이 바로 프롬프트 체이닝이 적용되는 지점입니다. 복잡한 워크플로에서는 독립적인 수집·추출에 병렬 처리를, 종합·검토에 프롬프트 체이닝을 결합하는 경우가 많습니다.

데이터 추출 및 변환

비정형 텍스트를 구조화된 형식으로 바꾸는 작업은 반복적인 프로세스이며, 정확성과 완전성을 개선하기 위한 순차적 보완이 필요합니다.

  • 프롬프트 1: 청구서 문서에서 특정 필드(이름, 주소, 금액)를 추출한다.
  • 사용자 작업: 필요한 필드가 모두 추출되었는지, 형식 요구 사항을 충족하는지 확인한다.
  • 프롬프트 2(조건부): 필드가 누락되었거나 형식이 잘못되었으면, 모델이 누락·오류 정보를 정확히 찾도록 새 프롬프트를 작성한다. 실패한 시도의 맥락을 함께 제공할 수도 있다.
  • 사용자 작업: 결과를 다시 검증하고, 필요하면 반복한다.
  • 출력: 추출되고 검증된 정형 데이터.

복잡한 OCR 작업에서 분해된 다단계 접근이 특히 효과적입니다. 먼저 LLM으로 문서 이미지에서 1차 텍스트를 추출하고, 다음으로 초기 OCR 출력을 정규화합니다(예: “one thousand and fifty” → 1050). LLM은 정밀한 수학 계산에 취약하므로, 이후 단계에서는 산술 연산을 외부 계산기 도구에 위임합니다. 텍스트 추출 → 데이터 정규화 → 외부 도구 사용으로 이어지는 체인이, 단일 질의로는 얻기 어려운 정확한 결과를 만듭니다.

콘텐츠 생성 워크플로

  • 프롬프트 1: 사용자의 관심사를 바탕으로 5개의 아이디어 주제를 생성한다.
  • 사용자 작업: 하나를 선택하거나 자동으로 최적의 아이디어를 선택한다.
  • 프롬프트 2: 선택된 주제로 상세한 개요를 생성한다.
  • 프롬프트 3: 개요의 첫 번째 항목을 기반으로 초안을 작성한다.
  • 프롬프트 4: 이전 섹션을 맥락으로 제공하며 다음 항목의 초안을 작성한다. 모든 항목에 대해 반복한다.
  • 프롬프트 5: 완성된 초안을 검토·수정해 일관성, 어조, 문법을 개선한다.

상태를 포함한 대화 에이전트

상태를 포괄적으로 관리하는 아키텍처가 더 정교하긴 하지만, 프롬프트 체이닝은 대화의 연속성을 유지하는 기본 메커니즘을 제공합니다. 각 턴을 새로운 프롬프트로 구성하되, 이전 상호작용에서 추출한 정보나 개체를 체계적으로 포함시켜 맥락을 이어 나갑니다.

  • 프롬프트 1: 첫 번째 사용자 입력을 처리하고, 의도와 핵심 개체를 식별한다.
  • 사용자 작업: 식별한 의도와 개체를 반영하여 대화 상태를 업데이트한다.
  • 프롬프트 2: 업데이트된 상태를 바탕으로 응답을 생성하고, 다음에 수집해야 할 정보를 식별한다.
  • 이후 새 입력이 들어오면 누적되는 대화 이력(상태)을 활용하는 동일한 체인을 반복한다.

코드 생성 및 정제

  • 프롬프트 1: 사용자의 코드 요청을 이해하고, 구현할 기능에 대한 의사 코드 또는 개요를 생성한다.
  • 프롬프트 2: 생성된 개요를 기반으로 초기 코드 초안을 작성한다.
  • 프롬프트 3: 코드에서 잠재적 오류나 개선 영역을 식별한다(정적 분석 도구나 다른 LLM을 호출해도 된다).
  • 프롬프트 4: 식별된 문제를 기반으로 코드를 재작성하거나 정제한다.
  • 프롬프트 5: 문서화 또는 테스트 케이스를 추가한다.

여기서 핵심은 모델 호출 사이에 결정론적 로직을 끼워 넣을 수 있다는 점입니다. 중간 데이터 처리, 출력 검증, 조건부 분기 같은 기능을 워크플로 안에 구현할 수 있습니다.

멀티모달 & 다단계 추론

텍스트가 포함된 이미지, 특정 텍스트 구간을 강조한 레이블, 각 레이블을 설명하는 표가 함께 제공된 데이터를 해석하는 작업입니다.

  • 프롬프트 1: 이미지에 포함된 텍스트를 추출하고 이해한다.
  • 프롬프트 2: 추출한 텍스트를 해당 레이블과 연결한다.
  • 프롬프트 3: 표를 활용해 수집한 정보를 해석하고 요구된 출력을 도출한다.

코드 예시 — LangChain LCEL

구현은 스크립트 내 함수를 순차 호출하는 단순한 방식부터, 제어 흐름·상태·구성 요소 통합을 관리하는 전문 프레임워크(LangChain, LangGraph, Crew AI, Google ADK)까지 다양합니다.

LangChain은 순차 실행을 위한 기본 추상화를 제공하고, LangGraph는 이를 확장해 상태 기반(stateful)·순환(cyclical) 연산까지 지원합니다. 더 정교한 에이전틱 행동에는 이 순환 연산이 필요합니다.

pip install langchain langchain-community langchain-openai langgraph

아래는 2단계 프롬프트 체인 예시입니다. 첫 단계는 비정형 텍스트를 파싱해 사양을 추출하고, 두 번째 단계는 그 출력을 JSON으로 변환합니다.

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 환경 변수 설정 (실제 실행 시 본인의 API 키를 입력하거나 .env 파일을 사용하세요)
os.environ["OPENAI_API_KEY"] = "your-api-key"

# ChatOpenAI를 활용한 언어 모델 초기화
llm = ChatOpenAI(temperature=0)

# --- Prompt 1: 정보 추출 ---
prompt_extract = ChatPromptTemplate.from_template(
    "Extract the technical specifications from the following text:\n\n{text_input}"
)

# --- Prompt 2: JSON 변환 ---
prompt_transform = ChatPromptTemplate.from_template(
    "Transform the following specifications into a JSON object with "
    "'cpu', 'memory', and 'storage' as keys:\n\n{specifications}"
)

# --- LCEL 체인 구성 ---
# StrOutputParser()는 LLM의 메시지 출력을 단순한 문자열로 변환합니다.
extraction_chain = prompt_extract | llm | StrOutputParser()

# 추출한 체인의 출력을 'specifications' 변수로 전달합니다.
full_chain = {"specifications": extraction_chain} | prompt_transform | llm | StrOutputParser()

# --- Run the Chain ---
input_text = "The new laptop model features a 3.5 GHz octa-core processor, 16GB of RAM, and a 1TB NVMe SSD."

final_result = full_chain.invoke({"text_input": input_text})

print("\n--- Final JSON Output ---")
print(final_result)

StrOutputParser가 출력을 다음 LLM에 입력할 수 있는 문자열 형식으로 만들고, LangChain Expression Language(LCEL)| 연산자가 프롬프트와 모델을 연결합니다. full_chain은 추출 단계의 출력을 받아 변환 프롬프트의 입력으로 전달합니다.

컨텍스트 엔지니어링과 프롬프트 엔지니어링

컨텍스트 엔지니어링은 토큰을 생성하기 전에 AI 모델에 제공될 완전한 정보 환경을 설계·구성·전달하는 체계적 학문입니다. 모델 출력의 품질이 모델 아키텍처 자체보다 제공되는 컨텍스트의 풍부함에 더 크게 좌우된다고 보는 방법론입니다.

컨텍스트 엔지니어링
├── 프롬프트 엔지니어링   (즉각적인 질의 표현 최적화)
├── RAG                  (지식 베이스 검색 결과)
├── 상태/기록             (이전 상호작용 이력)
├── 메모리                (누적된 장기 정보)
└── 구조화된 출력          (단계 간 안정적 데이터 전달)

그림 1.1 — 컨텍스트 엔지니어링: AI를 위한 풍부하고 포괄적인 정보 환경 구축

즉각적인 질의 표현 최적화에 주로 초점을 맞추던 전통적 프롬프트 엔지니어링을 크게 확장한 개념입니다. 컨텍스트 엔지니어링이 다루는 계층은 다음과 같습니다.

  • 시스템 프롬프트 — “당신은 기술 문서 작성자이며, 어조는 공식적이고 정밀해야 한다.”처럼 AI의 운영 매개변수를 정의하는 기초 지시
  • 검색 문서 — 지식 베이스에서 가져와 응답에 반영하는 외부 데이터(예: 프로젝트의 기술 사양 조회)
  • 도구 출력 — 외부 API로 얻은 실시간 데이터(예: 캘린더를 조회해 사용자의 가능 시간 확인)
  • 암묵적 데이터 — 사용자 신원, 상호작용 이력, 환경 상태

핵심 원칙은 아무리 발전된 모델이라도 운영 환경을 제한적이거나 잘못된 관점으로 보여주면 성능이 떨어질 수밖에 없다는 것입니다. 이 방식은 과제를 단순히 질문에 답하는 것에서 에이전트의 의사결정을 위한 포괄적인 상황도(operational picture)를 구축하는 작업으로 재정의합니다.

‘엔지니어링’이라는 구성 요소는 실행 시점에 이런 데이터를 가져와 변환하는 견고한 파이프라인을 구축하고, 컨텍스트 품질을 지속적으로 개선하기 위한 피드백 루프를 마련하는 일을 뜻합니다. 개선 과정을 자동화하는 튜닝 시스템(예: 구글 Vertex AI Prompt Optimizer)을 활용하면 샘플 입력과 사전 정의된 평가 지표에 대해 응답을 체계적으로 평가해, 대규모 수작업 재작성 없이도 다양한 모델에 맞게 프롬프트와 시스템 지시를 조정할 수 있습니다.

궁극적으로 컨텍스트 엔지니어링은 상태가 존재하지 않는(stateless) 챗봇을 상황 인지 능력을 갖춘 고성능 시스템으로 발전시키는 핵심 방법론입니다.

프롬프트 체이닝 패턴 개요도

                    ┌──────── 출력 ◄────────┐
                    ▼                       │
  사용자 ──► 프롬프트 n ──► 에이전트 n ───────┘
     │
     ├──►    · · ·    ──►    · · ·
     │                          ▲
     └──► 프롬프트 1 ──► 에이전트 1

그림 1.2 — 프롬프트 체이닝 패턴: 에이전트들은 사용자로부터 일련의 프롬프트를 받는데, 각 에이전트의 출력이 다음 에이전트의 입력이 되는 체인 구조를 갖는다.

정리

프롬프트 체이닝이란 무엇인가?

단일 프롬프트로 복잡한 작업을 처리하면 LLM이 과도한 인지 부하를 겪어 심각한 성능 문제가 발생하곤 합니다. 인지 부하가 커질수록 지시를 무시하거나, 맥락을 잃거나, 잘못된 정보를 생성하는 등 오류 가능성이 높아집니다. 특히 거대한 단일 프롬프트는 여러 제약과 순차적 추론 단계를 효과적으로 관리하는 데 어려움을 겪습니다.

왜 사용하는가?

복잡한 문제를 더 작고 서로 연결된 하위 작업 절차로 분해하는 표준화된 해결책을 제공합니다. 각 단계는 특정 연산에 집중된 프롬프트를 사용하며, 이를 통해 신뢰성과 제어 가능성을 크게 높입니다. 모듈식 분할 정복 전략은 전체 과정을 관리하기 쉽게 만들고 디버깅을 용이하게 하며, 단계 사이에 외부 도구나 정형화된 데이터 형식을 통합할 수 있게 합니다.

언제 사용해야 하는가?

  • 작업이 하나의 프롬프트로 처리하기에는 지나치게 복잡할 때
  • 서로 구분되는 여러 처리 단계를 거쳐야 할 때
  • 단계 사이에서 외부 도구와 상호작용이 필요할 때
  • 다단계 추론과 상태 유지를 수행해야 하는 에이전틱 시스템을 구축할 때

핵심 정리

  • 프롬프트 체이닝은 복잡한 작업을 더 작고 집중된 단계의 시퀀스로 분해합니다. 파이프라인 패턴이라고도 부릅니다.
  • 체인의 각 단계는 이전 단계의 출력을 입력으로 사용하는 LLM 호출 또는 처리 로직으로 구성됩니다.
  • 이 패턴은 언어 모델을 사용하며 이루어지는 복잡한 상호작용을 더 신뢰성 있고 관리하기 쉽게 만듭니다.
  • LangChain/LangGraph 및 구글 ADK 같은 프레임워크가 다단계 시퀀스를 정의·관리·실행하기 위한 견고한 도구를 제공합니다.

결론

프롬프트 체이닝은 복잡한 문제를 더 단순하고 관리 가능한 하위 작업들의 연속된 흐름으로 분해함으로써 LLM을 효과적으로 안내하는 견고한 프레임워크를 제공합니다. 이 “분할 정복” 전략은 모델이 한 번에 하나의 특정 연산에만 집중하도록 하여 출력의 신뢰성과 제어 가능성을 크게 높입니다.

이 패턴은 앞으로 전개될 내용의 기반이 되는 기초 패턴으로, 이를 이용해 다단계 추론, 도구 통합, 상태 관리가 가능한 정교한 AI 에이전트를 개발할 수 있습니다.