ZANI

Fullstack

학생 집중도를 실시간으로 분석하고 맞춤 리포트를 제공하는 AI 강의 플랫폼

2026.07 ~ 2026.08Fullstack Developer · Frontend / AI5인 팀

SSAFY 우수상(1등)

실시간 음성 전사와 다중 강의 RAG를 설계하고, 리포트 API·플레이어와 프론트엔드를 구현했습니다.

대외비 정책에 따라 저장소와 상세 코드는 공개하지 않습니다.

ZANI 서비스 화면

핵심 성과

근거 Recall합성 평가 · 기존 85.2%
93.7%
목록 페이지 LCP썸네일 최적화 · 기존 3.5초
1.4초
커밋 규칙 준수율1,300개 중 규칙 위반 5건
99.62%

시스템 아키텍처

실시간 강의 · 코칭 · 다중 강의 RAG

미디어는 LiveKit, 업무 API와 코칭은 Spring, 강의 검색·답변 검증은 LangGraph가 담당합니다.

ZANI 전체 시스템 아키텍처

ZANI 전체 시스템 아키텍처Next.js 브라우저는 Spring Boot와 REST API 및 STOMP WebSocket으로 업무 이벤트를 주고받고, LiveKit과 WebRTC로 음성·영상을 직접 주고받습니다. Spring은 LiveKit 토큰과 참가자 제어를 관리하며 Egress WebSocket의 강사 PCM 음성을 링버퍼에 수집합니다. Spring은 MySQL에 강의·전사·리포트를, Redis에 참여 상태·세션·빈도 제한 정보를 관리합니다. 실시간 코칭과 사후 전사는 GMS Whisper 및 LLM을 호출합니다. Python LangGraph에는 권한을 검사한 현재 강의와 다른 강의 최대 4개의 원문을 전달하며, LangGraph가 근거를 검색·선별하고 GMS LLM으로 답변 생성과 검증을 수행합니다. LiveKit Egress 원본 트랙과 Spring의 FFmpeg 영상 합성 결과는 로컬 파일 저장소에 보관하고, Spring이 권한을 검사해 영상과 썸네일을 제공합니다.CLIENTAPPLICATIONMEDIADATAAI GATEWAYLOCAL STORAGEWebRTC · 음성·영상REST · STOMP토큰 · 제어PCM · WS내부 HTTP조회 · 저장상태 · 세션전사 · 코칭생성 · 검증트랙 녹화FFmpeg · 영상 서빙Next.js강의 · 리포트 · 챗봇 UI브라우저 참여도 추론Spring Boot인증 · 강의 · 리포트 API참여 상태 집계 · 코칭 트리거오디오 링버퍼 · 사후 전사영상 처리 · 접근 권한 검사LiveKitWebRTC 미디어 서버Egress · 음성 수집·녹화MySQL강의 · 전사 · 리포트Redis참여 상태 · 세션 관리코칭 트리거 · 요청 빈도 제한Python · LangGraph목차·BM25 원문 검색LLM Wiki · 지식 그래프GMSWhisper · STTLLM · 코칭·답변·검증로컬 파일녹화 · 합성 영상 · 썸네일
주요 연결을 표시했습니다. 미디어는 브라우저와 LiveKit 사이에서 전송하며, 녹화·합성 영상은 로컬 파일로 저장합니다. Spring이 접근 권한을 검사한 강의 원문을 LangGraph에 전달합니다.

프로젝트 개요

목표

  • 실시간 수업 참여도를 파악하는 학습 환경 구현
  • 강의 음성·전사 데이터를 활용한 놓친 내용 복습 지원
  • 현재·이전 강의에 대한 검색·질의응답 지원

배경

  • 긴 온라인 강의에서 놓친 구간을 찾고 이전 강의와 연결하는 데 어려움 발생
  • 현재 강의 전체 전사 입력으로 질문과 무관한 내용까지 LLM에 전달
  • 다른 강의의 근거를 찾고 필요한 원문을 선별하는 검색 라우팅 필요

