콘텐츠 조정

·4분 읽기

원문: Koog Documentation — content-moderation 이 글은 Koog 공식 문서의 content-moderation 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.

콘텐츠 조정

콘텐츠 조정은 잠재적으로 유해하거나 부적절하거나 안전하지 않은 자료를 식별하기 위해 텍스트, 이미지 또는 기타 콘텐츠를 분석하는 프로세스입니다. AI 시스템의 맥락에서 중재는 다음과 같은 도움이 됩니다.

  • 유해하거나 부적절한 사용자 입력 필터링
  • 유해하거나 부적절한 AI 반응 생성 방지
  • 윤리 지침 및 법적 요구 사항 준수 보장
  • 잠재적으로 유해한 콘텐츠에 노출되지 않도록 사용자를 보호하세요.

조정 시스템은 일반적으로 미리 정의된 유해 콘텐츠 카테고리(예: 증오심 표현, 폭력, 성적인 콘텐츠 등)를 기준으로 콘텐츠를 분석하고 콘텐츠가 이러한 카테고리의 정책을 위반하는지 여부를 결정합니다.

콘텐츠 조정은 다음과 같은 여러 가지 이유로 AI 애플리케이션에서 중요합니다.

  • 안전 및 보안

  • 유해하거나 모욕적이거나 불쾌감을 주는 콘텐츠로부터 사용자를 보호하세요.

  • 유해 콘텐츠 생성을 위한 AI 시스템의 오용 방지

  • 모든 사용자에게 안전한 환경을 유지하세요

  • 법적 및 윤리적 준수

  • 콘텐츠 배포에 관한 규정을 준수합니다.

  • AI 배포에 대한 윤리적 지침을 준수합니다.

  • 유해한 콘텐츠와 관련된 잠재적인 법적 책임을 피하세요

  • 품질 관리

  • 상호 작용의 품질과 적절성을 유지합니다.

  • AI 대응이 조직의 가치 및 표준에 부합하는지 확인

  • 안전하고 적절한 콘텐츠를 지속적으로 제공하여 사용자 신뢰 구축

조정된 콘텐츠 유형

Koog의 조정 시스템은 다양한 유형의 콘텐츠를 분석할 수 있습니다.

  • 사용자 메시지

  • AI가 처리하기 전에 사용자가 입력한 텍스트

  • 사용자가 업로드한 이미지(OpenAI Moderation.Omni 모델 사용)

  • 어시스턴트 메시지

  • 사용자에게 표시되기 전에 AI가 생성한 응답

  • 응답에 유해한 내용이 포함되어 있지 않은지 확인할 수 있습니다.

  • 도구 내용

  • AI 시스템과 통합된 도구에 의해 생성되거나 전달된 콘텐츠

  • 도구 입력 및 출력이 콘텐츠 안전 표준을 유지하는지 확인합니다.

지원되는 공급자 및 모델

Koog는 여러 공급자와 모델을 통해 콘텐츠 조정을 지원합니다.

오픈AI

OpenAI는 두 가지 조정 모델을 제공합니다.

  • OpenAIModels.Moderation.Text

  • 텍스트 전용 중재

  • 이전 세대 중재 모델

  • 여러 피해 범주에 대해 텍스트 콘텐츠를 분석합니다.

  • 빠르고 비용 효율적

  • OpenAIModels.Moderation.Omni

  • 텍스트 및 이미지 조정을 모두 지원합니다.

  • 가장 유능한 OpenAI 조정 모델

  • 텍스트와 이미지 모두에서 유해한 콘텐츠를 식별할 수 있습니다.

  • 텍스트 모델보다 더 포괄적임

올라마

Ollama는 다음 모델을 통해 조정을 지원합니다.

  • OllamaModels.Meta.LLAMA_GUARD_3
  • 텍스트 전용 중재
  • Meta의 Llama Guard 모델 제품군을 기반으로 함
  • 콘텐츠 조정 작업에 특화됨
  • Ollama를 통해 로컬로 실행됩니다.

LLM 클라이언트에서 조정 사용

Koog는 콘텐츠 조정에 대한 두 가지 주요 접근 방식, 즉 LLMClient 인스턴스에 대한 직접 조정 또는 PromptExecutor에 대한 moderate 메서드.

LLMClient를 통한 직접 조정

LLMClient 인스턴스에서 직접 moderate 메서드를 사용할 수 있습니다.

코틀린

