일과 기술 목록으로
터미널의 텍스트 프롬프트가 깔끔한 와이어프레임 노드로 이뤄진 고도로 구조화된 3D 아키텍처 다이어그램으로 진화하는 추상적인 그래픽
일과 기술

프롬프트 엔지니어링의 종말?

모델이 더 견고해지고 개발자들이 에이전트 워크플로로 옮겨 가면서 프롬프트 해킹의 시대가 저물고 있다. 미래는 시스템 엔지니어링의 몫이다.

상록수v1.0버전작성 2026년 5월 15일→ 갱신 2026년 5월 15일

2023년과 2024년에 불었던 '프롬프트 엔지니어링' 골드러시를 기억하는가? 인터넷의 구루들은 LLM에 넣을 정확한 마법의 단어를 아는 것이야말로 21세기에 가장 값진 기술이라고 주장했다. 채용 게시판에는 모델에게 언제 "심호흡을 해라", "단계별로 생각해라", "숙련된 소프트웨어 엔지니어처럼 행동해라"라고 말해야 하는지 아는 전문가를 찾는, 천문학적인 연봉의 공고가 올라왔다.

컴퓨팅 역사에서 기묘한 과도기였다. 우리는 컴퓨터 칩에 자연어로 말을 걸고, 문자열을 해킹해 숨겨진 동작을 찾아내려 했다.

하지만 2026년 중반인 지금, 풍경은 완전히 달라졌다. 독립된 분야로서의 프롬프트 해킹은 사라지고 있다. 프런티어 모델이 더 똑똑해지고, 지시를 더 잘 따르게 되고, 에이전트 아키텍처에 네이티브로 통합되면서 초점이 옮겨 갔다. 이제 우리는 복잡한 작업을 해내도록 모델을 구슬리려고 긴 텍스트 프롬프트를 몇 문단씩 쓰지 않는다. 대신 시스템을 만든다.

'프롬프트 작성자'의 시대는 끝나고, AI 시스템 엔지니어의 시대가 왔다.


마법 문자열의 취약성

이런 변화가 왜 일어났는지 이해하려면 초기 프롬프트 기반 애플리케이션이 얼마나 취약했는지 살펴봐야 한다. 3,000자짜리 프롬프트에 의존하는 소프트웨어 기능을 만들어 봤다면, 프롬프트 엔지니어링이 카드로 쌓은 집이라는 사실을 금방 깨달았을 것이다.

  • 결정성의 부재: 95%의 경우 완벽하게 작동하던 프롬프트도 모델의 확률적 특성 때문에 96번째 실행에서 무작위로 실패할 수 있었다.
  • 프로바이더 종속: Claude 3.5 Sonnet에 맞춰 최적화한 프롬프트는 GPT-4o나 Gemini 1.5 Pro에 보내면 실패하는 일이 잦았다. 모델마다 자연어를 해석하는 방식에 저마다 미묘한 버릇이 있었다.
  • 업데이트로 인한 회귀: 프로바이더가 모델을 소폭 업데이트하면, 모델 내부의 가중치가 바뀌는 바람에 프롬프트가 갑자기 깨져 버렸다.
+-----------------------------------+
|  Original Prompt:                 |
|  "Write JSON output. Be concise." |
+-----------------------------------+
                 |
                 v (Model Version Update)
+-----------------------------------+
|  Failed Output:                   |
|  "Sure, here is your JSON..."     |
|  (Breaks parser with intro text)  |
+-----------------------------------+

'마법 문자열'에 의존하는 것은 안정적인 소프트웨어를 만드는 방법으로는 최악이었다. 사소한 인프라 업데이트 하나가 애플리케이션 엔드포인트의 문자열 포맷을 무작위로 깨뜨리는 컴퓨팅 환경이 또 어디 있겠는가?


구조화된 시스템으로의 전환

모놀리식 프롬프트의 취약성을 해결하기 위해 개발자들은 거대한 지시문을 쓰는 대신 작업을 구조화된 파이프라인으로 쪼개기 시작했다.

