개발 slecs

이커머스 PG AI 상담에 Claude 직접 연동

목차

외부 AI 래퍼 서비스를 쓰다 보면 어느 시점에 한계가 온다. 프롬프트를 건드리고 싶어도 인터페이스가 막혀 있고, 응답 파싱 방식이 서비스 사양에 종속되다 보니 UI 쪽에서 유연하게 처리하기가 어렵다. 레이턴시도 문제였다. 요청이 우리 서버 → 외부 래퍼 → LLM API → 래퍼 → 우리 서버 순으로 두 번 왕복하니, 사용자 입장에서 체감 응답 속도가 느릴 수밖에 없었다. 이번에 이커머스 PG 플랫폼의 AI 상담 페이지를 Claude API 직접 연동 방식으로 전환하면서 그 불편함을 한꺼번에 정리했다.

구조 변경과 FAQ 주입

전환 후 흐름은 단순하다.

사용자 질문
  → 내부 클래스 (API 호출 래퍼)
    → Claude API (messages endpoint)
  → 응답 파싱
  → 채팅 UI 렌더링

중간 레이어가 사라지면서 제어 가능한 지점이 늘었다. 가장 체감이 컸던 건 시스템 프롬프트 설계다. 이전에는 프롬프트를 직접 작성할 수 없어서 답변 톤이나 맥락 주입이 불가능했는데, 이제는 PG 플랫폼 특성에 맞게 상담사 페르소나, 안내 문구, FAQ를 직접 심을 수 있다.

FAQ 주입 방식은 시스템 프롬프트에 목록을 직렬화해서 넣는 구조다. DB나 파일에서 로드해서 매 요청 시 최신 FAQ가 반영되게 했다. 정적으로 하드코딩하면 FAQ가 바뀔 때마다 코드를 건드려야 하고, 운영 쪽에서 직접 수정하기도 어려워진다. 로드-주입 구조를 택하면 FAQ 관리와 코드 배포를 분리할 수 있어서 훨씬 유연하다.

def build_system_prompt(faqs: list[dict]) -> str:
    faq_block = "\n".join(
        f"Q: {item['question']}\nA: {item['answer']}" for item in faqs
    )
    return f"""당신은 PG 플랫폼 전문 AI 상담사입니다.
아래 FAQ를 참고해 일관된 답변을 제공하세요.

{faq_block}

답변 불가 영역은 '담당자에게 문의 부탁드립니다'로 안내하세요."""

처음 접속했을 때 어떤 걸 물어볼 수 있는지 안내가 있어야 사용자가 어색하지 않게 쓸 수 있다는 건 경험칙이다. 상담사 이름과 역할 소개 문구를 넣어두면 "AI한테 뭘 물어봐야 하지?"라는 진입 장벽이 낮아진다. 사소해 보이지만 실제로 이게 없으면 페이지 이탈률이 올라간다.

보안 레이어: 경고-정지-차단 삼단 구조

AI 상담창을 열면 반드시 생기는 문제가 있다. 비정상 요청이다. PG 플랫폼 특성상 민감한 데이터를 다루는 맥락이니 더 신경 써야 했다.

이번에 구현한 흐름은 아래와 같다.

단계 조건 처리
경고 부적절 요청 최초 감지 경고 메시지 출력, DB에 경고 횟수 기록
정지 경고 누적 후 재발 30분 임시 정지, 정지 횟수 DB 저장
차단 공격성 요청 감지 즉시 블랙리스트 자동 등록, 이후 요청 즉시 차단

로그인 필수 처리는 기본 전제다. 비인증 상태에서 API 호출이 가능하면 쿼터를 태우는 건 일도 아니다. 인증 미들웨어 단에서 막아두지 않으면 어느 날 청구서 보고 당황하는 상황이 온다.

블랙리스트 자동 등록 쪽에서 신경 쓴 부분이 몇 가지 있다. 오탐 가능성이 제일 까다롭다. 부하 테스트나 배치 성격의 내부 작업이 봇으로 오해받으면 엉뚱한 계정이 차단된다. 화이트리스트 IP나 내부 서비스 계정은 탐지 로직 전에 예외 처리를 해둬야 한다.

영구 차단 대신 TTL을 두는 것도 중요하다. 자동 탐지는 기본적으로 오탐을 동반한다. TTL 없이 영구 차단으로 가면 오탐 복구 과정이 수동 작업이 되고, 그 민원은 결국 팀으로 온다. 24-72시간 TTL을 설정해두면 오탐 시 자연 해제가 되고, 실제 악용자는 재차단 로직이 잡는다.

알림 연동도 빠뜨렸다가 나중에 추가하게 되는 케이스가 많다. 자동 차단이 발생해도 아무도 모르면 모니터링이 아니다. Slack이든 Discord든, 차단 이벤트 발생 시 알림이 떠야 운영팀이 이상 패턴을 인지하고 대응할 수 있다.

작은 변경이 쌓이는 이유

이번 작업은 규모가 크지 않았다. 기능 하나 추가, 보안 레이어 몇 개, 프롬프트 설계 정도다. 그런데 이런 작업이 의미 있는 이유는 나중에 쌓이는 방식 때문이다.

직접 연동으로 전환해두면 이후에 멀티턴 대화 히스토리를 넘기거나, 사용자별 컨텍스트를 주입하거나, 응답에 structured output을 요구하는 작업들이 훨씬 수월해진다. 래퍼 서비스를 유지했다면 그때마다 서비스 사양을 확인하고 우회 방법을 찾았어야 한다. 제어권을 가져오는 비용을 한 번 치르면, 그 이후의 확장 비용이 내려간다.

보안 쪽도 마찬가지다. 경고-정지-차단 구조를 처음부터 DB에 기록해두면 나중에 패턴 분석이 가능하다. 어떤 유형의 요청이 많이 걸리는지, 특정 시간대에 집중되는지, 계정 패턴이 있는지. 데이터가 없으면 분석도 없다.

운영 안정성이라는 게 결국 이런 것들의 합이다. 눈에 잘 안 띄는 수정들이 조용히 쌓여서 시스템이 버텨주는 것.

댓글 0

첫 댓글 달아줘.