Oluwa.io
모든 글
·읽기 5분AI 제품 방법론LLM 애플리케이션평가엔지니어링

프롬프트에서 제품으로: LLM을 진짜 앱으로 바꾸기

LLM 애플리케이션 구축을 위한 실무자의 방법론: 평가(eval), 가드레일, 지연 시간과 비용 예산, 휴먼 인 더 루프, 그리고 무엇을 자동화하지 말아야 하는지.

글쓴이 Vitor Lima

플레이그라운드에서 작동하는 프롬프트는 데모이지 제품이 아니다. 둘 사이의 간극이 바로 대부분의 AI 프로젝트가 조용히 죽어가는 곳이다. 실제 사용자를 견뎌내는 LLM 애플리케이션을 구축하는 일은, 데모가 시사하는 것보다 영리한 프롬프팅과는 훨씬 덜 관련되어 있고, 평범한 소프트웨어 규율과는 훨씬 더 관련되어 있다. 우리는 이런 것들을 충분히 출시해 봤다 — Youp, MadaiOps, 그리고 이제 Linea — 그래서 그 간극을 실제로 무엇이 메우는지에 대해 견해를 가지고 있다. 그중 어느 것도 화려하지 않다.

함정은 첫 버전이 완성된 것처럼 느껴진다는 것이다. 영리한 프롬프트를 붙여넣으면 모델이 인상적인 무언가를 반환하고, 그것을 UI로 감싸서 출시라고 부르고 싶어진다. 그러다 실제 사용자들이 당신이 상상조차 못 한 입력을 들고 나타나고, 모델은 확신에 차서 틀린 무언가를 하며, 당신은 자신의 수정이 상황을 나아지게 했는지 나빠지게 했는지 알아낼 방법이 없다는 것을 발견한다. 이 글은 그 인상적인 데모를, 프로덕션에서 운영하면서도 밤새 편히 잘 수 있는 무언가로 바꿔주는 골조에 관한 것이다.

프롬프트가 아니라 평가로 시작하라

일찍 구축할 수 있는 가장 지렛대가 큰 것은 평가 세트(evaluation set)다. 벤치마크도 리더보드도 아니라 — 실제 입력과 좋은 출력이 어떤 모습인지를 짝지은 폴더다. 스무 개가 영 개를 이기고, 잘 큐레이션된 쉰 개가 긁어모은 천 개를 이긴다.

이유는 간단하다. 평가가 있으면 프롬프트 엔지니어링은 감(vibes)에 의존하기를 멈춘다. 한 줄을 바꾸고, 세트를 돌리고, 숫자가 움직이는 것을 지켜본다. 평가가 없으면 모든 조정은 미신이다. 우리는 여러 팀이 프롬프트 개선에 일주일을 쓰고도 몇 달 전에 해결했던 케이스에서 퇴행하는 것을 지켜봤다. 그들이 보고 있지 않던 케이스들을 아무것도 측정하지 않았기 때문이다.

우리가 확고하게 견지하는 몇 가지 견해:

  • 문구가 아니라 결과로 채점하라. 추출, 분류, 라우팅처럼 구조화된 것에 대해서는 문자열 유사도가 아니라 파싱된 결과에 대해 단언(assert)하라. 자유 형식 텍스트에는, 촘촘한 채점 기준(rubric)을 갖춘 LLM-판정자(LLM-as-judge)도 괜찮지만, 먼저 소수의 사람이 붙인 레이블에 대해 판정자를 검증하라. 그러지 않으면 당신은 그저 한 모델의 취향을 측정하고 있는 것이다.
  • 퇴행(regressions) 파일을 유지하라. 모든 프로덕션 실패는 영구적인 테스트 케이스가 된다. 이것이 당신의 평가 세트를 정직하게 유지하는 방법이다 — 세트는 현실이 밀어붙이는 바로 그 방향으로 정확히 자라난다.
  • 평가를 프롬프트와 함께 버전 관리하라. 평가 세트가 없는 프롬프트는 테스트되지 않은 코드 변경이다.

