인하대학교 컴퓨터공학 종합설계 'Open-Lawyer'
2024학년도 2학기 캡스톤 디자인 교과목 프로젝트입니다.
프로젝트 주제
한 줄 요약: AI 기반 재판 판결 결과 예측 챗봇 서비스
대법원 판결문을 활용한 AWS Bedrock Fine-tuning(or Few-shot learning)을 통해 누구나 재판 내용을 입력하면 판결 결과를 쉽게 예측할 수 있도록 하는 챗봇 서비스 개발!
주제 선정 배경
법률서비스는 일상과 떼어 놓을 수 없는 한 부분중 하나입니다. 그러나 한국개발연구원 조사에 따르면, 법률서비스가 필요하지만 받지 못하는 사람이 40%나 된다고 한다. 또 한국법제연구원 조사에 따르면 양적으로 법률서비스가 충분하지 않다고 대답한 사람들이 과반수에 다다랐습니다.
이에 대해 저희는 해당 문제의 원인을 다음과 같이 분석하고 정의하여 해결하고자 했습니다.
- 문제 배경
- 법률 상담은 일반인에게 매우 높은 진입 장벽으로 작용
- 법적 문제에 대한 조언을 구하고자 할 때, 법률 상담비는 매우 큰 부담
- 법률적 분쟁을 미리 대비하거나 해결하기 위해서는 전문가의 도움이 필요하지만, 그 비용 때문에 상담 자체를 포기하는 경우가 빈번히 발생
- 문제 정의
- 법률 시스템은 복잡하고 방대한 법률 조항과 판례로 이루어져 있어 일반인들이 사건의 승소 가능성을 스스로 판단하기 매우 어려움
- 어떤 법률이 적용되는지, 유사한 판례는 무엇인지, 사건을 어떻게 진행해야 하는지에 대한 정보가 부족한 상황에서, 많은 사람들이 올바른 법적 대응 방법을 찾지 못함
- 사건이 심각한 상황임에도 불구하고 처음에 무엇을 해야 할지 몰라 법률 상담 자체를 포기하거나 지연하는 경우도 다수
- 새로운 서비스의 필요성
- 사용자들이 큰 비용 없이도 법률 정보를 쉽게 얻고, 사건의 결과를 미리 예측할 수 있는 서비스 필요
- 법률 상담 비용의 부담을 완화하면서, 법률 정보에 대한 접근성을 향상시키는 ‘나만의 법률 도우미’ 서비스를 개발해서 해당 문제를 해결하면 어떨까?
프로젝트 일정 (기간)
2024.09.04 - 2024.12.17 (약 13주)
팀 소개
인하대학교 컴퓨터공학과 4인으로 구성된 팀입니다.
각 팀원 정보는 깃허브 레포를 참고해주세요~!
아키텍처 디자인
각 파트별 Docker 이미지를 AWS ECR에 업로드한 다음 ECS Task를 생성하고, ECS Fargate를 통해 서비스를 실행시키는 구조입니다.
프로토타입
피그마 링크를 클릭해서 더 자세히 볼 수 있어요🙌
Figma
Created with Figma
www.figma.com
기술 스택
- 프론트엔드: React, Vite, Tanstack-query, Tailwind CSS, React Router Dom 등
- 백엔드/인프라: Spring, FastAPI, MySQL, AWS EC2/RDS, Docker 등
- AI: Python, PyTorch, AWS Bedrock, Hugging Face 등
사용 개발 툴/ 협업툴
- 개발툴: vscode, intellij, jupyter notebook, docker
- 협업툴: Github, Notion, Figma, Zep, Slack
주요 기능
프로젝트의 메인 기능은 바로 챗봇 서비스와 승소 확률 도출 기능이라고 할 수 있습니다.
챗봇 서비스에 질문을 입력하면, 승소 확률과 함께 해당 사안을 분석해 답변을 도출합니다.
해당 승소확률 예측 모델은 AI 파트 담당인 준혁 팀원님이 수고해주셨습니다.
- AI 모델의 정확도는 92% 정도를 기록했습니다.
- 학습 결과, Loss가 꾸준히 감소하고 Validation 정확도가 상승하는 추세를 관측하여 학습이 정상적으로 진행된 것을 확인했습니다.
- 이 과정에서 최신 법률 데이터를 반영하기 위해 RAG를 활용했습니다.
- 사용자가 입력으로 제공한 사건 정보 텍스트에 KoBERT로 임베딩을 생성하면 Pinecone으로 구현한 Vector DB에서 유사도를 계산하고, RDS에서 id를 기반으로 저장된 판결문을 가져와서 프롬프트에 제공합니다.
다음은 프로젝트에 대한 KPT 형식의 회고입니다.
배운 점과 실천한 부분 (Keep)
✅ Docker, Docker Compose의 사용
도커는 원래 대충은 알고 있었으나 약간의 진입장벽이 있고 사용하기 어렵다는 저만의 편견이 있었습니다.
그러나 실제로 프로젝트에서 도커를 사용해보니 그 유용성과 강력함을 몸소 느낄 수 있었습니다. 특히 도커 컴포즈를 활용하여 여러 서비스를 하나의 프로젝트에서 관리하고 배포하는 과정이 정말 신기했습니다. 각 서비스의 독립적인 환경을 관리하면서도 통합된 시스템을 운영할 수 있다는 점에서 도커의 장점이 정말 강력하다는 것을 느꼈습니다.
또한, 팀장 재현님께서 해당 부분을 맡아주셔서 배포 단계에서도 도커를 활용해 배포 시간을 단축시킬 수 있었는데, 이를 통해 환경 설정에 대한 고민을 줄일 수 있었습니다. 이렇게 Docker와 Docker Compose의 강력한 기능을 제대로 이해하고 실제 프로젝트에서 적용해보아서 재밌었습니다!
✅ 최신 웹 기술 트렌드 반영한 라이브러리 도입
이번 프로젝트는 사실 컴퓨터공학전공 학생으로서 학교에서 하는 최종 프로젝트의 장 느낌이었습니다. 따라서 지금껏 사용해보지 않은 최신 웹 기술 트렌드를 반영해보고자 노력했습니다.
- TailwindCSS
TailwindCSS는 처음 사용해본 CSS 프레임워크였습니다. 요즘 현업에서 많이 사용된다고 해서 관심을 가지게 되었습니다. 사실 처음에는 HTML 구조가 다소 복잡해지고 뭔가 자체적인 유틸리티 클래스들이 많아 직관적으로 느껴지지 않았습니다. 하지만 계속 코드를 작성하다보니 유틸리티 클래스들이 어떻게 빠르게 스타일을 적용할 수 있는지 이해하게 되었습니다. 특히 반응형 웹 디자인을 구현할 때 지금껏 사용해온 라이브러리들보다 훨씬 간단하고 직관적인 코드로 작성할 수 있다는 점이 마음에 들었습니다. 또한 일일히 스타일링 변수 네이밍을 고민하지 않아도 된다는 점도 매력적이었습니다. - TanStack Query
TanStack Query는 API와 서버 간의 데이터 통신을 효율적으로 관리할 수 있는 라이브러리로, 특히 서버에서 데이터를 가져오는 데 유용합니다. 특히 DevTool을 제공하여 api를 호출했을때 어떤 데이터가 주고 받아지는지 확인하기 편리했으며, 에러 발생 시 디버깅이 유리하고 여러 서버 호출을 관리하는 데 있어 편리하다고 생각했습니다.
✅ 로그인 과정에서 보안을 고려하기
보통 프로젝트에서 JWT 토큰을 활용한 로그인 과정 시 일반적으로 웹 애플리케이션에서 토큰을 로컬 스토리지나 세션 스토리지에 저장하는 방식으로 다수 설계해본 경험이 있었습니다.
하지만 이번 프로젝트에서는 자바스크립트의 in-memory에 JWT 토큰을 저장하는 방식으로 보안을 강화했습니다. 이 과정에서 팀장 재현님이 많은 인사이트를 제공해주었는데, 이를 바탕으로 보다 안전한 로그인 프로세스를 구축할 수 있었습니다. 감사합니다😊
소셜 로그인 과정 상세
- 사용자가 소셜 로그인 버튼을 클릭하면, 소셜 로그인 페이지로 리다이렉트됩니다.
- 사용자가 로그인 정보를 입력하고 로그인에 성공하면, code라는 1회성 인증 코드가 발급됩니다.
- 이 code와 함께 소셜 로그인 개발 홈페이지에 등록된 URL로 리다이렉트되며, 여기서 Spring Boot API가 호출됩니다.
- 발급된 code를 사용하여 소셜 로그인 서버에서 사용자 정보를 요청합니다.
- 서버로부터 전달받은 사용자 정보를 DB에 저장하고, accessToken과 refreshToken을 생성합니다.
- 생성된 refreshToken은 쿠키에 저장됩니다.
- accessToken은 쿼리스트링에 담아 /connect 페이지로 리다이렉트되며, 그곳에서 accessToken을 받아 accessToken.js에 저장합니다.
- 저장된 accessToken을 통해 /home 페이지로 리다이렉트되어 로그인 성공을 마칩니다.
- 이후, 새로고침 시 refreshToken을 사용하여 accessToken을 재발행하는 방식으로 로그인이 유지됩니다.
이 과정을 거쳐 새로고침 시에도 refreshToken이 발급되기 때문에 더욱 보안을 강화할 수 있었습니다. 로그인 과정에서 보안 취약점을 최소화하기 위한 방안을 생각해 볼 수 있는 유익한 시간이었습니다!
✅ 반응형 UI/UX 디자인 고도화
챗봇 서비스가 언제 어디서나 상담을 받을 수 있도록 하기 위해서 반응형 웹 디자인은 필수적인 요소였습니다. 특히 PC, 태블릿, 모바일 등 다양한 화면 크기에서 사용자 경험을 최적화하는 것이 중요했습니다. 프로젝트에서 프론트엔드 팀원이 저밖에 없었기에, UI/UX 디자인을 고도화하는 과정에서 여러 기기에서 사용자 인터페이스가 어떻게 다르게 보여야 하는지 고민하며 작업했습니다.
제가 가장 신경 쓴 부분은 헤더입니다. 모바일 뷰에서는 헤더 부분에서 PC에서 보이던 네비게이션 메뉴바가 사라지게 구현하였습니다. 대신 좌상단에 있는 로고를 클릭하면 메뉴바가 왼쪽에서 슬라이드로 열리는 방식으로 디자인하여 모바일 사용자가 메뉴를 쉽게 접근할 수 있도록 했습니다.
또 유저 테스트를 진행해 다양한 버그를 찾아내고 수정하는 작업도 최종 프로젝트 발표 전에 진행했습니다.
1차 데모 MVP를 개발 후 배포하여 사용자 피드백을 받아 리팩토링을 진행하면서 더 나은 결과를 도출할 수 있었습니다.
♻️ Refactor: UI 버그 수정 및 리팩토링 by abyss-s · Pull Request #9 · InhaCapstone2024/Open-Lawyer
📝작업내용 tanstack-query dev tool default를 끄기 userInfo fetch 수정 채팅, 결제 페이지에서 유저 네임으로 변경되도록 수정 로그아웃 기능 추가 WordModal 높이 제한 및 dangerouslysetinnerhtml 추가 (배포 링크
github.com
✅ 개발 문서 작성의 중요성 체감
이번 프로젝트에서는 노션을 중점적으로 활용하여 프로젝트를 체계적으로 관리하고 각자의 업무를 명확히 분담했습니다.
특히 저는 주간 회고를 작성해 매주 개발 일정을 관리하고, 어떤 에러가 왜 발생했는지, 그리고 어떻게 해결했는지 기록해두었습니다. 이를 통해 비슷한 에러가 발생할때 바로 해당 부분을 참고하여 빠르게 해결해여 개발 생산성을 증진시켰습니다.
또한 각자 맡은 부분에 대해 문서를 작성해 다른 팀원들이 쉽게 이해하고 사용할 수 있도록 했습니다. 예를 들어, AI나 백엔드와 관련된 부분 같이 제가 잘 모르는 파트들은 다른 팀원들이 작성한 문서를 통해 그 부분을 이해하고 배울 수 있었습니다. 이러한 사전 작업들은 단순 코드만 보는 것보다 훨씬 협업을 원활하게 만들고 프로젝트를 진행하는 데 큰 도움이 되었다고 생각합니다.
노션뿐만 아니라 슬랙에서 업무일지 채팅방을 따로 개설하고, github 봇과 연동하여 PR이 올라올때마다 알림이 오도록 설정했던 것도 더 열심히 개발하는데 한 몫 했던 것 같아요.
✅ 페이지네이션을 활용한 방대한 용어 사전 페이지 구현
페이지네이션은 데이터를 한 번에 모두 로드하는 대신, 필요한 만큼만 로드하여 성능 문제를 해결하고 사용자 경험을 개선하는 데 중요한 역할을 합니다. 프로젝트에서 페이지네이션 로직을 법률 용어 사전 페이지에 도입한 부분을 소개할게요!
1. 페이지네이션 도입 이유
승범님이 담당해주신 법률 용어 사전은 20000개 이상의 데이터를 포함하고 있기 때문에 한 번에 모든 데이터를 클라이언트로 불러오는 것은 불가능했습니다. 실제로 호출하는데 시간이 너무 오래 걸려서 api 자체가 불러와지지 않았습니다. 이를 해결하기 위해 페이지네이션 방식을 채택했습니다. 데이터가 많을 경우 데이터를 여러 페이지로 나누어 각 페이지에서 일정한 수의 항목만 불러오기 때문에 사용자에게 보다 빠르고 효율적인 성능을 제공할 수 있습니다.
원래는 무한 스크롤 방식도 고려했으나 많은 양의 데이터를 빠르게 처리하기 위해 페이지네이션 방식으로 전환했습니다. 무한 스크롤의 경우 네트워크 부하가 커지고, 페이지가 길어질 경우 사용자 경험이 저하될 수 있다고 판단했습니다.
2. 페이지네이션 방식 구현
페이지네이션을 구현하는 핵심 부분은 현재 페이지 상태와 페이지당 항목 수를 관리하는 것입니다.
- currentPage: 현재 사용자가 보고 있는 페이지 번호입니다.
- itemsPerPage: 한 페이지에 표시할 항목의 수입니다. 이 경우, 한 페이지에 30개의 법률 용어를 보여줍니다.
- startIndex: 현재 페이지에서 보여줄 첫 번째 항목의 인덱스입니다. currentPage가 1일 경우 startIndex는 0이고, 2일 경우 30이 됩니다. 이는 terms.slice() 메서드에서 사용되어, 현재 페이지에 맞는 용어 목록을 추출하는 데 사용됩니다.
- totalPages: 총 페이지 수로, 전체 데이터 수를 itemsPerPage로 나눈 뒤 올림하여 계산됩니다.
const startIndex = (currentPage - 1) * itemsPerPage;
const currentTerms = terms.slice(startIndex, startIndex + itemsPerPage);
const totalPages = Math.ceil(terms.length / itemsPerPage);
페이지네이션 버튼은 이전 버튼과 다음 버튼 2개로 이뤄져 있습니다.
버튼을 클릭하면 currentPage가 업데이트되며, 이를 통해 새로운 데이터가 표시됩니다. 각 버튼은 currentPage가 처음(1페이지) 또는 마지막 페이지일 때 비활성화됩니다. 그 사이에는 현재 페이지와 총 페이지 수를 표시하도록 했습니다.
<button
onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
disabled={currentPage === 1}
className="px-4 py-2 bg-gray-300 text-black rounded mx-2 hover:bg-gray-400 transition duration-200"
>
이전
</button>
<span className="px-4 py-2 text-black">{`페이지 ${currentPage} / ${totalPages}`}</span>
<button
onClick={() => setCurrentPage((prev) => Math.min(prev + 1, totalPages))}
disabled={currentPage === totalPages}
className="px-4 py-2 bg-blue-500 text-white rounded mx-2 hover:bg-blue-600 transition duration-200"
>
다음
</button>
useQuery 훅을 사용하여 데이터를 비동기적으로 가져옵니다. 데이터가 로딩 중일때와 에러가 발생했을때, 상황에 따라 적절한 메시지를 표시합니다. fetchLegalTerms 함수를 통해 초기 데이터를 가져오고, 각 단어를 클릭하면 아래 사진의 오른쪽 화면처럼 openModal 함수가 호출되어 해당 단어의 세부 정보를 모달로 띄워줍니다.
더 발전시킬 부분 (Problems & Try)
❌ TanStack Query의 실질적 사용 부족
TanStack Query의 useQuery를 제대로 활용하지 못한 점이 가장 아쉽습니다. 처음 사용하는 라이브러리였기 때문에 사용이 익숙하지 않았고, 프로젝트 후반에는 일정에 쫓겨 기존에 알고 있던 fetch를 사용해 API 처리를 했습니다. 실질적으로 useQuery를 제대로 사용한 부분은 Dictionary 페이지뿐이라고 생각합니다.
만약 라이브러리를 적절히 활용했더라면 유지보수성 측면에서 훨씬 더 효율적인 코드를 작성할 수 있었을 것입니다. 앞으로는 공식 문서와 튜토리얼을 참고해 학습하고 난 후에 다음 프로젝트에서 활용해 보고 싶습니다.
❌ TypeScript 미사용
TypeScript는 프로젝트 초기에 도입하려고 계획했으나, 초기 설정에 필요한 시간이 부족해 결국 순수 JavaScript를 사용하게 되었습니다. 특히 다른 파트의 팀원들과 함께하는 협업 프로젝트에서는 타입 정의가 명확할수록 다른 팀원이 코드를 이해하기 훨씬 용이할 것이라고 생각했는데 아쉬운 부분입니다. 다음 프로젝트에서는 TypeScript를 꼭 도입하여 타입 안전성과 명확한 에러 디버깅을 보장하는 코드를 작성할 수 있도록 준비하겠습니다!!
❌ 미완성된 기능 일부 존재
프로젝트에서 시간 부족으로 인해 완전히 구현하지 못한 기능들이 다소 있습니다.
- 법률 용어 사전 검색 기능 미구현: 법률 용어 사전은 사용자가 특정 키워드를 검색하여 법률 정보를 확인할 수 있는 기능입니다. 그러나 구현 시간 부족으로 인해 사전에서 단어 뜻 보기만 구현된 상태에서 마무리되었습니다. 사실 사전에서 검색 기능은 필수라고 생각하는데 이를 구현하지 못한 점이 아쉽습니다. 실제로 캡스톤 발표 당일 날 몇몇 분들이 최종 프로젝트를 보며 지적해주신 부분이기도 합니다.
- 채팅 로그 저장 및 사용자별 관리 기능 미구현: 원래 계획대로라면 상담 이력을 관리하기 위해 채팅 로그를 사용자별로 저장하는 기능을 계획했으나, 팀원들의 취준 및 마지학 학기와 병행하다 보니 구현 시간이 부족했습니다. 만약 해당 기능이 도입되었다면 사용자별 채팅 기록을 저장하여, 로그아웃후 다시 로그인했을때 채팅 내역이 남아있었을텐데, 현재는 useEffect를 사용하는 방식이라 새로고침하면 채팅 기록이 다 사라지게 됩니다. 사실 이 부분은 학교에서 제공하는 aws 계정의 요금락 이슈 문제도 있어서 해결하기는 다소 어려웠습니다.
종설 최종 발표 후기
처음 캡스톤을 시작했을때는 2학기 내내 진행되니깐 시간이 넘칠 것이라고 안일하게 생각했는데, 생각보다 최종 발표일이 다가올수록 수정사항도 많고 마지막 학기라는 이슈로 인해 다른 과목들과 병행하면서 프로젝트를 진행하기 다소 어려운 점이 있었습니다.
그래도 운이 좋게도 훌륭한 팀원들과 함께해서 성공적으로 프로젝트를 마칠 수 있었습니다!
또한 UI/UX와 더불어 ppt나 판넬 등 디자인 전반 영역에서 기여했는데, 부족한 실력이지만 저를 믿고 따라와주신 팀원분들께 다시 한 번 감사드립니다.
🖇️ 프로젝트 관련 링크 모아보기
Github
리드미를 통해 실행방법을 자세히 안내하고 있습니다.
GitHub - abyss-s/Open-Lawyer: 2024년 하반기 인하대학교 컴퓨터공학 종합설계 (1조) 프로젝트
2024년 하반기 인하대학교 컴퓨터공학 종합설계 (1조) 프로젝트. Contribute to abyss-s/Open-Lawyer development by creating an account on GitHub.
github.com
Notion
저희 팀은 노션에서 개발 일정과 문서를 기록했습니다.
더 자세한 내용이 궁금하시면 노션 링크에서 봐주세요😁
[Open-Lawyer] 인하대 컴퓨터공학 종합설계 프로젝트 ( 2024.09.04 ~ 2024.12.17 ) | Notion
🌞 일정
abyss-2.notion.site
Canva
분반 내 최종발표에 사용한 ppt 자료입니다!
1조_14주차_ver1
이영주 님이 디자인한 프레젠테이션 살펴보기
www.canva.com
'Activities > Project' 카테고리의 다른 글
[쉽게, 티켓] 티켓팅 교육 웹사이트 개발 프로젝트 회고록 (0) | 2025.01.18 |
---|