AI가 만든 답을 사용자에게 보내기 직전에 모델과 따로 한 번 더 검사해서, 유해한 내용·개인정보·형식 오류를 지우거나 막는 마지막 방어선이다. 안전하게 학습된 모델도 가끔 실수하므로, 고객 대면 챗봇이나 결과를 다른 프로그램에 넘기는 서비스처럼 잘못된 답이 그대로 나가면 안 될 때 쓴다.
| 방어 단계 | 언제 동작 | 막는 것 |
|---|---|---|
| 모델 안전 학습 | 답을 만들 때 | 대부분의 위험한 요청 |
| 입력 필터링 | 모델에 넣기 전 | 프롬프트 인젝션, 금지 주제 질문 |
| 출력 필터링 | 사용자에게 보내기 전 | 새어 나간 개인정보, 유해 표현, 깨진 형식 |
무엇을 막을지에 따라 도구가 달라진다. 보통 빠르고 싼 검사를 먼저 하고, 애매한 경우만 무거운 검사로 넘긴다.
| 방법 | 잘 잡는 것 | 특징 |
|---|---|---|
| 정규식 패턴 | 전화번호, 이메일, 카드번호 | 빠르지만 형태가 바뀌면 놓친다 |
| 분류 모델 | 욕설, 폭력, 위험한 안내 | 문맥을 보지만 지연과 비용이 든다 |
| 스키마 검증 | JSON 필드 누락, 잘못된 타입 | 프로그램에 넘기는 출력에 필수 |
가장 흔한 위치는 API 서버다. 모델 응답을 받은 뒤 검사하고, 결과에 따라 그대로 보내거나, 문제 부분만 가리거나(마스킹), 통째로 막고 안내 문구를 보내거나, 다시 생성하게 한다. 개인정보는 가리고, 유해 표현은 막고, 형식 오류는 다시 생성하게 하는 식으로 나누면 된다.
직접 짜기 번거롭다면 가드레일 도구를 쓴다. Amazon Bedrock Guardrails, NeMo Guardrails, Guardrails AI, LangChain의 가드레일 기능은 이런 검사 규칙을 설정으로 정의하게 해 준다. Claude Code에서는 PostToolUse 훅으로 도구 실행 결과를 검사하고 문제가 있으면 Claude에게 알릴 수 있다.
응답을 한 글자씩 흘려 보내면, 끝까지 기다려야 판단되는 내용은 사용자가 이미 일부를 본 뒤에 걸린다. 그래서 스트림 도중에 패턴을 실시간으로 가리거나, 문제가 보이면 스트림을 끊는 방식을 쓴다. 위험도가 높은 서비스라면 문장 단위로 모아서 검사한 뒤 내보내는 편이 안전하다.
필터가 엄격하면 멀쩡한 답까지 막혀 사용자가 답답해한다. 반대로 정규식만 믿으면 띄어쓰기나 표기를 바꾼 우회를 놓친다. 실제 대화 기록으로 막힌 답과 통과한 답을 자주 확인하고 기준을 조정해야 한다. 혼자 쓰는 내부 실험용 도구라면 무거운 분류 모델 없이 스키마 검증 정도만으로도 충분하다.
가장 흔한 건 고객 대면 챗봇의 답에서 개인정보와 유해 표현을 걸러 내는 방식이다. 결과를 다른 프로그램에 넘기는 서비스에서는 스키마 검증이 사실상 기본으로 붙는다.
| 어디서 | 어떻게 쓰나 |
|---|---|
| 고객 상담 챗봇 | 답에 섞인 전화번호·계좌번호는 가리고, 부적절한 표현이 나오면 안내 문구로 바꿔 보낸다 |
| 사내 문서 검색 | 검색된 문서에서 딸려 나온 개인정보나 밖에 보이면 안 될 내용을 답에서 가린다 |
| 구조화 출력 API | JSON을 스키마로 검사하고, 필드가 빠지거나 타입이 틀리면 다시 생성하게 한다 |
| 코딩 에이전트 | 훅으로 도구 실행 결과를 검사해 비밀 키 같은 민감한 값이 섞이면 에이전트에게 알린다 |