## 문제 상황: 메시지가 사라지는 블랙홀 현상
메시징 시스템이나 봇 기반 서비스를 운영하다 보면 흔히 마주치는 문제가 있습니다. 사용자가 요청을 보냈는데 아무런 응답이 없는 상황입니다. 시스템 내부에서는 보안 정책(Guard)이나 Rate Limit에 의해 정상적으로 차단되었지만, 사용자는 요청이 처리 중인지 실패했는지 알 수 없습니다.
이런 '블랙홀 문제'는 사용자 경험을 크게 해칩니다. 사용자는 같은 요청을 반복해서 보내거나, 시스템이 고장났다고 오해할 수 있습니다.
## 해결 방안: 양방향 피드백 프로토콜
이 문제를 해결하기 위해 두 가지 메커니즘을 도입했습니다.
### 1. 시스템 자동 차단 알림 [BLK]
시스템이 요청을 차단할 때 자동으로 알림 메시지를 발송합니다. 핵심 구현 요소는 다음과 같습니다.
**차단 사유 코드 체계**
```python
BLOCK_REASONS = {
'rate_limit_exceeded': '요청 한도를 초과했습니다. 1분 후 다시 시도해주세요.',
'invalid_format': '요청 형식이 올바르지 않습니다. 문서를 참고해주세요.',
'depth_exceeded': '응답 깊이가 제한을 초과했습니다.',
'circular_reference': '순환 참조가 감지되었습니다.'
}
```
**자동 알림 발송 로직**
```python
def send_block_notification(original_request, block_reason):
notification = {
'type': 'BLOCK_NOTIFICATION',
'original_msg_id': original_request['id'],
'reason_code': block_reason,
'reason_text': BLOCK_REASONS[block_reason],
'guidance': get_guidance_for_reason(block_reason),
'sender': 'System'
}
send_message(notification, to=original_request['from'])
```
**무한 루프 방지**
차단 알림 자체가 다시 차단 조건을 트리거하지 않도록 skip 리스트에 추가합니다.
```python
TERMINAL_MESSAGE_TYPES = ['BLOCK_NOTIFICATION', 'REJECTION']
if message['type'] in TERMINAL_MESSAGE_TYPES:
# 가드 체크를 건너뛰고 바로 전달
bypass_guard_check = True
```
### 2. 봇의 명시적 거부 응답 [REJ]
봇이 요청을 수행할 수 없을 때는 침묵하는 대신 명시적으로 거부 응답을 보내야 합니다.
**거부 응답 필수 요소**
```python
class RejectionResponse:
def __init__(self, original_request):
self.original_msg_id = original_request['id'] # (1) 원본 참조
self.reason = None # (2) 거부 사유
self.alternative = None # (3) 대안 제시
def validate(self):
if not all([self.reason, self.alternative]):
raise ValueError("거부 응답은 사유와 대안을 모두 포함해야 합니다")
```
**실제 사용 예시**
```python
# Bad: 조용히 무시
if not can_process(request):
return # 사용자는 영원히 기다림
# Good: 명시적 거부
if not can_process(request):
rejection = RejectionResponse(request)
rejection.reason = "현재 외부 API 연동이 불가능합니다"
rejection.alternative = "캐시된 데이터로 조회하려면 'cached:' 접두사를 사용해주세요"
send_rejection(rejection)
```
## 메시지 흐름 비교
**개선 전**
```
사용자 → [요청] → Guard 차단 → DB 로그 기록 → (끝)
사용자: "왜 응답이 없지? 다시 보내볼까?"
```
**개선 후**
```
사용자 → [요청] → Guard 차단 → DB 로그 + 자동 알림 발송
← [차단 알림: Rate Limit 초과, 1분 후 재시도] ←
사용자: "아, 너무 빨리 보냈구나. 잠시 후 다시 시도해야겠다."
```
## 구현 시 주의사항
### 1. 알림 메시지의 무한 루프 방지
차단 알림 자체가 다시 차단되는 상황을 방지해야 합니다. 특정 메시지 타입은 가드 체크를 우회하도록 설정하세요.
### 2. 명확한 가이드 제공
단순히 "차단되었습니다"가 아니라 "왜 차단되었고, 어떻게 해결할 수 있는지" 구체적으로 안내해야 합니다.
### 3. 구조화된 차단 사유 코드
로깅과 분석을 위해 사람이 읽을 수 있는 텍스트와 별도로 기계가 처리할 수 있는 코드를 함께 전송하세요.
### 4. 봇의 책임 명확화
봇이 요청을 받았다면 "처리 완료" 또는 "거부"를 반드시 회신하도록 규약을 명확히 하세요. 침묵은 금지입니다.
## 결론
메시징 시스템에서 투명한 피드백은 사용자 경험의 핵심입니다. 시스템이 요청을 거부하거나 차단할 때 그 이유와 해결 방법을 명확히 전달하면:
- 불필요한 재시도 요청 감소
- 사용자 만족도 향상
- 지원 문의 감소
- 시스템 신뢰도 향상
작은 알림 메커니즘이지만, 사용자와 시스템 간의 신뢰를 크게 높일 수 있습니다. 여러분의 시스템에도 "조용히 실패하는" 부분이 있다면, 오늘 당장 피드백 메커니즘을 추가해보세요.