오늘 배운 내용
오늘은 AI 서비스를 개발하는 것에서 한 단계 더 나아가, 실제 서비스로 운영할 때 고려해야 할 비용과 시스템 자원, 모니터링, 아키텍처에 대해 학습했다.
LLM을 활용한 기능을 구현하는 것만으로는 충분하지 않다. 서비스가 늘어나고 사용자가 많아지면 API 호출 비용과 서버 자원 사용량도 함께 증가한다.
따라서 오늘 수업에서는 FinOps를 통한 비용 관리, LLM 사용량 최적화, Docker 기반 모니터링, 프론트엔드와 백엔드의 역할 분리를 중심으로 AI 서비스 운영에 필요한 내용을 살펴봤다.
FinOps와 클라우드 비용 관리
가장 먼저 살펴본 개념은 FinOps(Financial Operations)였다.
FinOps는 단순히 클라우드 비용을 줄이는 활동이 아니라, 기술·재무·비즈니스 관점에서 클라우드 자원 사용량과 비용을 측정하고 최적화해 비즈니스 가치를 높이는 운영 방식이다.
수업에서는 다음 세 가지 흐름을 중심으로 설명했다.
-
Measure: 현재 사용량과 비용을 측정한다.
-
Optimize: 비용이 발생하는 원인을 분석하고 최적화한다.
-
Operate: 최적화된 상태를 지속적으로 관리한다.
비용을 줄이기 위해서는 먼저 어디에서 얼마나 비용이 발생하는지 알아야 한다.
특히 LLM 서비스는 단순히 서버 비용만으로 운영 비용을 판단하기 어렵다. 입력 토큰과 출력 토큰, 사용하는 모델, API 호출 횟수에 따라 비용이 달라지기 때문이다.
예를 들어 하나의 워크플로에서도 문서 분석, 검색, 답변 생성 등 여러 단계에서 LLM을 호출한다면 각각의 사용량을 구분해서 측정해야 한다.
또한 n8n 자체도 워크플로 실행과 데이터 처리, 동시 실행, 로그 저장 등에 CPU와 메모리를 사용한다. LLM 연산을 외부 API에서 처리한다고 해서 로컬 서버의 자원 사용량이 사라지는 것은 아니다.
결국 AI 서비스의 운영 비용은 API 비용과 서버·스토리지·네트워크 비용을 함께 살펴봐야 한다.
LLM 사용량 추적과 비용 최적화
오늘 수업에서 중요하게 다룬 부분 중 하나는 LLM 호출 비용을 구체적으로 추적하는 방법이었다.
단순히 월별 API 사용 금액만 확인하는 것이 아니라, 요청 단위로 사용량을 기록해야 한다.
예를 들어 다음과 같은 정보를 기록할 수 있다.
-
요청 ID와 사용자
-
실행된 워크플로 단계
-
사용한 모델
-
입력 토큰과 출력 토큰
-
요청별 비용
이 데이터를 집계하면 사용자별, 모델별, 워크플로 단계별로 비용을 분석할 수 있다.
LLM 비용을 줄이는 방법도 여러 가지로 나눠 살펴봤다.
1. 불필요한 컨텍스트 줄이기
LLM에 전달하는 시스템 프롬프트와 대화 이력, 참고 문서가 길어질수록 입력 토큰이 증가한다.
따라서 현재 작업에 필요하지 않은 문서나 오래된 대화 기록, 중복된 지침을 제거해야 한다.
특히 RAG를 사용하면 전체 문서를 전달하는 대신 필요한 문서 조각만 검색해 전달할 수 있다. 다만 임베딩과 검색 과정에도 비용이 발생하기 때문에 전체 운영 비용을 기준으로 판단해야 한다.
2. 적절한 모델 선택과 라우팅
모든 작업에 가장 비싼 모델을 사용할 필요는 없다.
단순한 분류나 짧은 응답은 상대적으로 저렴한 모델에 맡기고, 복잡한 분석이나 높은 정확도가 필요한 작업은 더 높은 성능의 모델로 전달하는 방식이 가능하다.
이때 중요한 것은 단순히 저렴한 모델로 바꾸는 것이 아니라, 결과의 품질이 유지되는지 함께 평가하는 것이다.
3. 불필요한 API 호출 줄이기
같은 요청을 반복해서 처리하거나 코드로 해결할 수 있는 작업까지 LLM에 맡기면 호출 횟수가 증가한다.
규칙 기반 처리, 중복 노드 제거, 캐싱 등을 활용하면 불필요한 호출을 줄일 수 있다.
4. 입력 크기와 사용량 제한
과도하게 큰 입력이 들어오거나 특정 사용자가 API를 반복 호출하면 예상하지 못한 비용이 발생할 수 있다.
이를 방지하기 위해 입력 크기 제한, 사용자별 예산, 요청 횟수 제한 등을 적용할 수 있다.
이러한 정책은 단순한 비용 절감뿐 아니라 서비스의 안정적인 운영에도 필요하다.
Docker 기반 자원 관리와 모니터링
LLM API 비용을 최적화하더라도 서버 자체의 자원 관리가 제대로 이루어지지 않으면 서비스 운영에 문제가 생길 수 있다.
수업에서는 CPU, 메모리, 디스크 사용량과 Docker 컨테이너의 자원 제한을 함께 살펴봤다.
특히 n8n처럼 여러 워크플로가 동시에 실행되는 환경에서는 동시 실행 수를 무제한으로 늘리는 것이 좋은 방법은 아니다.
동시 실행이 많아지면 메모리 사용량이 증가하고, 실행 기록과 로그가 쌓이면 디스크 공간도 부족해질 수 있다.
이를 관리하기 위한 방법으로 다음과 같은 내용을 학습했다.
-
워크플로 동시 실행 수 제한
-
대기열을 활용한 요청 처리
-
로그 보존 기간과 실행 기록 관리
-
Docker 컨테이너별 CPU·메모리 제한
-
디스크 사용량 모니터링
-
요청 제한 초과 시 HTTP 429 응답
Prometheus, InfluxDB, Grafana
모니터링 도구들의 역할도 구분해서 살펴봤다.
-
Prometheus는 시스템과 서비스의 메트릭을 수집하는 도구다.
-
InfluxDB는 시간에 따른 수치 데이터를 저장하는 시계열 데이터베이스다.
-
Grafana는 수집·저장된 데이터를 대시보드로 시각화한다.
강사님은 WSL2 환경에서 Docker Compose를 이용해 모니터링 환경을 구성하는 과정을 시연했다.
Grafana 대시보드에서는 시스템 자원과 컨테이너의 CPU·메모리 사용량, n8n 관련 실행 정보를 확인할 수 있었다.
특히 이 구조를 확장하면 n8n 워크플로에서 발생하는 LLM 토큰 사용량과 비용도 수집해 시스템 자원과 함께 확인할 수 있다는 점이 인상적이었다.
AI 서비스의 비용과 서버 상태를 별도로 관리하는 것이 아니라 하나의 운영 지표로 연결할 수 있기 때문이다.
사용자별 예산과 호출 횟수 제한
비용 최적화는 전체 서비스 차원뿐 아니라 사용자별 정책으로도 적용할 수 있다.
수업에서 다룬 Lab 3에서는 사용자별 일일 예산과 최근 요청 횟수를 기준으로 LLM 호출을 제한하는 구조를 살펴봤다.
예를 들어 사용자가 설정된 일일 예산을 초과했다면 LLM을 호출하지 않고 FAQ나 대체 안내를 반환할 수 있다.
또한 일정 시간 동안 허용된 요청 횟수를 초과하면 HTTP 429 응답을 반환하고, 다시 요청할 수 있는 시간을 안내할 수 있다.
여기서 중요한 것은 장애 상황과 예산 초과 상황을 구분하는 것이다.
-
장애 상황: LLM 서비스 자체에 문제가 발생한 경우
-
예산 초과: 서비스는 정상 작동하지만 사용자의 정책상 LLM 호출을 허용하지 않는 경우
두 상황은 원인이 다르기 때문에 대체 응답과 처리 정책도 구분해야 한다.
프론트엔드와 백엔드의 역할 분리
후반부에는 AI 서비스뿐 아니라 일반적인 웹 서비스의 구조를 이해하기 위한 프론트엔드와 백엔드의 역할 분리를 다뤘다.
과거에는 PHP와 같은 서버 중심 구조에서 화면을 구성하는 HTML과 비즈니스 로직, 데이터베이스 접근이 하나의 서버에 함께 들어가는 경우가 많았다.
이런 구조는 서비스가 커지고 모바일이나 다른 클라이언트가 추가될수록 유지보수와 재사용이 어려워질 수 있다.
이후 REST API와 AJAX, SPA 프레임워크 등이 발전하면서 화면을 담당하는 프론트엔드와 데이터를 처리하는 백엔드를 분리하는 구조가 보편화됐다.
각 영역의 역할은 다음과 같다.
프론트엔드
-
화면 구성과 사용자 입력 처리
-
기본적인 입력값 검증
-
로딩 및 오류 상태 표시
-
백엔드 API 호출
백엔드
-
인증과 권한 확인
-
비즈니스 규칙 처리
-
입력값 재검증
-
데이터베이스 트랜잭션
-
외부 API 및 LLM 호출
데이터 저장소
-
데이터 영속성 관리
-
데이터 무결성과 제약 조건 유지
-
인덱스 및 백업 관리
프론트엔드에서 입력값을 검증하더라도 백엔드에서 다시 검증해야 한다. 클라이언트의 검증은 사용자의 편의를 위한 것이지 보안 경계가 아니기 때문이다.
또한 프론트엔드가 데이터베이스에 직접 접근하거나 중요한 가격·권한 정책을 자체적으로 결정하도록 설계해서는 안 된다.
Streamlit, React, FastAPI, n8n의 역할
수업에서는 프로젝트를 구성할 때 선택할 수 있는 기술과 각각의 장단점도 비교했다.
Streamlit과 React
Streamlit은 Python만으로 빠르게 화면을 만들 수 있어 AI 기능을 테스트하거나 내부 대시보드, 프로토타입을 제작하는 데 유용하다.
반면 복잡한 UI와 대규모 서비스의 사용자 경험을 세밀하게 구성하려면 React나 Next.js 같은 프레임워크가 더 적합할 수 있다.
FastAPI와 Go
FastAPI는 Python 기반 백엔드 프레임워크로, 데이터 검증과 API 문서 자동 생성, AI 관련 라이브러리 활용에 강점이 있다.
Go는 컴파일된 실행 파일과 고루틴을 활용해 높은 동시성을 처리하는 데 장점이 있다.
두 기술 중 어느 하나가 무조건 더 좋은 것은 아니며, 서비스의 목적과 개발 환경에 따라 선택해야 한다.
n8n의 역할
오늘 수업에서 이해해야 할 중요한 부분은 n8n을 전체 백엔드와 동일하게 생각하지 않는 것이다.
n8n은 AI 에이전트와 RAG, 외부 API 연동 등 복잡하고 변경이 잦은 자동화 흐름을 구성하는 데 유용하다.
반면 인증·인가나 핵심 비즈니스 규칙처럼 안정성과 보안이 중요한 기능은 코드 기반 백엔드에서 관리하는 것이 적절할 수 있다.
전체적인 흐름은 다음과 같이 구성할 수 있다.
Frontend
↓
FastAPI
↓
인증 / 입력 검증 / 예산 확인
↓
n8n Webhook
↓
AI Agent / LLM / RAG
↓
Backend
↓
Frontend
이 구조에서 n8n은 백엔드가 호출하는 AI 워크플로 모듈로 볼 수 있다.
LLM 비용 사전 계산 CLI 도구
마지막으로 LLM 사용 전에 비용을 예측할 수 있는 CLI 도구 과제도 다뤘다.
핵심 요구사항은 decost 명령어를 어느 디렉터리에서든 실행할 수 있도록 만들고, 실제 API를 호출하지 않은 상태에서 입력·출력 토큰과 모델별 비용을 계산하는 것이다.
비용 계산은 다음과 같은 구조다.
예상 비용 =
(입력 토큰 수 / 1,000,000 × 입력 토큰 단가)
+
(출력 토큰 수 / 1,000,000 × 출력 토큰 단가)
OpenAI 모델의 토큰 수를 추정할 때는 tiktoken을 활용할 수 있다.
다만 토큰 수는 실제 요청에 포함되는 사용자 입력, RAG 검색 결과, 도구 호출 등에 따라 달라질 수 있다. 또한 모델과 제공 업체에 따라 토큰 계산 방식이 다르므로 추정치와 실제 사용량을 구분해야 한다.
과제 설계 과정에서는 다음과 같은 문서도 언급됐다.
-
TODO.md: 해야 할 작업 정리
-
SPEC.md: 기능 요구사항과 명세
-
IMPLEMENTATION_PLAN.md: 구현 계획
비용 계산 기능 자체에서 API를 호출하지 않는다는 점도 중요한 조건이었다.
멀티에이전트 협업과 검증
수업 후반에는 여러 AI 에이전트가 역할을 나눠 작업하는 방식도 다뤘다.
하나의 에이전트가 모든 작업을 처리하는 대신 조사, 작성, 검토, 사실 확인 등의 역할을 분리할 수 있다.
예를 들어 한 에이전트가 자료를 조사하고 다른 에이전트가 초안을 작성한 뒤, 별도의 에이전트가 내용을 검토하는 구조다.
다만 서로 다른 모델이 같은 내용을 말한다고 해서 그것이 반드시 사실이라는 의미는 아니다.
AI가 생성한 결과는 원본 자료와 비교해야 하며, 최종 방향과 결과물에 대한 책임은 사람이 가져야 한다.
프롬프트와 생성 파일, 작업 시간, 검토 및 승인 기록을 남기는 것도 협업 과정을 관리하는 데 중요하다.
오늘의 회고
오늘 수업을 통해 AI 에이전트를 만드는 것과 AI 서비스를 안정적으로 운영하는 것은 별개의 문제가 아니라는 점을 확인했다.
LLM을 호출하는 기능을 구현하는 데 집중하다 보면 토큰 비용이나 서버 자원, 로그 관리, 동시 실행 제한 같은 부분을 놓치기 쉽다.
하지만 실제 서비스에서는 이런 요소들이 서로 연결되어 있다. 호출이 많아지면 비용이 증가하고, 워크플로가 동시에 실행되면 서버 자원 사용량도 늘어난다. 사용량을 기록하고 모니터링하지 않으면 비용이 증가하는 원인을 파악하기도 어렵다.
또한 프론트엔드와 백엔드, n8n의 역할을 분리하는 이유도 조금 더 명확해졌다.
n8n을 모든 기능을 담당하는 서버로 생각하기보다는, 백엔드가 호출하는 AI 자동화 모듈로 바라보면 전체 서비스 구조를 설계하기 쉬워진다.
오늘은 여러 도구와 아키텍처를 직접 비교하고 설명을 들으며 운영 관점의 기술들을 살펴본 시간이었다. 강사 시연과 과제 안내를 통해 구성 방식을 확인했지만, 실제 환경에 적용하려면 각 도구의 설정과 실행 과정을 별도로 검증할 필요가 있다.
앞으로는 AI 기능을 구현하는 것뿐 아니라 얼마나 비용이 발생하는지, 어떤 자원을 사용하는지, 문제가 생겼을 때 어떻게 격리하고 대응할 것인지까지 고려하며 개발해야겠다.
핵심 정리
-
FinOps: 클라우드와 LLM 비용을 측정하고 최적화하는 운영 방식
-
LLM 비용 최적화: 컨텍스트 축소, 모델 라우팅, 호출 횟수 감소, 사용자별 예산 관리
-
모니터링: Prometheus, InfluxDB, Grafana를 활용한 자원 및 사용량 관리
-
시스템 운영: Docker Compose, 동시 실행 제한, 로그 관리, HTTP 429
-
서비스 아키텍처: 프론트엔드, 백엔드, 데이터 저장소의 책임 분리
-
AI 오케스트레이션: FastAPI와 n8n을 조합한 AI 워크플로 구성
-
개발 도구: LLM 비용을 사전에 추정하는 decost CLI 과제와 멀티에이전트 협업