주요 기능

  • 브라우저 참여도 분석과 학생 응답을 집계해 강사에게 실시간 코칭 제공
  • 녹화·전사·참여도를 연결한 리포트와 복습 클립·퀴즈 제공
  • 다중 강의 검색·비교와 실제 전사 인용, 근거 영상 구간 이동 지원

담당 역할

Fullstack Developer · Frontend / AI

강의 화면부터 리포트 API와 AI 입력 데이터 처리까지 연결해 전사·복습·질의응답을 하나의 학습 흐름으로 구현했습니다.

팀 협업 자동화 구축
  • 브랜치명 기반 커밋 자동화 훅

    브랜치명을 읽어 커밋에 티켓 번호를 자동으로 넣고 컨벤션을 검사하는 훅 구축

  • 지라 자동화 봇

    지라 이슈 상태 자동화와 JQL로 매일 아침 작업자별 할 일을 공지하는 봇 구현

실시간 오디오 파이프라인 구현
  • 오디오 링버퍼 수집

    강사 음성을 LiveKit Egress WebSocket으로 받아 세션마다 최근 300초를 링버퍼에 저장

  • 다운샘플·전사 연동

    헷갈림·놓침 유형의 코칭에서 확보된 최근 최대 300초 음성을 복사하고, 락 밖에서 16kHz 다운샘플·MP3 인코딩 후 Whisper 전사. 무응답·자리비움 유형은 STT·LLM 없이 고정 팁으로 처리

다중 강의 검색 라우팅 챗봇 구현
  • 강의 범위 판단·원문 검색

    질문·이력·강의 제목·목차로 필요한 강의와 강의별 검색 질문을 결정하는 LangGraph 구성. 강의별 목차 최대 3구간의 원문과 원래 질문의 BM25 상위 최대 3발화를 병합해 답변 근거 선별

  • LLM Wiki·지식 그래프 보완

    원문 참조를 가진 개념 페이지와 선수·대조·관련 관계를 사전 생성하는 파일 기반 인덱스 구현. 원문이 부족하거나 재검색할 때 활용하고, 원문 해시 대조·강의별 개념 ID 분리·최대 2홉 탐색 적용

  • 답변 검증·재시도

    질문의 필수 항목과 답변 문장을 원문 ID로 대조하고, 근거 부족은 재검색·내용 누락은 답변 수정으로 분기. 검증된 주장과 인용을 보존하며 최대 2회 재시도하고 최종 인용은 서버 원문에서 구성

  • 다중 강의 API·영상 이동 UI

    현재 강의 외 최대 4개 강의 선택, 강의별 참여·리포트 게시 권한 검사와 익명화·빈도 제한 구현. 범위 변경 시 요청 취소·대화 초기화, 다른 강의 인용 시 해당 영상 시각을 새 탭으로 여는 UI 연결

  • 품질 평가·코드 책임 분리

    합성 3강의 48문항·추가 24문항으로 검색 근거, 초안·최종 답변, 검증 피드백, 토큰·시간을 기록하고 gpt-4o로 익명 비교 채점. 그래프 연결·검색·검증·통신을 분리해 graph.py를 기존 저장 버전 478줄에서 현재 108줄로 정리하고 Python 관련 테스트 75개 통과

리포트 API·플레이어 구현
  • 리포트 API·플레이어

    학생·강사 리포트 API와 리포트 플레이어(화자별 전사 타임라인, 복습 클립, 구간 이동) 구현

  • 영상 접근 제어

    녹화 영상은 권한을 확인한 뒤 짧게 유효한 URL로 서빙해 무단 접근 차단

