샘호트만
샘호트만
⚔️ 베테랑 파트너
🔬 임팩트 찐친

복자 봇의 두뇌 완전 해부, 저희 집 고양이의 머릿 속을 들여다봅시다. GPT-4.1-nano + Gemini + Perplexity 결합 후 실제 운영 사례와 인사이트

소개

단순한 키워드 응답이나 간단한 ai 단일 모델만 붙인 봇들은 저희 스터디원의 도파민을 채울 수 없습니다. 저희 집 고양이 복자봇을 질문 의도를 파악하고 상황에 맞는 AI 모델을 선택해 답변합니다. 메신저봇R에서 OpenAI, Gemini, Perplexity를 오케스트레이션하는 고양이 봇의 로직을 공개합니다. 의도분류부터 멀티 AI 활용까지, 실제 제가 지인분들이 있는 여러개의 방에 복자를 투입해서 운영하며 얻은 인사이트를 공유합니다. 빠른 프로토타이핑과 사용자 피드백의 중요성도 함께 다룹니다.

글 시작 전 졸고 있는 고양이 사진으로 출발합니다.

나무 의자 아래에서 자고있는 고양이

진행 방법

1) 전체 복자 봇 아키텍처: 단순 응답을 넘어 의도 파악으로

봇은 혼자 쓰면 크게 스트레스를 받을 일이 없습니다. 근데 저는 다양한 사람들이 사용하는 것을 목표로 했흡니다. "/복자"라고 부르면 무조건 고양이처럼 대답하는 봇. 하지만 사용자들의 질문은 다양합니다. 날씨를 물어보는데 "냥냥거리기만" 하면 귀엽긴 해도 효용감이 떨어집니다.

그래서 의도분류 시스템을 도입했습니다.
보통 챗봇을 만들 때 사용자의 질문에 대해 의도분류나 Query-Rewriting 하는 전략은 많이 사용하는데요.
우선 사용자가 무엇을 원하는지 먼저 파악하고, 그에 맞는 AI를 선택하는 건데요.
전체 아키텍처는 다음과 같습니다.

한국 사업의 흐름도

2) 핵심 구현: GPT-4.1-nano로 초고속 의도분류

의도분류의 핵심은 속도와 정확성입니다. GPT-4.1-nano를 선택한 이유도 여기 있죠.

저는 사용방법, 복자에 대한 페르소나 질문, 일반 상식에 대한 질문, ai 검색을 수행하게 했습니다.
또 다른 분기를 나누는 것에 대해서는 사용자의 행동들을 모아서 모니터링하여 반영할 예정입니다.

시스템 프롬프트 일부를 첨부합니다. (동적 프롬프트를 반영해서 시간에 대한 시의성 관련된 정보는 ai 검색을 의사결정하는데 활용하였습니다.)

var IntentClassifier = {
    classifyIntent: function(question, callback) {
        var systemPrompt = "현재 시간: " + currentDateTime + " (한국 시간)\n\n" +
            "사용자 카카오톡 메시지가 인입됩니다. 사용자 메시지의 의도를 하나의 카테고리로 명확하게 분류하세요.\n\n" +
            "**분류 기준 (하나만 선택):**\n\n" +
            "1. **사용방법 (usage)** - 봇 사용법 문의\n" +
            "2. **복자아이덴티티 (bokja)** - 복자 고양이 캐릭터와의 직접적 상호작용\n" +
            "3. **일반상식 (general)** - 기존 지식과 추론으로 답변 가능한 모든 질문\n" +
            "4. **ai검색 (aisearch)** - 실시간/최신 정보가 절대적으로 필요한 질문만\n";
            
        // JSON 응답 형식 강제
        response_format: { type: "json_object" }
    }
};

💡 Tip: JSON 응답 형식을 강제하면 파싱 오류를 크게 줄일 수 있습니다!


3) 사용자별 맞춤 응답: 집사 vs 일반인

복자는 집사(저)와 다른 사람을 구별합니다. 이 부분이 사용자들에게 큰 호응을 얻었습니다. 저에겐 따뜻하고 다른 사람에게는 조금 시크하게 답변하게 해놨습니다. 물론 너무 싸가지 없다고 피드백이 왔었기에 프롬프트를 어느정도 조절하였습니다.

4) Cursor로 프롬프트 체인 구조 해결하기

솔직히 의도분류 후 각 AI를 호출하는 프롬프트 체인 구조를 짜는 게 제일 어려웠습니다. 비동기 처리, 에러 핸들링, 타임아웃... 머리가 아팠죠.

그런데 Cursor를 활용하니 이야기가 달라졌습니다. "의도분류 결과에 따라 다른 AI 모델을 호출하는 구조를 만들어줘"라고 요청하니 깔끔한 콜백 구조를 제안해줬어요.

// Cursor가 제안한 깔끔한 응답 생성 구조
ResponseGenerator.generateResponse(msg, function(error, intent) {
    switch(intent) {
        case 'usage':
            callback(null, "사용법 안내 메시지");
            break;
        case 'bokja':
            AIHandler.handleBokja(question, userName, callback);
            break;
        case 'general':
            AIHandler.handleGeneralKnowledge(question, callback);
            break;
        case 'aisearch':
            AIHandler.handleAISearch(question, callback);
            break;
    }
});

Rhino JS 코드를 디버깅 및 고도화 시 Cursor를 활용할 때에는 스터디장 복받어김현우 님 지침을 일부 활용하여 문서로 세팅하고 문제를 풀었습니다.

5) 실제 언어모델 사용 케이스

저랑 복자랑 1대1 대화를 할 때에는 로그를 남깁니다.

5-1) 복자와 직접적인 이야기를 할 때 (gpt-4.1-nano)

5-2) ai 검색 Case (perplexity)

예전에는 https://ai.google.dev/gemini-api/docs/google-search?hl=ko 구글에서 검색 도구가 지원되어서 사용했었는데 답변이 출력이 안되거나 조금씩 느렸던 케이스가 있었습니다. 잘못된 케이스는 다음과 같습니다.

한국인 두 사람 간의 대화의 스크린 샷
검은 색 화면에 한국 문자 메시지 스크린 샷

그래서 퍼플렉시티로 변경하였습니다. sonar 모델을 활용합니다. 지피터스는 잘 알고 있습니다. 퍼플렉시티 특성상 완전 최신 쪽 검색을 하려면 검색 세부조건 파라미터를 건드려야할 거 같습니다.

지인 분들도 쓰는 것을 보고 효용감을 느낀 케이스였습니다.

한국 문자 메시지의 스크린 샷

5-3) 일반 상식에 대한 이야기를 나눌 때

저는 답변의 다양성을 확보하기위해 사용자가 일반적인 질문을 하면 gpt-4.1-mini, gemini 2.5 flash 모델이 랜덤으로 선택되어 답변하게 했습니다. 실제로 일반 상식에 대해서는 일관성보다는 다양성을 주면서 답변을 주는게 복자와 대화하는데 재미를 줄 수 있지 않을까? 판단하여 이렇게 운영하고 있습니다.

아래 이미지는 제가 유튜브 촬영하면서 라이브로 활용하면서 썼는데 꽤 답변이 좋더군요.

한국 문자 메시지의 스크린 샷

6) 실사용자 피드백: 예상과 다른 니즈들

"냥이체로 날씨 알려주니 귀엽네요!"

"검색 결과까지 냥냥거리는 건 좀..."

재밌는 건, 사용자 반응이 극명하게 갈렸다는 점입니다.

  • 복자와의 대화: "냥이체 귀여워요! 더 고양이답게 해주세요!"

  • AI 검색 결과: "정보는 정확하게 전달해주세요"

결국 의도별로 응답 스타일을 다르게 적용했습니다. 이 부분은 조금 더 개발해보면서 생각을 해봐야 할 부분인 것 같습니다.:

  • bokja: 완전한 고양이 페르소나

  • general, aisearch: 정보 전달 우선, 마지막에만 "~다냥" 추가

아래 대화 내용은 제 지인 분이 롤백을 해달라고 했던 대화 케이스였습니다. 실제 톤과 아이덴티티는 누군가에게는 중요한 케이스로 다가왔었습니다.

한국어 문자 메시지의 스크린 샷

추후에는

따로 더 개발할 것이 뭐가 있을까? 아직은 고민 안 해봤는데 프롬프트의 중요성을 모르는 사용자는 대충 던졌을 때 좋은 답변을 얻는 것을 좋아하기 때문에 Query re-Writing 쪽 전략을 고민하고 있습니다. (api 비용이 더 들기는 하지만요)

결과와 배운 점

기술적 완성도보다 빠른 출시와 피드백이 핵심이었습니다.

완벽한 의도분류를 추구하기보다 실사용 데이터로 개선하는 것이 효과적이었습니다.

주요 성과:

  • 질문 유형별 최적화된 응답 제공

  • 사용자 만족도 향상 (특히 실시간 정보 검색)

  • 모듈화된 구조로 확장성 확보

깨달은 점:

  • MVP 먼저, 완벽은 나중에

  • 사용자 니즈는 예상과 다를 수 있음

  • 좋은 도구(Cursor)가 개발 속도를 좌우

전체 코드는 GitHub에 공개 예정입니다. (기다려주세요)

이 로직을 참고해 저희 스터디원 분들의 봇들 지능을 한 단계 퀀텀 점프하길 기대합니다!

글 작성하는데 걸린 시간 : 1시간 10분

  • 하고자 하는 이야기, 개요 정리 : 0분

  • 구현하는 데 걸린 시간 : 만들어져 있던 것을 활용함

  • 초안 글 작성 : 10분 (AI와 원만한 대화함. 은철님이 만든 지침을 재활용해서 따로 클로드에서 활용함)

  • 글 수정 : 55분 (실제 대화했었던 대화 내용 캡처하고 재활용)

  • 셀프 글 피드백 : 5분 (글 흐름 점검 )

(글의 8할 이상이 Ai가 작성한 글임을 알립니다.)

이전 관련 글

https://www.gpters.org/nocode/post/kakaotalk-originally-used-like-oSb4F5vHfMW1MjF

3
2개의 답글

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요