모델에게 "이 고객 지원 티켓을 읽고, 주문 내역을 찾고, 어조를 분석하고, JSON으로 답장을 써라"라고 요청하는 대신, 이제는 상태 머신을 만든다. 시스템은 각각 하나의 목적만 가진 별개의 단계로 나뉜다.

  1. 분류기: 가벼운 모델이 티켓 카테고리를 분류한다(엄격한 enum으로 출력).
  2. 데이터 조회기: API 쿼리가 티켓 메타데이터를 바탕으로 사용자의 주문 정보를 가져온다.
  3. 초안 생성기: 가져온 컨텍스트를 사용해 모델이 초안을 생성한다.
  4. 검증기: 마지막 코드 계층이 초안에 할루시네이션이 없고 스키마 규칙에 맞는지 확인한다.

문제를 분해하면 프롬프트 자체의 복잡도가 줄어든다. 각 노드의 프롬프트는 더 이상 긴 에세이가 아니라 단순하고 직접적인 지시다. 어떤 단계가 실패하면 그래프의 어느 노드에서 실패가 일어났는지 정확히 알 수 있다. 각 단계를 독립적으로 테스트하고, 디버깅하고, 최적화할 수 있다.

구조화된 출력으로 이를 어떻게 구현하는지 살펴보자. 모델에게 JSON을 쓰라고 요청하고 형식이 제대로 맞기를 바라는 대신, 스키마 검증으로 출력 구조를 보장한다.

다음은 Zod와 구조화된 출력 클라이언트를 사용한 최신 TypeScript 예제다.

import { z } from "zod";

// 1. 모델 출력에 대한 엄격한 스키마를 정의한다
const TicketAnalysisSchema = z.object({
  category: z.enum(["billing", "technical", "feature_request", "general"]),
  priority: z.enum(["low", "medium", "high", "critical"]),
  sentiment: z.enum(["positive", "neutral", "frustrated", "angry"]),
  suggestedAction: z.string().describe("The next immediate action the team should take"),
});

type TicketAnalysis = z.infer<typeof TicketAnalysisSchema>;

// 구조화된 노드를 나타내는 실행 함수 예시
async function analyzeTicket(ticketBody: string): Promise<TicketAnalysis> {
  // JSON 형식으로 출력하라는 프롬프트 지시를 쓰는 대신,
  // 스키마를 모델 설정에 직접 전달한다.
  const response = await aiClient.chat.completions.create({
    model: "gpt-4o-2026-05-10",
    messages: [
      { role: "system", content: "Analyze the customer ticket." },
      { role: "user", content: ticketBody }
    ],
    response_format: {
      type: "json_object",
      schema: TicketAnalysisSchema, // API 수준에서 강제된다
    }
  });

  return TicketAnalysisSchema.parse(JSON.parse(response.choices[0].message.content));
}

API 수준에서 스키마 준수를 강제하면 프롬프트 자체는 아주 단순해진다. 더 이상 "마크다운 태그를 넣지 마라, 'Sure, here is...'로 시작하지 마라, 유효한 JSON만 출력하라"라고 모델에게 지시하는 문단을 쓰지 않는다. 모델의 출력 토큰은 파서의 상태 머신에 맞도록 강제된다.


프롬프트에서 시스템으로 옮겨 가기 위한 실천 가이드라인

아직도 길고 복잡한 시스템 프롬프트를 쓰고 있다면 리팩터링할 때다. 다음 규칙에 따라 애플리케이션을 프롬프트 엔지니어링에서 시스템 엔지니어링으로 전환하자.

  • 복잡성을 분해하라: 프롬프트가 500단어를 넘는다면 너무 많은 일을 하고 있는 것이다. 여러 개의 순차적인 LLM 호출이나 도구 루프로 나눠라.
  • 어디서나 스키마를 검증하라: Zod, Pydantic, 네이티브 JSON 스키마 같은 도구를 사용해 모델 단계 사이를 오가는 모든 구조화된 입력과 출력을 검증하라.
  • 텍스트보다 코드: 간단한 정규식, 데이터베이스 쿼리, 깔끔한 유틸리티 함수로 작성할 수 있는 작업이라면 LLM을 쓰지 마라. LLM의 추론은 의미 분석과 종합에만 철저히 집중시켜라.
  • 프롬프트를 버전 관리하라: 시스템 지시를 코드처럼 다뤄라. 버전 관리(git)에 저장하고, 업데이트할 때마다 자동화된 회귀 평가를 돌리고, 여러 모델 엔드포인트에서 테스트하라.

