| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- 트러블슈팅
- 성능 개선
- 스프링
- 프록시 패턴
- 토스
- 스케줄러
- Spring
- java
- GoF 23
- 스프링 배치
- 코드카타
- 김영한
- 이펙티브 자바
- DB
- 추상클래스
- 디자인 패턴
- 빌더 패턴
- 템플릿 메서드 패턴
- redis
- spring boot
- Effective Java
- lv1
- Spring Batch
- 계산기
- 배치
- Til
- 로드밸런서
- 프로그래머스
- 자바
- 백엔드
- Today
- Total
김코딩
[ FINSight ] AI 요약 API 재설계를 통한 요약 비용 100배 절감 본문
들어가며
https://finsight-publish.vercel.app/
FINsight
내가 관심있어 하는 정보, 나의 자산과 직접적인 관련이 있는 금융 정보들만 놓치지 않고 따끈따끈하게 소화하고 싶지 않으신가요? FINsight와 함께라면 간단한 키워드 설정만으로 나에게 꼭 필요
finsight-publish.vercel.app
스위프 웹 11기에서 진행한 프로젝트입니다.
뉴스 기사를 한 곳에 모아서 자신이 원하는 키워드를 지정해 원하는 뉴스만 확인 할 수 있는 애플리케이션입니다.
뉴스 기사를 클릭해서 들어가보면 AI 요약본을 확인할 수 있는데, 이번에는 AI 요약 기능 API 재설계를 통해서 운영 비용을 절감시킨 이야기를 하겠습니다.
1. 문제 상황
기존의 AI 요약 API의 코드는 다음과 같이 설계되어있었습니다.
Before: AI API를 매번 호출
@Transactional(readOnly = true)
public SummarizeResponseDto summarize(SummarizeRequestDto requestDto) {
List<String> contents = articleService.findContentsByIds(requestDto.getArticleIds());
String summary = aiClient.summarize(contents);
return SummarizeResponseDto.toEntity(summary);
}
1. 사용자가 뉴스 기사를 클릭한다.
2. 뉴스 기사의 내용을 naver clova ai를 사용하여 요약한다.
3. 사용자에게 요약된 정보를 보내준다.


문제점:
1. 사용자가 기사 클릭할 때마다 AI API 호출
2. 같은 기사를 10명이 보면 10번 호출 (중복)
3. 응답 시간 느림 (2~3초)
2. 문제 분석

사용자가 기사를 클릭할때마다 clova ai를 호출하여 요약을 진행하고 있었고, 이에 따라서 비용적인 문제와 사용자 응답 속도 문제가 발생하고있었습니다.
2.1 비용 계산하기
먼저 Clova AI의 기사 1개 요청당 비용이 어느정도 발생하는지부터 확인해야했습니다.

- AI 스펙 : HCX-005 모델
- 입력 토큰 수 : 대략 1500 ~ 2000 토큰 사이(기사 내용에 따라 다름)
- 출력 토큰 수 : max 256토큰으로 지정
위의 값으로 설정을 해놓고 Naver Cloud Platform에서 비용을 계산해본 결과 건당 3원 정도의 비용이 발생하고 있었습니다.
https://www.ncloud.com/charge/calc/ko
NAVER CLOUD PLATFORM
cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification
www.ncloud.com
대다수의 분들은 "건당 3원 정도면 그냥 AI 요약을 사용해도 되는거 아닌가..?"라고 생각하실 수 있습니다.
예상 시나리오:
가정:
- 사용자 1000명
- 1인당 월 200건 조회
- 총 20만건/월
비용 계산:
- AI 요청 매번 호출: 20만건 x 3원 = 60만원/월
- 연간: 720만원
-> 같은 기사를 100명이 보면 AI를 100번 호출하고, 300원이 나갑니다.
3. 해결 과정
핵심 아이디어: 기사는 바뀌지 않으니까, 매번 새로 요약하지 말고 한번만 요약하자
-> 같은 기사를 100번 요약하는 대신, 1번만 요약하고 저장하면 된다.
그래서 저희는 AI 요약 로직을 다음과 같이 재설계를 진행하였습니다.

