지원 위젯은 모델이 도움을 줄 수 없다고 인정할 때까지 티켓을 열지 않습니다
요약
Nakodo는 고객 지원 위젯을 세 계층 구조로 설계하여, 상위 계층이 실패할 때까지 하위 계층으로 질문을 전달하는 방식을 채택했습니다. 첫 번째 계층은 코드에 배포된 매뉴얼이며, 두 번째 계층은 스스로 답변 여부를 판단하는 AI 어시스턴트입니다. 이 구조는 고객에게 정확하고 통제된 정보를 제공하며, 개발 과정에서 데이터의 일관성과 흐름 제어가 핵심임을 보여줍니다.
핵심 포인트
- 지원 위젯을 3단계 계층으로 설계하여 정보 전달의 신뢰도를 높임.
- 매뉴얼은 코드에 배포되어 제품 동작과 관련된 주장을 강제함.
- AI 어시스턴트는 스스로 답변 여부를 판단하며, 실패 시 즉시 종료되도록 제어됨.
- 질문은 모델에 도달하기 전 데이터로 감싸져(fenced) 맥락을 유지함.
Nakodo는 브랜드를 위해 크리에이터 아웃리치를 수행하며, 캠페인 도중 고객으로부터의 질문은 보통 그들에게는 긴급하지만 답변하기에는 지루합니다. 예를 들어, '제 플랜이 몇 명의 크리에이터에게 연락하나요?', '왜 이것만 일시 중지되었나요?', '언제 이메일이 발송되나요?'와 같은 질문들입니다. 로그인된 모든 페이지 왼쪽 하단에 있는 지원 위젯은 아무도 깨우지 않으면서 이러한 질문들에 답변하고, 더 이상 할 수 없을 때는 빠르게 자리를 비키는 역할을 합니다.
이 위젯은 세 개의 계층으로 구성되어 있으며, 순서 결정 규칙 자체가 전체 디자인의 핵심입니다. 바로 상위 계층이 눈에 띄게 실패하기 전까지는 아무것도 사람에게 도달하지 않는다는 것입니다.
첫 번째 계층: 코드와 함께 배포되는 매뉴얼
세 부분(질문, 문제, 청구)으로 나뉘어 총 18개의 주제가 있으며, 각 주제는 누르면 답변이 말풍선 형태로 나타나는 2~4문장의 칩 형태입니다. 이것은 데이터베이스의 테이블이 아니라 TypeScript 배열로 구현되어 있는데, 그 이유는 파일 헤더에 나와 있습니다:
// FAQ와 같은 이유로 코드에 존재합니다: 답변은 제품이 어떻게 작동하는지에 대한 주장(claim)이기 때문에, 설명하는 동작과 함께 검토되고 배포되어야 합니다. 숫자는 다음에서 가져옵니다...
이 임포트 방식이 저장소 문제보다 더 중요합니다. 지원 답변에 인용되는 모든 제한 사항은 가격 페이지를 렌더링하는 동일한 PLANS 객체에서 나옵니다. 따라서 위젯은 고객이 구매한 것과 다른 숫자를 알려줄 수 없습니다. CMS(콘텐츠 관리 시스템)를 사용했다면, 두 값이 어느 한쪽이 업데이트된 것을 기억하는 사람의 방향으로 조용히 어긋나게 했을 것입니다.
두 번째 계층: 스스로 등급을 매겨야 하는 모델
대부분의 질문은 매뉴얼에 있으며, 표현 방식만 다를 뿐입니다. 따라서 누군가 탭하지 않은 칩은 그들에게 아무 도움이 되지 않습니다. 그래서 이 위젯에는 매뉴얼과 다른 어떤 것에서도 답변하는 어시스턴트가 있습니다. 이 어시스턴트의 스키마는 두 개의 필드를 가지고 있습니다:
const answerSchema = z.object({
answer: z.string(),
// True only when it fully answered a question about how something works
...
answered는 모델이 스스로 그 질문에 도달했는지 여부를 기록한 것이며, UI는 이를 원격 측정(telemetry) 정보가 아닌 라우팅 결정으로 읽습니다:
두 번의 턴(turns)입니다. 왜냐하면 후속 질문 한 번은 유용하고, 세 번째는 사람이 개입하는 것을 막기 위해서이기 때문입니다. answered: false인 경우, 첫 답변을 하는 시점에도 어시스턴트는 즉시 종료됩니다. 문제 보고가 들어올 때마다 거짓(false)으로 돌아오도록 지시받는데, 이는 아무리 많은 수동 텍스트 수정도 고장 난 캠페인을 해결할 수 없기 때문입니다.
질문은 모델에 도달하기 전에 데이터로 감싸집니다 (fenced):
return [
history,
q.topic ? `They were reading the manual on: ${q.topic}` : null,
...
이는 고객이 지원 봇에게 지침을 무시하라고 요청하는 것이 재앙이기 때문이 아니라, 매뉴얼만이 그게 주장할 수 있는 유일한 것(assert)이고, 감싸지지 않은 질문은 다른 것을 주장하도록 초대하기 때문입니다.
게이트를 안전하게 만드는 규칙
이 패턴을 구축하는 사람이라면 누구나 검토 체크리스트에 넣어야 할 라인입니다:
// 어시스턴트가 시도해보기 전까지는 아무것도 사람에게 도달해서는 안 된다. 따라서 절대 일어나서는 안 되는 한 가지는, 어시스턴트가 접근 불가능하고 패널이 막다른 골목인 경우이다. 실패한 질문은 시도로 간주된다.
...
만약 인간 지원을 AI 단계 뒤에 배치한다면, 당신의 AI 단계는 이제 지원을 위한 하중 지지대(load bearing)가 됩니다. 모델이 다운되거나, 속도 제한(rate limited)에 걸리거나, 시간 초과(timing out)되는 것은 막힌 문일 수 없습니다. 따라서 실패한 호출은 한 번의 턴으로 계산되며, 폴백 답변(fallback answer)은 도움을 주었다고 거짓말하지 않습니다:
const GAVE_UP: SupportAnswer = {
answer: "제가 아는 것만으로는 답할 수 없습니다. 여기에 있는 사람이 제대로 살펴볼 수 있습니다.",
answered: false,
...
answerFromManual은 절대 오류를 발생시키지 않습니다. 답변이 있어야 할 곳에 에러를 렌더링하는 위젯은 사람을 두 번 놓친 것입니다.
레이어 세 개: 대화는 이미 말한 모든 것을 담고 있다
사람에게까지는 아무도 내용을 다시 입력하지 않습니다. 패널은 표시된 모든 줄, 탭된 칩, 수동 답변, 어시스턴트의 시도 등을 transcript로 보관하며, 운영자가 읽는 것과 동일한 스레드 컴포넌트로 티켓에 게시합니다.
서버는 그 배열을 신뢰하지 않습니다:
export const SEEDABLE_AUTHORS = ["user", "manual", "assistant"] as const;
...input.transcript
.filter((line) => isSeedableAuthor(line.author) && line.body.trim().length > 0)
.slice(0, SUPPORT_LIMITS.transcriptMax)
다섯 가지 작성자 유형(user, manual, assistant, operator, system)이 존재하며 브라우저는 처음 세 가지만 시딩할 수 있습니다. 그렇지 않으면 조작된 페이로드가 이미 운영자의 약속을 포함하거나 해결되었다고 말하는 시스템 라인이 있는 티켓을 열 수 있게 됩니다. 이 배열은 30줄로 제한되며, 모든 문자열은 zod에 의해 경계가 지정되고, 페이지 경로와 사용자 에이전트는 텍스트로 저장되어 다른 어떤 것으로도 렌더링되지 않습니다.
패널이 요청하지 않는 컨텍스트에도 같은 본능이 적용됩니다:
// A page was about, when it was one of a campaign's pages and it
// is this user's. Taken from the path rather than asked for, and checked
// against the owner, so a made-up id can't attach someone else's campaign to
...
정규식(regex)이 window.location.pathname에서 캠페인 ID를 추출하고 서버는 where 절에 eq(campaigns.userId, userId)로 이를 조회합니다. 질문 없이 자유로운 컨텍스트이며, 낯선 사람의 캠페인을 가리킬 방법이 없습니다.
프로덕션 환경에서만 나타나는 마지막 세부 사항입니다. 전체 스레드는 하나의 트랜잭션으로 작성되며, 줄마다 자체 타임스탬프가 필요했습니다:
// Each line gets its own timestamp a millisecond apart, because defaultNow()
// would stamp the batch with one instant and the thread would come back in
// whatever order the rows happened to land in.
고객이 보는 것
위젯은 로그인 후 작동하며, 따라서 공개적으로 접근 가능한 부분은 문서화된 내용입니다. 작동 방식(how it works) 페이지는 매뉴얼의 첫 답변을 길게 풀어쓴 것이며, 플랜이 언급하는 제한 사항들은 가격 정책 페이지(the pricing page)에 나와 있는 내용들입니다. 만약 이와 같은 흐름 자체를 구축할지 결정하고 있다면, 저희 블로그 게시물 플랫폼 사용 또는 직접 구현하기(a platform or doing it yourself)에서 제품에 적용된 것과 동일한 논리를 참고하실 수 있습니다.
패턴은 한마디로 요약하면 이렇습니다: 자동화가 먼저 답변하게 하고, 성공했는지 여부를 명확히 말하게 하며, 그 자체의 실패를 건너뛸 권한으로 간주하는 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기