
프롬프트 잘 쓰는 법: 컨텍스트 설계로 AI 결과물을 고정하기
같은 모델을 줘도 결과가 갈리는 첫 지점은 프롬프트예요. 프롬프트는 '주문'이 아니라 컨텍스트 설계라는 것, 그리고 그 한 방의 한계가 왜 다음 단계를 불렀는지 정리했어요.
프롬프트는 마법 주문이 아니라 컨텍스트 설계예요. 구조화 출력으로 LLM 출력 형식을 안정적으로 강제하고, 매번 달라지는 AI 결과물을 고정하는 법과 프롬프트만으로 안 되는 작업을 정리했어요.
프롬프트는 마법 주문이 아니라, 모델에게 깔아 주는 컨텍스트 설계예요. LLM을 처음 쓸 때는 누구나 똑같이 시작해요. 채팅창을 열고, 하고 싶은 걸 말로 적어요. 그런데 같은 모델, 같은 화면인데도 결과는 사람마다 크게 갈려요. 첫 번째 갈림길이 바로 프롬프트예요.
> 'LLM 활용의 진화' 시리즈 ①편. ① 프롬프팅 · ② 바이브 코딩 · ③ 에이전트 · ④ 하네스 엔지니어링 · ⑤ 오픈 모델. 사람이 LLM을 다뤄 온 방식이 어떻게 바뀌어 왔는지를 단계별로 풀어요.

