Skip to content

wwwshe/KorProfanityKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KorProfanityKit

Swift 기반 고성능 한국어 욕설 필터링 라이브러리입니다.

Fast, Offline, Korean-first Profanity Filter for Swift.

주요 기능

  • 룰 엔진 기반 탐지 (초성, 띄어쓰기, 특수문자, 반복 문자, 숫자 치환)
  • 커스텀 사전 및 예외 단어(ignore list) 지원
  • RuleEngine 외부 주입으로 패키지 밖에서 사전 구성 가능
  • iOS 26+ Foundation Models 연동 (선택)
  • AI 실패 시 룰 엔진으로 graceful fallback
  • 기본적으로 100% 오프라인 동작 (.rule 정책)

설치

Swift Package Manager

Package.swift에 패키지와 product를 추가합니다.

dependencies: [
    .package(url: "https://github.com/your-org/KorProfanityKit.git", from: "1.0.0"),
]
.target(
    name: "YourApp",
    dependencies: [
        .product(name: "KorProfanityKit", package: "KorProfanityKit"),
        // Foundation Models 사용 시 추가
        .product(name: "KorProfanityKitFoundationModels", package: "KorProfanityKit"),
    ]
)

로컬 패키지를 쓰는 경우:

dependencies: [
    .package(path: "../KorProfanityKit"),
]

Xcode 프로젝트

  1. File > Add Package Dependencies에서 패키지를 추가합니다.
  2. 타깃의 Frameworks, Libraries, and Embedded Content에서 product를 링크합니다.
    • 룰만 사용: KorProfanityKit
    • AI 사용: KorProfanityKit + KorProfanityKitFoundationModels 둘 다 링크

KorProfanityKitFoundationModels를 링크하지 않으면 import KorProfanityKitFoundationModels가 실패합니다.

사용법

검사는 항상 단일 메서드 check(_:) 하나로 합니다. 룰만 쓸지 AI까지 쓸지는 decisionPolicy가 결정하므로 호출부는 정책과 상관없이 동일합니다.

import KorProfanityKit

let filter = ProfanityFilter()
let result = try await filter.check("ㅅㅂ")

if result.isProfane {
    print(result.category, result.score, result.reason ?? "")
}

ProfanityFilter 초기화

ProfanityFilter(
    debug: false,                        // 디버그 로그
    decisionPolicy: .rule,               // .rule | .aiConfirm
    ruleEngine: RuleEngine(),            // 커스텀 사전 주입 가능
    classifier: nil                      // AI 분류기 (선택)
)

Foundation Models 사용 (iOS 26+, 모델 사용 가능 시)

import KorProfanityKit
import KorProfanityKitFoundationModels

let filter = ProfanityFilter.withFoundationModels()
let result = try await filter.check("너 사람 맞냐?")

withFoundationModels()는 기본적으로 decisionPolicy: .aiConfirmFoundationModelClassifier를 주입합니다.

직접 classifier를 주입할 수도 있습니다. AI는 .aiConfirm 정책일 때만 호출됩니다.

let filter = ProfanityFilter(
    decisionPolicy: .aiConfirm,
    classifier: FoundationModelClassifier()
)

판별 정책

정책 설명
.rule 기본값. 룰 엔진만 사용합니다. AI는 사용하지 않습니다.
.aiConfirm 룰 엔진과 AI 결과를 함께 평가합니다. 두 결과가 일치하면 그대로, 엇갈리면 AI 판단으로 덮어씁니다.

.aiConfirm의 판별 기준:

룰 엔진 AI 최종 source
욕설 욕설 욕설 .merged
정상 정상 정상 .merged
정상 욕설 욕설 .aiClassifier
욕설 정상 정상 .aiClassifier

AI fallback

.aiConfirm 정책이어도 아래 경우에는 에러 없이 룰 엔진 결과를 반환합니다.

  • .rule 정책이거나 classifier가 주입되지 않음
  • 온디바이스 모델을 사용할 수 없음 (isAvailable == false)
  • AI 가드레일·거부·파싱 실패

