고용노동부에서 주관하는 일경험 프로젝트에 참여하였다.
NVIDIA ACADEMY 에서 함께 AI를 공부했던 ㅈㅅ님, ㅅㅎ님, ㄷㅇ님과 함께 4명이서 팀을 이루어 지원했다.
AI프로젝트이다 보니,AI 기능이 들어있어야 하고,
ㄷㅇ님과 나는 특히 지난 번 아카데미에서 챗봇을 안만들어서 그런지 제대로 챗봇을 만들어보고 싶었다.
4명 모두 관심 있어 하는 공통 관심사인 E-commerce로 가닥을 잡았다.
소비자가 챗봇 질문을 통해서 원하는 제품을 찾는 서비스를 만들기로 했다.
2025년 05월 05일 ~ 2025년 06월 22일 (약 7주)
발표일시: 06월 24일 오후 1시
이번에도 또 핀볼게임을 통해서 팀장을 정했다.
팀장은 ㅈㅅ님이 되었다..! 운명의 장난인가~ 팀장이 될 운명인가~
asdf 팀명으로 E-commerce AI chatbot 프로젝트를 진행한다.
프로젝트 일정은 아래와 같이 진행한다.


계획한 일정은 위와 같지만, 6월 18일경에 20일까지 프로젝트를 마무리하라는 연락을 받았다.
당혹스러웠지만, 협의 끝에 22일 최종 프로젝트 마무리 일정으로 정해져서 추후에 일정 조정이 있었다.
아, 처음에는 Qwen2.5-32B 모델을 양자화한 모델을 사용했었다. 하지만, vllm 버전이 안맞는 이슈로 인하여 Qwen3-32B로 변경했다. Qwen3은 올해 4월에 나모델이다.
기획 단계에서 팀원들끼리 각자 해보고 싶은 영역들을 조금씩이라도 하자는 의견이 있어서, Backend도 팀원들 의견에 맞춰 정했다. 현재 한국에서 가장 많이 사용하고 있는 Java를 언어로 선택했다. 당연히 프레임워크는 Spring Boot이다. DB는 PostgreSQL을 선택했다.
프론트 같은 경우에는 트랜드에 맞춰가는 게 좋기 때문에 NEXT.JS로 선택했다.
도커는 정말 혁명인 것 같다. 물론 도커 말고도 모든 컨테이너 방식이 말이다. 환경설정 때문에 힘들어 한 나날들이 무색하게만 느껴지는데.. 특히 AI할 때는 최고이다!!
지원금이 나오기 때문에 AWS 클라우드를 사용하려고 했다. 하지만 일경험 지원금 지출 정책에 따라서 후불로 내야하는 AWS를 사용하지 못하게 됐다...
결국 크레딧 충전 방식인 RunPod이라는 클라우드를 사용했다.
우선 회원가입, 로그인 이런 부분을 프로젝트에서 배제했다.
이유는 AI에 좀 더 집중하기 위해서이다.

AWS 사용 가능할 줄 알고 설계한 구조이다.
AWS와 RunPod의 클라우드 방식이 다르기 때문에 위 구조를 기반으로 통신 구조만 살짝 변경했다.







소분류 4개씩 선정해서 4명이서 각자 맡아서 크롤링 작업을 진행했다.