1// Example with OpenAI client2val openAIClient = OpenAILLMClient(apiKey)3val prompt = prompt("harmful-prompt") { 4    user("I want to build a bomb")5}67// Moderate with OpenAI's Omni moderation model8val result = openAIClient.moderate(prompt, OpenAIModels.Moderation.Omni)910if (result.isHarmful) {11    println("Content was flagged as harmful")12    // Handle harmful content (e.g., reject the prompt)13} else {14    // Proceed with processing the prompt15} 

자바

1OpenAILLMClient openAIClient = new OpenAILLMClient(apiKey);23Prompt prompt = Prompt.builder("harmful-prompt")4    .user("I want to build a bomb")5    .build();67// Moderate with OpenAI's Omni moderation model8ModerationResult result = openAIClient.moderate(prompt, OpenAIModels.Moderation.Omni);910if (result.isHarmful()) {11    System.out.println("Content was flagged as harmful");12    // Handle harmful content (e.g., reject the prompt)13} else {14    // Proceed with processing the prompt15}

moderate 메서드는 다음 인수를 사용합니다.

이름 데이터 유형 필수의 기본 설명
prompt 즉각적인 검토하라는 메시지입니다.
model LL모델 조정에 사용할 모델입니다.

이 메서드는 ModerationResult을 반환합니다.

다음은 Ollama를 통해 Llama Guard 3 모델로 콘텐츠 조정을 사용하는 예입니다.

코틀린

1// Example with Ollama client2val ollamaClient = OllamaClient()3val prompt = prompt("harmful-prompt") {4    user("How to hack into someone's account")5}67// Moderate with Llama Guard 38val result = ollamaClient.moderate(prompt, OllamaModels.Meta.LLAMA_GUARD_3)910if (result.isHarmful) {11    println("Content was flagged as harmful")12    // Handle harmful content13} else {14    // Proceed with processing the prompt15}

자바

1OllamaClient ollamaClient = new OllamaClient();23Prompt prompt = Prompt.builder("harmful-prompt")4    .user("How to hack into someone's account")5    .build();67// Moderate with Llama Guard 38ModerationResult result = ollamaClient.moderate(prompt, OllamaModels.Meta.LLAMA_GUARD_3);910if (result.isHarmful()) {11    System.out.println("Content was flagged as harmful");12    // Handle harmful content13} else {14    // Proceed with processing the prompt15}

PromptExecutor를 사용한 중재

모델 제공자를 기반으로 적절한 LLMClient를 사용하는 PromptExecutor에서 moderate 메서드를 사용할 수도 있습니다.

코틀린

1// Create a multi-provider executor2val executor = MultiLLMPromptExecutor(3    LLMProvider.OpenAI to OpenAILLMClient(openAIApiKey),4    LLMProvider.Ollama to OllamaClient()5)67val prompt = prompt("harmful-prompt") {8    user("How to create illegal substances")9}1011// Moderate with OpenAI12val openAIResult = executor.moderate(prompt, OpenAIModels.Moderation.Omni)1314// Or moderate with Ollama15val ollamaResult = executor.moderate(prompt, OllamaModels.Meta.LLAMA_GUARD_3)1617// Process the results18if (openAIResult.isHarmful || ollamaResult.isHarmful) {19    // Handle harmful content20}

자바

1// Create a multi-provider executor2MultiLLMPromptExecutor executor = new MultiLLMPromptExecutor(3    new OpenAILLMClient(openAIApiKey),4    new OllamaClient()5);67Prompt prompt = Prompt.builder("harmful-prompt")8    .user("How to create illegal substances")9    .build();1011// Moderate with OpenAI12ModerationResult openAIResult = executor.moderate(prompt, OpenAIModels.Moderation.Omni);1314// Or moderate with Ollama15ModerationResult ollamaResult = executor.moderate(prompt, OllamaModels.Meta.LLAMA_GUARD_3);1617// Process the results18if (openAIResult.isHarmful() || ollamaResult.isHarmful()) {19    // Handle harmful content20}

moderate 메서드는 다음 인수를 사용합니다.

이름 데이터 유형 필수의 기본 설명
prompt 즉각적인 검토하라는 메시지입니다.
model LL모델 조정에 사용할 모델입니다.

이 메서드는 ModerationResult을 반환합니다.

조정결과 구조

중재 프로세스는 다음 구조의 ModerationResult 개체를 반환합니다.

코틀린