흔히 프롬프팅을 "마법 주문 찾기"로 오해해요. "이렇게 쓰면 잘 나온대"라는 문구를 수집하는 거죠. 하지만 실제로 결과를 가르는 건 주문이 아닌 모델에게 깔아 주는 컨텍스트의 설계예요. 프롬프팅은 LLM을 다루는 가장 첫 단계이자, 사실은 가장 작은 단위의 컨텍스트 엔지니어링이에요.
이 시리즈에서 다루는 것
| 편 | 주제 | 핵심 |
|---|---|---|
| ① | 프롬프팅 | 컨텍스트 설계로 결과의 분산을 줄여요 |
| ② | 바이브 코딩 | 의도만 말하면 코드가 나오지만 검증이 빠져요 |
| ③ | 에이전트 | 모델이 스스로 도구를 쓰고 결과를 보며 반복해요 |
| ④ | 하네스 엔지니어링 | 에이전트를 감싸는 실행·검증 환경을 설계해요 |
| ⑤ | 오픈 모델 | 자체 호스팅·튜닝 가능한 모델로 확장해요 |
프롬프트는 '주문'이 아닌 '컨텍스트 설계'예요
막연한 한 줄은 막연한 결과를 줘요. "이 주제로 글 써줘"는 모델에게 너무 많은 자유를 남겨요. 톤도, 길이도, 형식도 모델이 그때그때 정하니까 매번 다르게 나와요.
좋은 프롬프트는 모델이 추측해야 할 빈칸을 줄여요. 무엇을, 누구를 위해, 어떤 형식으로, 무엇을 피해서: 이 네 가지를 미리 채워 주면 결과의 분산이 확 줄어들어요. 같은 모델이라도요.
구조를 강제하면 결과가 안정돼요
프롬프트로 형식을 부탁하는 것만으로는 부족할 때가 많아요. "JSON으로 줘"라고 해도 가끔 앞에 설명을 붙이거나 줄바꿈이 흔들려서, 그걸 파싱하는 코드가 자꾸 깨져요.
그래서 실무에서는 형식을 부탁하지 않고 강제해요. Anthropic의 tool_use [1] 또는 OpenAI의 function calling [2]로 출력 스키마를 고정하면, 모델은 반드시 그 구조로만 답해요. 우리가 카드뉴스 생성 파이프라인에서 쓰는 패턴도 이거예요.
# ① 막연한 프롬프트 — 형식이 매번 흔들려요
resp = await client.messages.create(
model="claude-opus-4-8",
messages=[{"role": "user", "content": "이 주제로 슬라이드 6장 만들어줘"}],
)
text = resp.content[0].text # 머리말·줄바꿈이 들쭉날쭉 → 파싱이 깨져요
# ② tool_use 로 스키마를 고정 — 반드시 이 구조로만 답해요
tools = [{
"name": "emit_slides",
"input_schema": {
"type": "object",
"properties": {
"slides": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {"type": "string"},
"body": {"type": "string"},
},
"required": ["title", "body"],
},
},
},
"required": ["slides"],
},
}]
resp = await client.messages.create(
model="claude-opus-4-8",
tools=tools,
tool_choice={"type": "tool", "name": "emit_slides"}, # 이 도구를 반드시 호출
messages=[{"role": "user", "content": prompt}],
)
slides = resp.content[0].input["slides"] # 검증된 구조 — 파싱 불필요
①과 ②는 같은 모델, 같은 주제예요. 다른 건 출력을 설계했느냐뿐이에요. ②는 파싱 에러가 사라지고, 빈 값·잘못된 필드도 스키마 단계에서 걸러져요. 프롬프트를 "글"이 아닌 인터페이스로 다루기 시작하는 순간이에요.
레퍼런스를 같이 줘야 '우리답게' 나와요
구조를 잡아도 톤은 또 다른 문제예요. 모델은 "우리 브랜드 톤"을 몰라요. 그래서 말로 설명하는 대신, 실제 잘 나갔던 예시 몇 개를 같이 넣어요. 이걸 퓨샷(few-shot)이라고 해요. "이런 톤이에요"라는 설명 열 줄보다, 진짜 예시 두 개가 훨씬 정확하게 톤을 전달해요.
한발 더 나아가면, 매번 손으로 예시를 붙이는 대신 브랜드 컨텍스트를 한 번 정의해 두고 프롬프트 앞에 자동으로 붙여요. 우리 파이프라인에서는 이걸 메모리 블록으로 관리해서, 글·카드뉴스·상세페이지가 모두 같은 톤 컨텍스트를 물려받게 해요. 프롬프트가 일회용 문장에서 재사용되는 컨텍스트로 바뀌는 거죠.
그런데 프롬프트 한 방으로는 닿지 못하는 곳이 있어요
여기까지 오면 프롬프팅만으로도 꽤 멀리 가요. 하지만 프롬프트에는 구조적인 한계가 셋 있어요.
- 상태가 없어요(stateless): 한 번의 요청과 한 번의 응답이 전부예요. 모델은 직전에 뭘 했는지, 실제로 동작했는지 몰라요.
- 도구가 없어요(toolless): 코드를 실행하거나, 파일을 읽거나, 결과를 확인할 수 없어요. 머릿속으로만 답할 뿐이에요.
- 검증이 없어요: 틀려도 틀린 줄 몰라요. 맞는지 확인하고 고치는 일은 전부 사람 몫이에요.
이 세 한계가 다음 단계를 불렀어요. "한 번에 다 적지 말고, 모델이 코드를 쓰게 하고 돌려 보면서 고치면 어떨까" 하는 흐름이 바이브 코딩이고, "모델이 스스로 도구를 쓰고 결과를 보며 반복하게 하자"가 에이전트예요.
정리하면
프롬프팅은 LLM을 다루는 첫 번째 방식이자, 지금도 모든 단계의 바닥에 깔린 기본기예요. 핵심은 마법 주문이 아닌 컨텍스트 설계예요. 빈칸을 줄이고, 구조를 강제하고, 레퍼런스를 같이 주는 것. 그것만으로도 같은 모델에서 전혀 다른 안정성을 얻어요.
하지만 프롬프트 한 방은 상태도, 도구도, 검증도 없어요. 다음 편에서는 이 한계를 처음으로 흔든 방식, 바이브 코딩을 다뤄요.
이 글과 이어지는 내용은 바이브 코딩(vibe coding)이란? 한계와 AI 코드 검증 루프, AI 에이전트란? 모델이 스스로 루프를 돌 때 권한과 승인 게이트, 퍼스트파티 데이터가 뭐예요? 서드파티 쿠키 이후 마케팅 활용법에서 볼 수 있어요.
자주 묻는 질문
프롬프트 엔지니어링과 컨텍스트 엔지니어링은 다른 건가요?
프롬프팅은 LLM을 다루는 가장 첫 단계이자, 사실은 가장 작은 단위의 컨텍스트 엔지니어링이에요. 무엇을·누구를 위해·어떤 형식으로·무엇을 피해서를 미리 채워 주는 일이 곧 컨텍스트 설계예요.
tool_use와 그냥 'JSON으로 줘'라고 요청하는 건 뭐가 다른가요?
'JSON으로 줘'는 부탁이라 가끔 앞에 설명이 붙거나 줄바꿈이 흔들려서 파싱이 깨져요. tool_use나 function calling은 출력 스키마를 강제해서, 모델이 반드시 그 구조로만 답하고 빈 값·잘못된 필드는 스키마 단계에서 걸러져요.
퓨샷 예시는 몇 개가 적당한가요?
정해진 개수보다 실제 톤을 보여주는 예시인지가 중요해요. 본문에서 든 예로는, '이런 톤이에요'라는 설명 열 줄보다 진짜 잘 나갔던 예시 두 개가 훨씬 정확하게 톤을 전달해요.
참고자료
요약
- 프롬프팅은 마법 주문이 아니라 모델에게 깔아 주는 컨텍스트 설계예요.
- 무엇을·누구를 위해·어떤 형식으로·무엇을 피해서를 채우면 결과의 분산이 줄어요.
- 형식은 부탁이 아니라 tool_use 같은 구조화 출력으로 강제해야 안정돼요.
- 프롬프트는 상태·도구·검증이 없어서, 그 한계가 바이브 코딩과 에이전트를 불렀어요.
다른 글