검사 결과 (ProfanityResult)

필드 설명
isProfane 욕설/유해 여부
category 분류 카테고리
score 유해 점수 (0.0 ~ 1.0)
confidence 판별 신뢰도
reason 판별 사유 (한국어)
matchedTerms 룰 엔진이 매칭한 단어 목록
source 최종 판별 출처 (.ruleEngine, .aiClassifier, .merged)

Category: clean, profanity, insult, hate, sexual, violence, spam

커스텀 사전 및 예외 단어

생성 후 메서드로 추가:

var filter = ProfanityFilter()
filter.add(words: ["운영자", "광고"], category: .spam)
filter.ignore(words: ["병신년", "개발"])

생성 시 RuleEngine을 직접 구성해 주입:

let ruleEngine = RuleEngine(
    customWords: ["운영자", "광고"],
    customCategories: ["운영자": .spam, "광고": .spam],
    ignoreWords: ["개발"]
)

let filter = ProfanityFilter(decisionPolicy: .rule, ruleEngine: ruleEngine)

// AI 모드에서도 동일하게 주입 가능
let aiFilter = ProfanityFilter.withFoundationModels(ruleEngine: ruleEngine)

커스텀 AI 분류기

ProfanityClassifier 프로토콜을 구현해 주입할 수 있습니다.

struct MyClassifier: ProfanityClassifier {
    var isAvailable: Bool { true }

    func classify(text: String) async throws -> ClassificationResult {
        ClassificationResult(category: .clean, score: 0.9, reason: "테스트 분류기")
    }
}

let filter = ProfanityFilter(
    decisionPolicy: .aiConfirm,
    classifier: MyClassifier()
)

디버그 로그

debug: true로 설정하면 판별 과정이 콘솔에 출력됩니다.

let filter = ProfanityFilter(
    debug: true,
    decisionPolicy: .aiConfirm,
    classifier: FoundationModelClassifier()
)

let result = try await filter.check("미친 성능이다")
print(result.source) // .ruleEngine | .aiClassifier | .merged

출력 예시:

[KorProfanityKit] check(text:)
  input: 미친 성능이다
  policy: aiConfirm
  classifier: available
[KorProfanityKit] rule engine
  profane: false
  source: ruleEngine
[KorProfanityKit] AI classification started
[KorProfanityKit] final
  profane: false
  source: aiClassifier

플랫폼 지원

Product 최소 버전 설명
KorProfanityKit iOS 15+, macOS 12+ 핵심 룰 엔진
KorProfanityKitFoundationModels iOS 26+, macOS 26+ FoundationModels 프레임워크 연동

Foundation Models 실행 조건

  • iOS 26+ 실기기에서 Apple Intelligence가 활성화되어 있어야 합니다.
  • 시뮬레이터에서는 온디바이스 모델이 대부분 사용 불가(classifier unavailable)이며, 룰 엔진으로 fallback 됩니다.
  • 지원 기기: iPhone 15 Pro 이상, M 시리즈 iPad/Mac 등 (Apple Intelligence 지원 기기)
  • 설정에서 Apple Intelligence & Siri 메뉴가 보이고 켜져 있어야 합니다.

샘플 앱

실시간 욕설 판별 데모 앱이 Sample/에 포함되어 있습니다.

  1. Sample/KorProfanityKitSample.xcodeproj를 Xcode에서 엽니다.
  2. Apple Intelligence 지원 실기기 또는 시뮬레이터를 선택합니다.
  3. Run (⌘R) 합니다.
  4. 입력창에 문장을 입력하면 즉시 판별 결과가 표시됩니다.

샘플 앱은 KorProfanityKit + KorProfanityKitFoundationModels product를 링크합니다. iOS 26+ 실기기에서는 Foundation Models 기반 AI 확인을 기본으로 사용하고, 그 외 환경에서는 룰 엔진으로 fallback 합니다.

라이선스

MIT

About

Swift 욕설 감지 라이브러리

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages