통신사 부가서비스 조회
아이디어
이 아이디어는 “내 보험 찾아줌”을 사용하다가 문득 떠올랐습니다. 주민등록번호, 핸드폰 번호, 이름만 입력하면 내가 가입한 보험 상품들을 한눈에 조회할 수 있는 서비스인데, 이와 비슷하게 내가 가입한 통신사 부가서비스들도 한눈에 조회할 수 있으면 좋겠다는 생각이 들었습니다. 예를 들어, 내가 SKT를 사용하고 있는데, 내가 가입한 부가서비스가 무엇이 있는지 모르겠다면, 웹 상에서 “이름”, “휴대폰 번호”만 입력하면 내가 가입한 SKT 부가서비스들을 한눈에 조회할 수 있는 서비스를 구현하고 싶었습니다.
물론, T-world를 접속해서 내가 가입하고 있는 서비스를 조회할 수 있습니다. 저도 그렇게 하고 있고요;; 하지만, T-world에 접속하는 것보다 더 간편하게 부가서비스를 조회할 수 있으면 좋겠다는 생각이 들었습니다. “이름”, “휴대폰 번호”로만 조회가 가능한지 찾아보니 불가능하다고 합니다. 본인 인증 절차가 반드시 필요해서, 대한민국 통신 마이데이터 표준 API를 확인했고, API코드 별로 통신사 부가서비스 조회 API가 존재합니다. 이를 활용하면, 사용자가 휴대폰 번호로 인증을 하면 해당 번호의 통신사 부가서비스를 조회해주는 서비스를 개발할 수 있을 것 같습니다.
조회만 해서 뿌려주는 서비스가 끝이냐? 이렇게 만들면 조금 아쉬울 것 같아서, RAG + 챗 봇 기능을 붙여서, 내가 가입한 부가서비스를 바탕으로 궁금한 점을 물어보면 답변해주는 기능도 추가하거나, 요금제도 조회해서 추천해주는 기능까지 만들면 제법 쓸만한 서비스가 될 것 같습니다.
3대 통신사마다 부가서비스가 다르므로, SKT, KT, LG U+ 각각의 API를 연동해야 하는 번거로움이 있을 것이고, 부가서비스에 대한 RAG 기능을 구현하려면, 부가서비스에 대한 데이터 수집과 전처리가 필요할 것입니다.
만약, 사용자가 몰려서 트래픽이 급증할 경우를 대비해서, 서버리스 아키텍처로 구현하는 것도 고려해봐야겠습니다. AWS Lambda나 GCP Cloud Functions 같은 서버리스 플랫폼을 활용하면, 트래픽에 따라 자동으로 확장되므로, 안정적인 서비스를 제공할 수 있을 것입니다.
우선, 대한민국 통신 마이데이터 표준 API를 활용해서 휴대폰 번호로 본인 인증을 하고, 해당 번호의 통신사 부가서비스를 조회하는 기능부터 구현해봐야겠습니다. 만약 이게 잘 된다면, 그 다음에 해지 기능과 상세 설명 제공 기능도 추가해보겠습니다.
초기 개발 계획
서론이 좀 길어졌지만 요약하자면, “휴대폰 번호로 본인 인증을 하고, 해당 번호의 통신사 부가서비스를 조회 및 추천해주는 서비스” 를 개발하는 것을 목표로 합니다.
| Category | Tech | 선택 이유 |
|---|---|---|
| Languages | TypeScript & Python | Web/API 전 구간의 타입 안정성을 위한 TypeScript, LangGraph 기반 복잡한 AI 오케스트레이션을 위한 Python. |
| Frontend | Next.js 15+ (App Router) | 정적 통신 요금제 페이지에 Server Actions와 ISR을 적용해 최고 수준의 성능 확보. |
| Backend & Auth | Supabase | Postgres, Auth, RLS를 통합 제공하는 BaaS로 민감한 MyData 기록을 제로 설정으로 보호. |
| Vector Database | pgvector (Supabase) | 기존 Postgres 내에서 900+ 서비스 RAG를 가능하게 해 별도 벡터 DB가 불필요. |
| AI Orchestration | LangGraph | 상태 기반 다단계 추론으로 사용 로그 분석 및 수백 조합의 “낭비 지수” 계산. |
| LLM & SDK | sLLM / GPT-4o mini | sLLM 구축 & Vercel AI SDK의 모델 라우팅으로 GPT-4o mini로 보내 추가 작업 |
| Infrastructure | Vercel (Edge Functions) | 200–500ms 수준의 거의 없는 콜드스타트로 전 세계 서버리스 실행, 트래픽 스파이크에 높은 확장성 확보. |
| Caching & Scaling | Upstash (Redis) | 글로벌 레이트 리밋과 프롬프트 캐싱으로 LLM 비용 폭증 방지. |
| AI Observability | Langfuse | 사용자별 LLM 비용 추적, 에이전트 결정 단계 트레이싱, 추천 이유 디버깅에 필수. |
| System Monitoring | Sentry | 서버리스 함수와 프론트엔드 크래시 자동 오류 추적으로 솔로 운영의 가용성 확보. |
| Development Method | GitHub Spec Kit | Spec-Driven Development로 아키텍처로 개발 목적 및 일관성 유지 |
| Data & Simulation | Mockoon & SmartChoice API | Mockoon으로 2026 마이데이터 표준 API(통신-001/003) 모의, 스마트초이스 API로 실시간 요금제 데이터 제공. |
아키텍처 다이어그램

