DRC의 보험사를 위한 오픈 소스 WhatsApp 클레임 봇 구축 방법
요약
RapidOS는 보험사가 WhatsApp을 통해 받는 클레임 접수 과정을 자동화하는 오픈 소스 솔루션입니다. 이 시스템은 WhatsApp 어시스턴트와 대시보드를 결합하여, 고객의 언어로 받은 클레임을 구조화된 PDF 파일로 변환합니다. 개발자는 Go API, Next.js 대시보드 등을 사용하여 자체 호스팅 및 다양한 AI 모델(Gemini, OpenAI 등)을 지원하는 아키텍처를 구축했습니다.
핵심 포인트
- WhatsApp 웹훅과 AI를 결합하여 클레임 접수 자동화
- Go/Next.js 스택으로 구성된 오픈 소스 솔루션 제공
- 다양한 AI 모델(Gemini, OpenAI 등) 및 자체 호스팅 지원
- 클레임을 구조화된 PDF 파일로 변환하여 업무 효율성 증대
DRC의 보험사를 위한 오픈 소스 WhatsApp 클레임 봇 구축 방법
킨샤사에서는 아무도 온라인 클레임 양식을 작성하지 않습니다. 만약 당신의 차가 부르베르 부 30 Juin에서 미니버스로 인해 파손되었다면, 사진을 찍어 아는 보험사 담당자에게 WhatsApp 메시지를 보냅니다. 이 메시지는 개인 휴대폰에 도착하고, 사진들은 채팅방 속에서 분실되며, 누군가가 나중에 시스템에 클레임을 입력합니다. 심지어 그 과정 자체가 이루어지지 않을 때도 있습니다.
RapidOS는 이러한 문제를 해결하려는 저의 시도입니다. 이는 WhatsApp 어시스턴트와 대시보드를 결합한 형태입니다. 보험사는 자체 WhatsApp Business 번호와 자체 AI 키를 연결하고, 어시스턴트는 고객의 언어로 클레임을 수집하며, 클레임 팀은 PDF가 포함된 완전하고 구조화된 파일을 받게 됩니다. 이 시스템은 AGPL-3.0 하에 오픈 소스로 제공되며, 단 하나의 docker compose up 명령으로 실행할 수 있습니다.
이 글에서는 작동 방식과 예상보다 어려웠던 점들을 다룹니다.
아키텍처
총 네 가지 서비스로 구성되어 있습니다:
- Go API (Gin, GORM): Meta의 웹훅을 수신하고, 회사의 AI 제공업체와 대화를 진행하며, WhatsApp Cloud API를 통해 답장을 보냅니다.
- Next.js 대시보드 (Prisma): 클레임, 고객, 대화, 사용자 및 설정을 관리합니다. 또한 클레임 PDF도 생성합니다.
- 모든 영구 데이터 저장은 Postgres를 사용하며, 속도 제한(rate limiting)은 Redis를 사용합니다.
- 다른 서비스들이 시작되기 전에
prisma migrate deploy를 실행하는 일회성 migrate 컨테이너가 있습니다.
하나의 설치로 여러 회사가 이용할 수 있습니다. 각 회사마다 자체 WhatsApp 번호, AI 제공업체, 보장 유형(coverage types), 팀 및 역할(super admin, admin, moderator, agent, viewer)을 가집니다. WhatsApp 토큰과 AI 키는 암호화되어 저장되며 UI에서는 마스킹 처리되어 표시됩니다.
자체 WhatsApp 번호와 AI 키 연결하기
RapidOS가 중개자가 되는 것을 원하지 않았습니다. 각 회사는 자체 WhatsApp Cloud API 자격 증명을 붙여넣고 Meta에서 웹훅을 등록합니다. 웹훅 경로는 고정되어 있으며(/api/v1/whatsapp/webhook), API는 Meta의 GET 챌린지를 각 회사가 저장한 검증 토큰과 대조하므로, 토큰 변경이 즉시 적용됩니다. POST 요청은 회사 앱 비밀 키를 사용하여 본문에 대한 HMAC-SHA256인 X-Hub-Signature-256을 통해 확인합니다.
AI의 경우, 하나의 인터페이스 뒤에 두 가지 클라이언트 구현체가 있습니다: Gemini와 OpenAI 호환 클라이언트로, 이 클라이언트는 OpenAI, DeepSeek, Qwen 및 Ollama나 vLLM과 같은 자체 호스팅 환경까지 지원합니다. 고객 데이터를 클라우드 모델로 전송할 수 없는 회사는 RapidOS를 http://host.docker.internal:11434/v1을 가리키게 하여 모든 것을 자체 하드웨어에 유지할 수 있습니다. 한 가지 실질적인 단점은 다음과 같습니다: Ollama는 유휴 상태의 모델을 5분 후에 언로드하므로, 다음 고객이 온 콜드 로드를 위해 10~30초를 기다려야 합니다. OLLAMA_KEEP_ALIVE 설정을 하면 이 문제를 해결할 수 있습니다.
웹훅: 빠르게 응답하고 순서대로 처리하기
Meta는 빠른 200 응답을 원하며, 메시지 전송 실패 시 재시도합니다. 고객들은 또한 폭발적인 양의 메시지를 보냅니다: 2초 이내에 사진 세 장과 문장 하나를 보내는 식입니다. 따라서 핸들러는 즉시 확인(acknowledge)하고 메시지를 디스패처에게 전달합니다. 동일한 대화(회사 + 발신자)에서 온 메시지는 도착 순서대로 하나씩 실행됩니다. 다른 대화들은 병렬로 실행됩니다. 최근에 본 메시지 ID는 건너뛰어지고, 데이터베이스 중복 제거 기능이 진실의 원천으로 남아 있습니다. 대화별 순서가 없으면, 동시에 처리된 두 개의 메시지가 동일한 클레임 초안을 업데이트할 수 있습니다.
아무것도 발명하지 않고 채팅에서 클레임을 추출하는 방법
이 부분이 가장 오래 걸렸습니다. 플로우는 다음과 같습니다:
보장 유형(auto, home, health 등)에 필요한 필드와 문서를 정의합니다. 가입 시에는 합리적인 기본값(sensible defaults)이 설정됩니다.
매 턴마다 모델은 해당 필드를 기반으로 추출 도구를 얻고 가능한 정보를 채웁니다.
근거화(Grounding): 추출된 모든 값은 고객이 실제로 작성한 내용에 의해 뒷받침되어야 합니다. 고객의 메시지에 없는 정책 번호, 차량 번호판 또는 날짜는 표시되거나 저장되기 전에 제외됩니다. 각 필드 유형(ID, 전화번호, 날짜, 숫자, 자유 텍스트)에는 자체 매처가 있습니다.
부분 청구서("초안")는 메시지 메타데이터에 포함되어 다음 턴에서 이를 이어서 진행합니다. 챗봇은 누락된 정보만 요청합니다.
초안이 완성되면, 챗봇이 내용을 다시 읽어주고 고객은 예(YES), 아니오(NO)(수정할 경우), 또는 취소(CANCEL)로 답변합니다.
청구서가 번호와 함께 생성되고, 대화 중에 전송된 사진들이 첨부되며, PDF 파일이 생성되고, 팀은 이를 대시보드에서 확인할 수 있습니다.
근거화 단계가 필요한 이유: LLM은 정책 번호를 "도움이 되게" 완성하는 경향이 있습니다. 보험 분야에서 지어낸 정책 번호는 누락된 것보다 더 나쁩니다. 또한 저는 실제 환경의 복잡성도 처리해야 했습니다. 근사한 날짜("지난 화요일쯤이었던 것 같아요")나 고객이 대화 중간에 스스로 정정하는 경우("사실은 아내 차였어요, 2014년식 혼다 Fit요") 등이 있습니다. 이런 경우에는 차량 필드들이 섞이는 것이 아니라 함께 대체되어야 합니다.
15개 언어 지원 및 투명성
대시보드와 어시스턴트는 다음 15개 언어를 지원합니다: 영어, 프랑스어, 포르투갈어, 스페인어, 아랍어(오른쪽에서 왼쪽), 스와힐리어, 링갈라어, 하우사어, 요루바어, 암하라어, 힌디어, 벵골어, 베트남어, 인도네시아어, 필리피노어. 기본적으로 어시스턴트는 회사 측의 언어가 아닌 고객이 작성한 언어로 답변합니다.
탐지(Detection)는 또 다른 모델 호출이 아니라 작은 결정론적 휴리스틱입니다. 비라틴 문자 스크립트는 즉시 판단하며, 라틴 문자 스크립트 언어는 언어별 불용어("mbote", "nalingi" 및 Lingala의 "motuka", Swahili의 "habari" 및 "ajali")를 사용하여 점수를 매깁니다. 확신할 수 없는 경우("ok", 이모지, 숫자)에는 아무것도 반환하지 않고 현재 언어를 유지합니다.
솔직히 말하자면: 영어와 프랑스는 검토되고 있습니다. 나머지 13개 언어는 기계 번역되었으며 언어 선택기에서 "커뮤니티 검토 필요"로 표시됩니다. PDF 문서는 영어, 프랑스어, 스페인어, 포르투갈어, 스와힐리어로 완벽하게 번역되었고, 다른 언어들은 현재 영어 PDF를 제공합니다. 만약 원어민이시라면, 로케일(locale)을 검토하는 것은 두 개의 JSON 파일과 하나의 검사기 스크립트가 필요합니다.
인간의 통제 하에 유지 (Humans stay in charge)
모든 대화는 대시보드에서 확인할 수 있습니다. 직원은 특정 대화를 일시 중지하고 직접 답장할 수 있습니다. 일시 중지된 동안 해당 고객에게 대한 자동 WhatsApp 상태 업데이트는 보류되므로, 고객은 사람이 진행하는 대화 도중에 봇 메시지를 받지 않습니다. 직원이 청구 건(claim)의 상태를 변경하면, 업데이트된 PDF와 함께 고객에게 WhatsApp으로 통보됩니다.
각 WhatsApp 번호는 하나의 고객 기록이며, 재방문 고객도 인식하므로 한 사람이 시간이 지나면서 여러 개의 청구 건을 가질 수 있습니다.
오픈 소스인 이유와 AGPL인 이유 (Why open source, and why AGPL)
신흥 시장의 보험사들은 종종 고객 데이터를 국내에 유지해야 할 필요가 있으며, 많은 경우 새로운 것을 시도하기 위해 엔터프라이즈 계약을 정당화할 수 없습니다. 오픈 소스는 이 두 가지 문제를 모두 해결합니다: 직접 실행하고 무료입니다. AGPL-3.0은 서비스로 수정된 버전을 제공하는 모든 사람이 자신의 변경 사항을 공유해야 함을 의미합니다. 저는 호스팅 버전으로 프로젝트에 자금을 지원하고, WhatsApp Business 온보딩이 까다롭기 때문에 설정도 돕습니다.
청구 건을 넘어 (Beyond claims)
근본적으로 RapidOS는 구조화된 접수(structured intake)를 갖춘 WhatsApp 지원 데스크입니다. 신흥 시장의 은행, 통신사, 공공 시설 및 클리닉은 모두 "개인 휴대폰으로 메시지가 오는" 문제를 안고 있습니다. 청구 건 처리는 제가 시작한 부분일 뿐입니다.
사용해 보기 (Try it)
git clone https://github.com/raphmwanza/RapidOS-open-source.git rapidos
cd rapidos && cp .env.example .env
docker compose up -d --build
...
- Repo: https://github.com/raphmwanza/RapidOS-open-source
- Docs and hosted version: https://rapidos243.com
WhatsApp Business API를 이용해 구축했거나 신흥 시장에서 지원 업무를 해보신 분들은 제가 무엇을 잘못 이해했는지 꼭 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기