프론트엔드 초기 세팅 및 퍼블리싱
  • 프론트엔드 아키텍처 세팅

    Next.js에 DDD 4계층 구조를 잡고 Vitest, TanStack Query·Zustand, OpenAPI 타입 자동 생성 구성

  • 화면 퍼블리싱

    12개 전체 화면 퍼블리싱과 공통 UI 컴포넌트 담당

기술 선택과 구현

Next.js · React · TypeScript
선택 이유
강의 플레이어, 전사, 채팅처럼 상호작용이 많은 화면을 모듈로 나누고 API 데이터 구조를 타입으로 관리하기 위해 사용했습니다.
구현 내용
DDD 4계층 구조, 공통 UI, 리포트 플레이어와 채팅 드로어를 구성하고 OpenAPI 기반 타입 생성을 연결했습니다.
TanStack Query · Zustand
선택 이유
강의·리포트 서버 데이터의 수명과 화면 내부 상태의 수명을 분리하기 위해 선택했습니다.
구현 내용
서버 데이터 조회·동기화와 UI 상태 관리를 구분해 학습 화면에 연동했습니다.
LiveKit · Whisper
선택 이유
강의 트랙 수집·녹화와 시점별 음성 전사가 필요했습니다.
구현 내용
최근 300초 음성을 링버퍼에 저장하고 필요한 구간을 16kHz로 다운샘플·MP3 변환해 전사했습니다. 음소거 중에는 무음을 보충했습니다.
Python · LangGraph
선택 이유
현재 강의 전체 전사를 입력하던 방식에서 필요한 강의를 먼저 고르고, 검색·생성·검증 결과에 따라 다음 동작을 달리해야 했습니다.
구현 내용
강의 범위 판단 → 강의별 검색 → 답변 생성 → 검증을 노드로 구성했습니다. 근거 부족은 재검색, 답변 누락은 재생성으로 분기하고 캐시·원문 출처를 확인했습니다.
RAG · BM25
선택 이유
질문과 무관한 전사를 줄이면서, 목차 요약이나 재작성한 검색 질문에서 빠진 코드·실습 조건도 찾아야 했습니다.
구현 내용
목차·요약으로 고른 구간 원문에 원래 질문의 BM25 검색 결과를 보완했습니다. 후보 강의 안에서 검색하고 중복 제거·강의별 배분 후 근거를 최대 24,000바이트·80발화로 제한했습니다.
LLM Wiki · 지식 그래프
선택 이유
원문 검색이 부족할 때 개념별 설명과 선수 관계를 통해 추가 근거를 찾기 위한 보완 수단으로 연결했습니다.
구현 내용
개념 페이지와 prerequisite_of·contrasts_with·related_to 관계를 원문 참조와 함께 사전 생성했습니다. 실제 선수 간선이 있을 때만 선수 관계를 탐색하고, Wiki·그래프에서 연결한 원문으로 답변을 뒷받침하도록 했습니다.

문제 해결 사례

사례 1다중 강의 RAG 검색 개선으로 합성 평가 정답률 81.25% 확보

1. 오류 분석

문제 현상
기존 챗봇은 현재 강의의 전체 전사를 LLM에 전달해 답변을 생성했습니다. 질문과 무관한 설명·실습 안내까지 함께 입력됐고, 다른 강의의 내용을 묻거나 여러 강의를 비교하는 질문에는 필요한 자료를 가져올 수 없었습니다.
원인
입력 자료가 현재 강의에 한정되어 있었고, 질문에 필요한 강의·구간을 먼저 고르는 과정이 부족했습니다. 여러 강의를 지원하려면 자료 접근 범위를 확장하는 동시에, 모든 전사를 답변 모델에 넣지 않도록 근거를 선별해야 했습니다.
추가 확인 사항
  • 현재 강의·다른 강의·강의 간 비교 질문을 구분하고, 필요한 각 강의의 원문을 확보할 수 있는지 확인했습니다.
  • 선택한 강의의 접근 권한, 서로 다른 강의의 동일 구간 번호, 캐시의 원문 버전과 인용 출처를 함께 검사했습니다.
  • 합성 Java·Spring 3강의 48문항과 추가 24문항에서 원문·질문·정답 근거를 고정하고, 검색 결과·답변·검증 피드백·토큰·시간을 기록했습니다.
  • Python 평가 실행기로 실제 LangGraph와 gpt-4o-mini 생성·검증을 실행하고 gpt-4o로 후보 순서를 섞어 채점했습니다. 저장 응답으로 결과를 재현하고 pytest 75개와 Ruff·strict mypy 검사도 통과했습니다.
측정 기준
수치는 라우팅 도입 후 BM25 보완 전후의 합성 자료·LLM 채점 결과로, 최초 전체 전사 입력 방식과의 직접 비교나 실서비스 정답률은 아닙니다. 48문항의 평균 처리 시간은 8.86초에서 9.84초, 토큰은 556,552에서 620,040으로 늘었고 기존 답변 4건의 채점 변동도 있었습니다. Spring → LangGraph에는 전체 원문을 전달하며 답변 생성·검증 모델에 제공할 근거를 선별합니다.

2. 개선 과정

  1. 1.전체 전사 입력의 한계 확인
  2. 2.다중 강의 선택·권한 검사
  3. 3.질문에 필요한 강의 결정
  4. 4.목차·BM25 원문 검색
  5. 5.LLM Wiki·지식 그래프 조건부 보완
  6. 6.답변 검증·재시도 분기
  7. 7.강의별 인용·영상 이동 연결
  8. 8.합성 질문으로 검색·답변 평가

LangGraph 검색 라우팅을 도입해 질문·이력·제목·목차로 필요한 강의를 먼저 고르고 강의별 검색 질문을 만들도록 구성했습니다. 각 강의에서 목차 최대 3구간의 실제 전사 원문을 읽고, 원래 질문의 BM25 검색으로 최대 3발화를 보완해 중복·용량을 정리했습니다. 원문이 없거나 재검색할 때는 사전 구축된 LLM Wiki의 개념 페이지와 지식 그래프의 관계·연결 원문으로 근거를 보완합니다. 질문의 필수 내용·주장·인용을 검증해 근거 부족은 재검색, 답변 누락은 수정으로 분기했습니다. 사용자는 현재 강의 외 최대 4개 강의를 선택하고 답변 인용에서 해당 영상 시각으로 이동할 수 있습니다.

변경 전 · 변경 후

주황색: 추가·변경한 부분

다중 강의 RAG 검색 개선으로 합성 평가 정답률 81.25% 확보 구조 변경 비교

다중 강의 RAG 검색 개선으로 합성 평가 정답률 81.25% 확보 구조 변경 비교변경 전: 사용자 질문: 강의 내용에 대한 질의; 현재 강의 전체 전사: 질문과 무관한 내용까지 모델 입력; LLM 답변: 현재 강의 자료에 한정. 변경 후: 사용자 질문: 강의 내용에 대한 질의; LangGraph 검색 라우팅: 원문 검색: 목차 선택 + BM25 LLM Wiki·지식 그래프: 원문 부족 / 재검색 (추가·변경); LLM 답변 생성·검증: 근거 부족은 재검색·답변 누락은 재생성 (추가·변경); 인용·출처 영상 이동: 현재 강의 + 최대 4개 강의 지원 (추가·변경). 목차 선택·BM25로 강의 원문을 검색하고, 원문이 없거나 재검색할 때 사전 구축된 LLM Wiki·지식 그래프로 보완합니다. 선별한 근거로 LLM 답변을 생성·검증하고 인용과 영상 시각을 연결합니다.BEFORE변경 전사용자 질문강의 내용에 대한 질의현재 강의 전체 전사질문과 무관한 내용까지 모델 입력LLM 답변현재 강의 자료에 한정AFTER변경 후사용자 질문강의 내용에 대한 질의LangGraph 검색 라우팅원문 검색: 목차 선택 + BM25LLM Wiki·지식 그래프: 원문 부족 / 재검색변경LLM 답변 생성·검증근거 부족은 재검색·답변 누락은 재생성변경인용·출처 영상 이동현재 강의 + 최대 4개 강의 지원변경
목차 선택·BM25로 강의 원문을 검색하고, 원문이 없거나 재검색할 때 사전 구축된 LLM Wiki·지식 그래프로 보완합니다. 선별한 근거로 LLM 답변을 생성·검증하고 인용과 영상 시각을 연결합니다.

