다른 ai모델들에 비해 gemini 2.5 flash-lite를 쓰고 Reasoning 기능을 끄기로 한 이유
성능과 속도에 비해 압도적으로 저렴한 가격.
Structured output 기능
Spring ai를 활용하지 않은 이유1(성능 지표 문제)
Spring ai를 활용하지 않은 이유2 (Json schema 준수)
Response Schema의 변경 가능성 고려(확장성)
위 구조에서 text 부분에 prompt가 들어가고,
responseSchema 부분에 저희가 원하는 structured output이 들어갑니다.
추후 확장성을 고려했을 때 이 responseSchema를 String 값으로 따로 관리해주는 것이 합리적인 선택이었습니다. responseSchema를 Dto로 처리했을 때, 추후 이 부분에 변경이 있을 때 정말 복잡한 수정사항이 생길 수 있지만, 이 부분을 string으로 관리했을 때는 정말 간단하게 수정이 됩니다.
따라서 이 responseSchema를 string 값으로 env파일에 넣어놓고, 꺼내와서 json으로 변형한 후 요청을 보내는 방식으로 기능을 구현했습니다.
위의 수정하기 뷰에서는 만다라트 생성 완료 후, 하나의 상위 목표에 대해 해당 상위 목표와 하위 목표를 한번에 수정할 수 있습니다.
만다라트를 수정하면, 다음 두 가지 상황을 고려해야 합니다.
이러한 경우, 상위 목표나 하위 목표의 수정을 단순히 기존 테이블에 저장된 값을 수정해버리면, 이전 기록을 보여주는 뷰에서 잘못된 값이 나올 수 있다고 생각했습니다.
예를 들면, 사용자가 만다라트 수정 전 “밥 먹기” 라는 하위 목표를 완료한 후, 만다라트 수정 후 해당 목표를 “운동하기”로 바꾸면, 스트릭 트래커에서 보여줄 때 “밥 먹기”를 완료한 날에는 “운동하기”가 아닌 “밥 먹기”를 보여주어야 합니다. 즉, 만다라트가 한번 생성된 이후에 목표를 수정, 삭제 할 때에는 모두 POST하여 이력을 쌓아두고, 완료 여부를 체크할 때에도 각 이력에 대한 완료 여부를 체크해야 합니다. 따라서, 수정 전 날짜의 기록을 조회했을 때에도 사용자가 완료한 목표가 온전히 보여질 수 있도록 합니다.
따라서, 기존 Mandalart ← CoreGoal ← SubGoal ← History로 설계했던 테이블 구조를 위 ERD 그림과 같이 바꾸었습니다. 기존의 CoreGoal과 SubGoal은 해당 데이터의 위치만 저장하고, 해당 위치에 대한 이력은 각각의 스냅샷 테이블에 저장합니다. 할 일 완료 여부를 저장하는 할 일 히스토리 또한 하위 목표 스냅샷에 연결하여 어떤 이력에 대한 할 일인지 알 수 있도록 하였습니다.