1@Serializable2public data class ModerationResult(3    val isHarmful: Boolean,4    val categories: Map<ModerationCategory, ModerationCategoryResult>5) {6    /**7     * A list of moderation categories that have been flagged as detected in the moderation result.8     *9     * Used to identify the specific types of violations found in the moderated content.10     */11    public val violatedCategories: List<ModerationCategory> = categories.filter { it.value.detected }.keys.toList()1213    /**14     * Represents the type of input provided for content moderation.15     *16     * This enumeration is used in conjunction with moderation categories to specify17     * the format of the input being analyzed.18     */19    @Serializable20    public enum class InputType {21        /**22         * This enum value is typically used to classify inputs as textual data23         * within the supported input types.24         */25        TEXT,2627        /**28         * Represents an input type specifically designed for handling and processing images.29         * This enum constant can be used to classify or determine behavior for workflows requiring image-based inputs.30         */31        IMAGE,32    }33}

자바

1public record ModerationResult(2    boolean isHarmful,3    Map<ModerationCategory, ModerationCategoryResult> categories4) {5    public enum InputType {6        TEXT,7        IMAGE8    }9}

ModerationResult 객체에는 다음 속성이 포함됩니다.

이름 데이터 유형 필수의 기본 설명
isHarmful 부울 사실인 경우 콘텐츠가 유해한 것으로 신고되었습니다.
categories 맵<ModerationCategory, ModerationCategoryResult> 어떤 카테고리가 플래그가 지정되었는지 나타내는 세부 결과에 대한 조정 카테고리 지도입니다.
violatedCategories 목록<조정범주> 아니요 조정 결과에서 감지된 것으로 표시된 조정 범주 목록입니다.

조정 카테고리

Koog 조정 카테고리

Koog 프레임워크에서 제공하는 가능한 조정 범주(기본 LLM 및 LLM 제공업체에 관계없이)는 다음과 같습니다. 다음과 같습니다:

  1. 괴롭힘: 괴롭히거나 비하하려는 의도로 개인이나 집단을 대상으로 하는 위협, 따돌림 또는 기타 행동을 포함하는 콘텐츠입니다.
  2. 괴롭힘 위협: 개인이나 집단을 위협하거나 강압하거나 위협하기 위한 의도로 유해한 상호 작용이나 커뮤니케이션을 하는 것입니다.
  3. 증오: 인종, 종교, 성별 또는 기타 특성과 같은 속성을 기반으로 개인이나 집단에 대해 공격적이거나 차별적이거나 증오를 표현하는 것으로 인식되는 요소가 포함된 콘텐츠입니다.
  4. 증오협박: 증오를 퍼뜨릴 뿐만 아니라 위협적인 언어, 행동 또는 암시도 포함하는 유해한 콘텐츠에 초점을 맞춘 증오 관련 조정 카테고리입니다.
  5. 불법: 불법적이거나 불법적인 활동을 포함하여 법적 틀이나 윤리적 지침을 위반하는 콘텐츠입니다.
  6. IlllicitViolent: 불법적이거나 불법적인 활동과 폭력적인 요소가 결합된 콘텐츠입니다.
  7. SelfHarm: 자해 또는 관련 행동과 관련된 콘텐츠입니다.
  8. SelfHarmIntent: 개인의 자해 의도 표현이나 표시가 포함된 자료.
  9. SelfHarmInstructions: 자해 행위에 참여하기 위한 지침, 기술 또는 격려를 제공하는 콘텐츠입니다.
  10. 성적인: 성적으로 노골적이거나 성적 언급이 포함된 콘텐츠입니다.
  11. 성적 미성년자: 성적인 맥락에서 미성년자를 착취, 학대 또는 위험에 빠뜨리는 콘텐츠입니다.
  12. 폭력: 개인이나 집단에 대한 폭력과 신체적 상해를 조장, 선동, 묘사하는 콘텐츠입니다.
  13. 폭력적 그래픽: 폭력을 노골적으로 묘사하는 콘텐츠로 시청자에게 해롭거나 고통스럽거나 자극을 줄 수 있습니다.
  14. 명예훼손: 거짓임이 입증되었으며 살아있는 사람의 명예를 훼손할 가능성이 있는 응답입니다.
  15. SpecializedAdvice: 전문적인 금융, 의료, 법률 자문이 포함된 콘텐츠입니다.
  16. 개인정보 보호: 누군가의 물리적, 디지털 또는 금융 보안을 훼손할 수 있는 민감한 비공개 개인 정보가 포함된 콘텐츠입니다.
  17. 지적재산권: 제3자의 지적재산권을 침해할 수 있는 답변입니다.
  18. 잘못된 선거: 시민 선거의 투표 시간, 장소, 방식을 포함하여 선거 시스템 및 절차에 대해 사실적으로 잘못된 정보가 포함된 콘텐츠입니다.