3. Before & After 비교

ZANI · 다중 강의 RAG 검색 개선으로 합성 평가 정답률 81.25% 확보 비교
항목BeforeAfter
답변 모델 입력현재 강의 전체 전사질문에 필요한 강의·구간·발화를 선별한 근거
검색 범위현재 강의에 한정현재 강의 + 선택한 다른 강의 최대 4개
정답률 · BM25 보완 전후72.92% · 35/48문항81.25% · 39/48문항 · +8.33%p
근거 Recall · BM25 보완 전후85.2%93.7% · +8.5%p
인용 탐색현재 강의 안에서 확인강의 ID·원문 시각을 보존해 다른 강의 영상으로 이동

해결 결과

다중 강의 라우팅 도입 후 BM25 검색 보완의 합성 48문항 비교에서 정답률을 72.92%(35/48)에서 81.25%(39/48)로 8.33%p 높였습니다. 근거 Recall도 85.2%에서 93.7%로 8.5%p 개선했습니다. 현재 강의 외 최대 4개 강의의 검색·비교와 출처 영상 이동을 지원하며, 추가 24문항은 Recall 100%·정답 19/24로 생성·검증의 개선 과제도 확인했습니다.

사례 2썸네일 용량 약 94% 감소로 목록 페이지 LCP 60% 단축

1. 오류 분석

문제 현상
내 강의실 페이지의 LCP가 3.5초, Performance 점수가 81점에 머물렀습니다. 555×312 카드에 녹화 영상에서 추출한 1280×720 PNG 썸네일을 그대로 넣고 있어 이미지 전송량이 컸습니다.
원인
555×312 카드에 1280×720 PNG를 그대로 사용했고, 요청마다 달라지는 URL 때문에 이미지 캐시 재사용이 어려웠습니다.
추가 확인 사항
  • 원본 변경 시 캐시 갱신과 첫 화면 밖 이미지의 로딩 시점을 함께 점검했습니다.
  • JDK에 WebP 인코더가 없어 네이티브 라이브러리에 의존하게 되므로, 인코딩이 실패하더라도 썸네일이 사라지지 않도록 대체 경로를 설계했습니다.
  • 포맷을 바꾸면서 화질이 떨어지지 않는지 동일한 축소 결과를 기준으로 비교했습니다.

2. 개선 과정

  1. 1.LCP·이미지 요청 분석
  2. 2.카드 크기로 리사이즈
  3. 3.WebP 변환·캐시(JPEG 대체 경로)
  4. 4.화면 밖 이미지 지연 로딩
  5. 5.용량·화질 비교 측정
  6. 6.Lighthouse 재측정

썸네일 URL이 요청마다 달라 Next.js 이미지 캐시를 쓰기 어려웠습니다. 그래서 서버에서 원본을 카드 크기에 맞게 줄이고 WebP로 변환했습니다. JDK 이미지 라이브러리에는 WebP 인코더가 없어 네이티브 라이브러리를 추가해야 했기 때문에, 인코더를 불러오지 못하는 환경에서는 JPEG로, 변환 자체가 실패하면 원본으로 단계적으로 대체하도록 설계했습니다. 변환한 이미지는 캐시해 다시 쓰고, 원본이 바뀌면 캐시도 함께 갱신했습니다. 첫 화면 밖 썸네일은 지연 로딩으로 바꿨습니다.