앞으로의 전망: 중간 표현(IR)으로서의 프롬프트

에이전트 프레임워크가 발전할수록 사람이 직접 쓰는 프롬프트는 줄어들 것이다. 프롬프트는 중간 표현(Intermediate Representation, IR), 즉 컴파일러와 프레임워크가 자동으로 생성하는 저수준 명령어 집합이 될 것이다.

DSPy(Declarative Self-Improving Language Programs) 같은 시스템이 이미 이 개념을 증명하고 있다. 프롬프트를 손으로 쓰는 대신 프로그램 구조(입력, 출력, 모듈)를 정의하고 소수의 학습 예시를 제공한다. 그러면 프레임워크가 프로그램을 컴파일하면서 제약 최적화를 이용해 특정 모델에 맞는 프롬프트를 자동으로 생성하고, 테스트하고, 최적화한다.

이런 미래에는 프롬프트를 손으로 쓰는 일이 어셈블리 언어를 손으로 쓰는 일처럼 느껴질 것이다. 저수준 디버깅이나 성능 튜닝에는 여전히 쓸모가 있겠지만, 대부분의 개발자는 고수준 로직, 스키마, 어서션을 작성하고 명령어 컴파일은 프레임워크에 맡기게 될 것이다.


관련 글

참고 자료

  • 구조화된 스키마와 프롬프트 관리는 OpenAI Developer Blog에서 살펴볼 수 있다.
  • 자기 개선형 프롬프트 컴파일러와 연구 논문은 Stanford NLP Group에서 읽을 수 있다.
  • 견고한 에이전트를 구축하기 위한 개발 패턴은 Vercel AI SDK Docs에서 확인할 수 있다.

내 생각을 바꾼 계기

2024년, 나는 우리 제품의 분류 기능에 쓸 시스템 프롬프트를 최적화하는 데 2주를 썼다. 형용사를 이리저리 바꾸고, 퓨샷 예시를 추가하고, 심지어 모델에게 "내 일자리가 이 출력에 달려 있다"고 말해 보기까지 했다. 정확도가 92%에 이르자 내가 천재라도 된 것 같았다.

한 달 뒤 프로바이더가 모델을 업데이트했다. 정확도는 78%로 떨어졌고, 모델이 갑자기 공손한 도입 문구를 덧붙이면서 JSON 파서가 구문 오류를 내뱉기 시작했다.

그때 나는 프롬프트 엔지니어링이 환상이었다는 것을 깨달았다. 견고한 소프트웨어를 만드는 대신, 혼돈스러운 블랙박스의 파라미터를 조정하느라 몇 주를 보낸 것이다.

우리는 거대한 단일 프롬프트를 버리고, 스키마 강제와 엄격한 입력 파싱을 사용하는 단순한 3단계 상태 머신으로 대체했다. 코드는 수십 줄 늘었지만 프롬프트는 한 문장으로 줄었다. 정확도는 98%로 올라갔고, 모델을 업데이트한 뒤에도 그대로 유지됐다. 모델 불안정성의 해법은 더 나은 프롬프트가 아니라 더 나은 아키텍처였다.

연결된 글

같은 시리즈, 직접 링크, 주제 모음, 태그로 이 글과 이어진 글입니다.

수정 이력

v1.0

프롬프트 해킹에서 시스템 엔지니어링으로의 전환을 논했다.

  • •‘프롬프트보다 시스템’이라는 주장을 발행

DailySay에 묻기

이어서 읽기

업무 속 게이미피케이션의 중요성: 《호모 루덴스》로 다시 읽는 놀이와 일
일과 기술17 min

업무 속 게이미피케이션의 중요성: 《호모 루덴스》로 다시 읽는 놀이와 일

하위징아는 《호모 루덴스》에서 문화가 놀이 속에서, 놀이로서 생겨났다고 봤습니다. 놀이의 특징을 일과 온보딩에 겹쳐 보고, 포인트와 배지에 그치지 않는 게이미피케이션을 정리했습니다.

글 읽기

Jayden의 발자취가 궁금하신가요?

일과 제품, 여행, 그리고 지금 만들고 있는 이야기들을 가끔 보내드릴게요.

스팸 없이, 가끔만요. 개인정보 처리방침.