$10,000의 교훈: Function Calling과 Caching을 활용한 비용 효율적인 AI 기능 구축
요약
AI 파이프라인 구축 시 발생하는 막대한 비용 문제를 해결하기 위한 아키텍처 설계 전략을 다룹니다. Function Calling을 통한 토큰 낭비 방지와 다계층 캐싱 전략을 통해 품질 저하 없이 비용을 효율적으로 절감하는 방법을 제시합니다.
핵심 포인트
- Function Calling을 사용하여 불필요한 텍스트 생성을 방지하고 토큰 사용량을 절감함
- 구조화된 출력을 통해 모델의 환각(Hallucination)을 줄이고 데이터 신뢰성을 확보함
- 임베딩 캐싱을 통해 RAG 파이프라인의 반복적인 임베딩 비용을 최소화함
- 단순한 모델 선택보다 시스템 아키텍처 설계가 비용 최적화의 핵심임
한 고객이 AI 파이프라인 비용을 확인했던 그 정확한 순간이 기억납니다. 화요일 아침이었고, 그 숫자를 본 고객은 "당장 중단하세요"라고 말했습니다.
그 파이프라인은 백만 개 이상의 채용 공고가 있는 플랫폼을 위해 직무 기술서(job descriptions)를 다시 작성하는 작업이었습니다. 아이디어는 확실했습니다. 유능한 LLM (Large Language Model)을 사용하여 가공되지 않은 ATS (Applicant Tracking System) 텍스트를 구조화되고 SEO (Search Engine Optimization)에 최적화된 콘텐츠로 변환하는 것이었습니다. 하지만 공고당 발생하는 비용이 빠르게 쌓였습니다. 그 기능은 기술적으로는 인상적이었지만, 경제적으로는 완전히 비효율적이었습니다.
그것은 뼈아픈 교훈이었습니다. 하지만 그 경험은 이후 제가 진행한 모든 AI 프로젝트에서 적용해 온 교훈을 주었습니다. 비용 효율적인 AI 기능을 구축하는 것은 단순히 가장 저렴한 모델을 선택하는 문제가 아닙니다. 그것은 아키텍처 (Architecture)의 문제입니다. 시스템을 올바르게 설계한다면 품질을 낮추지 않고도 비용을 획기적으로 절감할 수 있습니다.
실제로 효과가 있는 방법은 다음과 같습니다.
Function Calling은 토큰 낭비를 절반 이상 줄여줍니다
AI 기능에서 가장 큰 숨겨진 비용은 필요하지 않은 텍스트를 생성하는 것입니다. 대부분의 개발자는 프롬프트 (Prompt)를 보내고, 단지 구조화된 데이터 포인트만 필요할 뿐인데도 LLM이 한 단락의 해설을 작성하도록 내버려 둡니다. 이는 불필요한 채우기용 토큰 수천 개에 비용을 지불하는 것과 같습니다.
Function calling (또는 구조화된 출력, structured output)이 이 문제를 해결합니다. 모델에게 반환할 필드를 정확히 알려주면, 모델은 오직 해당 필드만을 JSON 형식으로 출력합니다. 군더더기가 없습니다.
제가 운영 환경에서 사용하는 패턴은 다음과 같습니다:
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
...
도입 문구도 없고, "네, 추출된 데이터는 다음과 같습니다"와 같은 말도 없습니다. 오직 JSON 객체만 존재합니다. 대량 추출 파이프라인에서 이 방식은 동일한 데이터를 요청하는 자유 형식 프롬프트에 비해 토큰 사용량을 크게 줄여줍니다.
부수적인 이점은 신뢰성입니다. 스키마 (Schema)를 강제하면 존재해서는 안 될 필드에 대한 환각 (Hallucination)을 제거할 수 있습니다. 저는 조건부 스키마 플래그 (presence guards와 같은)를 사용하여 모델이 존재하지 않는 필드를 꾸며내는 것을 방지해 왔습니다. 예를 들어, 이전 직장이나 학력 항목을 절대로 지어내지 않도록 보장하는 식입니다. 이것은 단순한 비용 최적화가 아니라 신뢰의 문제입니다.
Caching은 공짜 돈과 같지만, 대부분의 사람들이 잘못 사용하고 있습니다
모든 사람이 LLM 응답을 캐싱(Caching)해야 한다는 사실은 알고 있습니다. 하지만 (정확한 프롬프트 문자열을 키로 사용하는) 순진한 접근 방식은 절감할 수 있는 비용의 대부분을 놓치게 됩니다.
핵심은 여러 계층에서 캐싱을 수행하는 것입니다.
임베딩 캐시 (Embedding cache). RAG (Retrieval-Augmented Generation) 파이프라인을 위해 문서를 임베딩(Embedding)하고 있다면, 사용자가 유사한 질문을 할 때마다 동일한 임베딩에 대해 비용을 지불하고 있는 것입니다. 임베딩 벡터를 데이터베이스에 저장하고, API를 호출하기 전에 콘텐츠 해시(Content hash)로 쿼리하세요. 초기 시딩(Seeding) 기간이 가장 비용이 많이 들지만, 그 이후에는 반복되는 쿼리가 캐시를 타게 되어 비용이 들지 않습니다. 시간이 지나 캐시가 워밍업(Warm up)됨에 따라 임베딩 비용은 실질적으로 감소합니다.
시맨틱 키잉을 활용한 LLM 응답 캐시 (LLM response cache with semantic keying). 정확한 프롬프트 매칭은 너무 취약합니다. 한 사용자는 "이것을 요약해줘"라고 묻고, 다른 사용자는 "요약을 해줘"라고 물을 수 있습니다. 이들은 동일한 캐시 항목을 참조해야 합니다. 정규화된 프롬프트(Normalized prompt)와 함수 호출(Function call) 파라미터의 결정론적 해시(Deterministic hash)를 사용하세요. 정규화된 키를 데이터 신선도(Data freshness)와 연동된 TTL (Time To Live)을 가진 Redis와 같은 캐시에 저장할 수 있습니다. 안정적인 콘텐츠의 경우 24시간, 빠르게 변하는 데이터의 경우 1시간이 적당합니다.
스마트한 캐시 무효화 (Smart cache invalidation). 대부분의 사람들이 실패하는 지점이 바로 여기입니다. 그들은 영원히 캐싱을 하고 오래된(Stale) 데이터를 제공합니다. 데이터 소스에 따라 캐시 TTL을 설정하세요. 기반 데이터가 변경되면(새로운 채용 공고, 업데이트된 사용자 프로필 등), 해당 특정 키에 대한 캐시를 무효화(Invalidate)해야 합니다. 이를 통해 "이력서를 업데이트했는데 AI는 여전히 옛날 버전을 보고 있다"는 문제를 방지할 수 있습니다.
전체적인 영향: 매일 많은 LLM 호출을 처리하는 운영 시스템에서, 캐싱은 초기 워밍업 이후 API 호출의 상당 부분을 제거할 수 있습니다. 많은 요청이 첫 번째 동일한 쿼리 이후에는 API에 전혀 닿지 않게 됩니다.
대규모 워크로드를 위한 Batch API 및 프롬프트 압축 (Prompt Compression)
OpenAI의 Batch API는 대부분의 모델에 대해 50% 할인을 제공합니다. 트레이드오프(Tradeoff)는 지연 시간(Latency)입니다. 결과가 몇 초가 아니라 몇 시간 후에 돌아옵니다. 이는 사용자 대상 채팅이 아닌, 야간 데이터 보강(Enrichment) 작업에 완벽합니다.
대규모 구인구직 플랫폼에서 저는 설명문 재작성 파이프라인(Description rewrite pipeline)을 Batch API로 이전했습니다. 수천 개의 매물을 밤새 처리함으로써, 동기식 호출 (Synchronous calls)과 비교했을 때 매물당 비용을 절반으로 줄였습니다. 그럼에도 불구하고 전체 비용은 여전히 상당했기에, 해당 워크로드(Workload)를 위해 DeepSeek V4 Flash (GPT-4.1보다 약 23배 저렴함)와 같은 더 저렴한 모델을 검토하고 있습니다.
프롬프트 압축 (Prompt compression) 또한 또 다른 레버(Lever)입니다. 불필요한 컨텍스트 (Context)를 제거하세요. 시스템 프롬프트 (System prompt)가 길고 많은 요청을 보내고 있다면, 시스템 프롬프트에서 제거하는 모든 토큰은 모든 요청에 걸쳐 배수로 적용됩니다. 저는 중복된 지침을 제거하고 더 짧은 예시를 사용함으로써 프롬프트를 눈에 띄는 수준으로 다듬었습니다.
모델 선택: 언제 4o에 비용을 지불하고, 언제 Flash를 사용할 것인가
저는 간단한 의사결정 트리 (Decision tree)를 유지합니다:
- 복잡한 추론, 법률 또는 금융 작업: GPT-4o 또는 4.1. 출력 품질이 비용을 정당화합니다.
- 구조화된 데이터 추출 (Structured data extraction), 분류 (Classification), 요약 (Summarization): GPT-4o mini 또는 Gemini 2.0 Flash. 빠르고 저렴합니다.
- 품질 요구사항이 느슨한 대량 처리: DeepSeek V4 Flash. GPT-4.1보다 약 23배 저렴하여, 가끔 발생하는 오류가 허용되는 파이프라인에서 경제적입니다.
- 실시간, 대용량, 중간 정도의 품질: Gemini 2.0 Flash. 무료 티어(Free tier)가 관대한 한도를 제공하며, 유료 요금제는 GPT-4o mini보다 낮습니다.
만약 한 고객이 모든 작업에 최상위 모델을 사용하겠다고 고집한다면, 추출 작업을 더 저렴한 모델로 전환하고 채팅 응답을 가성비 좋은 제공업체로 바꾸는 것만으로도 월간 청구 금액을 극적으로 낮출 수 있습니다. 사용자 만족도로 측정되는 품질은 거의 변하지 않습니다.
가드레일 (Guardrails)은 통제 불능의 비용 발생을 방지합니다
가장 비싼 버그는 무한 루프 (Infinite loop)입니다. 실패 시 재시도하는 AI 에이전트(AI agent)나 생성 버튼을 스팸처럼 누르는 사용자는 단 몇 분 만에 상당한 돈을 태워버릴 수 있습니다.
저는 모든 AI 기능에 세 가지 엄격한 가드레일을 설정합니다:
- 요청당 토큰 제한 (Per-request token limits). max_tokens에 대한 하드 캡 (Hard cap)을 설정합니다. 모델이 답변 길이를 스스로 결정하게 두어서는 안 됩니다.
- 사용자별 속도 제한 (Rate limiting per user). 생성 엔드포인트 (Generation endpoints)에 대해 분당 및 일일 요청 횟수에 합리적인 제한을 둡니다.
- 비용 알림 (Cost alerts). 일일 API 사용량을 확인하고 임계값을 초과하면 알림을 보내는 간단한 스크립트입니다. 통제 불능의 프롬프트 (Runaway prompt)는 모델이 지나치게 긴 응답을 생성하게 만들 수 있습니다. 비용 알림은 상황이 악화되기 전에 이를 조기에 포착합니다.
이것들은 이론적인 이야기가 아닙니다. 저는 가드레일 하나가 누락되어 파이프라인이 예상보다 훨씬 빠르게 수백 달러를 태워버리는 것을 직접 보았습니다. 이제 저는 이 세 가지가 모두 갖춰지지 않은 상태로는 절대 AI 기능을 출시하지 않습니다.
만약 귀하의 팀이 AI 기능 비용 문제로 골머리를 앓고 있거나 그로 인해 배포 속도가 늦어지고 있다면, 그것이 바로 제가 도움을 드릴 수 있는 부분입니다. 저는 프로덕션 AI 파이프라인을 구축하고, 이를 망가뜨려 보기도 하며, 실제로 무엇이 작동하는지 파악해 왔습니다. 함께 의견을 나누고 싶다면 언제든 환영합니다.
작성자: Abdul Rehman, 프로덕션 SaaS, MVP 및 AI 자동화를 구축하는 풀스택 AI 엔지니어. 더 많은 정보는 PrimeStrides에서 확인하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기