변경 전 · 변경 후

주황색: 추가·변경한 부분

썸네일 용량 약 94% 감소로 목록 페이지 LCP 60% 단축 구조 변경 비교

썸네일 용량 약 94% 감소로 목록 페이지 LCP 60% 단축 구조 변경 비교변경 전: 강의 목록: 555×312 카드 표시; 모든 썸네일 즉시 요청: 첫 화면 밖 이미지도 함께 로딩; 원본 PNG: 1280×720·0.5~1MB 전송. 변경 후: 강의 목록: 555×312 카드 표시; 화면 밖 이미지는 지연 로딩: 먼저 보여줄 썸네일부터 요청 (추가·변경); 리사이즈·WebP·캐시: 카드 크기 이미지·수십 KB 전송 (추가·변경). 서버에서 이미지 크기·포맷·캐시를 최적화하고, 화면 밖 이미지는 지연 로딩했습니다.BEFORE변경 전강의 목록555×312 카드 표시모든 썸네일 즉시 요청첫 화면 밖 이미지도 함께 로딩원본 PNG1280×720·0.5~1MB 전송AFTER변경 후강의 목록555×312 카드 표시화면 밖 이미지는 지연 로딩먼저 보여줄 썸네일부터 요청변경리사이즈·WebP·캐시카드 크기 이미지·수십 KB 전송변경
서버에서 이미지 크기·포맷·캐시를 최적화하고, 화면 밖 이미지는 지연 로딩했습니다.

3. Before & After 비교

ZANI · 썸네일 용량 약 94% 감소로 목록 페이지 LCP 60% 단축 비교
항목BeforeAfter
LCP3.5초1.4초 · 2.1초(60%) 단축
Lighthouse Performance81점96점
썸네일 전송량0.5~1MB수십 KB · 약 94% 감소
썸네일 포맷PNG 원본WebP · 동일 원본에서 JPEG 대비 약 28% 추가 감소
포맷 전환 시 화질JPEG SSIM 0.9171WebP SSIM 0.9300

해결 결과

목록 페이지 LCP를 3.5초에서 1.4초로 2.1초(60%) 단축하고, Lighthouse Performance 점수를 81점에서 96점으로 높였습니다. 썸네일 전송량은 0.5~1MB에서 수십 KB로 약 94% 줄였습니다. 동일 원본의 JPEG 대비 WebP 용량도 90.4KB에서 64.9KB로 약 28% 줄이면서 화질 지표를 개선했습니다.

사례 3오디오 버퍼 개선으로 락 점유 약 800ms → 3ms 단축

1. 오류 분석

문제 현상
실시간 코칭을 위해 강사의 최근 5분 음성을 링버퍼에 저장했습니다. 하지만 LiveKit에서는 음소거 중 오디오 프레임이 오지 않아, 실제 최근 5분이 아니라 음성이 들어온 시간만 따진 최근 5분이 조회됐습니다.
원인
음소거 중 오디오 프레임이 오지 않아 버퍼가 실제 경과 시간 대신 수신한 음성 길이만 누적했습니다.
추가 확인 사항
  • 짧은 네트워크 지연을 음소거로 오인하지 않도록 0.5초 기준을 적용했습니다.
  • MP3 인코딩 중 락이 오디오 수집을 막는지도 확인했습니다.

2. 개선 과정

  1. 1.음소거 재현
  2. 2.수신 시간·실제 시간 비교
  3. 3.긴 공백에 무음 삽입
  4. 4.인코딩을 락 밖으로 분리
  5. 5.시간 오차·락 점유 확인

버퍼 시간이 실제 시간과 맞도록 0.5초 이상 오디오가 비면 서버에서 무음 데이터를 채웠습니다. 짧은 네트워크 지연은 기다리고, 긴 공백만 보정해 불필요한 무음 삽입을 줄였습니다. MP3 변환은 필요한 음성만 먼저 복사한 뒤 락 밖에서 진행했습니다.