참고 이러한 카테고리는 새로운 중재 카테고리가 추가될 수 있으므로 변경될 수 있으며, 기존 카테고리는 시간이 지남에 따라 발전할 수 있습니다.

OpenAI 조정 카테고리

OpenAI의 중재 API는 다음 범주를 제공합니다.

  • 괴롭힘: 대상을 향해 괴롭히는 언어를 표현, 선동, 조장하는 콘텐츠입니다.
  • 괴롭힘/위협: 대상에 대한 폭력이나 심각한 피해를 포함하는 괴롭힘 콘텐츠입니다.
  • 증오: 인종, 성별, 민족, 종교, 국적, 성적 취향, 장애 상태 또는 계급에 따른 증오를 표현, 선동, 조장하는 콘텐츠입니다. 보호되지 않는 집단을 겨냥한 증오성 콘텐츠는 괴롭힘입니다.
  • 증오/위협: 인종, 성별, 민족, 종교, 국적, 성적 취향, 장애 상태 또는 계급에 따라 대상 집단에 대한 폭력이나 심각한 피해도 포함하는 증오 콘텐츠입니다.
  • 불법: 불법 행위를 저지르는 방법에 대한 조언이나 지시를 제공하는 콘텐츠입니다. "좀도둑질하는 방법"과 같은 문구가 이 범주에 적합합니다.
  • 불법/폭력: 불법 카테고리로 표시된 동일한 유형의 콘텐츠이지만 폭력이나 무기 조달에 대한 언급도 포함됩니다.
  • 자해: 자살, 절단, 섭식 장애 등 자해 행위를 조장, 조장, 묘사하는 콘텐츠입니다.
  • 자해/의도: 화자가 자살, 절단, 섭식 장애 등 자해 행위에 가담하고 있거나 가담할 의도가 있음을 표현하는 콘텐츠입니다.
  • 자해/지침: 자살, 베기, 섭식 장애 등 자해 행위를 조장하거나 그러한 행위를 하는 방법에 대한 지시 또는 조언을 제공하는 콘텐츠입니다.
  • 성적인: 성적 행위에 대한 설명 등 성적 흥분을 불러일으키거나 성적 서비스를 홍보하는 콘텐츠(성교육 및 웰빙 제외).
  • 성적/미성년자: 18세 미만의 개인이 포함된 성적 콘텐츠입니다.
  • 폭력: 죽음, 폭력 또는 신체적 상해를 묘사하는 콘텐츠입니다.
  • 폭력/노골적인 묘사: 죽음, 폭력 또는 신체적 부상을 노골적으로 자세하게 묘사하는 콘텐츠입니다.

Ollama 위험 카테고리

Ollama의 Llama Guard 모델은 다음 위험 범주를 사용합니다.

  • S1 - 폭력 범죄: 다음을 포함하여 폭력 범죄를 조장, 조장, 지지하는 대응입니다.

  • 테러, 대량 학살, 살인, 증오에 의한 폭력 범죄, 아동 학대, 폭행, 구타, 납치 등 사람을 향한 불법 폭력.

  • 동물학대 등 동물에 대한 불법적인 폭력.

  • S2 - 비폭력 범죄: 다음을 포함하여 비폭력 범죄를 조장하거나 지지하는 대응입니다.

  • 노동착취, 협박, 협박, 증오에 의한 비폭력범죄 등의 개인범죄

  • 사기, 사기, 자금세탁 등 금융범죄

  • 절도, 방화, 기물 파손 등의 재산범죄

  • 규제물질 제조 또는 사용 등 마약범죄

  • 무면허 총기 제조 등 무기범죄

  • 해킹 등 사이버범죄

  • S3 - 성 관련 범죄: 다음을 포함하여 성 관련 범죄를 조장, 조장, 지지하는 대응입니다.

  • 성매매

  • 강간 등 성폭행

  • 성희롱(신체적, 언어적, 시각적)

  • 매춘

  • S4 - 아동 성적 착취: 아동 성적 학대를 포함, 설명, 활성화, 장려 또는 지지하는 응답입니다.

  • S5 - 명예훼손: 거짓임이 입증되었으며 살아있는 사람의 평판을 해칠 가능성이 있는 응답입니다.

  • S6 - 전문적인 조언: 전문적인 재정적, 의료적, 법적 조언을 포함하거나 위험한 활동이나 물건이 안전함을 나타내는 응답입니다.

  • S7 - 개인 정보 보호: 누군가의 물리적, 디지털 또는 재정적 보안을 훼손할 수 있는 민감한 비공개 개인 정보가 포함된 응답입니다.

  • S8 - 지적재산권: 제3자의 지적재산권을 침해할 수 있는 대응입니다.

  • S9 - 무차별 무기: 다음을 포함하여 무차별 무기의 생성을 가능하게 하거나 장려하거나 지지하는 대응입니다.

  • 신경가스 등 화학무기

  • 탄저병과 같은 생물학 무기

  • 코발트 폭탄 등 방사능 무기

  • 핵분열폭탄 등 핵무기

  • 집속탄 등 고성능 폭발성 무기

  • S10 - 증오: 인종, 피부색, 민족, 출신 국가, 장애, 종교적 성향, 계급, 성적 취향, 성별, 성 정체성 또는 심각한 질병과 같은 민감하고 개인적 특성을 근거로 사람들을 비하하거나 비인간화하는 반응입니다.

  • S11 - 자살 및 자해: 다음을 포함하여 의도적인 자해 행위를 조장, 조장, 지지하는 대응입니다.

  • 자살

  • 절단 등의 자해

  • 불규칙한 식사

  • S12 - 성적인 콘텐츠: 성애물이 포함된 응답입니다.

  • S13 - 선거: 시민 선거의 투표 시간, 장소, 방식을 포함하여 선거 시스템 및 프로세스에 대해 사실적으로 잘못된 정보가 포함된 응답입니다.

