Community

개발자 99% 커뮤니티에서 수다 떨어요!

← Go back

FinLit - 정답보다 “읽는 힘”을 길러주는 금융문해력 학습 에이전트

#side-projects
5일 전
103
4

안녕하세요, AI엔지니어 2기 진행하고 있는 Ethan_Lee 입니다.

최종 배포 URL : https://finlit-learn-finance.vercel.app

프로젝트 설명

FinLit Education Agent는 사회초년생이 뉴스, 기업공시, 재무제표 같은 실제 금융 자료를 스스로 읽고 이해할 수 있도록 돕는 금융문해력 학습 에이전트입니다. 이 프로젝트는 투자 종목을 추천하거나 공시를 단순 요약하는 서비스가 아닙니다. 사용자가 “이 공시가 무슨 뜻이지?”, “이 숫자를 어떻게 봐야 하지?”, “이 용어는 왜 중요한 거지?”라고 느끼는 순간에, 실제 자료를 학습 세션으로 바꾸고, 핵심 용어와 확인 문제, 복습 흐름까지 연결해 주는 교육용 에이전트를 목표로 만들었습니다. 이번 프로젝트에서 가장 중요하게 생각한 방향은 “답을 대신 내려주는 AI”가 아니라, 사용자가 문서를 읽는 힘을 기를 수 있도록 돕는 AI 학습 코치였습니다.

처음에는 “공시를 쉽게 설명해주는 서비스”처럼 보일 수 있었지만, 만들면서 방향을 다시 정리했습니다. FinLit의 핵심은 공시 자체가 아닙니다.공시는 여러 학습 모듈 중 하나입니다.

FinLit이 해결하고 싶은 문제는 더 넓습니다.경제뉴스를 봐도 어렵고,재무제표 숫자를 봐도 의미를 모르겠고,기업공시를 봐도 어디부터 읽어야 할지 모르는 사람에게 자료를 읽는 순서”와 “이해하는 방법”을 알려주는 것입니다. 그래서 FinLit은 투자 추천 서비스가 아니라, 뉴스·숫자·기업을 읽는 힘을 길러주는 금융문해력 학습 에이전트를 목표로 하고 있습니다.

예상 사용 시나리오

  1. 사업보고서가 어떤 문서인지 설명

  2. 처음 읽을 때 봐야 할 핵심 항목 안내

  3. 어려운 용어 정리

  4. 핵심 질문 제시

  5. 짧은 퀴즈 제공

  6. 학습기록 저장

  7. 나중에 다시 볼 복습 포인트 생성

핵심 기능 설명 & 현재 구현 방향

현재는 FastAPI 백엔드와 LangGraph 기반 학습 그래프를 중심으로 구현하고 있습니다.

프론트엔드는 사용자의 입력과 학습 화면을 담당하고, 백엔드에서는 Meta Agent가 요청을 분류한 뒤
Disclosure Lesson Graph, News Learning Graph, Financial Statement Graph, Review Plan Graph 같은 하위 그래프로 연결하는 구조를 지향하고 있습니다. 또한 Litty라는 학습 코치 캐릭터를 통해 에이전트가 지금 사용자의 요청을 분석 중인지, 자료를 찾는 중인지, 학습 세션을 만드는 중인지 보여주는 UI도 함께 실험하고 있습니다.

1. 실제 OpenDART 공시 기반 학습 세션 생성

사용자가 “삼성전자 사업보고서”처럼 입력하면 백엔드가 OpenDART 공시 후보를 검색하고, 실제 접수번호, 공시일, 원문 링크를 포함한 학습 자료 후보를 보여줍니다. 단순히 예시 데이터를 보여주는 것이 아니라, 실제 공시 문서를 바탕으로 학습 세션을 만들 수 있도록 구성했습니다. 현재는 사업보고서, 공급계약 공시, 유상증자 공시, 자기주식 관련 공시 등 주요 공시 유형을 읽는 흐름을 만들었습니다.

2. 공시 유형별 핵심 항목 파싱

공시마다 읽어야 할 포인트가 다르기 때문에, 문서 유형별로 다른 파싱 로직을 적용했습니다.

사업보고서는 회사 개요, 사업 부문, 주요 제품, 시장 지위 같은 항목을 읽고, 공급계약 공시는 계약 상대방, 계약 금액, 계약 기간, 매출 대비 비중을 확인합니다. 유상증자는 발행 방식, 신주 수, 발행가액, 자금조달 목적, 희석 가능성을 읽고, 자기주식 공시는 취득/처분 목적, 수량, 금액, 기간, 방법을 확인하도록 구성했습니다.이를 통해 사용자가 공시를 “뉴스처럼 훑는 것”이 아니라, 문서 구조에 맞게 차근히 읽는 연습을 할 수 있도록 했습니다.