변경 전 · 변경 후

주황색: 추가·변경한 부분

오디오 버퍼 개선으로 락 점유 약 800ms → 3ms 단축 구조 변경 비교

오디오 버퍼 개선으로 락 점유 약 800ms → 3ms 단축 구조 변경 비교변경 전: LiveKit PCM 수집: 실시간 강사 음성; 수신 프레임만 버퍼 저장: 음소거 중 시간 공백 누락; 버퍼 락 안에서 MP3 변환: 변환 중 새 음성 수집 대기. 변경 후: LiveKit PCM 수집: 실시간 강사 음성; 시간 기준 버퍼·무음 보충: 음소거 구간도 최근 300초에 포함 (추가·변경); 오디오 복사 후 락 해제: 필요한 음성만 빠르게 복사 (추가·변경); 락 밖에서 MP3 변환·STT: 변환 중에도 새 음성 수집 (추가·변경). 음소거 공백을 무음으로 보정하고, 무거운 오디오 변환을 버퍼 락 밖으로 분리했습니다.BEFORE변경 전LiveKit PCM 수집실시간 강사 음성수신 프레임만 버퍼 저장음소거 중 시간 공백 누락버퍼 락 안에서 MP3 변환변환 중 새 음성 수집 대기AFTER변경 후LiveKit PCM 수집실시간 강사 음성시간 기준 버퍼·무음 보충음소거 구간도 최근 300초에 포함변경오디오 복사 후 락 해제필요한 음성만 빠르게 복사변경락 밖에서 MP3 변환·STT변환 중에도 새 음성 수집변경
음소거 공백을 무음으로 보정하고, 무거운 오디오 변환을 버퍼 락 밖으로 분리했습니다.

3. Before & After 비교

ZANI · 오디오 버퍼 개선으로 락 점유 약 800ms → 3ms 단축 비교
항목BeforeAfter
버퍼 시간 기준수신한 음성 길이실제 시간 · 오차 최대 0.5초
락 점유 시간약 800ms약 3ms

해결 결과

버퍼 락 점유 시간을 약 800ms에서 3ms로 약 99.6% 단축하고, 음소거 구간을 보정해 버퍼 시간 오차를 최대 0.5초 이내로 줄였습니다. MP3 변환 중에도 새 오디오를 수집할 수 있도록 했습니다.

사례 4커밋 규칙 준수율 99.62%를 만든 팀 협업 자동화

1. 오류 분석

문제 현상
이전 팀 프로젝트에서 Jira 티켓 누락, 서로 다른 커밋 형식, 작업 상태 갱신 지연으로 진행 상황을 파악하기 어려웠습니다. 기록만으로 확인할 수 없어 팀원들에게 진행 상황을 다시 물어야 했습니다.
원인
협업 기록과 상태 갱신이 팀원들의 수작업에 의존했습니다. 개발 중에도 기록이 남도록 규칙을 작업 흐름에 연결하고, 반복되는 관리 작업을 줄일 필요가 있었습니다.
추가 확인 사항
  • 브랜치 검사 → 이슈 키 자동 삽입 → 커밋 메시지 검사가 순서대로 실행되는지 확인했습니다.
  • 이미 이슈 키가 있는 메시지는 중복 삽입하지 않고, 자동 생성 커밋과 보호·릴리스 브랜치에는 단계별 예외를 적용했습니다.
  • 총 1,300개 커밋 중 메시지 규칙 위반 5건을 집계해 준수율을 계산했습니다.

2. 개선 과정

  1. 1.티켓·담당자·스크럼 규칙 합의
  2. 2.이슈 키 자동 삽입·형식 검사
  3. 3.Jira 상태·아침 공지 자동화
  4. 4.커밋 규칙 준수율 집계

