AI 상담 직접 연동
목차
외부 서비스를 통해서 AI 상담을 붙여두면 처음엔 편한데, 시간이 지날수록 답변 품질을 건드릴 수 없다는 게 계속 걸린다. 프롬프트 한 줄을 바꾸려 해도 중간 레이어가 끼어 있으면 뭘 어떻게 전달해야 하는지 애매해지고, 레이턴시도 경유지가 하나씩 늘어날 때마다 쌓인다. 이번에 그걸 정리했음. Claude API messages endpoint를 내부 클래스에서 직접 호출하는 구조로 전환했고, 보안 처리와 FAQ 주입까지 한 세트로 달았음.
직접 연동 구조와 미들레이어 제거
기존 흐름에서는 사용자 입력이 외부 서비스를 한 번 거쳐서 Claude에 닿았음. 별도 요금 체계도 있었고, 응답 포맷을 우리 채팅 UI에 맞게 후처리하는 코드도 따로 있었음. 뺄 게 많았다.
전환 후 구조는 이렇게 됨:
사용자 질문
→ 내부 클래스 (API 호출)
→ Claude API (messages endpoint)
→ 응답 파싱
→ 채팅 UI 렌더링
내부 클래스를 하나 두고 거기서 API 키 관리, 요청 직렬화, 응답 파싱을 전부 처리하게 했음. 컨트롤러나 뷰 레이어는 그 클래스만 바라보면 되니까, 나중에 모델을 바꾸거나 파라미터를 조정할 때 한 곳만 고치면 됨. 미들레이어가 없어지니 레이턴시도 눈에 띄게 줄었고, 타임아웃 처리나 재시도 로직도 우리 코드 안에서 직접 제어할 수 있게 됐음.
시스템 프롬프트를 자유롭게 짤 수 있다는 것도 생각보다 차이가 크다. 이번에 AI 상담사 이름과 역할 소개 문구를 정리하고, 처음 접속했을 때 어떤 걸 물어볼 수 있는지 안내 문구를 달았음. 사람들이 상담창을 처음 열었을 때 "이거 뭘 물어봐야 하지?"라고 느끼는 순간을 없애려는 거임. 온보딩이 짧더라도 첫 화면이 낯설면 이탈이 빠름.
FAQ 주입은 시스템 프롬프트에 목록을 직접 넣는 방식으로 했음. DB나 파일에서 로드해서 주입하는 구조라 FAQ를 업데이트해도 배포 없이 반영됨. 자주 묻는 질문에 일관된 답변이 나오게 하는 게 목표인데, 여기서 주의할 점이 있음. 프롬프트 길이가 길어질수록 토큰 비용이 올라가고, 너무 장황하면 모델이 핵심을 놓치기도 함. FAQ는 핵심 항목만 간결하게 주입하고, 긴 설명이 필요한 건 별도 컨텍스트로 분리하는 게 낫다.
보안 처리 - 경고, 정지, 자동 차단
AI 상담 기능에 로그인 필수 처리를 달았음. 비로그인 상태에서 열어두면 스팸성 요청이나 크롤러가 API 비용을 그냥 써버림. 로그인 게이팅은 기본이고, 그 위에 부적절 이용 감지 로직을 추가했음.
처리 흐름은 아래처럼 됨:
| 상태 | 조건 | 처리 |
|---|---|---|
| 정상 | 위반 없음 | 상담 허용 |
| 경고 | 부적절 요청 감지 | 경고 메시지 표시, 횟수 DB 저장 |
| 정지 | 경고 누적 또는 심각 위반 | 30분 이용 정지 |
| 차단 | 공격성 요청 패턴 | 블랙리스트 자동 등록, 즉시 차단 |
경고/정지 횟수를 DB에 저장하는 이유는 세션이 끊겨도 이력이 남아야 하기 때문임. 세션 변수에 넣으면 브라우저를 닫으면 초기화되니까 의미가 없음. 30분 정지는 영구 차단보다 오탐 시 복구가 쉽고, 일반 사용자가 실수로 걸렸을 때 대응하기도 편함.
공격성 요청 자동 차단 쪽은 좀 더 신경 쓸 부분이 있음. 수동 대응은 속도가 느리니까 감지 즉시 DB에 등록하고 다음 요청부터 바로 막는 구조가 필요했음. 다만 자동화할 때 놓치기 쉬운 것들이 있다:
- 오탐 가능성: 로드 테스트나 배치 작업이 봇으로 오해받지 않도록 예외 IP나 API 키 기반 예외 처리를 미리 넣어야 함. 실수로 내부 시스템이 잡히면 조용히 장애가 남.
- 만료 설정: 영구 차단 대신 TTL을 걸어두는 게 낫다. 오탐 복구가 가능하고, 운영 부담도 줄어듦. 정말 심각한 케이스만 수동으로 영구 등록하면 됨.
- 알림 연동: 자동 차단이 발생했을 때 슬랙이나 디스코드로 알림이 와야 모니터링이 됨. 차단이 얼마나 자주 일어나는지 추세를 보면 이상 징후도 빨리 잡힘.
작업 규모 대비 효과
작업 자체는 크지 않았음. 그런데 이런 류의 작업이 애매하게 뒤로 밀리다가 나중에 더 큰 문제가 되는 경우를 많이 봤음. 외부 서비스 의존도를 낮추고 제어권을 안으로 가져오는 건 기능 추가보다 눈에 덜 띄지만, 운영 안정성 측면에서 쌓이는 효과가 있음.
FAQ 주입 구조도 마찬가지임. 배포 없이 답변 품질을 조정할 수 있는 레버를 하나 만든 거라서, 이후에 운영하면서 계속 손볼 수 있음. 처음부터 완벽하게 만들 수는 없고, 손대기 쉬운 구조를 만들어두는 게 결국 더 빠름.
보안 처리도 비슷함. 경고-정지-차단 레이어를 지금 잡아두지 않으면, 나중에 이상 트래픽이 들어왔을 때 그때 가서 급하게 붙이게 됨. 그게 훨씬 위험함.
댓글 0
첫 댓글 달아줘.