<아래 작성된 글은 AI의 도움을 받아 작성되었습니다.>
부가서비스닥터(Add-on Doctor) v1 아키텍처 개요
- 개인 정보 보안: 마이데이터 원본은 제한된 저장소에만 두고, LLM/RAG 레이어로는 비식별·요약 데이터만 전달한다.
- sLLM 우선, 클라우드 LLM 보조: 주 추론은 자체 호스팅 sLLM이 처리하고, 복잡한 요청만 상용 LLM으로 폴백한다. (안 그러면 비용 감당을 하지 못할 듯 -> 실제 서비스에는 이 기능을 막아두거나, 사용자에게 요금을 청구하는 방법을 고려)
- 운영 효율성: 운영 복잡도를 최소화하기 위해 S3 + 로컬 벡터 스토어(Chroma) + 서버리스 프론트엔드를 사용한다.
Front End: Vercel + Next.js + Redis
- 프론트엔드는 Next.js(App Router) 를 Vercel로 배포
기능:
- 사용자 입력 수집: 통신사 선택, 부가서비스 목록 확인 요청, 분석 실행 버튼 등
- API Routes / Server Actions:
- 통신 마이데이터 API 호출 트리거
- 스마트초이스 API 호출 트리거
- LangGraph 분석 API 호출 (
/api/analyze_addons)
여기서는 로그인 기능을 사용하지 않는다.
요청마다 session_id를 생성해 이 세션에 대한 분석을 한 번 수행하고, 결과를 바로 보여주는 단발성 구조다.
화면은 우리가 흔히 사용하는 간편 인증으로 구현해서 사용자의 통신사에 따른 데이터를 가져와 뿌려준 뒤에, 사용자가 분석 버튼을 누르거나 챗 봇을 클릭하면 그 때만 부가적인 기능들을 수행하도록 한다.
Upstash Redis (Rate Limit & Prompt Cache)
- Edge에서 가까운 서버리스 Redis로, 두 가지 용도로 사용한다.
- Rate Limit: IP 또는
session_id기준으로 분석 요청 횟수를 제한해 LLM 비용 폭주를 방지한다. - Prompt Cache:
- 동일한 부가서비스 조합과 요금제에 대한 재분석 요청이 들어온 경우, LLM을 다시 부르지 않고 캐시된 결과를 바로 반환한다.
- Rate Limit: IP 또는
Storage & Metadata: AWS S3
S3는 서비스의 “원본 데이터 저장소” 역할을 한다.
- 저장할 데이터:
- 통신 3사의 부가서비스 설명/요금제 안내서/정책 문서 (HTML, Markdown, JSON 등)
- 부가서비스 마스터 테이블(서비스명, 카테고리, 월 요금, 통신사 등)
- 모델 관련 리소스(예: 프롬프트 템플릿, 도메인 규칙 정의)
- 분석 리포트 스냅샷(선택:
reports/{session_id}.json형식)
이 정도까지 저장할 가치가 있는지는 개발을 하면서 판단해야할 것 같다.
External Services: 마이데이터 API + 스마트초이스 API
통신 마이데이터 API
- 사용자 동의를 전제로, 통신‑001/003 등 마이데이터 표준 API를 통해:
- 가입 정보(통신사, 요금제명, 약정/결합상품 등)
- 청구 내역(월별 부가서비스 청구 항목/금액)를 가져온다.
- 이 데이터는 S3/내부 스토리지에 session_id 기준으로만 저장되고, LLM 쪽에는 비식별 요약만 전달한다.
스마트초이스 API
- 한국통신사업자연합회(KTOA)가 운영하는 요금제·부가서비스 추천 open API를 사용한다.
- 역할:
- 현재 가입 요금제와 사용 패턴을 기반으로, 공공 포털 기준 “요금제 추천 결과”를 받아온다.
- sLLM가 만든 추천과 교차 검증하거나, 대체 요금제 후보 목록을 보강하는 데 사용된다.
AI Orchestration & Observability: LangGraph + Chroma + Langfuse
LangGraph Orchestrator
LangGraph는 Python 기반 에이전트/워크플로우 오케스트레이션 레이어로 사용한다.
- Next.js가
/api/analyze_addons로 요청을 보내면, LangGraph에 다음 정보를 전달한다. [session_id, 요약된 가입 정보/청구 내역] - LangGraph는 세 단계로 분석한다.
- 전처리 & 비식별화
- 통신‑001/003 원본에서 필요한 필드만 추출해 요약 구조로 만든다.
예:{carrier, plan_name, addon_list[], monthly_addon_total} - 이름/전화번호/주민번호 등 식별자는 LLM/RAG 입력에서 제거한다.
- 통신‑001/003 원본에서 필요한 필드만 추출해 요약 구조로 만든다.
- RAG + 규칙 기반 판단
- Chroma에 질의해 부가서비스 설명/정책/대체 옵션을 가져온다.
- 요금제 기본 혜택 vs 유료 부가서비스 중복 여부, 단순한 규칙 기반 체크를 병행한다.
- LLM 호출
- sLLM에 컨텍스트를 주고 “해지/유지/조건부 유지 + 이유 + 예상 절감액”을 생성하게 한다.
- 필요 시 클라우드 LLM으로 폴백해 자연어 리포트를 더 매끄럽게 다듬는다.
- 전처리 & 비식별화
Chroma (Local RAG Index)
- RAG 인덱스는 Chroma를 사용해 LangGraph 프로세스 옆에 붙인다.
- 초기화 시:
- S3에서 통신 3사 부가서비스 문서를 로드.
- 임베딩을 생성해 Chroma 컬렉션에 upsert.
- 질의 시:
- “스마트 콜키퍼”, “V 컬러링”, “PASS 전월세 안심케어” 등 해당 서비스명/키워드를 기준으로 top-k 문서를 검색해 LLM 컨텍스트로 사용한다.
Langfuse (LLM Trace & Costs)
- 모든 LLM 호출/체인 스텝은 Langfuse에 기록한다.
session_id또는 비식별user_id기준으로 Trace를 묶고,- 토큰 사용량·비용·지연 시간 등을 모니터링한다.
- 이 정보는:
- 비용 폭주 감지,
- 프롬프트/체인 튜닝,
- “왜 이런 추천이 나왔는지” 설명(디버깅/설명 가능성)에 활용한다.
LLM Layer: sLLM + Vercel AI SDK
Local sLLM
- 주 추론 엔진은 자체 호스팅 sLLM이다.
- vLLM/Ollama 등으로 서빙되는 한국어 친화 모델(예: K-EXAONE 계열, A.X 계열, Solar 등)을 사용할 수 있다.
- 역할:
- 부가서비스 목록/요금제/SmartChoice 결과/Chroma 컨텍스트를 받아:
- “해지/유지/조건부 유지” 분류,
- 항목별 설명,
- 간단한 요약 리포트 를 생성.
- 부가서비스 목록/요금제/SmartChoice 결과/Chroma 컨텍스트를 받아:
Vercel AI SDK + GPT‑4o mini (Fallback)
- 더 복잡한 자연어 리포트나, sLLM이 자신 없는 케이스에만 Vercel AI SDK를 통해 GPT‑4o mini / Claude 등 상용 LLM을 호출한다.
- LangGraph에서 폴백 조건을 정의:
- 리포트 길이가 길어야 하는 경우,
- 다국어 설명 필요,
- 내부 평가 스코어가 낮은 경우 등.
Observability & Error Tracking: Sentry
- Next.js/Vercel, LangGraph, sLLM 게이트웨이에서 발생하는 에러와 경고는 모두 Sentry로 전송한다.
- 주요 목적:
- 외부 API 실패 (MyData/SmartChoice),
- LLM 호출 예외,
- 성능 저하/타임아웃,
- 프론트엔드 런타임 에러 모니터링
개인 정보 보안
- 마이데이터 원본(통신‑001/003 JSON), 이름/전화번호 등은 S3/내부 스토리지에만 저장되고, LLM/RAG 레이어로는 구조화된 요약 데이터만 전달한다.
- 세션 식별은
session_id로 하고, 일정 기간이 지나면 MyData 스냅샷과 리포트를 삭제하는 TTL 정책을 둘 수 있다. - Langfuse/Sentry에는 비식별 ID와 메타데이터만 남기고, 민감한 원문은 남기지 않는다.
마치며
추가적으로 생각난 로직:
- API호출 제한으로 인해 : API 호출 로그를 보여주는 기능(화면에 뿌려준다)
이거 말고는 이 글을 작성하는 시점에 생각나는 추가 구현 아이디어는 없네요. 구현하면서, 생각나면 그때 추가하도록 하겠습니다.
댓글