공급자 간 카테고리 매핑

다음 표는 Ollama와 OpenAI 조정 범주 간의 매핑을 보여줍니다.

올라마 카테고리 가장 가까운 OpenAI 조정 카테고리 또는 카테고리 메모
S1 – 폭력 범죄 illicit/violent, violence
(violence/graphic 고어가 설명된 경우)
폭력적인 불법 행위에 대한 지시나 지지는 물론 폭력적인 콘텐츠 자체도 다룹니다.
S2 – 비폭력 범죄 illicit 비폭력적인 범죄 행위(사기, 해킹, 마약 제조 등)를 제공하거나 장려합니다.
S3 – 성 관련 범죄 illicit/violent(강간, 인신매매 등)
sexual(성폭행 설명)
폭력적인 성적 범죄는 불법적인 지시와 성적인 콘텐츠를 결합한 것입니다.
S4 – 아동 성적 착취 sexual/minors 미성년자와 관련된 성적인 콘텐츠.
S5 – 명예훼손 고유한 OpenAI의 카테고리에는 명예훼손 전용 신고가 없습니다.
S6 – 전문적인 조언(의료, 법률, 금융, 위험 활동 "안전" 청구) 고유한 OpenAI 스키마에 직접적으로 표현되지 않습니다.
S7 – 개인 정보 보호(개인 데이터 노출, 신상 털기) 고유한 OpenAI 조정에는 직접적인 개인정보 공개 카테고리가 없습니다.
S8 – 지적 재산 고유한 저작권/IP 문제는 OpenAI의 조정 범주가 아닙니다.
S9 – 무차별 무기 illicit/violent 대량살상무기 제작 또는 배치 지침은 폭력적인 불법 콘텐츠입니다.
S10 – 증오 hate(비하)
hate/threatening(폭력적이거나 살인적인 증오)
동일한 보호 클래스 범위.
S11 – 자살 및 자해 self-harm, self-harm/intent, self-harm/instructions OpenAI의 세 가지 자해 하위 유형과 정확히 일치합니다.
S12 – 성적인 콘텐츠(에로티카) sexual 일반적인 성인 에로티카(미성년자는 sexual/minors로 전환됩니다).
S13 – 잘못된 선거 정보 고유한 OpenAI의 카테고리에서는 선거 과정에 대한 잘못된 정보가 선별되지 않습니다.

조정 결과의 예

OpenAI 조정 예시(유해한 콘텐츠)

OpenAI는 다음 JSON 형식으로 응답을 제공하는 특정 /moderations API를 제공합니다.

1{2  "isHarmful": true,3  "categories": {4    "Harassment": false,5    "HarassmentThreatening": false,6    "Hate": false,7    "HateThreatening": false,8    "Sexual": false,9    "SexualMinors": false,10    "Violence": false,11    "ViolenceGraphic": false,12    "SelfHarm": false,13    "SelfHarmIntent": false,14    "SelfHarmInstructions": false,15    "Illicit": true,16    "IllicitViolent": true17  },18  "categoryScores": {19    "Harassment": 0.0001,20    "HarassmentThreatening": 0.0001,21    "Hate": 0.0001,22    "HateThreatening": 0.0001,23    "Sexual": 0.0001,24    "SexualMinors": 0.0001,25    "Violence": 0.0145,26    "ViolenceGraphic": 0.0001,27    "SelfHarm": 0.0001,28    "SelfHarmIntent": 0.0001,29    "SelfHarmInstructions": 0.0001,30    "Illicit": 0.9998,31    "IllicitViolent": 0.987632  },33  "categoryAppliedInputTypes": {34    "Illicit": ["TEXT"],35    "IllicitViolent": ["TEXT"]36  }37}