3. 학습 흐름: 레슨 → 핵심 개념 → 퀴즈 → 기록 → 복습

FinLit은 한 번 읽고 끝나는 구조가 아니라, 학습이 이어지도록 설계했습니다.학습 세션에서는 문서 유형 확인, 핵심 항목 읽기, 숫자와 조건 보기, 확인 문제, 한 줄 복습으로 이어집니다. 학습 중 만난 개념은 단어장과 연결되고, 완료한 학습은 학습기록과 복습 계획으로 이어지도록 구성했습니다.학습자가 “오늘 무엇을 읽었고, 어떤 개념을 만났고, 다음에 무엇을 다시 봐야 하는지”를 남기는 것이 핵심입니다.

4. Litty 학습 코치 UI

FinLit에는 Litty라는 작은 학습 코치 캐릭터를 넣었습니다.Litty는 단순한 장식 캐릭터가 아니라, 사용자가 지금 학습을 시작할 수 있는지, 자료를 불러오는 중인지, 복습할 내용이 있는지 같은 상태를 알려주는 Ambient Learning Dock 역할을 합니다.학습 앱이 너무 딱딱해지지 않도록 하면서도, 금융 학습 서비스답게 차분하고 신뢰감 있는 톤을 유지하려고 했습니다.

5. 프론트엔드와 백엔드 분리 배포

프론트엔드는 Vercel에 배포했고, 백엔드는 Render에 배포했습니다.프론트에서는 사용자가 학습을 시작하고 세션을 진행하며, 백엔드에서는 OpenDART API, OpenAI API, 문서 파싱 로직, 레슨 생성 로직을 처리합니다. 민감한 API 키는 프론트에 넣지 않고 백엔드 환경변수로 분리했습니다.

배포 과정에서 Vercel 환경변수, Supabase Auth, TanStack/Nitro 설정, Render 배포 설정까지 직접 다루면서 로컬에서만 동작하는 앱을 실제 URL이 있는 프로젝트로 만드는 경험을 했습니다.

관련 스크린샷

개발 기술/스택

Frontend

  • React

  • Vite

  • TanStack Start

  • TypeScript

  • Tailwind CSS

  • shadcn 스타일 UI 구성

  • Vercel 배포

  • Supabase Auth 연동

  • Litty Ambient Learning Dock UI

Backend

  • FastAPI

  • Python

  • OpenDART API 연동

  • OpenAI API 기반 학습 생성

  • 공시 문서 XML/ZIP 파싱

  • 문서 유형별 파서

    • 사업보고서

    • 공급계약

    • 유상증자

    • 자기주식

  • Render 배포

  • 환경변수 기반 보안 설정

Infra / Deployment

  • Vercel

  • Render

  • Supabase

  • GitHub

엔지니어 클럽을 진행하며 느낀 점

이번 프로젝트를 하면서 가장 크게 느낀 점은 “아이디어를 앱처럼 보이게 만드는 것”과 “실제로 동작하고 배포되는 제품으로 만드는 것” 사이에는 꽤 큰 차이가 있다는 것이었습니다. 처음에는 금융문해력 학습 앱이라는 컨셉과 화면 흐름을 만드는 데 집중했습니다. 그런데 실제로 OpenDART 공시를 불러오고, 공시 원문을 파싱하고, 학습 세션으로 바꾸고, 프론트와 백엔드를 분리해서 배포하기 시작하니 훨씬 많은 문제가 보였습니다. 특히 배포 과정에서 많이 배웠습니다. 로컬에서는 잘 되던 것이 Vercel에서는 환경변수 문제로 다르게 보였고, TanStack Start 프로젝트는 일반 Vite 정적 배포처럼 처리하면 404가 났습니다. 결국 Nitro Vercel preset, Render 백엔드 설정, CORS, Supabase Auth 환경변수까지 하나씩 확인하면서 해결했습니다. 뭐든지 처음 하는 일들은 어렵고 고통스럽지만 하고 나면 재미있는 것 같습니다. 어제는 배포 했는데.. 분명히 배포를 했는데.. 예전버전이 올라가 있어서.. 그거 해결한다고 새벽이 되어버렸네요.. ㅠㅠ..

아침에 보니까, 못난 자식 아쉬운점이 많이 보이네요 ㅎㅎ

  • 웹화면에 최적화 되어 있습니다. 폰으로는 무리에요! :)

  • 전자공시시스템의 api를 사용하고 있는데, 체감상 로컬에서 했을 때보다,
    배포하고 나니까 엄청 체감상 느리긴 하네요.. "삼성전자 사업보고서" 치고 기다리시면,
    세월아 네월아 하지만 언젠간 선택할 수 있고 그걸 기반으로 학습을 만들수 있...긴합니다.

AI엔지니어 2기분들 모두들 고생하셨습니다!!!

4 comments