이 글에서 딱 하나만 구축한다면, 이것을 구축하라. 하류의 모든 것은 "그게 상황을 나아지게 했는가?"에 답할 수 있는 능력에 달려 있다.

가드레일은 사과보다 싸다

모델은 평범한 소프트웨어가 실패하지 않는 방식으로 실패한다. 존재하지 않는 API를 지어내거나, 사용자의 잘못된 전제에 동의하거나, 환각으로 지어낸 필드가 든 그럴듯한 JSON을 내놓는다. 가드레일은 이것이 사용자에게, 혹은 더 나쁘게는 실행 단계에 도달하기 전에 잡아내는 계층이다.

세 가지 위치에서 생각하라.

  • 입력 가드레일은 모델이 실행되기 전에 거부하거나 정제한다: 프롬프트 인젝션 선별, 개인정보(PII) 마스킹, 주제 이탈 필터링.
  • 출력 가드레일은 돌아온 것을 검증한다: 스키마 검증, 인용 근거(citation-grounding) 확인, 정책 필터.
  • 행동 가드레일은 모델과, 부수 효과를 가진 무언가 사이에 놓인다.

세 번째가 바로 진짜 위험이 사는 곳이다. 우리의 워크플로 자동화 에이전트인 Linea에서, 모델은 행동을 제안할 수 있다 — API 호출, 레코드 이동, 메시지 전송. 제안과 실행은 의도적으로 별개의 단계다. 결과가 중대한 모든 행동은 무언가 실행되기 전에 타입이 지정된 계약(typed contract)과 정책 확인을 통과하며, 파괴적이거나 되돌릴 수 없는 행동은 명시적인 확인 관문(confirmation gate)을 요구한다. 잘못된 것을 제안하는 에이전트는 당신이 개선해 나갈 수 있는 UX 문제다. 잘못된 것을 실행하는 에이전트는 사고(incident)다. 그 두 실패 모드를 단단한 경계선의 반대편에 두어라.

견해가 담긴 버전은 이렇다. 구조화된 출력을 스키마에 대해 검증하고, 모델이 일관되기를 믿는 대신 실패 시 재시도하라. 그리고 모델의 원시 출력이 되돌릴 수 없는 행동을 촉발하는 그것이 되게 하지 마라. 그 사이에 결정론적 확인을 두어라, 항상.

지연 시간과 비용을 기능처럼 예산하라

지연 시간과 비용은 마지막에 측정하는 것들이 아니다. 그것들은 처음부터 대비해 설계하는 제약이다. 청구서만이 아니라 아키텍처를 바꾸기 때문이다.

사용자 대면 행동마다 명시적인 예산을 설정하라: p95 지연 시간 목표와 호출당 비용 상한. 일단 이것들이 적혀 있으면 설계 결정이 쉬워진다. 우리가 반복적으로 손을 뻗는 몇 가지 패턴:

  • 단계마다 모델 크기를 알맞게 맞춰라. 대부분의 파이프라인에는 진정으로 프런티어 모델이 필요한 한두 단계와, 더 작고 빠른 모델이 잘 처리하는 여러 단계가 있다. 단순 분류를 값싼 모델로 라우팅하고 비싼 모델은 어려운 추론 단계에 아껴두는 것은 가용한 최고 수익률의 최적화이며, 대개 지연 시간도 개선한다.
  • 첫 토큰을 스트리밍하라. 대화형인 무엇이든, 체감 지연 시간은 첫 토큰까지의 시간(time-to-first-token)이 지배한다. 4초 걸리는 스트리밍 응답이 2초 걸리는 블로킹 응답보다 낫게 느껴진다.
  • 공격적으로 캐싱하라. 안정적인 시스템 컨텍스트에는 프롬프트 캐싱을, 반복되는 입력에는 평범한 결과 캐싱을. 프로덕션 트래픽의 상당 부분은 거의 중복이다.

머릿속에 담아둘 트레이드오프는 이렇다. 더 큰 모델은 당신의 엔지니어링 노력을 줄여주지만 한계 비용과 지연 시간을 영원히 올린다. 더 값싼 모델은 일을 당신에게 떠넘긴다 — 더 세심한 프롬프트, 더 많은 가드레일, 더 많은 평가 — 하지만 그 일은 영구적인 절감에 대한 일회성 비용이다. 물량이 있는 무엇이든, 엔지니어링에 투자하라.