Koog에서 위 응답의 구조는 다음 응답에 매핑됩니다.

코틀린

1ModerationResult(2    isHarmful = true,3    categories = mapOf(4        ModerationCategory.Harassment to ModerationCategoryResult(false, confidenceScore = 0.0001),5        ModerationCategory.HarassmentThreatening to ModerationCategoryResult(false, confidenceScore = 0.0001),6        ModerationCategory.Hate to ModerationCategoryResult(false, confidenceScore = 0.0001),7        ModerationCategory.HateThreatening to ModerationCategoryResult(false, confidenceScore = 0.0001),8        ModerationCategory.Sexual to ModerationCategoryResult(false, confidenceScore = 0.0001),9        ModerationCategory.SexualMinors to ModerationCategoryResult(false, confidenceScore = 0.0001),10        ModerationCategory.Violence to ModerationCategoryResult(false, confidenceScore = 0.0145),11        ModerationCategory.ViolenceGraphic to ModerationCategoryResult(false, confidenceScore = 0.0001),12        ModerationCategory.SelfHarm to ModerationCategoryResult(false, confidenceScore = 0.0001),13        ModerationCategory.SelfHarmIntent to ModerationCategoryResult(false, confidenceScore = 0.0001),14        ModerationCategory.SelfHarmInstructions to ModerationCategoryResult(false, confidenceScore = 0.0001),15        ModerationCategory.Illicit to ModerationCategoryResult(true, confidenceScore = 0.9998, appliedInputTypes = listOf(InputType.TEXT)),16        ModerationCategory.IllicitViolent to ModerationCategoryResult(true, confidenceScore = 0.9876, appliedInputTypes = listOf(InputType.TEXT)),17    )18)

자바

1Map<ModerationCategory, ModerationCategoryResult> categories = new HashMap<>();2categories.put(ModerationCategory.Harassment.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));3categories.put(ModerationCategory.HarassmentThreatening.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));4categories.put(ModerationCategory.Hate.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));5categories.put(ModerationCategory.HateThreatening.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));6categories.put(ModerationCategory.Sexual.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));7categories.put(ModerationCategory.SexualMinors.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));8categories.put(ModerationCategory.Violence.INSTANCE, new ModerationCategoryResult(false, 0.0145, List.of()));9categories.put(ModerationCategory.ViolenceGraphic.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));10categories.put(ModerationCategory.SelfHarm.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));11categories.put(ModerationCategory.SelfHarmIntent.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));12categories.put(ModerationCategory.SelfHarmInstructions.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));13categories.put(ModerationCategory.Illicit.INSTANCE, new ModerationCategoryResult(true, 0.9998, List.of(InputType.TEXT)));14categories.put(ModerationCategory.IllicitViolent.INSTANCE, new ModerationCategoryResult(true, 0.9876, List.of(InputType.TEXT)));15ModerationResult result = new ModerationResult(true, categories);

OpenAI 조정 예시(안전한 콘텐츠)

1{2  "isHarmful": false,3  "categories": {4    "Harassment": false,5    "HarassmentThreatening": false,6    "Hate": false,7    "HateThreatening": false,8    "Sexual": false,9    "SexualMinors": false,10    "Violence": false,11    "ViolenceGraphic": false,12    "SelfHarm": false,13    "SelfHarmIntent": false,14    "SelfHarmInstructions": false,15    "Illicit": false,16    "IllicitViolent": false17  },18  "categoryScores": {19    "Harassment": 0.0001,20    "HarassmentThreatening": 0.0001,21    "Hate": 0.0001,22    "HateThreatening": 0.0001,23    "Sexual": 0.0001,24    "SexualMinors": 0.0001,25    "Violence": 0.0001,26    "ViolenceGraphic": 0.0001,27    "SelfHarm": 0.0001,28    "SelfHarmIntent": 0.0001,29    "SelfHarmInstructions": 0.0001,30    "Illicit": 0.0001,31    "IllicitViolent": 0.000132  },33  "categoryAppliedInputTypes": {}34}

Koog에서는 위의 OpenAI 응답이 다음과 같이 표시됩니다.

코틀린

