Files

5.7 KiB

운영 안정화 · 예외 처리 · 보안

원본 요구 3단계: "예상 가능한 상황을 확인하고, 각 예외에서 재시도 · 실행 중단 · 담당자 이관 · 알림 중 어떤 처리가 실행되는지 설정하고, 개인정보와 접근 권한이 흐름과 로그에 반영되는지 점검합니다." 이 문서는 그 표를 미리 채운 출발점입니다. 팀은 자기 워크플로우에 맞게 고치고 실제로 일으켜 보고 결과를 결과서에 씁니다.

1. 예외 처리 표 (설계서 7절의 출발점)

상황 알아채는 법 처리 사용자에게 기록 시나리오 64~79일차
잘못된 입력 Code 검사 즉시 400 codes 형식 오류 수 WF-13 73
인증 실패 (Webhook 키) n8n Header Auth 401 (n8n) — n8n 실행 기록 팀 —
인증 실패 (외부 API 401 · 403) HTTP 상태 재시도 없이 중단 → 이관 "담당자에게 연결합니다" 알림 severity: high 팀 76
호출 한도 초과 (429) HTTP 상태 Retry-After만큼 기다려 재시도 (최대 N회) → 이관 이관 안내 재시도 수 팀 72 · 75
외부 서비스 장애 (5xx) HTTP 상태 · 오류 출력 재시도 1~2회 → DLQ + 알림 → 이관 이관 안내 (ticket: null이어도 200) DLQ · 알림 WF-04 72 · 76
외부 서비스 느림 timeout 시간 초과 → 대체 경로 정해진 시간 안 답 reason WF-11 72
LLM 멈춤 · 시간 초과 Agent 오류 출력 근거 원문 안내 또는 이관 (fail-closed: 판별 · 검증이 멈추면 자동 답변하지 않음) 이유 있는 안내 reason: llm_down WF-10 72 · 73
검색 결과 없음 · 점수 미달 Code (점수 기준) 답 생성 중단 → 이관 "확인 후 담당자가 연락" reason: no_evidence WF-03 71
검증 실패 (근거 밖 내용) 검증 Agent + Code 이관 (또는 한 번 다시 쓰기) 이관 안내 issues 팀 69
중복 요청 request_id 캐시 · 티켓 key 저장된 결과 그대로, 티켓 하나 같은 답 duplicate WF-09 72 · 76
프롬프트 주입 규칙 · 판별 차단 (LLM 앞에서) 정해진 안내 security WF-08 73
권한 없음 데이터 API 403 · 메타데이터 권한 없음 정해진 안내 security WF-05 · 06 73
처리 못 한 예외 (버그) Error Workflow 알림 + DLQ (n8n이 500) 알림 팀 76

재시도 원칙 (72 · 76일차)

다시 해도 되는 것 다시 하면 안 되는 것
timeout, 5xx, 429 (기다린 뒤) 400 · 401 · 403 · 404 (요청 · 권한이 틀림, 몇 번 해도 같음)
조회 (GET) 같은 생성(POST)을 key 없이 (티켓이 두 개 생김) → 중복 방지 key를 달면 다시 해도 됨
  • 최악의 시간 = 시도 수 × timeout + 기다림. 응답 시간 기준(예: 6초) 안에 들어오게 정합니다 (72일차).
  • 재시도도 실패하면 DLQ에 남깁니다: 무엇을(요청 요약 · 개인정보 없이), 왜(사유), 몇 번(시도 수). 나중에 다시 처리(76일차 replay)할 수 있어야 합니다.
  • 알림은 실패마다가 아니라 사람이 할 일이 있을 때 보냅니다. 같은 장애로 알림이 100개 오면 아무도 보지 않습니다 (76일차 묶어 보내기).

2. Error Workflow (원본 "실행 중단 · 알림")

  • n8n 워크플로우 설정의 Error Workflow에 팀의 <팀>-errors를 지정하고, 그 워크플로우는 Error Trigger → 알림(POST /alerts) → DLQ로 둡니다 (76일차).
  • 오류 출력(onError: continueErrorOutput)으로 예상한 실패를 처리하고, Error Workflow는 예상하지 못한 실패의 마지막 그물입니다. 둘 다 둡니다.
  • Error Workflow는 게시(활성화)되어 있어야 동작합니다.

3. 보안 기준 (73일차를 프로젝트에)

기준 확인 방법
입력 검증은 LLM 앞에서 WF-13 400, LLM 호출 0
주입 차단 (규칙 + 판별, 글자 정리) WF-08, 팀 시나리오에 숨긴 공격 하나
정상 질문을 막지 않음 팀 시나리오 "지나치게 막지 않음"
권한의 근거는 시스템 (user → /employees의 dept, requester=user) WF-05 · WF-06
지시문(systemMessage)에 비밀 없음 워크플로우 JSON grep
출력 필터 (전화 · 메일 · 주민번호 가림) WF-07, security.masked
티켓 본문 · 알림 · 로그에도 개인정보 가림 GET /tickets-created, GET /alerts, 로그에 연락처 모양 0
키는 Credential에만 워크플로우 JSON · 문서 · 저장소에 키 없음 (tscan scan .)

4. 실행 기록 (원본 결과서 2절 "실행 로그")

요청마다 한 줄을 남깁니다 (POST /logs, 73일차 감사 로그 · 77일차 실행 기록).

{"request_id": "req-001", "user": "박서연", "started_at": "...", "ended_at": "...", "route": "자동 답변",
 "agents": ["triage", "retriever", "writer", "verifier"], "nodes": 14, "llm_calls": 3,
 "sources": [{"doc": "remote-work-vpn", "score": 0.71}], "retries": 0, "external": {"tickets": "ok"},
 "error_code": null, "masked": 0, "total_ms": 2840}
남김 남기지 않음
원본 요구 결과서 2절의 칸: request_id · 시각 · 실행 노드 · 외부 API 상태 · 재시도 수 · 검색 문서 ID와 점수 · 최종 분기 · 오류 코드 · 마스킹 여부 질문 · 답 글자 전체, 연락처 (가린 것도)
  • 결과서의 "노드별 입력 · 출력 요약"은 n8n 실행 화면(Executions)에서 시나리오마다 한 번 캡처하거나 복사합니다 (개인정보를 가리고).