사람을 의도적으로 루프 안에 두어라

"휴먼 인 더 루프(human in the loop)"라는 말은 너무 자주 쓰여서 아무 의미도 없게 되어버렸다. 잘 해내면, 그것은 AI가 실패할 때의 대비책이 아니라 — 설계된 노동 분업이다. 질문은 사람을 포함할 것인가가 아니라 사람의 판단이 그것이 더하는 지연 시간보다 더 가치 있는 곳이 어디인가이다.

우리에게 가장 잘 통한 패턴은 **신뢰도 기반 에스컬레이션(confidence-gated escalation)**이다. 시스템은 확신하는 다수를 자동으로 처리하고 불확실한 소수를 사람에게 라우팅하되, 모델의 추론을 첨부해서 사람이 몇 분이 아니라 몇 초 안에 결정하도록 한다. MadaiOps에서는 정상 파라미터 범위 안의 주문 작업은 그냥 흘러가고, 무엇이든 이상한 것은 조용히 실행되는 대신 컨텍스트와 함께 운영자에게 드러난다. 검토자는 기계를 돌보고 있는 것이 아니다. 그들은 자신의 주의를 희소하고 가치 있는 곳에만 쓰고 있는 것이다.

한 가지 규칙 더: 사람의 교정을 계측(instrument)해서 당신의 평가 세트와 프롬프트로 다시 피드백하라. 자신의 사람들로부터 배우지 않는 휴먼 인 더 루프 시스템은 그저 같은 일에 두 번 값을 치르고 있는 것이다.

무엇을 자동화하지 말아야 하는지 알라

이 분야에서 가장 어려운 판단은 절제다. 모든 작업을 모델에 넘겨야 하는 것은 아니며, 성숙함이란 어느 것을 내버려 둬야 하는지 아는 것이다.

우리의 대략적인 시험은 이렇다. 실수의 비용이 낮거나, 실수를 감지하고 되돌리기 쉬운 곳을 자동화하라. 초안 작성, 요약, 추출, 분류, 라우팅 — 좋은 후보들이다. 잘못된 초안은 수정하면 되고, 잘못된 요약은 읽으며 잡힌다. 오류가 비싸거나, 감지하기 어렵거나, 되돌릴 수 없는 곳에서는 훨씬 더 신중하라. 돈을 움직이거나, 철회할 수 없는 커뮤니케이션을 보내거나, 법률적·의료적 판단을 내리는 무엇이든. 거기서 모델은 조력자 역할에 속한다 — 선택지를 드러내고, 검토용 초안을 작성하는 것 — 운전석이 아니다.

우리가 견지하는 선은 이렇다. 모델이 틀리고 있음을 어떻게 잡아낼지 서술할 수 없다면, 당신은 그 단계를 자동화할 준비가 되지 않은 것이다. 실패를 감지하는 능력이야말로 진짜 전제 조건이며, 정확도보다 더 그렇다. 완전히 검증할 수 있는 95% 정확한 단계가, 검증할 수 없는 99% 정확한 단계보다 출시하기에 더 안전하다.

이 일의 형태

프롬프트를 제품으로 바꾸는 것은 대부분 화려하지 않은 부분이다. 측정할 수 있게 해주는 평가, 실패를 가둬두는 가드레일, 빠르고 저렴하게 유지해 주는 예산, 판단이 중요한 곳에 배치된 사람, 그리고 일부는 자동화하지 않고 남겨두는 규율. 모델은 아마 시스템의 20%다. 나머지 80%는 모델의 이따금씩 나오는 탁월함을 안심하고 의지할 수 있게 만드는 엔지니어링이다.

좋은 소식은 이것이 익숙한 일이라는 것이다. 그것은 어떤 종류의 좋은 소프트웨어든 만드는 것과 같은 본능에 보상한다. 바꾸기 전에 측정하고, 폭발 반경을 가두고, 사용자의 시간을 존중하는 것. 모델은 새롭다. 장인정신은 그렇지 않다.