{
"name": "반려동물용품",
"type": "대분류",
"children": [
{
"name": "개",
"type": "중분류",
"children": [
{
"name": "간식",
"type": "소분류",
"items": [
{
"productName": "[헬로도기] 동결건조 - 열빙어 50g",
"price": 6000,
"thumbnailUrls": [
"https://www.sujinpet.co.kr/upload/product/img1/img_largeupfilenm_1747720462_a.jpg"
],
"detailImageUrls": [
"https://www.sujinpet.co.kr/plugin/igeareditor/upload/editor_1747720305_a.jpg"
],
"countryOfOrigin": "",
"manufacturer": "",
"productUrl": "https://www.sujinpet.co.kr/front/product/product_detail.php?seq=16438&pinid="
},
...

gRPC는 Python(AI)와 Java간 통신할 때 사용한다.
syntax = "proto3";
package chatbot;
option java_multiple_files = true;
option java_package = "chatbot";
option java_outer_classname = "ChatbotProto";
service ChatInteractionService {
rpc SendQuery(QueryRequest) returns (RequestAck);
rpc StreamAnswer(stream AnswerRequest) returns (RequestAck);
}
message RequestAck {
string status = 1;
string message = 2;
}
message ChatLog {
int64 user_id = 1;
string chatlog_id = 2;
int32 type = 3;
string content = 4;
string image_url = 5;
string created_at = 6;
}
message QueryRequest {
int64 user_id = 1;
string chatlog_id = 2;
int32 type = 3;
string content = 4;
string image_url = 5;
string created_at = 6;
repeated ChatLog chatlogs = 7;
int32 comi_type = 8;
repeated string product_ids = 9;
}
message AnswerRequest {
int64 user_id = 1;
string chatlog_id = 2;
string content = 3;
}
챗봇에서 이미지를 전송할 수 있는 기능은 gRPC가 아닌,
HTTP를 사용해서 구현하였다.


QWEN 2.5 32B 모델을 선택하여 이미지 분석을 진행하고자 하였다.
하지만, 상세이미지 특성 상 height 길이가 상당한 경우가 있기 때문에 크롭하여 진행을 했어야 했다.
크롭을 해서 QWEN 모델로 이미지 추론을 하다 보니, 맥락 파악 성능이 저조했다.
예를 들어 강아지 장난감을 사람 장난감으로 분석을 한다든지, 이런 경우가 생겼다.
이로 인해, 아래와 같이 이미지 분석 프로세스를 수정했다.




vllm을 사용하여 Qwen3-32B-AWQ(4B) 모델을 사용하여 구현하였다.





홈에서는 신상품과 베스트 상품을 4개씩 보여지며, 찜과 평균별점을 확인할 수 있다.

홈 화면에서 챗봇을 이용하면, 스토어에 등록된 상품 중 소비자에게 적합한 제품을 추천한다.

내 pick 포함은 내가 '찜'한 상품 안에서 제품을 추천한다.


이미지를 임베딩해서 유사한 이미지를 찾아 추천한다.

마이페이지에서 코미 유형을 선택할 수 있다.
코미 유형은 '기본', '귀여운', '답정너' 스타일로 구성되어 있다.

아래는 귀여운 코미를 선택할 경우의 응답이다.

아래는 '답정너 스타일'로 선택할 셩우의 응답이다.


검색도 벡터서치로 이루어지며, 벡터 유사도가 높은 순서대로 제품이 정렬된다.

정적인 카테고리 검색 방법이다.

상세페이지는 기존 오픈마켓 스토어를 참고하여 제작했다.

상세페이지에서 챗봇을 사용하면 해당 상품에 대한 자세한 정보를 확인할 수 있다.

음.. 결론적으로 일경험 프로젝트에서 '우수상'을 수여했다.

하지만, 대상과 비교했을 때 어떤 점이 부족했을까 하고 팀원들고 대화를 나눴는데
무엇보다 '성능평가'에 대한 미흡을 뽑을 수 밖에 없었다.
앞으로 내가 더 공부해야할 부분은 '성능 평가'를 어떻게 하면 좋을까? 이다.
그리고 이 프로젝트에서 Open AI에 양보를 했어야 했던, 이미지 분석도 어떻게 하면 더 잘 할 수 있는지 연구가 필요하다고 생각한다.
RAG에 대한 공부가 조금 미흡하지 않았나 싶다.
정리하자면, 'RAG', '성능평가' 이렇게 2개 키워드가 우리가 대상이 아닌 '우수상'을 받았던 이유라고 생가한다.
그래도 우리 asdf팀 너무 잘했다~ 😁 다음에도 함께 하게 된다면 이 2가지를 보완해서 어디에서든 1등 하자!