티스토리 뷰
들어가며 — 용어가 너무 빨리 늘어난다
요즘 LLM을 다루는 글을 읽다 보면 비슷한 모양의 단어가 빠르게 늘어나는 것을 느낍니다. 프롬프트 엔지니어링이라는 말에 어느 정도 익숙해질 무렵 컨텍스트 엔지니어링이 등장하고, 그다음에는 하네스 엔지니어링, 루프 엔지니어링 같은 표현이 따라옵니다. 단어마다 그럴듯한 정의가 붙어 있지만, 이것들이 서로 어떤 관계인지, 어디서 갈라져 나온 것인지는 좀처럼 한눈에 들어오지 않습니다. AI 코딩 도구를 매일 쓰면서도 이 용어들의 계보를 정리하지 못한 채 넘어가는 일이 적지 않습니다.
이 시리즈는 그 계보를 출발점부터 한 층씩 따라가 보려는 기록입니다. 그리고 그 출발점에 놓이는 것이 프롬프트 엔지니어링입니다. 뒤에 나오는 용어들이 전부 "프롬프트만으로는 부족한 지점"에서 한 칸씩 올라간 것이라면, 먼저 이 첫 칸이 무엇을 전제로 서 있는지를 분명히 해 둘 필요가 있습니다. 이 글에서는 프롬프트 엔지니어링이라는 분야가 어떤 기술적 사건 위에서 생겨났는지, 그것이 무엇을 증명했고 어떤 전제 위에 서 있는지를 공식 문서와 논문에서 확인되는 범위 안에서 정리하겠습니다.
미리 한 가지를 분명히 해 두겠습니다. 이 글은 "prompt engineering"이라는 용어가 정확히 언제, 누구에게서 처음 나왔는지를 밝히는 글이 아닙니다. 그 기원은 신뢰할 수 있는 공식 출처로 확인하지 못했습니다. 대신 확인할 수 있는 것은 그 분야를 떠받치는 기법들의 기원입니다. 그 기법들이 어떤 논문에서 처음 증명됐고, 공식 문서가 그것을 어떻게 정리하고 있는지를 따라가는 쪽이 훨씬 단단한 이야기가 됩니다. 그래서 이 글은 용어의 족보가 아니라 기법의 근거를 추적합니다.
2020년 이전 — 과제를 시키려면 모델을 학습시켜야 했다
프롬프트라는 말이 기술 용어로 자리 잡기 전에는, 언어 모델에 새로운 일을 시키는 방식이 지금과 달랐습니다. 큰 모델을 한 번 학습해 두고, 거기에 특정 과제를 시키려면 그 과제에 맞는 데이터를 따로 모아 모델을 한 번 더 학습시키는 방식이 일반적이었습니다. 이렇게 이미 학습된 모델을 특정 과제용으로 추가 학습시키는 것을 fine-tuning이라고 부릅니다. 감정 분류를 시키고 싶으면 감정이 라벨링된 데이터셋이 필요했고, 번역을 시키고 싶으면 번역 쌍 데이터가 필요했습니다. 과제가 바뀔 때마다 데이터셋과 학습 과정이 한 벌씩 더 필요했던 셈입니다.
GPT-3 논문(Brown et al., Language Models are Few-Shot Learners, arXiv:2005.14165, 2020년 5월 28일 제출)은 서론에서 이 방식의 한계를 짚으면서 출발합니다. 과제마다 라벨링된 데이터를 모아 fine-tuning을 해야 한다는 점이, 언어 모델을 폭넓게 쓰는 데 걸림돌이 된다는 문제의식입니다. 사람은 새로운 일을 배울 때 보통 그렇게 많은 예시를 필요로 하지 않습니다. 짧은 설명 한두 줄과 예시 몇 개면 대체로 무엇을 해야 하는지 감을 잡습니다. 모델은 그렇지 못했고, 그 간극을 메우는 일이 매번 새로운 학습이었습니다.
이 시절의 모습을 더 길게 묘사하는 것은 이 글의 목적이 아니고, 근거 없이 과장할 위험도 있어 여기까지만 적겠습니다. 중요한 것은 하나입니다. 2020년 이전에는 "모델에 일을 시킨다"가 곧 "모델을 (다시) 학습시킨다"와 가까운 의미였다는 점입니다. 그렇다면 입력 문장을 잘 쓰는 일이 따로 기술이 될 자리가 마땅치 않았습니다. 과제를 정의하는 것은 데이터셋과 학습이었지, 입력 텍스트가 아니었기 때문입니다.
GPT-3가 바꾼 것 — 입력 텍스트가 곧 과제 지시가 된다
GPT-3 논문이 보여 준 것은, 모델을 다시 학습시키지 않고도 과제를 시킬 수 있다는 사실이었습니다. 논문 초록은 이 방식을 두고, 모델에 어떤 gradient update나 fine-tuning도 가하지 않은 채 "tasks and few-shot demonstrations specified purely via text interaction with the model", 즉 과제와 소수의 예시를 오로지 모델과의 텍스트 상호작용만으로 지정한다고 적습니다. 다시 풀어 쓰면, 무엇을 할지에 대한 설명과 예시 몇 개를 입력 텍스트 안에 적어 넣는 것만으로 모델이 그 과제를 수행하더라는 것입니다. 참고로 이 모델의 크기는 1,750억 개(175B) 매개변수입니다.
여기서 두 단어가 나옵니다. few-shot과 in-context learning입니다. few-shot은 입력 안에 예시를 몇 개 넣어 주는 것을 가리킵니다. 예시를 하나도 주지 않으면 zero-shot, 하나면 one-shot, 여러 개면 few-shot입니다. in-context learning은 그 예시와 지시가 모델의 가중치를 바꾸는 학습이 아니라, 입력 컨텍스트 안에서만 작동하는 학습이라는 뜻입니다. 모델 자체는 그대로 둔 채, 같은 모델에 어떤 텍스트를 넣어 주느냐로 결과가 달라집니다.
이 지점이 프롬프트 엔지니어링이라는 분야가 설 자리를 만들어 준 사건이라고 볼 수 있습니다. 과제를 정의하는 무게추가 데이터셋과 학습에서 입력 텍스트로 옮겨 왔기 때문입니다. 같은 모델이라도 입력을 어떻게 쓰느냐에 따라 결과가 달라진다면, "입력을 잘 쓰는 일"이 비로소 다룰 가치가 있는 대상이 됩니다. 모델을 건드리지 않고도 결과를 바꿀 수 있는 손잡이가 입력 텍스트라는 사실, 그것이 문장 쓰기를 기술의 영역으로 끌어들인 출발점이었습니다.
다만 한 가지는 짚어 두고 싶습니다. GPT-3 논문이 "프롬프트 엔지니어링"이라는 분야를 선언한 것은 아닙니다. 논문이 보인 것은 in-context learning이 작동한다는 사실이고, 그 사실 위에서 입력을 다루는 기법들이 자라난 것입니다. 원인과 결과를 너무 매끄럽게 이어 붙이면 없는 인과를 만들게 됩니다. 논문은 가능성을 열었고, 그 가능성을 분야로 키운 것은 그 뒤의 여러 연구와 실무였다는 정도로 적는 편이 사실에 가깝습니다.
Chain-of-Thought — 프롬프트가 성능을 좌우한다는 증명
입력을 바꾸면 결과가 달라진다는 말은, 자칫 "운에 따라 흔들린다"는 부정적 의미로도 들릴 수 있습니다. 그 흔들림이 사실은 다룰 수 있는 변수이고, 잘 설계하면 성능을 끌어올린다는 것을 또렷하게 보여 준 연구가 Chain-of-Thought 논문입니다(Wei, Wang, Schuurmans et al., Chain-of-Thought Prompting Elicits Reasoning in Large Language Models, arXiv:2201.11903, 2022년 1월 28일 제출).
이 논문의 발상은 단순합니다. 모델에 답만 예시로 주는 대신, 답에 이르는 중간 풀이 과정을 함께 예시로 주는 것입니다. 예를 들어 산수 문제라면 "정답은 11"만 보여 주는 게 아니라 "처음에 5개가 있었고 6개를 더 받았으니 5 더하기 6은 11"이라는 풀이 단계를 예시 안에 적어 둡니다. 논문은 이렇게 중간 추론 단계를 예시로 제시하면 "significantly improves the ability of large language models to perform complex reasoning", 즉 복잡한 추론을 수행하는 능력이 크게 향상된다고 적습니다. 그 효과는 산수뿐 아니라 상식 추론과 기호 추론 과제에 걸쳐 나타났습니다.
논문이 든 구체적인 결과 하나가 인상적입니다. 5,400억 개(540B) 매개변수 모델에 단 여덟 개의 chain-of-thought 예시를 준 것만으로, 산수 문장제 벤치마크인 GSM8K에서 당시 최고 수준의 정확도에 이르렀고, 검증기(verifier)를 붙여 fine-tuning한 GPT-3마저 앞섰다는 것입니다. 모델의 크기도, 질문도 그대로입니다. 달라진 것은 입력에 풀이 과정을 함께 넣었다는 것뿐입니다. 그런데도 결과가 크게 바뀌었습니다.
이 결과가 프롬프트 엔지니어링이라는 분야에 갖는 의미는 분명합니다. 입력을 어떻게 구성하느냐가 단순한 표현의 문제가 아니라, 측정 가능한 성능의 문제라는 것을 보여 줬기 때문입니다. 같은 모델에서 입력만 바꿔 벤치마크 점수가 오른다면, 입력 설계는 취향이 아니라 엔지니어링의 대상이 됩니다. fine-tuning만이 성능을 끌어올리는 길이라고 여기던 자리에, 입력 설계라는 또 하나의 길이 데이터로 증명된 셈입니다. 다만 한 가지 단서는 남깁니다. 논문 자체가 이 효과가 충분히 큰 모델에서 두드러진다는 점을 함께 보고하고 있어, "프롬프트만 잘 쓰면 어떤 모델이든 똑똑해진다"는 식으로 일반화하는 것은 논문이 말한 것보다 멀리 나가는 해석입니다.
공식 문서가 정리한 기법의 체계
논문이 개별 기법을 증명한다면, 공식 문서는 그 기법들을 실무에서 쓸 수 있게 체계로 정리합니다. Anthropic의 프롬프트 엔지니어링 개요 문서를 보면, 기법 목록으로 바로 들어가기 전에 전제 조건부터 짚는다는 점이 눈에 띕니다. 문서는 이 가이드가 세 가지를 갖춘 상태를 전제한다고 적습니다. 첫째 자기 use case에 대한 성공 기준이 분명히 정의돼 있을 것, 둘째 그 기준에 견주어 결과를 경험적으로 시험해 볼 방법이 있을 것, 셋째 개선하려는 초안 프롬프트가 하나 있을 것입니다. 이 셋이 없다면 먼저 그것부터 갖추라고 권합니다.
이 전제가 중요한 이유는, 프롬프트를 다듬는 일이 측정 위에서만 의미를 갖기 때문입니다. 성공 기준과 평가 방법이 없으면, 프롬프트를 바꿔도 더 나아졌는지 나빠졌는지 알 길이 없습니다. 앞서 Chain-of-Thought가 벤치마크 점수로 효과를 증명할 수 있었던 것과 같은 맥락입니다. 측정할 수 있어야 개선이 엔지니어링이 됩니다. 공식 문서가 기법보다 먼저 성공 기준과 평가를 요구하는 것은, 이 분야를 감이 아니라 검증의 자리에 두려는 태도로 읽힙니다. CLAUDE.md가 강조하는 "성공 기준을 정하고 검증될 때까지 반복한다"는 원칙과도 정확히 같은 자리에 있습니다.
문서가 짚는 또 하나는, 모든 실패를 프롬프트로 풀려고 하지 말라는 권고입니다. 문서는 이 가이드가 프롬프트 엔지니어링으로 다룰 수 있는 성공 기준에 초점을 둔다고 분명히 한 뒤, 모든 성공 기준이나 실패하는 평가가 프롬프트 엔지니어링으로 가장 잘 풀리는 것은 아니라고 적습니다. 그 예로 지연 시간(latency)과 비용은 다른 모델을 고르는 편이 더 쉬운 해법일 때가 있다고 안내합니다. 즉 프롬프트로 풀 문제와 모델 선택으로 풀 문제를 처음부터 구분하라는 것입니다. 이 구분은 실무에서 의외로 자주 어긋나는 지점입니다. 응답이 느리거나 비싼 문제를 프롬프트 문구를 다듬어 해결하려다 시간을 쓰는 경우가 있는데, 문서는 그 둘이 다른 손잡이라는 점을 분명히 합니다.
구체적인 기법 목록 자체는 별도의 실무 가이드 문서로 정리돼 있습니다. 명확하고 직접적으로 지시하기, 예시를 주기(multishot), 모델이 생각하도록 두기(앞서 본 chain-of-thought가 여기에 해당합니다), XML 태그로 입력을 구조화하기, 역할을 부여하기, 프롬프트를 여러 단계로 쪼개 잇기(prompt chaining)가 그 줄기입니다. 이 글에서 이 기법들을 하나씩 백과사전처럼 풀어 쓰지는 않겠습니다. 그것은 이 글의 각이 아니거니와, 공식 문서가 가장 최신 상태로 관리하는 영역이라 원문 링크로 넘기는 편이 정확합니다. 다만 한 가지만 짚자면, 이 목록 가운데 prompt chaining, 즉 프롬프트를 여러 단계로 잇는다는 기법이 다음 편으로 가는 다리가 됩니다. 한 번의 입력과 한 번의 출력만으로는 풀리지 않는 일이 있다는 것을 이 기법이 이미 인정하고 있기 때문입니다.
프롬프트 엔지니어링의 전제 — 한 턴, 한 과제
지금까지의 이야기를 한 발 떨어져 보면, 프롬프트 엔지니어링이 다루는 설계 대상이 무엇인지가 드러납니다. 그 대상은 "문장"입니다. 더 정확히는, 모델에 들어가는 입력 한 번과 거기서 나오는 출력 한 번, 그 사이를 최적화하는 일입니다. 어떤 지시를 어떤 순서로 적을지, 예시를 몇 개 어떻게 넣을지, 역할을 부여할지, 출력 형식을 어떻게 정할지를 고민하는 것이 모두 이 한 번의 입출력 안에서 벌어집니다.
이것을 이 글에서는 "한 턴, 한 과제"라는 전제로 부르겠습니다. 한 번의 입력으로 한 가지 과제를 시키고, 그 한 번의 출력으로 결과를 받는다는 전제입니다. GPT-3가 보인 in-context learning도, Chain-of-Thought가 끌어올린 추론도, 공식 문서가 정리한 기법 대부분도 기본적으로 이 한 번의 입출력을 더 좋게 만드는 일에 초점이 맞춰져 있습니다. 입력 텍스트가 과제 지시가 된다는 발견 위에서, 그 입력 텍스트를 어떻게 쓰면 출력이 좋아지는지를 다루는 것, 그것이 프롬프트 엔지니어링의 자리입니다.
이 전제를 분명히 해 두는 이유는, 이것이 곧 한계의 윤곽이기도 하기 때문입니다. 한 턴의 입출력을 아무리 잘 설계해도, 그 한 턴 안에 담기지 않는 일들이 있습니다. 모델이 외부 정보를 찾아오고, 그 결과를 보고 다음 행동을 정하고, 여러 단계를 거쳐 하나의 목표에 다다라야 하는 일이 그렇습니다. 공식 문서가 prompt chaining을 기법으로 둔 것 자체가, 한 번의 프롬프트로는 부족한 순간이 있다는 것을 이미 가리킵니다. 프롬프트를 여러 개로 쪼개 잇기 시작하면, 더 이상 설계 대상이 "문장 하나"가 아니라 "문장들이 오가는 흐름"으로 넓어집니다.
마무리 — 전제가 깨질 때 다음 단계가 온다
정리하면 이렇습니다. 2020년 GPT-3 논문이 모델을 다시 학습시키지 않고 입력 텍스트만으로 과제를 시킬 수 있다는 것을 보였고, 그 순간부터 입력을 잘 쓰는 일이 다룰 가치가 있는 대상이 됐습니다. Chain-of-Thought 논문은 그 입력 설계가 취향이 아니라 측정 가능한 성능의 문제라는 것을 벤치마크로 증명했습니다. 공식 문서는 그 위에서 성공 기준과 평가를 먼저 갖추라고 요구하며 기법들을 체계로 묶었고, 동시에 모든 문제를 프롬프트로 풀려 하지 말라는 선도 함께 그었습니다. 이 모든 것이 "한 턴, 한 과제"라는 전제 위에서 작동합니다.
개인적으로 이 출발점을 정리하면서 남은 인상은, 프롬프트 엔지니어링이 생각보다 익숙한 개발 습관과 닮아 있다는 점이었습니다. 성공 기준을 먼저 정의하고, 측정 가능한 방법으로 검증하고, 풀 문제와 다른 수단으로 풀 문제를 구분하라는 공식 문서의 권고는 새로운 분야의 낯선 규칙이라기보다, 좋은 엔지니어링이 늘 해 오던 일을 입력 텍스트라는 새 대상에 옮겨 놓은 것에 가깝습니다. 입력을 바꾸면 결과가 달라진다는 사실에 휘둘리지 않으려면, 결국 무엇이 좋은 결과인지를 먼저 또렷하게 정의해 둬야 한다는 것. 그 자리가 도구가 바뀌어도 변하지 않는 기본기라는 생각이 들었습니다.
그래서 이 글은 답을 닫기보다 질문 하나를 열어 두고 마치려 합니다. 한 턴, 한 과제라는 전제가 깨지면 어떻게 될까요. 모델이 여러 번의 입출력을 오가며 스스로 다음 행동을 정해야 하는 상황이 오면, 잘 쓴 프롬프트 하나만으로는 다루기 어려운 문제가 생깁니다. 모델이 매 턴 무엇을 알고 있어야 하고, 이전 턴의 결과 가운데 무엇을 다음 턴으로 넘겨야 하는가 하는 문제입니다. 입력 한 번이 아니라, 모델이 매 순간 보게 될 맥락 전체를 설계하는 일로 무게추가 옮겨 가는 셈입니다. 컨텍스트 엔지니어링이라는 다음 용어는 정확히 이 자리에서 자라났습니다. 그 이야기는 시리즈의 다음 편에서 이어 가겠습니다. 비슷한 자리에서 용어의 계보를 정리하려는 분들에게 이 첫 칸이 작은 참고가 되기를 바랍니다.
참고한 공식 문서·논문
- Brown et al., Language Models are Few-Shot Learners, arXiv:2005.14165 (2020-05-28) — https://arxiv.org/abs/2005.14165
- Wei, Wang, Schuurmans et al., Chain-of-Thought Prompting Elicits Reasoning in Large Language Models, arXiv:2201.11903 (2022-01-28) — https://arxiv.org/abs/2201.11903
- Anthropic — Prompt engineering overview — https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/overview
- Anthropic — Prompting best practices (기법 목록의 최신 레퍼런스) — https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices
'TECH AND AI' 카테고리의 다른 글
- Total
- Today
- Yesterday
- 트래픽 처리
- Redis 캐시 전략
- Initialization-on-Demand Holder Idiom
- 캐시 성능 비교
- 동시성처리
- 백엔드 아키텍처
- Spring Batch
- Eager Initialization
- Hot Key 문제
- 백엔드 성능
- 백엔드 성능 설계
- Cache Aside
- InterruptedException
- Java Performance
- Cache Avalanche
- spring batch 5
- Cache Penetration
- Redis vs DB
- 백엔드 성능 튜닝
- Redis 성능 개선
- 스레드 생명주기
- mybatis
- DB 트랜잭션
- 캐시 장애
- Double-Checked Locking
- DB 인덱스 성능
- TTL 설계
- Enum 기반 싱글톤
- 캐시와 인덱스
- 트랜잭션 관리
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