다음 5인 프로젝트에서는 기능별 티켓 생성·담당자 지정·매일 스크럼을 팀과 합의했습니다. 제가 구축한 Husky 훅은 브랜치명에서 티켓 번호를 읽어 커밋 메시지에 자동으로 넣고, 정해진 메시지 형식을 검사하도록 했습니다. Jira 작업 상태 변경도 자동화하고, JQL로 필요한 티켓을 조회해 매일 아침 담당자별 할 일을 공지하는 봇을 만들었습니다. 스크럼 전에 각자의 작업을 확인할 수 있도록 기록과 공지를 연결했습니다.

변경 전 · 변경 후

주황색: 추가·변경한 부분

커밋 규칙 준수율 99.62%를 만든 팀 협업 자동화 구조 변경 비교

커밋 규칙 준수율 99.62%를 만든 팀 협업 자동화 구조 변경 비교변경 전: 개발·작업 관리: 진행 상황을 팀에 공유; 커밋 수동 관리: 이슈 키·형식 직접 확인; Jira 수동 관리: 상태 갱신·진행 재확인. 변경 후: 개발·작업 관리: 티켓·담당자·스크럼 규칙 합의; Husky 커밋 훅: 이슈 키 자동 입력·검사 (추가·변경); Jira 자동화 봇: 상태 변경·아침 공지 (추가·변경). 커밋 훅과 Jira 봇이 각각 반복 관리 작업을 자동화해, 스크럼 전에 같은 작업 정보를 확인하도록 했습니다.BEFORE이전 프로젝트개발·작업 관리진행 상황을 팀에 공유커밋 수동 관리이슈 키·형식 직접 확인Jira 수동 관리상태 갱신·진행 재확인AFTERZANI개발·작업 관리티켓·담당자·스크럼 규칙 합의Husky 커밋 훅이슈 키 자동 입력·검사변경Jira 자동화 봇상태 변경·아침 공지변경
커밋 훅과 Jira 봇이 각각 반복 관리 작업을 자동화해, 스크럼 전에 같은 작업 정보를 확인하도록 했습니다.

3. Before & After 비교

ZANI · 커밋 규칙 준수율 99.62%를 만든 팀 협업 자동화 비교
항목BeforeAfter
이슈 연결Jira 티켓 누락·수동 이슈 연결브랜치에서 자동 추출·삽입, 중복 방지
협업 규칙 확인팀원마다 다른 커밋 형식브랜치·커밋 훅에서 자동 검사
작업 현황 공유작업 상태 갱신 지연·진행 상황 재확인상태 변경·아침 공지 자동화, 스크럼 전 작업 확인

해결 결과

총 1,300개 커밋 중 메시지 규칙 위반은 5건으로, 1,295건이 규칙을 준수해 준수율 99.62%를 달성했습니다. 협업 규칙을 합의하는 데서 나아가 이를 지킬 수 있는 자동화까지 마련하고, 팀이 같은 작업 기록을 확인하며 협업하도록 했습니다.

프로젝트 회고

기술적 한계와 개선 방안

한계·아쉬운 점
추가 합성 24문항에서 근거 Recall은 100%, 정답 판정은 19/24로 답변 생성·검증의 개선 과제를 확인했습니다.
개선 방향
실제 강의 STT와 새 질문으로 평가 범위를 넓히고, 질문의 필수 조건·답변 누락·인용 정확성을 각각 검증하겠습니다.
한계·아쉬운 점
검색 보완 후 합성 48문항의 평균 처리 시간이 8.86초에서 9.84초로 늘었고, Spring → LangGraph에는 여전히 선택한 강의의 전체 전사를 전달합니다.
개선 방향
단계별 호출·입력량·재시도를 계측하고, 원문 버전 기반 캐시와 필요한 구간만 조회하는 방식으로 지연·전송량을 줄이겠습니다.