새벽 2시 17분. Slack #ops 채널에 inbound 알림이 한 줄 떠 있었습니다. 일본 오사카의 한 제조 업체 담당자가 5ya.io 문의 폼에 "AI 봇 도입을 검토 중인데, 30분만 통화 가능하냐"고 남겼더군요. 그 메시지는 영업일 시작까지 9시간을 답장 없이 그대로 떠 있었습니다. 그날 오전 회의에서 결정했습니다 — 우리도 봇을 직접 빌드한다.
이 시리즈는 우리가 손으로 빌드한 AI 도구들의 운영 노트입니다. 첫 회는 자사 inbound 처리 봇.

왜 SaaS 챗봇 대신 직접 만들었나
외부 챗봇 SaaS 두 곳을 한 주 정도 비교했습니다. FAQ 응대까지는 어느 쪽이든 무난했지만, 우리가 받는 inbound 의 70% 이상은 단순 질문이 아니라 BoFu 상담 요청이었습니다. "월 100만원대 PoC 가능한가" "제조업 사례 보여줄 수 있나" 같은 결재자 톤의 문의에 미리 짜둔 흐름도 답변으로는 응대 품질이 들쭉날쭉했습니다.
저는 처음엔 그냥 Claude API 를 한 번 호출하는 스크립트로 충분하다고 봤습니다. 실제로 돌려보니 다른 문제가 튀어나왔습니다. 문의 분류·이전 대화 회수·CRM 업데이트·내부 검토 큐 — 한 호출로 묶기 시작하니 프롬프트가 800줄을 넘어갔고, 실패 한 번이면 모든 단계가 같이 무너졌습니다.
아키텍처 한 장 — Claude · LangGraph · OpenRouter
네 번째 시안에서 다음 조합으로 좁혔습니다.
- Claude Opus 4.7 — 긴 컨텍스트와 톤 안정성. 결재자 문의는 한 줄 응답이 아니라 4~6문장의 무게감 있는 회신이 필요합니다.
- LangGraph — 노드와 엣지로 상태 흐름을 직접 그리는 라이브러리. 분류·리서치·초안·검토를 별도 노드로 쪼개니 실패 지점에서만 재개할 수 있습니다.
- OpenRouter — 모델 게이트웨이. 가벼운 분류 단계는 Haiku 4.5 로, 본문 작성은 Opus 4.7 로 라우팅해 비용을 눌렀습니다.
비용은 모델 교체로 크게 흔들렸습니다.
| 모델 | 입력 (1M 토큰) | 출력 (1M 토큰) |
|---|---|---|
| Claude Opus 4 (구버전) | $15 | $75 |
| Claude Opus 4.6 / 4.7 | $5 | $25 |
같은 회신 1건당 토큰 단가가 1/3 수준으로 떨어졌습니다. 4주차에 누적 API 비용이 약 18만원 — 사람 한 명의 야간 응대 시간으로 환산하면 비교가 무의미한 수준이었습니다.
LangGraph 그래프 — 5개 노드
그래프 골격만 간단히 옮기면 이렇습니다.
from langgraph.graph import StateGraph, END
graph = StateGraph(InboundState)
graph.add_node("classify", classify_intent)
graph.add_node("research", fetch_context)
graph.add_node("draft", draft_reply_with_claude)
graph.add_node("review_queue", push_to_slack)
graph.add_node("crm_sync", upsert_to_crm)
graph.set_entry_point("classify")
graph.add_conditional_edges(
"classify",
lambda s: "research" if s["intent"] == "lead" else END,
)
graph.add_edge("research", "draft")
graph.add_edge("draft", "review_queue")
graph.add_edge("review_queue", "crm_sync")
graph.add_edge("crm_sync", END)
핵심은 두 가지였습니다. 첫째, classify 노드에서 단순 FAQ 와 리드를 갈라 리드만 무거운 파이프를 태웠습니다. 둘째, review_queue 노드는 봇이 작성한 회신 초안을 Slack 채널에 던지고 사람이 한 번 검수한 뒤에야 발송되도록 막아 두었습니다. 자동화의 마지막 1cm 는 의도적으로 사람에게 남긴 셈입니다. 우리 팀이 4주 동안 가장 잘했다고 자평하는 결정이기도 합니다.
4주 운영, 숫자로 본 풍경
4월 28일부터 5월 25일까지의 4주 데이터입니다.
- 처리한 inbound: 142건 (FAQ 89 / 리드 53)
- 평균 초안 작성 시간: 47초
- 야간(22시~9시) 응답률: 100% (전 회차 봇 초안 → 다음 영업일 9시 일괄 검수 발송)
- 사람 검수에서 수정 발생률: 31%
- 봇 초안 그대로 발송: 69%
수정 발생률 31% 가 처음엔 높게 느껴졌습니다. 그런데 한 건씩 뜯어 보니 절반 가까이는 "이메일 끝인사 한 줄 추가" "약속 시간 후보 한 줄 보강" 같은 가벼운 손질이었습니다. 톤·사실관계가 무너진 건 4주 동안 4건. 그중 2건은 봇이 자사 가격을 임의로 추정해 답한 사례였고, 즉시 프롬프트에 "가격은 절대 직접 답하지 말고 무료 진단 권유로 돌려라" 가드를 박았습니다. 솔직히 말하면 이 부분은 운영 룰을 쥐어짜는 쪽에 가까웠고, 코드 한 줄로 깔끔히 끝나는 종류의 문제가 아니었습니다.
응답률 100% 라고 적으니 거창해 보이지만, 풀어 말하면 "새벽에 들어온 일본 결재자 문의가 한국 영업시간 시작 시점에 검수 가능한 초안 상태로 대기"라는 뜻입니다. 이전엔 9시간 동안 비어 있던 자리에 사람 손길이 한 번 닿아 있는 풍경이 됐습니다.
막힌 지점 두 가지, 그리고 운영 룰
환각은 끝까지 0이 되지 않았습니다. 다국어도 문제였습니다 — 일본어로 들어온 문의에 한국식 어순이 새어 나간 회신이 두 번 있었습니다. 우리는 이 두 가지를 코드가 아니라 운영 룰로 풀었습니다. "발송 전 사람 검수 1회"라는 마지막 노드가 그것입니다. 자세한 빌드 방식은 AI 자동화 서비스 소개 페이지에 시나리오별로 정리해 두었습니다.
마무리 — 봇은 사람을 줄이는 도구가 아니다
한국 중소기업 사장님께서 이런 말씀을 하신 적이 있습니다. "상담을 못 받는 밤 시간에도 고객을 놓치지 않게 됐다." 우리의 4주 운영도 결국 같은 자리에 도착했습니다. 봇은 사람을 줄이는 도구가 아니라, 사람이 닿지 못하는 시간대에 리드를 잃지 않게 받쳐 주는 인프라에 가깝습니다.
저희 5years+ 에서는 한국·일본 중소기업 대상으로 inbound 자동화 봇을 4주 사이클로 빌드합니다. 자사 환경(메신저·CRM·상품 카탈로그)에 맞춘 진단 30분 무료 — 상담 신청 → 5ya.io/contact 에서 받습니다.
다음 회(2회)에서는 결이 다른 자동화를 다룹니다. Runway Gen-4 + Gemini Image 로 주 5편 광고 영상 만들기 — 영업 봇이 리드를 받는 자리라면, 영상 파이프라인은 그 리드를 데려오는 자리입니다. 두 축이 연결됐을 때 비로소 자동화가 매출 곡선을 건드리기 시작합니다.