퓨샷 프롬프팅으로 AI 에이전트의 신뢰도를 한 단계 높이는 방법
AI 에이전트를 개발하다 보면 테스트 환경에서는 완벽하게 작동하던 녀석이 실제 배포만 하면 엉뚱한 짓을 하는 경우를 자주 보게 된다. 지침도 잘 따르고 도구 호출도 깔끔하게 하던 모델이 갑자기 이상한 출력을 내놓으면 당황스럽기 그지없다. 모델이 갑자기 멍청해진 것도 아니고 프롬프트가 바뀐 것도 아닌데 왜 이런 일이 벌어질까? 대부분의 경우 그 이유는 실제 사용자들이 입력하는 데이터가 우리가 예상한 것보다 훨씬 지저분하고 모호하기 때문이다. 단순히 지시 사항을 나열하는 것만으로는 실제 환경의 복잡한 변수들을 모두 통제하기 어렵다는 뜻이다.
이런 문제를 해결하기 위해 가장 효과적인 방법 중 하나가 바로 퓨샷 프롬프팅이다. 퓨샷 프롬프팅은 거대 언어 모델에게 단순히 무엇을 하라고 명령하는 대신, 2개에서 5개 정도의 구체적인 예시를 보여주는 방식이다. 즉, '이런 입력이 들어오면 저런 식으로 생각해서 요런 결과를 내놓아라’라고 직접 보여주는 것이다. 모델은 이 예시들을 통해 우리가 원하는 출력의 패턴과 추론 과정을 학습한다. 이를 '인 컨텍스트 러닝(In-context learning)'이라고 부르는데, 모델 자체를 재학습시키지 않고도 문맥 안에서 새로운 지식이나 규칙을 익히게 만드는 기법이다.
퓨샷 프롬프팅은 단순히 명령만 내리는 제로샷 프롬프팅이나 예시를 딱 하나만 보여주는 원샷 프롬프팅과는 확실히 다르다. 여러 개의 예시를 제공하면 모델은 그 안에서 공통된 패턴을 찾아낸다. 어떤 것이 정답인지, 어떤 과정을 거쳐 사고해야 하는지, 그리고 최종적으로 어떤 형식을 갖춰야 하는지를 명확하게 인지하게 된다. 특히 복잡한 시스템 내부에서 여러 단계로 작동하는 AI 에이전트에게 퓨샷 프롬프팅은 선택이 아닌 필수적인 인프라와도 같다.
에이전트는 보통 하나의 거대한 프롬프트로 움직이지 않는다. 사용자 요청을 해석하는 단계, 어떤 도구를 사용할지 결정하는 단계, 도구에 들어갈 파라미터를 생성하는 단계, 그리고 결과를 요약하는 단계 등 여러 개의 작은 프롬프트들이 엮여서 하나의 시스템을 이룬다. 이때 각 단계에서 발생하는 작은 오류들이 쌓이면 최종 결과물은 완전히 엉망이 될 수 있다. 퓨샷 프롬프팅은 바로 이 각 단계의 '연결 고리’를 단단하게 만들어주는 역할을 한다.
예를 들어 도구 호출 단계에서 사용자가 '어제 주문한 거 취소해줘’라고 말했을 때, 모델은 주문 ID를 찾아야 한다. 단순히 규칙으로 '주문 ID를 찾아라’라고 적는 것보다, 비슷한 대화 내용과 그에 대응하는 API 호출 형식을 세 가지 정도 보여주는 것이 훨씬 정확하다. 모델은 예시를 통해 어떤 데이터를 무시하고 어떤 데이터에 집중해야 하는지 패턴을 익히기 때문이다. 언어 모델은 본질적으로 규칙을 따르는 기계라기보다 패턴을 따르는 기계에 가깝기 때문에 '이 15가지 규칙을 지켜라’라고 말하는 것보다 '이 예시들처럼 해라’라고 보여주는 것이 훨씬 잘 먹힌다.
퓨샷 프롬프팅을 적용하면 얻을 수 있는 이점은 정말 많다. 첫 번째는 정확도와 일관성이다. 예시는 모델이 내놓을 수 있는 결과값의 범위를 좁혀준다. 모델이 독자적으로 해석을 지어내는 시간을 줄이고 우리가 보여준 패턴에 맞추도록 유도한다. 두 번째는 작업에 대한 이해도가 깊어진다는 점이다. '관련 있는 정보를 추출하라’는 지시는 매우 모호하지만, 예시를 통해 무엇이 중요하고 무엇이 안전하며 무엇이 긴급한 것인지 보여주면 모델은 도메인 특화된 지식을 빠르게 흡수한다.
특히 구조화된 출력물을 얻을 때 퓨샷 프롬프팅의 위력은 대단하다. JSON 형식을 맞춰달라는 요청을 할 때, 10줄의 서술형 규칙보다 3개의 완벽한 JSON 예시가 훨씬 효과적이다. 비어 있는 필드를 어떻게 처리할지, 에러 상황에서는 어떤 구조를 반환할지 예시로 보여주면 파싱 에러 때문에 시스템이 터지는 일을 획기적으로 줄일 수 있다. 또한 파인 튜닝처럼 무거운 인프라 작업 없이도 프롬프트 수정만으로 에이전트의 행동을 즉각적으로 바꿀 수 있다는 것도 큰 장점이다.
하지만 현실적으로 생각해보자. 사실 나도 처음에는 이 방식이 비효율적이라고 생각했다. 프롬프트를 짤 때마다 매번 수작업으로 예시를 서너 개씩 넣는 과정이 얼마나 번거로운지 다들 공감할 거다. 시스템 프롬프트에 한 번 박아두면 끝나는 문제도 아니고, 상황에 따라 예시를 바꿔줘야 할 때면? 일반적인 프롬프트에 매번 예시를 넣으려면 토큰 비용도 늘어나고 관리 포인트도 많아져서 귀찮게 느껴지는 게 당연하다.
그럼에도 불구하고 퓨샷 프롬프팅을 포기할 수 없는 이유는 그 귀찮음을 상쇄할 만큼의 성능 향상이 있기 때문이다. 이 귀찮음을 해결하기 위해서는 동적으로 예시를 관리하는 전략이 필요하다. 모든 예시를 프롬프트에 하드코딩하는 것이 아니라, 데이터베이스에 수많은 사례를 저장해두고 현재 사용자 질문과 가장 유사한 사례들만 골라서 프롬프트에 주입하는 방식이다. 이렇게 하면 토큰 낭비도 줄이고 각 상황에 최적화된 예시를 모델에게 보여줄 수 있다.
좋은 예시를 만드는 데도 요령이 있다. 무작정 많이 넣는다고 좋은 게 아니다. 보통 3개에서 5개 정도면 충분하다. 각 예시는 서로 다른 상황을 커버해야 한다. 아주 전형적인 상황 하나, 조금 복잡한 상황 하나, 모호한 입력이 들어왔을 때의 대응 하나, 그리고 예외적인 엣지 케이스 하나 정도로 구성하는 것이 좋다. 또한 모든 예시는 동일한 구조를 가져야 한다. 입력, 사고 과정, 출력 순서로 구성했다면 모든 예시가 그 형식을 유지해야 모델이 혼란을 겪지 않는다.
특히 사고 과정을 포함하는 체인 오브 쏘트(Chain-of-Thought) 기법을 퓨샷 예시에 녹여내면 효과가 배가된다. 단순히 결과값만 보여주는 게 아니라, 모델이 ‘왜’ 그런 결과에 도달했는지 논리적인 단계를 예시 안에 적어주는 것이다. 그러면 모델은 새로운 문제를 만났을 때도 예시에서 본 논리 구조를 따라가며 정답을 찾으려 노력한다. 이는 복잡한 추론이 필요한 에이전트 작업에서 결정적인 차이를 만든다.
물론 퓨샷 프롬프팅에도 비용이 따른다. 예시가 늘어날수록 입력 토큰 수가 많아지고, 이는 곧 비용과 지연 시간(latency)의 증가로 이어진다. 따라서 모든 단계에 무거운 퓨샷 프롬프트를 적용할 필요는 없다. 실수가 발생했을 때 치명적인 단계, 예를 들어 결제 관련 로직이나 보안 체크, 중요한 데이터 라우팅 같은 곳에 예산을 집중 투자하고, 간단한 텍스트 변환이나 요약 같은 작업은 제로샷이나 가벼운 프롬프트로 처리하는 영리함이 필요하다.
흔히 하는 실수 중 하나는 너무 이상적인 데이터만 예시로 넣는 것이다. 깔끔하게 정제된 데이터만 보여주면 실제 현장의 지저분한 입력을 만났을 때 모델이 당황한다. 실제 운영 로그에서 가져온 생생한 사례들을 예시로 활용해야 한다. 오타가 섞여 있거나 문법이 틀린 요청을 모델이 어떻게 세련되게 처리해야 하는지 직접 보여주는 것이 중요하다. 또한 서비스가 업데이트되거나 비즈니스 로직이 바뀌면 프롬프트 속의 예시들도 함께 업데이트해야 한다는 점을 잊지 말아야 한다. 예시도 코드처럼 버전 관리가 필요하다.
정리하자면 퓨샷 프롬프팅은 AI 에이전트의 예측 가능성을 높여주는 가장 강력한 도구다. 단순히 명령어로만 모델을 제어하려고 애쓰지 말고, 모델이 따라 할 수 있는 좋은 이정표를 제시해주길 바란다. 예시를 작성하는 그 짧은 번거로움이 에이전트의 품격을 완전히 바꿀 수 있다. 모델이 내 마음을 읽어주길 기대하기보다, 내 마음이 반영된 결과물을 미리 보여주는 것, 그것이 바로 고도화된 프롬프트 엔지니어링의 핵심이다.
퓨샷 프롬프팅으로 AI 에이전트의 신뢰도를 한 단계 높이는 방법