이코에코(Eco²)가 2025 새싹톤 우수상에 선정됐다. 10월 30일 즘부터 시작했으니 한 달간 Cluade/GPT와 골방 작업을 이어와서 체력과 몰골..이 말이 아니었다. 대부분의 시간은 API 개발보단 K8s 클러스터 + Gitops 구축 및 개발에 소요했다. 25년은 클라우드 스토리지 / 네트워크가 주스택이었던 만큼 코드 기반 인프라 역량을 내세우고 싶던 면이 컸다. 본선에서도 배포 환경에서 개선/테스트가 발표 직전까지 진행됐기에 배포 파이프라인은 쓰임을 다한 편이다. FastAPI 기반 백엔드 API는 얇디얇아서 API 측면에선 도메인별 서비스를 분리한 점 외에는 딱히 내세울 지점은 없었다. GPT 5.1 Codex가 없었으면 이런 방식으로 구성하긴 힘들었겠지만, 파이썬/FastAPI 코드를 읽을 수 있고 Spring으로 분산된 API를 짰던 경험은 있으니 바이브코딩으로도 각종 상황에 대응할 수 있었다고 본다.
본선날에 주로 수행했던 작업은 AI Chat과 Scan 조정, 버그 픽스였다. 프론트 측의 요구에 맞게 Chat의 답변이 정갈하게 나오도록 조정할 필요가 있었다. 이외에도 AI 파트에서 성능을 높이기 위한 작업들(Classification 프롬프트 수정, 분류 체계 정비)이 계속 진행됐지만 배포된 API 성능이 올라가지 않았다. ArgoCD와 CI 파이프라인을 살폈을 땐 싱크 여부와 배포 시간 및 버전, 패키징된 코드와 백엔드 측 로컬 / 배포 스펙이 일치했다. AI 파이프라인에서 프롬프트와 데이터가 주입되는 지점을 INFO, DEBUG 레벨 로그로 확인해도 업데이트된 프롬프트가 파드로 잘 패키징이 되어있던 상태여서 '이게 왜 적용이 안되지..?'라는 상황이 반복됐다.
모델에게 주입되는 시스템 프롬프트 중 일부
AI 파이프라인은 Vision Classification -> Rule-based retrieval -> disposal rules -> answer로 구성돼 있다. Classification에선 분리배출 누리집 정보를 바탕으로 만든 yaml 기반 계층적 분류 체계를 모델에 주입해 이미지를 분류한다. Rule-based retrieval에서 분류 결과를 키로 활용해 JSON 기반 지식 베이스에서 배출 방법을 검색하고, 시스템 프롬프트에 부정 제약 조건을 명시해 LLM이 주입된 컨택스트 내에서 근거 기반 생성(Grounding)을 하도록 강제한다. 정의된 분류 체계에 속하지 않는 입력은 즉시 파이프라인을 이탈(Fail-fast)한다. 이러한 조치는 LLM의 유연성을 제한하지만 할루시네이션을 극도로 줄일 수 있기에 답변의 품질을 높일 수 있다. Disposal step에서 LLM이 구조화된 JSON으로 출력하도록 강제하기에, Character API(internal)에서 별도의 추가 정제 과정 없이 결정론적 인터페이스에 따라 매칭시키는 게 가능해진다. 13종의 캐릭터는 재활용 중분류 태그에 따라 제작된 상태여서 캐릭터 스키마에 중분류 태그를 match 칼럼으로 추가해 1:1 대응을 시킨 상황이었다.
scan api의 답변 예시, 위 이미지의 경우 insufficiencies가 존재해 보상이 비어있는 걸 확인할 수 있다.
Character API(internal)은 Scan API에서 보상 트리거가 활성화된 경우에만 호출한다. (Scan -> Character -> Scan) Scan에서 모델이 생성한 JSON에 insufficient 태그가 하나라도 존재하면 트리거가 활성화되지 않도록 구성했다. Input Image가 분류 체계에 속하지 않아 파이프라인을 이탈하는 경우는 프론트 측과 합의해 분류 판정 실패 페이지로 가도록 해 UX로 푸는 방식을 택했다. 배포된 Chat API는 위 AI 파이프라인에 더해 백엔드(본인) 편의로 추가한 사용자 대화 캐싱 + 세션 기반 히스토리를 포함시켜 주입을 하고 있었다. 이 과정에 저장 로직도 섞여있던 터라 응답시간이 5-8초 남짓으로 로컬 AI 파이프라인보다 정확도와 속도가 낮은 상태였다. 모델은 GPT 5.1로 고정이 돼있었으니, AI 파이프라인의 프롬프트와 정보 체계 외 백엔드 캐싱 + 히스토리 로직을 거치며 오염된 정보들이 추가로 주입되는 상태라 판단했다.
Chat에 있던 캐싱 + 세션 기반 히스토리 주입 로직을 모두 제거하고, 사용자 입력 분기별로 적합한 AI 파이프라인만 타도록 수정한 결과 Chat의 답변이 안정되었다. Chat의 답변 수정 요구가 떠오른 건 12월 2일 0-1시, 원인 파악 및 대응은 당일 새벽 2-3시에 끝났지만 이때는 한창 프론트와 디자인에서 시연영상을 만들고 있던 때라 Chat 엔드포인트가 어떤 이유로도 다운 혹은 훼손되면 안 됐다. 백엔드 클러스터는 Dev/Prod 배포 환경 분리가 이뤄지지 않은 상태여서 무작정 코드를 배포할 수 없었기에 /api/v1/{chat | scan}을 /api/{v1 | v2}/{chat | scan}으로 엔드포인트를 분할해 개발->배포->테스트를 이어가는 방식을 택했다. Scan도 Chat과 동일한 파이프라인을 타니, 이젠 AI 파트가 수정을 진행하고 싶다면 언제든 배포된 클러스터에 즉시 반영할 수 있는 상태가 됐다. 이때부턴 긴장이 싹 풀렸다. 그전까지는 '이거 잘못하면 서비스가 클러스터에 압사 당하겠다.' 싶어 전전긍긍했다.
이코에코는 Scan의 성능이 우수한 게 강점이었다. (마지막 시연 때 한 번 오판이 나긴 했지만, 생성형 AI라 쩔수다.) 디자인된 캐릭터와 UI도 예쁜 편이라 분리수거라는 주제만 벗어나면 시장성이 확 넓어질 거란 심사 피드백이 주였다. 첫 심사 때부터 마지막까지 시장성의 한계와 서비스 사이클(1회성 사용)에 대한 피드백이 많았다. B2C에서 서비스가 진행되려면 비즈니스 모델이 유저에게 직관적이고 날카롭게 어필돼야 한다는 인상을 받았다. 심사평만 봤을 땐 '수상은 힘드려나..'싶었다. 14-nodes 및 LB, CDN 등 인프라 구축, 운용으로 청구된 비용만 60만원/month, 클러스터, 배포 파이프라인, API 구현에 사용한 LLM 토큰 40억개, 체력과 외관을 갈아 넣은 한 달간의 골방생활이 물거품이 될 수도 있겠다 싶어 심히 다운된 상태였다. 이코에코가 우수상 수상팀으로 불렸을 땐 문자 그대로 눈이랑 속이 시원해지는 기분을 받았다.
DDP가 춥긴 해도 밥은 잘줬다. 나눠져 있는 API들이 불안불안할 땐 진짜 밥도 안넘어가더라.
프론트 팀은 수상 때 울기도 했다. AI와 프론트는 업무랑 병행하던 상황이고, 디자인의 경우 석사 과정 말미던 상황이어서 강도가 더 높았을 거다. 온전히 프로젝트만 하던 사람은 나밖에 없었다. Chat API에서 정갈한 답변이 나오지 않는 상황이니 '이러다 라이브 서비스가 흔들리면 어쩌지'라는 압박감이 심했을 거라 생각한다. 백엔드만 봤을 때 구현, 배포, 인프라 면에선 타 팀 대비 비교우위에 있긴 했지만, 펼쳐놓은 클러스터가 팀에 부메랑으로 전파된 상황이라 머쓱했다. API 안정화시키고 수상해서 다행이다. 안 그랬으면 PPT에서 이름 지워질 뻔했다.
인프라+백엔드의 작업량이 타파트 대비 많았더라도 API가 흔들리면 안 됐다. 본선에서 작업을 이어가며 설명과 근거, 백엔드와 클러스터 현황을 전달했지만 API가 흔들리면 신뢰가 떨어질 수밖에 없다. 클러스터 로그를 보여주거나 OpenDocs, md, 블로그 포스팅으로 문서화하고, 대시보드와 코드를 보여주며 설명을 덧붙여도, 타파트 입장에선 ‘현재 클러스터가 어떤 상태인지, 어느 시점의 코드가 배포된 건지’ 직관적으로 인지하기 어려운 경우가 많다. 그러니 ‘늦지 않게, 기능이 깔끔하게 동작하는 API‘가 타파트 입장에선 아무래도 베스트다. 만약 팀원들끼리 어떤 이유라도 상대방을 못 믿는 상황이 되거나, 서로의 신뢰를 깎는 언행이 반복된다면.. 정말 큰 사고다. 그렇게 되면 일이 진행 자체가 안된다. 프로젝트에 들어갈 때마다 ‘일단 믿어라.‘는 말을 괜히 하는 게 아니다. 전에도 지나가듯 언급했지만 LLM이 없던 학부시절부터 현재까지 참여한 모든 사이드 프젝은 배포, 시연, e2e까지 어떻게든 끌고 갔다. (그러니 믿어라.)
획득할 수 있는 캐릭터는 총 13종이다. 분리수거 누리집의 재활용품 카테고리 중 중분류를 기준으로 캐릭터와 매칭을 시켰다. (2레벨)
수상도 했고, 클러스터도 정상동작에, 시연도 잘됐으며 현재까지도 문제없이 배포 중이지만 어딘지 모르게 찝찝하다.. 그만큼 애살이 붙었다는 걸로 이해하면 좋겠다. (난 아직 배고프다. 그치만 지쳤다.) 이제 이코에코도 마무리됐으니, 백엔드 API랑 인프라 코드 정비하고 다시 이력서 넣을 시간이다. 당분간은 재취준 + 개발 정비만 쭉 할 듯싶다. 일단은 미뤄뒀던 미용실부터 다녀오는 게 먼저긴 하다. 코드 + 건강 면에서 정비가 끝나면 이코에코 개발기를 이어서 작성할 예정이다. 연말 잘 보내길 바란다.