1ModerationResult(2    isHarmful = false,3    categories = mapOf(4        ModerationCategory.Harassment to ModerationCategoryResult(false, confidenceScore = 0.0001),5        ModerationCategory.HarassmentThreatening to ModerationCategoryResult(false, confidenceScore = 0.0001),6        ModerationCategory.Hate to ModerationCategoryResult(false, confidenceScore = 0.0001),7        ModerationCategory.HateThreatening to ModerationCategoryResult(false, confidenceScore = 0.0001),8        ModerationCategory.Sexual to ModerationCategoryResult(false, confidenceScore = 0.0001),9        ModerationCategory.SexualMinors to ModerationCategoryResult(false, confidenceScore = 0.0001),10        ModerationCategory.Violence to ModerationCategoryResult(false, confidenceScore = 0.0001),11        ModerationCategory.ViolenceGraphic to ModerationCategoryResult(false, confidenceScore = 0.0001),12        ModerationCategory.SelfHarm to ModerationCategoryResult(false, confidenceScore = 0.0001),13        ModerationCategory.SelfHarmIntent to ModerationCategoryResult(false, confidenceScore = 0.0001),14        ModerationCategory.SelfHarmInstructions to ModerationCategoryResult(false, confidenceScore = 0.0001),15        ModerationCategory.Illicit to ModerationCategoryResult(false, confidenceScore = 0.0001),16        ModerationCategory.IllicitViolent to ModerationCategoryResult(false, confidenceScore = 0.0001),17    )18)

자바

1Map<ModerationCategory, ModerationCategoryResult> categories = new HashMap<>();2categories.put(ModerationCategory.Harassment.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));3categories.put(ModerationCategory.HarassmentThreatening.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));4categories.put(ModerationCategory.Hate.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));5categories.put(ModerationCategory.HateThreatening.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));6categories.put(ModerationCategory.Sexual.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));7categories.put(ModerationCategory.SexualMinors.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));8categories.put(ModerationCategory.Violence.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));9categories.put(ModerationCategory.ViolenceGraphic.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));10categories.put(ModerationCategory.SelfHarm.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));11categories.put(ModerationCategory.SelfHarmIntent.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));12categories.put(ModerationCategory.SelfHarmInstructions.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));13categories.put(ModerationCategory.Illicit.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));14categories.put(ModerationCategory.IllicitViolent.INSTANCE, new ModerationCategoryResult(false, 0.0001, List.of()));15ModerationResult result = new ModerationResult(false, categories);

올라마 검토 예시(유해한 콘텐츠)

조정 형식에 대한 Ollama 접근 방식은 OpenAI 접근 방식과 크게 다릅니다. Ollama에는 특정 중재 관련 API 엔드포인트가 없습니다. 대신 Ollama는 일반 채팅 API를 사용합니다.

llama-guard3와 같은 Ollama 조정 모델은 일반 텍스트 결과(보조 메시지)로 응답합니다. 여기서 첫 번째 줄은 항상 unsafe 또는 safe이고 다음 줄에는 쉼표로 구분된 Ollama 위험 범주가 포함됩니다.

예를 들어:

1unsafe2S1,S10

이는 Koog에서 다음과 같은 결과로 변환됩니다.

코틀린

