네 개의 채팅 기능을 구축했습니다. 당연히 가장 현명한 선택이었습니다.
요약
본 글은 개발자가 AI 기능을 구현할 때 '직접 구축'하는 것이 가장 현명한 선택임을 강조합니다. 복잡한 외부 벤더 솔루션 대신, 자체적으로 필요한 기능만 갖춘 경량의 채팅 위젯을 만드는 접근 방식을 제시하며, 이를 통해 사용자 경험과 운영 효율성을 높일 수 있음을 설명합니다.
핵심 포인트
- AI 기능을 구현할 때 직접 구축하는 것이 가장 효과적입니다.
- 필요한 최소한의 기능(MVP)에 집중하여 개발해야 합니다.
- 외부 벤더 솔루션보다 자체 구축이 유연성과 통제력을 제공합니다.
개발자가 문제에 직면할 때, 첫 질문은 항상 “어떻게 해결할까?”가 아닐 때가 많습니다. 종종 “무엇을 가지고 해결할 것인가?”입니다. 직접 만들 것인가, 아니면 이미 만들어진 것을 사용할 것인가? 오픈 소스일까, 아니면 호스팅 서비스일까?
오늘날 AI를 가지고 있다면, 답은 명백해 보입니다:
“직접 구축하자! 우리 스스로가!”
왜 안 되겠습니까? 매머드 시대에 만들어진 오래되고 무겁고 느린 장치를 집으로 끌어오는 대신, AI가 점심 식사 전에 반짝이는 새것을 만들 수 있는데 말입니다?
우리는 그 선택 앞에 놓여 있었습니다. 돌이켜보면, 편집기를 열기 전에 우리가 했어야 할 비교는 이것입니다:
| 옵션 | 가져다주는 것 | 공개 가격 (USD) | 세부 사항 / “무게” |
|---|---|---|---|
| 직접 구축 | 원하는 호텔 FAQ 흐름과 정확히 일치하며, 필요하지 않은 받은 편지함이나 지원 기능은 없습니다 | 벤더 수수료 없음; 개발자 시간은 별도 판매 (아무래도) | 모든 버그, 통합, 업데이트 및 향후 기능이 당신에게 함께 옵니다 |
| ... |
여기는 2026년 10월 16일에 확인된 공개 가격 및 제품 설명의 스냅샷이며, 보편적인 기준은 아닙니다. 계획, 결제 조건 및 포함된 할당량은 변경될 수 있습니다. 링크된 벤더 페이지가 진실의 원천입니다. Chatwoot의 커뮤니티 코드는 MIT 라이선스이며, 자체 호스팅 가이드는 서버 요구 사항을 문서화합니다.
그리고 누군가 묻기 전에: 아닙니다, 이것은 번들 크기 비교가 아닙니다. 이 벤더들은 인용된 페이지에 직접적으로 비교 가능한 위젯 JavaScript 크기를 게시하지 않습니다. “무겁다”는 것은 다운로드된 바이트일 수도 있고, 작은 도시가 안에 있는 대시보드일 수도 있고, 청구서일 수도 있으며, Postgres와 Redis를 만족스럽게 유지하는 운영상의 부담일 수도 있습니다. 우리는 이 모든 것을 측정하지 않았기 때문에, 테이블을 더 과학적으로 보이게 하기 위해 킬로바이트 열을 만들지 않을 것입니다.
게시판 구축 전에 이 스프레드시트를 완성하지는 않았습니다. 저희에게 작고 구체적인 필요가 있었고, 작은 구체적인 위젯을 원했습니다. 이 스프레드시트는 이야기의 책임 있는 버전일 뿐이며, 실제 버전은 코딩을 시작한 후에야 패턴을 발견했다는 것입니다.
시작하게 된 사소한 문제
저희 호텔 웹사이트에 문제가 있었습니다. 관광객들이 그것들을 탐색해야 했기 때문입니다.
그들은 가격이 얼마인지, 무엇이 포함되어 있는지, 이동 서비스가 제공되는지 알고 싶어 했습니다. 물론 그 답은 사이트에 있었고, 어딘가에 존재했습니다. 보통 메뉴 뒤나 페이지 깊숙한 곳에 숨겨져 있어, 자신의 끈기를 시험하는 작지만 의미 있는 과정이 필요했습니다.
저희는 단순히 "방 가격이 얼마인가요?"라는 질문에 답하기 위해서 크고 의견이 많은(opinionated) 컴포넌트를 도입하고 싶지 않았습니다. 그래서 저희의 간단한 호텔 사이트에 작은 채팅 기능을 만들었습니다. 페이지에 배치하고, 기본적인 정보만 제공하며, 관광객들이 일반 언어로 질문하게 했습니다. 거창한 전략도, 플랫폼 로드맵도 필요하지 않았습니다. 단지 질문과 답변 사이에 클릭 횟수만 줄이면 되는 것이었습니다.
이렇게 많은 거대한 전략들은 시작됩니다. 즉, 거대한 전략이 없다고 주장하는 것에서부터 말입니다.
한편, 코드베이스의 다른 세 부분에서는…
저희는 택시 서비스도 구축하고 있었습니다. 승객들이 운전자와 대화할 방법이 필요했습니다.
저희는 금융 애플리케이션을 만들고 있었습니다. 고객들의 지원이 필요했습니다.
그리고 저희는 여전히 호텔 사이트를 구축하고 있었는데, 그 첫 번째 작은 채팅 기능은 꽤 좋은 아이디어처럼 보였습니다.
이 프로젝트들은 서로가 끝날 때까지 예의 바르게 줄 서서 기다리지 않았습니다. 이들은 병렬적으로 진행되었습니다. 이는 생산적인 작업 방식이지만, 주변을 둘러보고 동시에 네 개의 채팅 기능을 개발하고 있다는 것을 발견할 때까지는 말입니다.
네 개의 채팅 기능. 각각이 다른 세 개보다 더 좋았습니다. 당연하게도요.
그 문장은 엔지니어로 하여금 화재 경보기를 찾게 만들 것입니다. 저희는 근처에 없었기에, 아키텍처를 찾아보게 되었습니다.
평소의 복사-붙여넣기 전략이 완벽하게 작동했다
여기서 "완벽하게"라는 것은 모든 채팅 기능이 개선되고 있었다는 의미이며—그리고 그 어떤 것도 완전히 똑같은 방식으로 개선되지는 않았다는 뜻입니다.
하나의 기능은 유용한 상호작용을 포착했고, 다른 하나는 특정 워크플로우에 대한 더 나은 처리를 제공했습니다. 세 번째 것은 지원에 대해 무언가를 배웠습니다. 이 중 한 곳의 작은 것을 수정하면 나머지 세 곳은 평온하게 모르는 상태를 유지합니다. 그것들이 고장 난 것이 아니라, 단순히 같은 질문에 대한 네 개의 분리된 답변이 되어가고 있었던 것입니다.
그들 사이에서 수정을 복사하는 것은 가능했습니다. 자신에게 점점 더 엄격한 이메일을 보내면서 네 개의 캘린더를 유지 관리하는 것도 마찬가지입니다. 가능하다는 것이 계획과 같지는 않습니다.
중요한 깨달음은 제품들이 동일한 '행동(behavior)'을 필요로 하는 것이 아니라는 점이었습니다. 그들은 각 호스트 애플리케이션이 자체 행동을 공급할 수 있는 방식을 가진 동일한 '채팅 컴포넌트(chat component)'를 필요로 했습니다.
모든 것을 아우르는 하나의 채팅 기능
저희는 공유되는 부분들을 하나의 임베디드 인터페이스 뒤에 배치했습니다. 호스트 애플리케이션은 여전히 자체 데이터, 비즈니스 규칙 및 결정을 소유합니다. 채팅은 대화 표면을 제공하며 작업에 맞게 구성될 수 있습니다.
호텔 사이트의 경우, 시작점은 의도적으로 지루합니다:
<script src="https://chat.fodylabs.com/chat-engine.js" defer></script>
<script>
window.addEventListener('load', function () {
...
이 두 개의 플레이스홀더는 마법의 자격 증명(credentials)을 만들 필요가 없는 프로젝트 식별자입니다. FodyChat 대시보드에서 프로젝트를 생성하고, FAQ나 기타 지식을 추가한 다음, 생성된 임베드 스니펫을 복사하세요. 이것은 프로젝트 ID와 pub_… 공개 키를 제공합니다. ID는 FodyChat에게 어떤 프로젝트의 설정과 지식을 사용할지 알려주며; 공개 키는 위젯이 API를 호출할 때 해당 프로젝트를 식별합니다. 이는 페이지 소스에 나타나도록 되어 있으므로 비밀번호나 보안 정보가 아닙니다. 또한 프로젝트는 웹사이트의 출처(origin)를 허용해야 합니다.
'지루하다'는 표현은 여기서는 칭찬입니다. 비즈니스의 FAQ나 기본 정보를 추가하면, 방문자는 내비게이션을 통해 돌아가는 복잡한 경로를 거치지 않고도 질문할 수 있습니다.
FAQ가 라이브러리로 성장하면, 동일한 채팅 기능을 더 큰 지식 기반에 대한 검색(retrieval)을 사용할 수 있습니다. 애플리케이션이 실시간 데이터(live data)를 가지고 있다면, 해당 애플리케이션의 API를 호출할 수 있습니다. 만약 애플리케이션이 특정 동작(action)을 수행해야 한다면, 호스트가 그 동작을 명시적으로 허용하고 직접 처리할 수 있습니다.
채팅 기능은 성장할 수 있습니다. 첫날부터 엔터프라이즈 아키텍처를 갖추고 나타나야 하는 것은 아닙니다.
대화는 트랜잭션이 아니다
택시 애플리케이션을 통해 우리는 “채팅이 말했다”와 “시스템이 했다”의 차이에 대해 특히 주의해야 한다는 것을 배웠습니다.
승객은 나들이를 요청하고, 날짜와 시간을 알려주며, 몇 명이 올 것인지 말할 수 있습니다. 이는 유용한 초안(draft)입니다. 이것은 예약(booking)이 아닙니다. 주문이 제출되었다는 의미도 아니며, 운전기사가 승낙했다는 의미는 절대 아닙니다.
어시스턴트는 세부 사항을 준비하는 데 도움을 줄 수 있습니다. 현재 흐름에서 택시가 예약 양식, 유효성 검사(validation), 확인 및 실제 주문 상태를 소유하고 있습니다. 우리는 그 경계(boundary)를 선택했으며, 개발자는 주문을 제출하기 위한 다른 흐름을 승인할 수 있었습니다. 운전기사는 디스패치 시스템이 그렇게 말했기 때문에 배정되는 것이지, 언어 모델이 낙관적이 되었기 때문은 아닙니다.
이러한 경계는 금융 지원에서도 중요합니다. 채팅은 누군가가 정보를 찾거나 워크플로우를 탐색하는 데 도움을 줄 수 있습니다. 애플리케이션은 여전히 누가 로그인했는지, 그들이 무엇을 할 수 있는지, 그리고 어떤 작업이 실제로 발생했는지를 결정합니다.
다시 말해: 어시스턴트는 도움이 될 수는 있지만, 데이터베이스로 승격되지는 않습니다.
“채팅 기능을 구축하는 것”보다 더 작지만 유용한 문제들이 있었는데, 그것들을 잘 해결함으로써 경험을 훨씬 좋게 만들었습니다. 택시 승객은 주소를 입력하는 대신 어디로 가야 할지 구두로 지시할 수 있습니다. 채팅 기능이 장소를 찾고, 인-채팅 지도에 표시하며, 선택된 지점을 택시의 예약 양식으로 전달하고, 승객은 그곳에서 주문을 검토하고 확인할 수 있습니다.
음성 받아쓰기(Dictation) 기능은 방문자가 타이핑 대신 말할 수 있게 하며, 녹취록이 메시지 상자에 배치되어 전송 전에 검토할 수 있습니다. 또한 대화가 실제 운영자에게 전달될 경우, 메시지는 양방향으로 번역됩니다. Telegram이나 Slack의 운영자는 음성 메모로 답장할 수 있으며, 이는 녹취되고 게스트의 언어로 타이핑된 응답처럼 번역됩니다.
그리고 때로는 채팅이 그저 채팅일 뿐입니다
채팅과 AI가 동일한 유용한 정보에 연결되면, 우리는 그 작업을 한 곳 이상의 장소에서 재사용할 수 있습니다. 거의 추가적인 인프라 없이도, 기업은 방문자가 사이트를 탐색하는 대신 자연스럽게 질문하도록 할 수 있으며—그 잘 구조화된 지식을 생성 엔진 최적화(GEO)를 위한 실질적인 출발점으로 활용할 수 있습니다.
중요한 구분이 있습니다. 임베디드 채팅이 웹사이트를 외부 AI 검색 엔진에 자동으로 노출시키지는 않습니다. 사이트의 페이지나 robots.txt 파일을 재작성하지 않으며, 다른 AI가 크롤링하거나 해당 기업을 인용할 것이라고 약속할 수 없습니다. 이 GEO 기반이 무엇을 하고 무엇을 하지 않는지 저희는 공개 통합 가이드에서 설명합니다.
작업이 AI 클라이언트가 실시간 데이터를 직접 쿼리해야 하는 경우, 우리는 도구(tools) 또는 MCP를 통해 관련 API를 노출할 수 있습니다. 저희는 Radioller의 라이브 스테이션 카탈로그에 대해 그렇게 했습니다. 이것은 모든 채팅을 범용 MCP 서버로 바꾸는 버튼이 아니라 특정 통합입니다.
조금 더 미래를 내다본다면, 어쩌면 AI가 아침 커피를 마시거나—혹은 반쯤 형성된 생각—우리의 계획을 알아차리고 채팅이나 웹사이트 없이도 택시를 예약할지도 모릅니다. 그 미래는 1년 또는 2년 정도 남았을 수 있습니다. 시간을 좀 더 주도록 합시다.
그때까지, FodyChat과 플레이그라운드(playground)를 탐색해 보세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기