[25-겨울 이화캡스톤] EASY-STOCK 개발 핀포인트 회고

Sujung Shin·2025년 1월 15일
0
post-thumbnail

📍 RAG(Retrieval Augumented Generation) 도입기


EASY-STOCK의 도우미 챗봇 '스토기'는 사전학습(Pretrained) 모델인 GPT-4-Turbo 가 주식 데이터를 반환하지 않음에 따라, 외부 지식 베이스에서 사실을 검색하여 정확하고 최신의 정보에 근거하는 AI 프레임워크인 RAG를 도입하였다.

쉽게 말해, RAG는 LLM이 생성을 할 때, 올바르고 최신의 정보를 사용하도록 도와주는 도구이다.


⌨️ RAG 작동 방식


1. 데이터 검색(Retrieval)

  • Yahoo Finance API를 연동해서, 우리 EASY-STOCK에서 제공하는 국내 주요 5개의 Ticker들에 대한 2년 간의 일별 주식 동향 데이터베이스를 구축한다.
  • 1일 단위로 업데이트 되는 데이터이므로, SQLite를 채택한다.

2. 데이터 보강(Augumentation)

  • 유저의 질문에 적합한 데이터를 SQLite에서 검색하여 LLM으로 전달한다.
  • 검색된 데이터는 JSON 형식으로 변환되어, LLM의 프롬포트에 포함된다. 즉, 해당 LLM 모델이 최신 정보 기반의 응답을 반영할 수 있게 한다.

3. 응답 생성(Generation)

  • 응답을 생성한 후, FastAPI로 유저에게 응답을 반환한다.

'챗봇 스토기'는 EASY-STOCK의 인앱형 서비스 이기 때문에,
다른 비즈니스 로직과 독립적인 모듈화 방식이 필요하다고 생각했다.
따라서, FastAPI로 유저와 통신하는 방식을 채택한다.




📍 모의 투자 시스템 구축


챗봇 시스템인 스토기를 RAG로 구축하고 나서, 다음 나의 개발 관련 고민 이슈는 바로 모의 투자 시스템 구축이었다.

왜냐하면 '주가'는 실시간성이 있는 데이터이고, 그 중에서도 우리 EASY-STOCK에서 매도/매수는 매우 코어한 로직이기 때문이다.

따라서 어떻게 처리를 할까 생각하다가, 2가지 방식을 고민해보았다.


1. FastAPI + Spring Boot (분리형)

  • FastAPI: 실시간 주가 정보 조회를 Redis와 통합하여 처리한다.
  • Spring Boot: 매수/매도와 같은 EASY-STOCK의 핵심 비즈니스 로직을 처리하며, RDBMS(Mysql)과 통합한다.

요청 흐름
1. 유저가 매수/매도 요청을 전송한다.
2. Spring Boot 서버가 요청을 받아,

  • FastAPI에서 실시간 주가를 조회한다.
{
  "종목": "삼성전자",
  "주량": 10,
  "주가": 71500
}
  • 잔액 및 보유 주식을 검증한다.
  • 거래 내역을 저장한다.
  1. 거래 결과를 클라이언트한테 전달한다.

해당 다이어그램의 장점은 '실시간 주가 정보 제공' 이라는 서버 자체를 완전히 모듈화하여 분리할 수 있다는 점이다.

'매수/매도' 같은 경우에는 가상토큰인 STOKEN을 소모한다는 점에서 EASY-STOCK의 코어한 비즈니스 로직이기 때문에, 이렇게 설계하는 것이 EASY-STOCK의 요구사항 및 SRP 원칙에도 부합한다.

즉 객체지향적으로 재사용성이 매우 높은 설계방식이다.
나중에 서비스가 확대되면 조회의 MQ(Messaging Queue)와 같은 스트림 처리를 고려해볼 수도 있다.

단점은 2개의 프레임워크라는 점에서 러닝 커브가 있다는 점과 두 프레임워크를 각각 배포해야 한다는 점, 네트워크 오버헤드의 비용이 증가할 수 있다는 아주 치명적인단점이 있다.

사용자가 매수/매도 요청을 하면 매수/매도에 관한 비즈니스 로직을 Spring Boot에서 처리한다.


2. Spring Boot 단독형

해당 다이어그램의 장점은 역시나 단순화된 아키텍처 구조이다.

단일 프레임워크로 모든 요구사항들을 처리함으로써, 관리와 배포가 간단하므로 현재의 개발 단계에 적합하다고 볼 수 있다.
개발 효율성을 증진해야 하는 초기 개발 단계에 적합한 구조라고 볼 수 있다.



🤔 결론


개발 초기 단계인 우리 팀은 회의에서 더 논의해보아야겠지만, 아마 2. Spring Boot 단독형 으로 가야하지 않을까 싶다.
아무래도 개발 초기 단계에서는 현실적으로 이후에 스케일업/스케일아웃하더라도 인프라 비용을 최소화하는 것이 옳은 방향이라고 생각된다.

1. FastAPI + Spring Boot 혼합형 은 실시간 주가 정보 조회 트랜잭션을 아주 잘 처리할 수 있지만, 그건 어디까지나 개발 이후의 운영 단계에서 고려해보아야 할 상황인 것 같다.

개발을 하면서 항상 느끼는 거지만, 어떤 방식이든 비용과 성능의 트레이드오프가 존재하는 것 같다.

구현은 어떤 방식으로든 하게 되어있는데,
이를 잘 조율하고 생각해보는 것이 정말 어려운 것 같다.




📍 사용자 매월 투자 리포트


EASY-STOCK의 핵심 기능인 '매월 투자 리포트' 분석 기능은,
사용자가 한 달 동안 투자한 주식 내역에 기반하여 데이터를 분석하고, 다양한 시각화 차트, 투자 유형 등으로 제공한다.

이걸 보자마자 다들 드는 생각이 있을 것이다.

데이터 분석에 특화된 Python의 라이브러리를 이용하고 싶다😊🧡

마침, 스토기의 SQLite 데이터베이스에는 ticker들의 2년 간의 일별 주식 정보가 들어가있다.

그리고, 아까처럼 인프라 비용에 대한 걱정을 크게 하지 않아도 될거라고 판단한 이유는 '매월' 이라는 정기 트리거 주기가 정해져 있기 때문에, 실시간 스트리밍을 해야 하는 주가 정보 조회와는 사뭇 다른 상황이라고 생각했다.

요청 흐름
1. Spring Boot 서버는 사용자의 월간 투자 내역 정보를 RDBMS에서 조회하여 가져온다.
2. Spring Boot 서버가 챗봇 스토기의 FastAPI 서버로 넘겨준다.
3. 챗봇 스토기의 FastAPI 서버에서 Spring Boot로부터 받아온 데이터를 SQLite 데이터베이스를 활용하여 분석한다.
4. 챗봇 스토기의 FastAPI 서버는 전체 주식 흐름도 - 나의 투자 정보 흐름도를 NumPy Pandas 라이브러리를 이용하여 분하여 월별 투자 결과 요약 및 통계정보를 생성한다.
5. 분석된 데이터를 Spring Boot로 변환하여 클라이언트에게 전달한다.

{
  "month": "2025-01",
  "total_investment": 5000000,
  "total_profit": 200000,
  "top_gainers": ["삼성전자", "카카오"],
  "top_losers": ["네이버"]
}
profile
백문이불여일타

0개의 댓글

관련 채용 정보