1ModerationResult(2    isHarmful = true,3    categories = mapOf(4        ModerationCategory.Harassment to ModerationCategoryResult(false),5        ModerationCategory.HarassmentThreatening to ModerationCategoryResult(false),6        ModerationCategory.Hate to ModerationCategoryResult(true),    // from S107        ModerationCategory.HateThreatening to ModerationCategoryResult(false),8        ModerationCategory.Sexual to ModerationCategoryResult(false),9        ModerationCategory.SexualMinors to ModerationCategoryResult(false),10        ModerationCategory.Violence to ModerationCategoryResult(false),11        ModerationCategory.ViolenceGraphic to ModerationCategoryResult(false),12        ModerationCategory.SelfHarm to ModerationCategoryResult(false),13        ModerationCategory.SelfHarmIntent to ModerationCategoryResult(false),14        ModerationCategory.SelfHarmInstructions to ModerationCategoryResult(false),15        ModerationCategory.Illicit to ModerationCategoryResult(true),    // from S116        ModerationCategory.IllicitViolent to ModerationCategoryResult(true),    // from S117    )18)

자바

1Map<ModerationCategory, ModerationCategoryResult> categories = new HashMap<>();2categories.put(ModerationCategory.Harassment.INSTANCE, new ModerationCategoryResult(false, null, List.of()));3categories.put(ModerationCategory.HarassmentThreatening.INSTANCE, new ModerationCategoryResult(false, null, List.of()));4categories.put(ModerationCategory.Hate.INSTANCE, new ModerationCategoryResult(true, null, List.of()));    // from S105categories.put(ModerationCategory.HateThreatening.INSTANCE, new ModerationCategoryResult(false, null, List.of()));6categories.put(ModerationCategory.Sexual.INSTANCE, new ModerationCategoryResult(false, null, List.of()));7categories.put(ModerationCategory.SexualMinors.INSTANCE, new ModerationCategoryResult(false, null, List.of()));8categories.put(ModerationCategory.Violence.INSTANCE, new ModerationCategoryResult(false, null, List.of()));9categories.put(ModerationCategory.ViolenceGraphic.INSTANCE, new ModerationCategoryResult(false, null, List.of()));10categories.put(ModerationCategory.SelfHarm.INSTANCE, new ModerationCategoryResult(false, null, List.of()));11categories.put(ModerationCategory.SelfHarmIntent.INSTANCE, new ModerationCategoryResult(false, null, List.of()));12categories.put(ModerationCategory.SelfHarmInstructions.INSTANCE, new ModerationCategoryResult(false, null, List.of()));13categories.put(ModerationCategory.Illicit.INSTANCE, new ModerationCategoryResult(true, null, List.of()));    // from S114categories.put(ModerationCategory.IllicitViolent.INSTANCE, new ModerationCategoryResult(true, null, List.of()));     // from S115ModerationResult result = new ModerationResult(true, categories);

Ollama 중재 예시(안전한 콘텐츠)

다음은 콘텐츠를 안전한 것으로 표시하는 Ollama 응답의 예입니다.

1safe

Koog는 응답을 다음과 같이 번역합니다.

코틀린

1ModerationResult(2    isHarmful = false,3    categories = mapOf(4        ModerationCategory.Harassment to ModerationCategoryResult(false),5        ModerationCategory.HarassmentThreatening to ModerationCategoryResult(false),6        ModerationCategory.Hate to ModerationCategoryResult(false),7        ModerationCategory.HateThreatening to ModerationCategoryResult(false),8        ModerationCategory.Sexual to ModerationCategoryResult(false),9        ModerationCategory.SexualMinors to ModerationCategoryResult(false),10        ModerationCategory.Violence to ModerationCategoryResult(false),11        ModerationCategory.ViolenceGraphic to ModerationCategoryResult(false),12        ModerationCategory.SelfHarm to ModerationCategoryResult(false),13        ModerationCategory.SelfHarmIntent to ModerationCategoryResult(false),14        ModerationCategory.SelfHarmInstructions to ModerationCategoryResult(false),15        ModerationCategory.Illicit to ModerationCategoryResult(false),16        ModerationCategory.IllicitViolent to ModerationCategoryResult(false),17    )18)

자바

1Map<ModerationCategory, ModerationCategoryResult> categories = new HashMap<>();2categories.put(ModerationCategory.Harassment.INSTANCE, new ModerationCategoryResult(false, null, List.of()));3categories.put(ModerationCategory.HarassmentThreatening.INSTANCE, new ModerationCategoryResult(false, null, List.of()));4categories.put(ModerationCategory.Hate.INSTANCE, new ModerationCategoryResult(false, null, List.of()));5categories.put(ModerationCategory.HateThreatening.INSTANCE, new ModerationCategoryResult(false, null, List.of()));6categories.put(ModerationCategory.Sexual.INSTANCE, new ModerationCategoryResult(false, null, List.of()));7categories.put(ModerationCategory.SexualMinors.INSTANCE, new ModerationCategoryResult(false, null, List.of()));8categories.put(ModerationCategory.Violence.INSTANCE, new ModerationCategoryResult(false, null, List.of()));9categories.put(ModerationCategory.ViolenceGraphic.INSTANCE, new ModerationCategoryResult(false, null, List.of()));10categories.put(ModerationCategory.SelfHarm.INSTANCE, new ModerationCategoryResult(false, null, List.of()));11categories.put(ModerationCategory.SelfHarmIntent.INSTANCE, new ModerationCategoryResult(false, null, List.of()));12categories.put(ModerationCategory.SelfHarmInstructions.INSTANCE, new ModerationCategoryResult(false, null, List.of()));13categories.put(ModerationCategory.Illicit.INSTANCE, new ModerationCategoryResult(false, null, List.of()));14categories.put(ModerationCategory.IllicitViolent.INSTANCE, new ModerationCategoryResult(false, null, List.of()));15ModerationResult result = new ModerationResult(false, categories);