RAG 할루시네이션 방어 전략: 유형을 나누고 검증 자동화의 한계 알기
RAG는 외부 문서를 검색해 답변 근거로 쓰는 기법이지만 검색·생성 단계 모두에서 할루시네이션이 생겨요. 소스 미참조와 소스 왜곡 유형의 차이, 막는 법, AI 답변 검증을 자동화할 때의 한계를 정리했어요.

GEO 데이터 AI 에이전트 설계 원칙: 구조화 도구 호출, 되돌릴 수 없는 작업 막기
GEO 데이터를 다루는 AI 에이전트를 설계할 때 지키는 원칙이에요. 텍스트 파싱과 구조화 도구 호출의 차이, 되돌릴 수 없는 작업을 막는 법, 평가 없이 배포하면 위험한 이유를 정리했어요.

오픈 웨이트 모델 vs API 모델: Hermes로 도메인 특화 모델 소유하기
모델을 빌리는 대신 소유하는 단계예요. 오픈 웨이트 모델을 쓰는 이유, API 모델과의 선택 기준, Nous Research Hermes(4.3)의 특징과 함수 호출 표준, 도메인 특화 모델용 데이터를 모으는 플라이휠을 정리했어요.
같은 주제로 이어 읽기
- 하네스 엔지니어링이란? 같은 LLM인데 결과가 다른 이유에이전트를 안전하고 일정하게 굴리는 건 모델 주변의 하네스예요. 프롬프트 엔지니어링과의 차이, 스코프된 도구·훅·컨텍스트 계층화·검증 루프, MCP self-call, AI 에이전트 팀 운영의 저점을 높이는 법이에요.
- AI 에이전트란? 모델이 스스로 루프를 돌 때 권한과 승인 게이트OpenClaw(전 Moltbot)가 띄운 자율 AI 에이전트를 정리했어요. 프롬프트와 에이전트의 차이, 에이전트에 넓은 권한을 주면 생기는 위험, 사람 승인 게이트를 두는 이유예요.
- 바이브 코딩(vibe coding)이란? 한계와 AI 코드 검증 루프바이브 코딩은 의도만 말하면 AI가 코드를 만드는 방식이에요. 무엇을 풀었고 어디서 깨지는지(한계), 에이전트 코딩과의 차이, AI가 만든 코드에 검증 루프를 붙이는 법을 정리했어요.
이 글은 TRAIL Labs 카테고리에 속해요. 같은 카테고리 글 16편을 한자리에서 볼 수 있어요. TRAIL Labs 카테고리 글 전체 보기