처리 흐름:
1. 첫 번째 사용자 : AI로 요약 -> DB와 캐시에 저장
2. 두 번째 사용자부터 : 캐시에서 바로 반환 (캐시 히트)
3. 캐시에 없으면: DB 조회 후 캐시에 저장 (캐시 미스 - 서버 재시작 후)
@Transactional
public SummarizeResponseDto summarize(SummarizeSingleRequestDto requestDto) {
Long id = requestDto.getArticleId();
Optional<AIArticle> cacheAiArticleOpt = aiCache.findArticleById(id);
if ( cacheAiArticleOpt.isPresent() ){
return SummarizeResponseDto.toEntity(cacheAiArticleOpt.get().getSummary());
}
Optional<AIArticle> dbAiArticleOpt = aiArticleRepository.findById(id);
if ( dbAiArticleOpt.isPresent() ){
aiCache.put(id, dbAiArticleOpt.get());
return SummarizeResponseDto.toEntity(dbAiArticleOpt.get().getSummary());
}
List<String> contents = articleService.findContentsByIds(List.of(id));
Optional<String> contentOpt = contents.stream().findFirst();
String content = contentOpt.orElseThrow(()->new ArticleException(ArticleErrorCode.ARTICLE_NOT_FOUND));
String summary = aiClient.summarize(content);
Article article = articleService.findArticleById(id);
AIArticle aiArticle = new AIArticle(article, summary);
aiCache.put(id, aiArticle);
aiArticleRepository.save(aiArticle);
return SummarizeResponseDto.toEntity(summary);
}

4. 성과
예상 시나리오:
가정:
- 사용자 1000명
- 1인당 월 200건 조회
- 총 20만건/월
비용 계산:
- 실제 AI 호출: 2천건
- 비용: 2천건 x 3원 = 6천원/월
- 연간: 7.2만원
비교 표
| 비용 개선(1000명의 사용자가 월 200건 조회) | |||
| 비교 항목 | Before (기존 방식) | After (재설계) | 개선 효과 |
| 월 요청 수 | 20만건 | 2천건 | -99% 감소 |
| AI 호출 비용(월) | 60만원 | 6천원 | 약 100배 절감 |
| AI 호출 비용(연) | 720만원 | 7.2만원 | 약 100배 절감 |
| 중복 호출 | 동일 기사 100명 → 100회 | 동일 기사 → 1회만 | 중복 제거 |
| 응답 속도 | 2~3초 | 캐시 히트 시 거의 즉시 | 사용자 경험 개선 |
| 응답 속도 개선(캐싱 적용 전 후) | |||
| 비교 항목 | Before (기존 방식) | After (재설계) | 개선 효과 |
| 응답 속도 | 2.86초 | 19ms | 약 99.3% 감소 |
5. 마치며
이 개선의 핵심 이번 개선 작업의 본질은 "캐싱 기술을 적용한 것"이 아닙니다.
핵심은 "불필요한 중복 작업을 제거한 것"입니다.
- 캐시가 중요했던 게 아니라
- 중복 요약을 방지하는 것이 중요했습니다
캐시는 그저 수단일 뿐, 목적은 비용 절감이었습니다.
가장 중요했던 질문 > "기사는 바뀌지 않는데, 왜 매번 새로 요약하지?"
이 질문 하나가 연간 712만원을 절약했습니다.
'개발팁' 카테고리의 다른 글
| [ FINSight ] 단일 서버 환경에서 JWT 대신 Session을 선택한 이유 (0) | 2025.12.01 |
|---|---|
| [ 내돈 네돈 챌린지 ] 외부 API 장애 전파 방지: Circuit Breaker & Retry 패턴 (0) | 2025.11.28 |
| [ 내돈 네돈 챌린지 ] 결제 시스템 데이터 정합성 보장: Saga 패턴 구현기 (0) | 2025.11.27 |
| [ 내돈 네돈 챌린지 ] 결제 API 성능 개선기: 트랜잭션 경계 재설계로 DB 커넥션 점유 시간 96% 단축 (0) | 2025.11.27 |
| 인덱스(Index)란 무엇인가? (0) | 2025.11.25 |