
챗봇 또는 AI 에이전트에 콘텐츠 모더레이션을 추가하는 방법

챗봇이나 AI 에이전트에 콘텐츠 모더레이션을 추가하는 것은 단순히 비속어를 차단하는 것이 아닙니다. 프로덕션 워크플로우에서는 사용자 입력, 모델 출력, 그리고 에이전트가 수행할 수 있는 액션까지 모두 검사해야 합니다.
가장 안전한 멘탈 모델은 다음과 같습니다:
input moderation
-> model or agent reasoning
-> tool-call validation
-> output moderation
-> allow / review / block요약
- 사용자 입력이 챗봇이나 에이전트에 도달하기 전에 모더레이션을 적용하세요.
- 모델 출력이 사용자에게 표시되기 전에 모더레이션을 적용하세요.
- 에이전트가 액션을 실행하기 전에 도구 호출을 검증하세요.
- 콘텐츠 모더레이션을 완벽한 프롬프트 인젝션 방어 수단으로 간주하지 마세요.
- 중간 위험도나 영향이 큰 경우에는 사람이 직접 검토하세요.
- EvoLink의
evolink_summary.risk_level을 활용하면 허용 / 검토 / 차단 로직을 간소화할 수 있습니다.
콘텐츠 모더레이션과 에이전트 보안은 다릅니다
콘텐츠 모더레이션은 유해한 텍스트나 이미지를 식별하는 데 도움을 줍니다. 안전하지 않은 프롬프트, 유해한 출력, 정책을 위반하는 사용자 콘텐츠의 위험을 줄일 수 있습니다.
에이전트 보안은 범위가 더 넓습니다. 프롬프트 인젝션, 도구 권한, 데이터 접근, 사람의 승인, 구조화된 출력, 평가, 로깅, 워크플로우 설계 등이 포함됩니다.
OpenAI의 에이전트 안전성 가이드에서는 가드레일, 도구 승인, 트레이스 그레이딩, 평가, 구조화된 워크플로우 설계 등의 기법을 조합할 것을 권장합니다. OWASP 역시 프롬프트 인젝션을 데이터 유출, 의도하지 않은 액션, 도구 오용으로 이어질 수 있는 별도의 LLM 보안 위험으로 분류하고 있습니다.
참고 자료:
핵심은 이것입니다: 모더레이션은 하나의 가드레일입니다. 유일한 가드레일이 되어서는 안 됩니다.
Layer 1: 입력 모더레이션
입력 모더레이션은 사용자의 메시지가 모델에 도달하기 전에 검사합니다.
다음을 감지하는 데 활용할 수 있습니다:
- 명백히 유해한 요청
- 정책을 위반하는 사용자 메시지
- 욕설이나 괴롭힘 텍스트
- 안전하지 않은 이미지 업로드
- 금지된 콘텐츠를 요청하는 프롬프트
입력 모더레이션이 유용한 이유는 명백히 안전하지 않은 요청이 모델 워크플로우에 진입하는 것 자체를 방지하기 때문입니다.
def handle_user_message(user_input: str):
input_check = client.moderations.create(
model="evolink-moderation-1.0",
input=user_input
)
if input_check.evolink_summary.risk_level == "high":
return {
"status": "blocked",
"message": "I can't help with that request."
}
return run_chatbot(user_input)중요한 한계: 입력 모더레이션은 완벽한 프롬프트 인젝션 방어 수단이 아닙니다. 공격자는 간접 프롬프트, 인코딩된 텍스트, 이미지, 외부 문서 또는 도구 출력을 통해 워크플로우 후반부에서 에이전트에 영향을 줄 수 있습니다.
Layer 2: 출력 모더레이션
출력 모더레이션은 모델 응답이 사용자에게 전달되기 전에 검사합니다.
다음을 감지하는 데 활용할 수 있습니다:
- 안전하지 않은 생성 콘텐츠
- 정책을 위반하는 응답
- 민감한 분야의 유해한 조언
- 안전해 보이는 입력에도 불구하고 빠져나간 응답
def safe_chat(user_input: str):
input_check = moderate(user_input)
if input_check.evolink_summary.risk_level == "high":
return "I can't help with that request."
answer = llm.generate(user_input)
output_check = moderate(answer)
if output_check.evolink_summary.risk_level == "high":
return "I generated a response that needs to be revised. Please try rephrasing."
return answer출력 모더레이션은 퍼블릭 챗봇, AI 코파일럿, 생성된 콘텐츠가 사용자에게 직접 노출되는 워크플로우에서 특히 유용합니다.
Layer 3: 도구 호출 검증
AI 에이전트에서 도구 호출은 대개 가장 위험도가 높은 계층입니다.
에이전트가 이메일을 보내거나, 데이터베이스를 조회하거나, 티켓을 업데이트하거나, API를 호출하거나, 파일을 작성할 수 있다면, 실행 전에 도구 호출을 반드시 검증해야 합니다. 이것은 단순한 모더레이션이 아닙니다. 권한 부여와 정책 집행입니다.
검증 항목:
- 도구 이름
- 허용된 사용자 또는 계정 범위
- 필수 사람 승인 여부
- 허용된 파라미터 값
- 읽기 vs 쓰기 작업
- 외부 수신자
- 파괴적 액션
- 데이터 유출 위험
def validate_tool_call(tool_name: str, args: dict, user_context: dict):
if tool_name == "send_email":
if not args["to"].endswith("@company.com"):
return False, "External email requires approval."
if tool_name == "database_query":
query = args.get("query", "")
forbidden = ["DROP ", "DELETE ", "TRUNCATE "]
if any(word in query.upper() for word in forbidden):
return False, "Destructive database operation blocked."
if tool_name == "refund_customer":
if args["amount"] > user_context["approval_limit"]:
return False, "Refund amount requires human approval."
return True, NoneOpenAI의 에이전트 안전성 가이드에서도 MCP 도구에 대해 도구 승인을 활성화하여 최종 사용자가 작업을 검토하고 확인할 수 있도록 권장하고 있습니다.
Layer 4: 허용 / 검토 / 차단 라우팅
안전/위험의 이분법적 모더레이션은 대개 너무 단순합니다. 프로덕션에서 더 유용한 패턴은 다음과 같습니다:
| 위험도 | 조치 |
|---|---|
| 낮음 | 허용 |
| 중간 | 검토 대기열에 추가, 경고 표시, 또는 배포 제한 |
| 높음 | 차단 또는 이의 신청 요구 |
evolink_summary.risk_level 필드를 반환합니다.def route_by_risk(content: str):
result = client.moderations.create(
model="evolink-moderation-1.0",
input=content
)
risk = result.evolink_summary.risk_level
if risk == "high":
log_block(result)
return {"action": "block"}
if risk == "medium":
queue_for_review(content, result)
return {"action": "review"}
return {"action": "allow"}전체 챗봇 모더레이션 패턴
다음은 실용적인 엔드투엔드 구조입니다:
def handle_chatbot_turn(user_input: str, user_context: dict):
# 1. Moderate input
input_route = route_by_risk(user_input)
if input_route["action"] == "block":
return "I can't help with that request."
if input_route["action"] == "review":
log_review_event("input", user_input)
# 2. Generate model response and proposed tool calls
agent_result = agent.run(user_input, user_context)
# 3. Validate tool calls before execution
for call in agent_result.tool_calls:
ok, reason = validate_tool_call(call.name, call.args, user_context)
if not ok:
log_security_event(call, reason)
return "That action requires additional review."
# 4. Execute approved tools
tool_outputs = execute_tool_calls(agent_result.tool_calls)
# 5. Generate final response
final_answer = agent.format_response(tool_outputs)
# 6. Moderate output
output_route = route_by_risk(final_answer)
if output_route["action"] == "block":
return "I need to revise that response."
if output_route["action"] == "review":
queue_for_review(final_answer, output_route)
return final_answer실제 구현은 다를 수 있지만, 구조는 동일합니다: 입력을 검사하고, 액션을 제한하고, 출력을 검사하고, 결정을 기록하세요.
오탐(False Positive) 처리
오탐은 피할 수 없습니다. 목표는 정상적인 사용자를 너무 자주 차단하지 않으면서 피해를 줄이는 것입니다.
다음의 경우 검토 대기열을 활용하세요:
- 중간 위험도 콘텐츠
- 맥락이 불분명한 경우
- 정책상 민감한 카테고리
- 고가치 사용자 또는 영향이 큰 액션
- 이의 신청
디버깅에 충분한 맥락과 함께 각 모더레이션 결정을 로깅하세요:
- content hash
- user id 또는 account id
- risk level
- 트리거된 카테고리
- 수행된 조치
- 검토자 오버라이드
- timestamp
명확한 보존 및 개인정보 보호 정책이 없다면 민감한 원본 콘텐츠를 로깅하지 마세요.
내부적으로 약속해야 할 것
모더레이션이 챗봇을 "100% 안전하게" 만들어 준다고 약속하지 마세요.
더 현실적인 약속은 다음과 같습니다:
- 유해한 입력은 모델 실행 전에 검사합니다
- 모델 출력은 사용자에게 표시되기 전에 검사합니다
- 에이전트 도구 호출은 실행 전에 검증합니다
- 고위험 또는 애매한 경우는 사람에게 라우팅할 수 있습니다
- 로그와 검토 결과를 활용하여 임계값을 개선합니다
이것이 현실적인 프로덕션 체계입니다.
흔한 실수
실수 1: 입력만 모더레이션하기
입력 검사는 유용하지만, 모델은 여전히 안전하지 않은 출력을 생성할 수 있습니다. 사용자에게 표시하기 전에 출력도 반드시 모더레이션하세요.
실수 2: 프롬프트를 보안 경계로 취급하기
시스템 프롬프트는 동작을 안내하지만, 유일한 보안 계층이 되어서는 안 됩니다. 도구 권한, 구조화된 워크플로우, 승인 절차를 함께 활용하세요.
실수 3: 검증 없이 에이전트가 도구를 실행하도록 방치하기
도구 호출은 항상 모델 외부에서 검증하세요. 모델은 액션을 제안해야 하고, 애플리케이션이 해당 액션의 허용 여부를 결정해야 합니다.
실수 4: 불확실한 모든 경우를 차단하기
지나치게 엄격한 시스템은 사용자 불만을 초래합니다. 불확실한 경우는 항상 차단하는 대신 검토 대기열로 보내세요.
실수 5: 로그를 남기지 않기
로그 없이는 임계값을 조정하거나, 사고를 조사하거나, 오탐을 이해할 수 없습니다.
구현 체크리스트
- 모델 호출 전에 사용자 입력을 모더레이션합니다.
- 사용자에게 표시하기 전에 모델 출력을 모더레이션합니다.
- 실행 전에 에이전트 도구 호출을 검증합니다.
- 허용 / 검토 / 차단 라우팅을 적용합니다.
- 중간 위험도 콘텐츠는 검토 대기열에 추가합니다.
- 필요한 곳에 사용자 신고 및 이의 신청 기능을 추가합니다.
- risk level, 카테고리, 조치, 검토자 오버라이드를 로깅합니다.
- 필수가 아닌 한 민감한 원본 콘텐츠를 저장하지 않습니다.
- 실제 제품의 사례로 테스트합니다.
- 프로덕션 데이터가 확보된 후 임계값을 재검토합니다.
FAQ
챗봇 입력과 출력 중 어느 쪽을 모더레이션해야 하나요?
둘 다 해야 합니다. 입력 모더레이션은 안전하지 않은 요청이 모델에 도달하기 전에 줄여줍니다. 출력 모더레이션은 안전하지 않은 생성 콘텐츠가 사용자에게 노출되기 전에 잡아줍니다.
콘텐츠 모더레이션으로 프롬프트 인젝션을 막을 수 있나요?
아닙니다. 모더레이션은 일부 안전하지 않거나 의심스러운 콘텐츠를 감지할 수 있지만, 프롬프트 인젝션에는 도구 검증, 구조화된 출력, 최소 권한, 사람의 승인, 워크플로우 격리 등 더 광범위한 방어가 필요합니다.
AI 에이전트에서 모더레이션을 어디에 배치해야 하나요?
사용자 입력에 대해서는 모델 이전에, 모델 출력에 대해서는 표시 이전에 모더레이션을 배치하고, 에이전트 액션이 실행되기 전에 도구 호출 검증을 결합하세요.
EvoLink는 챗봇 모더레이션에 어떤 도움을 주나요?
evolink_summary.risk_level을 포함한 OpenAI 호환 모더레이션 엔드포인트를 제공하여, 챗봇 콘텐츠를 허용, 검토, 차단 워크플로우로 라우팅하기 쉽게 해줍니다.사람의 검토가 여전히 필요한가요?
프로덕션 시스템에서는 그렇습니다. 이의 신청, 중간 위험도 경우, 정책 변경, 영향이 큰 의사결정에서 사람의 검토는 중요합니다.
관련 모더레이션 가이드
- OpenAI Moderation API 가격: 무료인가요? 한도 및 대안
- 이미지 모더레이션 API 가이드: 안전하지 않은 사용자 업로드 이미지를 필터링하는 방법
- omni-moderation-latest 설명: OpenAI Moderation API 가이드
- 개발자를 위한 최고의 콘텐츠 모더레이션 API 및 도구


