Skip to content

설정과 사용법

English | 한국어

이 문서는 Spring AI Privacy Guardrails를 사용하는 애플리케이션을 위한 종합 참고 문서입니다.

기본 Spring Boot 스타터는 개인정보 탐지 설정과 ChatClient·도구의 보호 구성을 제공합니다. Presidio와 OpenNLP 스타터는 여기에 각 분석기 연동을 추가하며, 같은 개인정보 보호 설정을 사용합니다. Spring Security 스타터를 추가하면 사용자별 도구 권한 검사도 사용할 수 있습니다.

스타터 선택

사용할 분석기에 맞는 개인정보 보호 스타터를 선택하고, 필요한 연동 스타터를 추가하세요.

스타터 이름을 누르면 Gradle·Maven 의존성 예제로 이동합니다.

스타터 용도
Presidio 외부 Presidio 서비스를 연동해 다양한 유형의 개인정보를 탐지합니다.
기본 Regex 또는 사용자 정의 분석기를 사용합니다. 별도의 분석기 연동은 포함하지 않습니다.
OpenNLP 직접 준비한 OpenNLP 모델로 애플리케이션 내부에서 개인정보를 탐지합니다. 외부 분석 서비스가 필요하지 않습니다.
Spring Security 애플리케이션의 기존 Spring Security 인증 정보로 도구 권한을 검사합니다. 단독으로 사용하거나 개인정보 보호와 함께 사용할 수 있습니다.

Presidio와 OpenNLP 스타터에는 기본 스타터가 포함되어 있습니다. 두 스타터를 함께 사용할 때도 기본 스타터를 별도로 추가할 필요가 없습니다. 함께 사용하는 Privacy Guardrails 모듈은 같은 버전을 사용하세요.

개인정보 보호 스타터를 추가한 뒤에는 다음 순서로 설정하세요.

  1. 분석기 설정: 사용할 Regex, Presidio, OpenNLP를 설정하거나 사용자 정의 분석기PiiAnalyzer Bean으로 등록합니다.
  2. 클라이언트에 보호 적용: ChatClient에 보호 적용의 코드 예제를 따라 보호할 클라이언트를 구성합니다.

여러 분석기를 함께 사용할 때의 설정과 동작은 탐지와 해석을 참고하세요.

Spring Security 스타터

현재 사용자의 권한에 따라 모델에 공개할 도구와 실행 가능한 도구를 제한하려면 spring-ai-privacy-guardrails-spring-security-spring-boot-starter를 추가합니다. 이 스타터는 기본 Privacy Guardrails 스타터와 독립적이고 개인정보 분석기 없이 사용할 수 있습니다. 인증 정보는 애플리케이션의 기존 Spring Security 설정을 사용합니다.

AuthorizationManager<ToolAuthorizationContext> Bean을 등록하고 ToolAuthorizationChatClientFactory로 클라이언트를 생성하세요.

개인정보 보호와 함께 사용하려면 개인정보 보호 스타터를 추가하고 분석기를 구성한 뒤 PrivacySecurityChatClientFactory를 사용하세요.

전체 설정은 Spring Security 도구 권한을 참고하세요.

ChatClient에 보호 적용

분석기를 구성해도 모든 ChatClient에 보호가 자동으로 적용되지는 않습니다. 개인정보 보호가 필요한 ChatClient.BuilderPrivacyChatClientConfigurer를 적용하세요.

@Bean
ChatClient chatClient(
        ChatClient.Builder builder,
        PrivacyChatClientConfigurer privacyConfigurer
) {
    return privacyConfigurer.configure(builder).build();
}

PrivacyChatClientConfigurer는 입력, 모델 호출, 도구 실행과 요청 수명주기에 필요한 개인정보 보호 경계를 구성하며, 출력 보호가 활성화되어 있으면 출력 경계도 함께 적용합니다.

다른 모델 요청 기능과 함께 사용할 때는 ModelRequestBoundaryConfigurer.compose(...)로 기능별 configurer를 합친 뒤 configure(builder)를 한 번 호출하세요. 공통 바운더리는 개인정보 보호 → 도구 인가 → 모델 요청 최종 검사 순서로 실행하며, 등록하지 않은 단계는 건너뜁니다. 각 기능을 따로 구성하면 바운더리가 중복 생성되어 요청 시 거부됩니다. 여기서 최종 검사는 모델의 출력이 아니라 준비된 모델 요청을 검사하는 단계입니다.

개인정보 보호와 도구 권한 검사를 함께 적용하려면 PrivacySecurityChatClientFactory로 클라이언트를 생성하세요. 이 Factory는 개인정보 보호도 구성하므로 반환된 builder에 PrivacyChatClientConfigurer를 추가로 적용하지 마세요. 도구 권한 검사만 필요하면 ToolAuthorizationChatClientFactory를 사용합니다. 두 구성의 예시는 ChatClient 구성을 참고하세요.

보호된 클라이언트에서 mutate()로 새 클라이언트를 만들면 개인정보 보호 설정도 이어집니다. PrivacyChatClientConfigurer를 다시 적용하지 마세요.

ChatClient protectedClient = privacyConfigurer.configure(builder).build();
ChatClient derivedClient = protectedClient.mutate().build();

보호 설정이 적용된 ChatClient.Builderclone()으로 복사할 때도 설정이 이어지므로 PrivacyChatClientConfigurer를 다시 적용하지 마세요.

도구 이름, 설명과 JSON 스키마도 모델에 전달되기 전에 개인정보를 검사합니다.

Spring AI의 표준 UserMessage, SystemMessage, AssistantMessage, ToolResponseMessageDeepSeekAssistantMessage를 지원합니다. 그 밖의 모델 제공자 전용 Message 하위 클래스와 애플리케이션이 직접 구현한 Message는 오류로 처리합니다. 알 수 없는 필드의 개인정보가 보호되지 않은 채 전달되는 것을 막기 위해서입니다.

사용자 정의 Advisor 순서

이 절은 개인정보 보호만 사용하면서 도구 호출을 담당하는 ToolCallingAdvisor의 실행 순서를 변경하는 경우에 해당합니다. 기본 순서(ToolCallingAdvisor.DEFAULT_ORDER)를 사용한다면 앞의 configure(builder) 구성으로 충분합니다.

실행 순서를 변경할 때는 advisorOrder(...)forToolAdvisorOrder(...)에 같은 값을 전달하세요. 아래 예시는 도구 호출 순서를 100으로 설정하고, 도구 실행 전후의 개인정보 보호 처리도 그에 맞춰 배치합니다.

@Bean
ChatClient privacyClientWithCustomToolOrder(
        ChatModel chatModel,
        ToolCallingManager toolCallingManager,
        PrivacyChatClientConfigurer privacyConfigurer
) {
    int toolOrder = 100;
    ToolCallingAdvisor toolCallingAdvisor = ToolCallingAdvisor.builder()
            .toolCallingManager(toolCallingManager)
            .advisorOrder(toolOrder)
            .build();
    ChatClient.Builder builder = ChatClient.builder(chatModel)
            .defaultAdvisors(toolCallingAdvisor);

    return privacyConfigurer.forToolAdvisorOrder(toolOrder)
            .configure(builder)
            .build();
}

도구 권한 검사도 함께 사용한다면 PrivacySecurityChatClientFactory에 도구 Advisor의 builder를 전달하세요. Factory가 실행 순서에 맞춰 개인정보 보호까지 구성하므로 위처럼 Advisor나 configurer를 별도로 등록할 필요가 없습니다. 사용자 정의 도구 Advisor에서 예시를 확인할 수 있습니다.

다른 Spring AI Advisor와 함께 사용할 수 있습니다. 다만 별도의 Advisor가 개인정보 보호 경계 밖에서 입력·도구·응답 데이터를 추가하거나 변경하면, 그 내용은 자동으로 보호되지 않을 수 있습니다. 개인정보 보호 경계의 순서를 유지하려면 개별 구성 요소를 직접 조립하기보다 PrivacyChatClientConfigurer를 사용하세요.

설정 속성

아래 표에서 전체 경로를 따로 적지 않은 속성은 모두 spring.ai.privacy 아래에 설정합니다.

속성 기본값 의미
analysis.language en 대소문자를 구분하지 않는 ASCII 언어 코드입니다. 소문자 정규형으로 분석기에 전달합니다.
analysis.included-entity-types 비어 있음 탐지 허용 목록입니다. 신뢰할 수 있는 유형을 등록하는 설정은 아닙니다.
analysis.minimum-score 0.0 탐지 결과를 채택할 최소 신뢰도입니다. 모든 분석기에 적용합니다.
analysis.mode UNION 여러 분석기를 실행하고 결과를 조합하는 방식입니다. 탐지와 해석을 참고하세요.
analysis.primary-provider 미설정 PRIMARYPRIMARY_WITH_FALLBACK 모드와 REQUIRE_PRIMARY 실패 정책에서 사용할 주 분석기의 ID입니다. 대소문자를 구분하지 않습니다.
analysis.supplemental-providers 비어 있음 주 분석기와 함께 실행해 탐지를 보완할 보조 분석기의 ID 목록입니다.
analysis.failure-policy REQUIRE_ALL 분석기 가용성에 대한 실패 정책입니다.
analysis.provider-minimum-scores 비어 있음 분석기 ID별 최소 신뢰도입니다. 전체 최소 신뢰도와 비교해 더 큰 값을 적용합니다.
analysis.entity-aliases 비어 있음 분석기 엔티티 레이블을 정규 유형에 연결하는 명시적 매핑입니다.
analysis.type-conflict-fallback PII 해석하지 못한 중첩 유형 충돌에 사용할 유형입니다.
output.enabled false 출력 보호를 활성화합니다.
output.action TOKENIZE TOKENIZE, REDACT 또는 유형이 지정된 예외를 던지는 BLOCK을 선택합니다.
output.block-exception-message Response blocked by privacy guardrail. BLOCK 예외에 사용할 안전한 메시지입니다.
response-inspection.max-stream-frames 1024 스트리밍 응답 하나에서 검사할 최대 프레임 수입니다.
response-inspection.max-characters 1000000 호출 또는 스트리밍 응답 하나에서 검사하는 텍스트 기반 콘텐츠의 최대 누적 문자 수입니다.
response-inspection.max-media-bytes 16777216 응답 하나에서 허용하는 미디어 데이터의 최대 누적 바이트 수입니다.
response-inspection.stream-idle-timeout 60s 스트리밍 응답 프레임이 도착하지 않아도 기다리는 최대 시간입니다.
tools.disclosures 비어 있음 특정 도구에 원문으로 복원해 전달할 엔티티 유형을 지정합니다.
regex.enabled false 애플리케이션이 제공한 Regex 규칙을 활성화합니다.
regex.rules[].entity-type 규칙마다 필수 규칙의 일치 결과에 부여할 정규 엔티티 유형입니다.
regex.rules[].pattern 규칙마다 필수 원문 텍스트에 적용할 Java 정규식입니다.
regex.rules[].score 0.85 각 일치 결과에 부여할 신뢰도입니다.
regex.rules[].capture-group 0 탐지 범위(span)로 사용할 정규식 캡처 그룹 번호입니다. 0은 전체 일치를 의미합니다.
regex.rules[].validator-id 미설정 일치 후보를 추가로 검사할 선택적 RegexPiiMatchValidator의 ID입니다. Spring Bean 이름이 아닙니다.
presidio.enabled false Presidio 분석기를 활성화합니다.
presidio.analyzer-url http://localhost:5002 분석기의 기본 URI입니다.
presidio.timeout 5s 응답 본문 수신 완료까지 포함해 각 HTTP 요청 시도와 상태 확인에 적용되는 제한 시간입니다.
presidio.max-retries 1 첫 시도 이후의 재시도 횟수입니다.
presidio.retry-backoff 300ms 시도 사이의 대기 시간입니다.
presidio.max-response-bytes 8388608 검증을 위해 보존할 Presidio 응답 본문의 최대 바이트 수입니다.
presidio.headers 비어 있음 Presidio 요청에 추가할 HTTP 헤더입니다. Content-Type은 라이브러리가 관리하므로 설정할 수 없습니다.
opennlp.enabled false 사용자가 제공한 로컬 OpenNLP 모델을 활성화합니다.
opennlp.tokenizer-model 미설정 선택적인 tokenizer 모델 리소스입니다. 설정하지 않으면 SimpleTokenizer를 사용합니다.
opennlp.entity-models 비어 있음 정규 엔티티 유형을 필수 name-finder 모델 리소스에 연결합니다.

Regex rules, Presidio headers, OpenNLP entity-models의 기본값은 비어 있습니다. Spring Boot 설정 메타데이터는 IDE 자동 완성을 제공합니다. analysis.language는 영숫자 단어를 하나의 하이픈 또는 밑줄로 구분한 1~64자 ASCII 식별자를 받습니다. 대소문자를 구분하지 않으며 core는 소문자 정규형을 모든 분석기에 전달합니다. 공백, 문법에 없는 문장부호, 빈 구분자와 반복된 구분자는 자동으로 잘라내거나 보정하지 않고 거부합니다.

스타터는 PiiAnalyzer Bean이 하나 이상 있으면 PrivacyService를 생성합니다. 자동 구성되거나 애플리케이션이 직접 등록한 PrivacyService Bean이 있으면 PrivacyChatClientConfigurerPrivacyToolCallbackFactory를 제공합니다. 이 서비스가 없으면 두 연동 Bean을 생성하지 않으며, 이를 주입받지 않는 애플리케이션은 정상적으로 시작할 수 있습니다.

설정 오타 진단

기본 Spring Boot 스타터는 이 라이브러리가 정의한 고정 spring.ai.privacy 설정에서 알 수 없는 프로퍼티 이름을 발견하면 경고합니다. 이 경고는 애플리케이션 시작을 막지 않으며, 분석기를 구성하지 않아도 진단은 실행됩니다.

예를 들어 다음처럼 output.enabled를 잘못 입력하면 애플리케이션은 계속 시작되지만 올바른 프로퍼티 이름을 제안하는 경고가 기록됩니다.

spring:
  ai:
    privacy:
      output:
        enabledd: true

진단 대상은 output, response-inspection, analysis, regex, tools 안의 프로퍼티 이름입니다. 알 수 없는 최상위 영역과 분석기별 설정은 검사하지 않습니다.

analysis.provider-minimum-scores, analysis.entity-aliases, tools.disclosures 아래의 동적 키와 analysis.included-entity-types, analysis.supplemental-providers의 목록 항목은 진단 대상이 아닙니다. Presidio의 headers와 OpenNLP의 entity-models처럼 분석기별 설정에서 사용하는 동적 맵도 검사하지 않습니다.

올바른 프로퍼티 이름으로 보이는 후보가 하나뿐이면 경고 메시지에 해당 이름을 제안합니다. 진단 메시지에는 설정값, 자격 증명 또는 동적 맵 키를 포함하지 않습니다.

탐지와 해석

분석기는 원문에서 개인정보를 찾은 위치와 유형, 신뢰도를 반환합니다. 개인정보 유형은 PERSON, EMAIL_ADDRESS처럼 구분하며, 설정과 API에서는 이를 엔티티 유형이라고 부릅니다. 라이브러리는 분석 결과에 엔티티 별칭, 탐지 허용 목록, 신뢰도 하한, 분석기 선택과 겹치는 범위의 처리 규칙을 적용합니다. 탐지 위치는 항상 원문 텍스트를 기준으로 합니다. Regex, Presidio, OpenNLP와 Spring Bean으로 등록한 사용자 정의 PiiAnalyzer를 함께 사용할 수도 있습니다.

UNION 모드에서는 설정한 모든 분석기를 실행하고 탐지 결과를 병합합니다. 겹치는 범위 중 하나가 다른 범위를 완전히 포함하면 해당 범위의 유형을 유지합니다. 일부만 겹치는 경우 개인정보의 일부가 노출되지 않도록 범위를 하나로 합치며, 유형 충돌을 해결할 수 없으면 범용 개인정보 유형인 PII로 처리합니다.

분석기 실행 실패는 analysis.failure-policy 설정에 따라 처리합니다. REQUIRE_ALL은 분석기 하나라도 실패하면 요청 처리도 실패합니다. REQUIRE_PRIMARY는 주 분석기의 성공을 요구하지만 다른 분석기의 실패는 허용합니다. ALLOW_PARTIAL은 성공한 분석기의 탐지 결과만 사용하므로 보호 범위가 줄어들 수 있으며, 모든 분석기가 실패하면 요청도 실패합니다.

다음 설정은 Presidio와 애플리케이션 전용 Regex 분석기를 함께 실행하고, 기본 UNION 모드로 탐지 결과를 병합합니다.

spring:
  ai:
    privacy:
      analysis:
        entity-aliases:
          US_SSN: NATIONAL_ID
      presidio:
        enabled: true
      regex:
        enabled: true
        rules:
          - entity-type: EMPLOYEE_ID
            pattern: "(?<![A-Za-z0-9_])EMP-[0-9]{4}(?![A-Za-z0-9_])"
            score: 0.90

PRIMARY 모드에서는 주 분석기와 보조 분석기만 실행하며, 그 외의 분석기가 구성되어 있으면 설정 오류로 처리합니다.

PRIMARY_WITH_FALLBACK 모드를 사용하려면 실패 정책을 ALLOW_PARTIAL로 설정하고, 주 분석기 외에 분석기를 하나 이상 구성해야 합니다. 보조 분석기는 주 분석기와 항상 함께 실행하고, 대체 분석기는 주 분석기가 실패한 경우에만 실행합니다.

analysis.provider-minimum-scores에 분석기 ID를 추가해도 해당 분석기가 자동으로 등록되거나 활성화되지는 않습니다. 이 설정은 이미 등록된 분석기의 탐지 결과에 적용할 신뢰도 하한만 지정합니다. 분석기를 사용하려면 앞의 예시처럼 presidio.enabled 또는 regex.enabled를 설정하거나 직접 분석기 Bean을 등록해야 합니다.

분석기 ID(provider ID)는 REGEX, PRESIDIO, OPENNLP처럼 각 분석기를 구분하는 이름입니다. 영문자와 숫자로 이루어진 구간을 단일 하이픈(-) 또는 밑줄(_)로 연결한 1~128자의 ASCII 식별자이며, 라이브러리는 분석기 ID의 대소문자를 구분하지 않고 대문자 형태로 정규화합니다. 허용되지 않은 문장부호나 공백, 잘못되거나 연속된 구분자, 중복된 분석기 ID는 거부합니다.

엔티티 레이블은 대문자 영문자와 숫자로 이루어진 구간을 단일 밑줄(_)로 연결한 1~128자의 ASCII 식별자입니다. 소문자, 공백, 하이픈(-), 허용되지 않은 문장부호와 빈 구간은 자동으로 보정하지 않고 거부합니다. 잘못된 설정값이나 분석기가 반환한 유효하지 않은 레이블은 오류로 처리합니다.

기본으로 인정하는 정규 엔티티 유형은 PII, PERSON, ORGANIZATION, LOCATION, EMAIL_ADDRESS, PHONE_NUMBER, NATIONAL_ID, CREDIT_CARD, DATE_TIME, IP_ADDRESS, URL, IBAN_CODE, CRYPTO, NRP, MEDICAL_LICENSE입니다. 분석기별 별칭은 자동으로 등록되지 않습니다. 따라서 Presidio의 US_SSN처럼 특정 분석기, 모델, 국가 또는 애플리케이션에 종속된 레이블을 공통 정책 유형으로 사용하려면 entity-aliases를 통해 명시적으로 매핑해야 합니다.

spring:
  ai:
    privacy:
      analysis:
        entity-aliases:
          US_SSN: NATIONAL_ID
          KR_RRN: NATIONAL_ID

형식은 올바르지만 기본 정규 엔티티 유형 목록에 없는 레이블은 PII로 처리됩니다. 탐지 허용 목록에서 PII를 제외했다면 해당 결과도 제거됩니다. 필요하면 허용된 정규 유형으로 매핑하세요. PiiAnalyzer.trustedEntityTypes()를 사용하면 로컬 분석기가 자신의 탐지 결과에서 신뢰할 엔티티 유형을 선언할 수 있습니다.

탐지 허용 목록에 엔티티 유형을 추가해도 해당 유형이 자동으로 신뢰 유형으로 등록되지는 않습니다. 또한 한 분석기가 선언한 신뢰 유형은 다른 분석기의 엔티티 레이블에 적용되지 않습니다. 엔티티 별칭 매핑과 명시적으로 등록한 신뢰 정규 유형은 특정 분석기에 한정되지 않고 모든 분석기 결과에 공통으로 적용됩니다.

구조화된 JSON

구조화된 JSON에서는 속성 이름과 문자열 값, 숫자 값을 분석합니다. 비어 있거나 공백으로만 이루어진 속성 이름과 문자열 값은 분석하지 않습니다. 각 항목은 독립적으로 분석하며, 탐지한 문자열의 시작·끝 위치는 해당 항목의 텍스트를 기준으로 계산합니다.

예를 들어 {"name":"Alice","city":"Seoul"}에서는 name, Alice, city, Seoul이 각각 분석 대상이 됩니다. 외부 요청 횟수와 처리 비용은 선택한 분석기와 분석할 텍스트의 양에 따라 달라집니다.

사용자 정의 분석기

이 절은 PiiAnalyzer를 직접 구현하거나 분석 메서드를 직접 호출할 때 참고하세요. 스타터에서 제공하는 분석기만 사용하는 경우에는 건너뛰어도 됩니다.

사용자 정의 분석기는 여러 요청에서 공유될 수 있으므로 스레드 안전(thread-safe)하고 재진입 가능하게 구현해야 합니다. 각 분석기는 고유한 분석기 ID를 제공해야 하며, 블로킹 작업에는 유한한 제한 시간을 적용하고 스레드 중단 요청도 적절히 처리해야 합니다.

PiiAnalyzer.analyzeSegments(...)는 서로 독립된 여러 텍스트를 받습니다. 기본 구현은 각 텍스트에 대해 analyze(...)를 호출합니다.

텍스트 배열을 받는 외부 분석 서비스를 사용하는 경우에는 analyzeSegments(...)를 재정의해 여러 텍스트를 한 번의 요청으로 처리할 수 있습니다. 재정의한 구현은 입력 순서에 맞춰 텍스트별 결과를 반환하고, 탐지한 범위의 시작·끝 위치를 해당 텍스트를 기준으로 계산해야 합니다. 애플리케이션에서도 PrivacyService.analyzeSegments(...)를 직접 호출해 여러 텍스트를 같은 방식으로 분석할 수 있습니다.

한 번의 PrivacyService.analyzeSegments(...) 호출에는 최대 100,000개의 텍스트 (PiiAnalyzer.MAX_ANALYSIS_SEGMENTS)를 전달할 수 있으며, 전체 입력 길이는 PrivacyService.MAX_TEXT_INPUT_CHARACTERS를 초과할 수 없습니다. 반환할 수 있는 탐지 범위의 총합은 최대 100,000개(PiiAnalyzer.MAX_RESULT_SPANS)입니다. 사용자 정의 분석기도 처리 중 생성하는 임시 데이터와 결과 크기에 적절한 한도를 적용해야 합니다. 텍스트 크기 제한은 입력·응답 처리 제한을 참고하세요.

Regex 분석기

Regex 분석기는 모든 개인정보를 탐지하기 위한 용도가 아니라, 사번이나 고객번호처럼 형식이 명확한 애플리케이션 고유 식별자를 탐지하는 데 적합합니다. 정규식 패턴은 애플리케이션이 관리하는 신뢰된 설정으로 사용하고, 불필요하게 복잡한 패턴은 피하세요.

spring:
  ai:
    privacy:
      regex:
        enabled: true
        rules:
          - entity-type: CUSTOMER_ID
            pattern: "(?<![A-Za-z0-9_])CUST-[0-9]{6}(?![A-Za-z0-9_])"
            score: 0.90
            capture-group: 0
            validator-id: customer-id-check

각 규칙에는 entity-typepattern이 필요합니다. score 기본값은 0.85, capture-group 기본값은 0입니다. validator-id는 선택 사항이며 Spring Bean 이름이 아니라 애플리케이션이 제공한 RegexPiiMatchValidatorid()가 반환하는 고정 ID를 참조합니다.

@Bean
RegexPiiMatchValidator customerIdMatchValidator() {
    return new RegexPiiMatchValidator() {
        @Override
        public String id() {
            return "customer-id-check";
        }

        @Override
        public boolean isValid(String candidate) {
            return CustomerIds.hasValidChecksum(candidate);
        }
    };
}

CustomerIds.hasValidChecksum(...)은 애플리케이션의 검증 로직을 나타내는 예시입니다. 실제 사용할 검증 로직은 애플리케이션에서 구현해야 합니다.

ID는 소문자 ASCII 영문자와 숫자로 이루어진 구간을 하나의 하이픈으로 연결합니다. 애플리케이션을 시작할 때 ID를 확인하며, 빈 값이나 잘못된 형식, 알 수 없는 ID가 있거나 둘 이상의 검증기 Bean이 같은 ID를 사용하면 시작에 실패합니다. 여러 규칙이 같은 ID를 참조하는 것은 허용됩니다.

isValid()에는 capture-group이 선택한 일치 후보만 전달됩니다. true를 반환하면 기존 탐지 범위와 점수를 유지하고, false를 반환하면 해당 후보를 제외합니다. 실행 중 발생한 예외는 설정한 분석기 실패 정책에 따라 처리합니다.

RegexPiiMatchValidator 구현체는 여러 요청에서 공유되므로 스레드 안전하게 작성해야 합니다. 검증 대상 문자열에는 개인정보 원문이 포함될 수 있으니 로그나 예외 메시지에 남기거나 장기간 보관하지 마세요. validator-id를 설정하지 않으면 정규식에 일치한 후보를 별도의 검증 없이 사용합니다.

Presidio 분석기

Presidio는 분석할 원문 텍스트를 설정한 Presidio 서버로 전송합니다. Presidio 스타터를 추가한 뒤 분석기를 활성화하고 서버 접속 정보를 설정합니다.

spring:
  ai:
    privacy:
      analysis:
        language: en
      presidio:
        enabled: true
        analyzer-url: https://presidio.internal
        timeout: 5s
        max-retries: 1
        retry-backoff: 300ms
        max-response-bytes: 8388608
        headers:
          X-API-Key: ${PRESIDIO_API_KEY}

analyzer-url에는 Presidio 서버의 HTTP(S) 주소를 설정합니다. 기본값은 http://localhost:5002이며, 서버가 다른 주소에서 실행된다면 해당 주소로 변경하세요. 인증 정보가 필요한 경우 URL에 포함하지 말고 headers와 애플리케이션의 비밀값 관리 기능을 사용하세요.

구조화된 JSON을 Presidio로 분석하려면 Presidio Analyzer 2.2.361 이상을 사용하세요. 네트워크 요청을 줄이기 위해 여러 텍스트를 묶어서 전송하며, 입력이 크면 여러 요청으로 나누어 처리합니다. 각 텍스트는 독립적으로 분석합니다.

timeout은 Presidio 응답 본문을 모두 받을 때까지의 HTTP 요청 시간에 적용됩니다. 전송 실패, timeout 초과, HTTP 408/429와 5xx 응답은 max-retries 설정에 따라 재시도하며, 그 밖의 4xx 응답은 즉시 실패합니다.

max-response-bytes는 Presidio 응답 본문의 최대 크기이며 기본값은 8 MiB입니다. 이 값을 늘리면 응답 처리에 필요한 최대 메모리도 증가할 수 있습니다. 크기 제한을 초과하거나 올바르게 처리할 수 없는 응답은 분석 실패로 처리합니다.

Spring Boot의 상태 점검 기능을 사용하는 경우 Presidio 서비스의 상태도 함께 확인할 수 있습니다.

로컬 Docker 구성은 samples/presidio에 있습니다.

OpenNLP 분석기 (JVM 전용, 선택 사항)

이 구성은 호환되는 OpenNLP NER 모델을 사용해 별도의 외부 분석 서비스 없이 애플리케이션과 같은 JVM에서 개인정보를 분석하려는 경우에 적합합니다. OpenNLP NER 모델은 라이브러리에 포함되지 않으므로 사용할 모델 파일을 별도로 준비해야 합니다.

spring:
  ai:
    privacy:
      analysis:
        language: en
      opennlp:
        enabled: true
        tokenizer-model: classpath:/models/en-token.bin
        entity-models:
          PERSON: classpath:/models/en-ner-person.bin
          ORGANIZATION: classpath:/models/en-ner-organization.bin

tokenizer-model을 지정하지 않으면 OpenNLP SimpleTokenizer를 사용합니다. entity-models에는 각 엔티티 유형에 사용할 NER 모델 파일의 위치를 설정합니다. 사용하는 NER 모델과 토큰화 방식이 맞지 않으면 탐지 품질이 달라질 수 있으므로 실제 데이터에 맞게 검증해야 합니다.

OpenNLP 연동은 기존 NER 모델을 활용하려는 애플리케이션을 위한 선택적 구성으로, 범용 개인정보 탐지의 기본 방식으로 권장하지는 않습니다.

실행 가능한 샘플 가이드에서 모델 준비, 설정 및 실제 연동 테스트 방법을 확인할 수 있습니다.

도구별 원문 공개

개인정보 보호가 적용된 도구에는 탐지된 값을 기본적으로 **불투명 토큰(opaque token)**으로 전달합니다. 불투명 토큰은 원문 값을 직접 드러내지 않는 대체 문자열입니다. 특정 도구가 원문을 받아야 한다면 tools.disclosures에 해당 도구에 공개할 엔티티 유형을 지정하세요.

spring:
  ai:
    privacy:
      tools:
        disclosures:
          customerLookup:
            - CUSTOMER_ID

위 설정에서는 customerLookup 도구에만 CUSTOMER_ID의 원문을 전달합니다. 공개하도록 지정하지 않은 엔티티 유형과 tools.disclosures에 등록되지 않은 도구에는 보호된 값이 그대로 전달됩니다.

개인정보 보호가 적용된 ChatClient에서 사용하는 ToolCallbackPrivacyToolCallbackFactory로 감싸서 등록하세요. 아래의 customerLookupknowledgeSearch는 애플리케이션에서 준비한 ToolCallback입니다.

List<ToolCallback> protectedTools = privacyToolCallbackFactory.wrapAll(
        List.of(customerLookup, knowledgeSearch));

ChatClient chatClient = privacyConfigurer.configure(ChatClient.builder(chatModel)
        .defaultTools(protectedTools.toArray()))
        .build();

MCP처럼 실행 중에 도구 목록이 달라질 수 있다면 현재 콜백 목록만 감싸지 말고 ToolCallbackProvider 자체를 감싸세요. 하나는 wrapProvider(...)로, 여러 개는 wrapProviders(...)로 감싸 하나의 보호된 ToolCallbackProvider로 결합할 수 있습니다.

ToolCallbackProvider protectedTools = privacyToolCallbackFactory.wrapProviders(
        mcpTools,
        localToolProvider
);

ChatClient mcpClient = privacyConfigurer.configure(builder)
        .defaultTools(protectedTools)
        .build();

tools.disclosures의 도구 이름은 대소문자를 구분하며 최종 ToolDefinition.name()과 일치해야 합니다. 동적 provider가 도구 이름에 접두사를 추가한다면 변경된 최종 이름을 사용하세요. 와일드카드는 지원하지 않으며 PII를 포함해 원문 공개가 필요한 엔티티 유형은 모두 명시적으로 지정해야 합니다. 공개할 유형이 없다면 해당 도구를 tools.disclosures에 등록하지 마세요.

도구가 호출되기 전에 입력을 검사하고, 해당 도구에 허용된 엔티티 유형만 원문으로 복원합니다. 도구 실행 결과도 다시 검사하여 모델에 전달되기 전에 개인정보를 보호합니다.

원문 공개가 허용된 도구는 실제 개인정보를 전달받을 수 있으므로 도구 구현의 예외 메시지나 로그에 개인정보가 남지 않도록 주의하세요.

Spring Security 연동을 활성화하면 원문 공개 정책을 적용하기 전에 도구 사용 권한을 확인합니다. 권한 정책은 현재 사용자의 권한에 따라 모델에 공개할 도구와 실행 가능한 도구를 결정합니다. tools.disclosures는 권한 검사를 통과한 도구에 어떤 개인정보 유형의 값을 원문으로 제공할지 결정합니다. 자세한 내용은 Spring Security 도구 권한을 참고하세요.

이 기능은 Spring AI의 표준 ToolCallbackToolCallbackProvider 등록 경로를 대상으로 합니다. 사용자 정의 도구 실행 경로는 자동 개인정보 보호 경계에 포함되지 않으므로 별도의 보호 구성이 필요합니다. Spring Security 연동에서 사용자 정의 ToolCallingManager를 사용하는 방법은 사용자 정의 ToolCallingManager를 참고하세요.

출력 정책과 스트리밍

spring:
  ai:
    privacy:
      output:
        enabled: true
        action: tokenize

출력 보호를 활성화하면 모델이나 도구에서 애플리케이션으로 반환되는 개인정보에 설정한 정책을 적용합니다.

  • TOKENIZE는 같은 요청 안에서 동일한 개인정보를 일관된 불투명 토큰으로 치환합니다.
  • REDACT는 개인정보를 원문으로 복원할 수 없는 유형 마커로 대체합니다.
  • BLOCK은 개인정보가 포함된 출력을 차단하고 PrivacyOutputBlockedException을 발생시킵니다.

출력 보호는 일반 모델 응답, 도구 호출 인자와 returnDirect 결과에 적용됩니다.

returnDirect 도구 흐름

returnDirect는 Spring AI에서 도구 실행 후 모델을 다시 호출할지 결정하는 설정입니다. returnDirect=true인 도구는 실행 결과를 모델에 다시 전달하지 않고 최종 응답으로 직접 반환할 수 있습니다. 개인정보 보호 기능 자체를 켜거나 끄는 설정은 아닙니다.

returnDirect 동작 사용 시점
false 도구 결과를 보호한 뒤 모델에 다시 전달합니다. 모델은 결과를 바탕으로 답변을 생성하거나 다른 도구를 호출할 수 있습니다. 모델이 도구 결과를 계속 처리해야 할 때
true 도구 결과를 보호한 뒤 최종 응답으로 직접 반환할 수 있습니다. 도구 결과 자체를 최종 응답으로 사용할 때

ChatClient에 두 종류의 도구를 함께 등록할 수 있습니다. 한 번의 모델 응답에서 선택된 도구가 모두 returnDirect = true인 경우에만 Spring AI가 모델을 다시 호출하지 않고 결과를 직접 반환합니다. 그렇지 않으면 도구 결과는 모델로 다시 전달됩니다.

output.enabled=false인 경우에도 returnDirect로 직접 반환되는 도구 결과의 개인정보는 불투명 토큰 상태를 유지합니다. 출력 보호를 활성화하면 최종 결과에 TOKENIZE, REDACT 또는 BLOCK 정책을 적용합니다.

최종 모델 출력 검사

output.enabled는 모델이 생성한 최종 응답에 출력 정책을 적용할지를 결정합니다. 이 설정을 비활성화해도 입력, 모델 호출 경계와 도구 결과에 대한 개인정보 보호는 계속 적용됩니다.

output.enabled 최종 모델 출력 검사 전달 방식
false 하지 않음 최종 모델 출력을 별도로 검사하지 않습니다. 스트리밍 호출에서는 모델이 생성하는 텍스트를 실시간으로 전달할 수 있습니다. 다른 개인정보 보호 경계는 계속 적용되며, returnDirect 결과의 개인정보도 불투명 토큰으로 바뀝니다.
true 적용 완성된 응답을 검사한 뒤 TOKENIZE, REDACT 또는 BLOCK 정책을 적용하여 전달합니다.

출력 보호가 활성화되어도 Spring AI의 스트리밍 API를 사용할 수 있지만, 개인정보를 검사하기 위해 완성된 응답을 먼저 버퍼링합니다. 따라서 모델 응답이 생성되는 즉시 전달되는 실시간 스트리밍은 사용할 수 없습니다. 실시간 스트리밍이 반드시 필요하다면 output.enabled=false로 두고 최종 모델 출력의 개인정보 보호를 애플리케이션에서 처리해야 합니다.

추론 텍스트 보호

출력 보호를 활성화하면 응답 본문뿐 아니라, 아래에 명시된 추론 텍스트에도 같은 보호 정책을 적용합니다.

보호 대상 필드

  • DeepSeekAssistantMessage.getReasoningContent()가 반환하는 텍스트
  • 메시지(AssistantMessage)와 생성 결과(Generation) 메타데이터의 최상위 reasoningContent, thinking 필드에 담긴 문자열

다른 이름의 메타데이터 필드나 중첩된 값은 자동으로 검사하지 않습니다.

입력·응답 처리 제한

response-inspection.* 설정은 output.enabled와 별개입니다. 이 설정들은 도구 호출 과정의 중간 응답 등 라이브러리가 검사해야 하는 콘텐츠의 크기와 스트리밍 범위를 제한합니다. 출력 보호가 활성화되면 response-inspection.max-charactersresponse-inspection.max-media-bytes 제한을 최종 응답에도 적용합니다. 미디어 제한은 데이터 크기만 확인하며, 이미지나 오디오 내용에서 개인정보를 탐지하지는 않습니다.

설정으로 변경할 수 없는 처리 상한도 있습니다. 지나치게 크거나 복잡한 입력으로 인한 메모리 사용을 제한하기 위한 값이며, output.enabled=false인 경우에도 적용됩니다.

제한 적용 지점 측정 대상 최대치
Spring AI 경계 JSON 파싱 또는 평문 처리 전의 전체 페이로드 길이(UTF-16 코드 단위) 1,000,000
core 텍스트 처리 자동 분석하거나 호출자가 제공한 탐지 범위(span)로 처리하는 단일 텍스트 길이(UTF-16 코드 단위) 1,000,000
core 세그먼트 분석 한 번의 analyzeSegments(...) 호출에 전달된 모든 텍스트의 길이 합계(UTF-16 코드 단위) 1,000,000
core 값 트리 처리 단일 값 트리에 포함된 문자열, 맵 키 및 숫자 표현 길이의 합계(UTF-16 코드 단위) 1,000,000
JSON 또는 값 트리 처리 단일 JSON 문서 또는 core 값 트리의 노드 수 100,000
JSON 또는 값 트리 처리 단일 JSON 문서 또는 core 값 트리의 중첩 깊이 128
개인정보 변환 한 번의 변환으로 생성되는 전체 출력 길이(UTF-16 코드 단위) 8,000,000

텍스트 길이는 Java String.length() 기준입니다. 일반적인 글자는 대부분 UTF-16 코드 단위 1개로 계산하지만, 여러 이모지는 화면에 한 글자로 보여도 2개로 계산됩니다.

안전 상한을 초과하면 처리 또는 결과 전달 전에 PAYLOAD_LIMIT_EXCEEDED 오류가 발생합니다.

일반 메시지나 도구 결과가 JSON 형식이 아니더라도 평문으로 개인정보 보호를 적용할 수 있습니다. 구조화된 JSON이 반드시 필요한 경계에서만 잘못된 JSON을 거부합니다.

core 모듈 직접 사용

이 절은 Spring AI 스타터를 통한 일반적인 사용이 아니라 core 모듈의 PrivacyService 메서드를 직접 호출하는 경우에만 해당합니다. 스타터를 사용하는 경우에는 아래의 세션이나 값 구조를 직접 관리할 필요가 없습니다.

PrivacyService를 직접 사용하는 경우에는 먼저 PrivacySession을 엽니다. session.handle()은 사용할 세션을 지정하는 값으로, 개인정보 분석·토큰화·원문 복원 메서드에 전달합니다. 아래는 탐지된 개인정보를 불투명 토큰으로 바꾼 뒤, 애플리케이션이 공개를 허용한 고객번호 (CUSTOMER_ID)만 같은 세션에서 복원하는 예시입니다.

try (PrivacySession session = privacyService.openSession()) {
    PiiTokenizationResult result = privacyService.analyzeAndTokenize(
            session.handle(), sourceText);
    String protectedText = result.tokenizedText();

    String disclosedText = privacyService.detokenize(
            session.handle(), protectedText, Set.of("CUSTOMER_ID"));
}

detokenize(...)의 세 번째 인자에 지정한 유형만 원문으로 복원되고, 다른 유형의 불투명 토큰은 유지됩니다. 공개할 유형은 애플리케이션의 정책에 따라 지정하세요. try 블록을 벗어나 세션이 닫히면 그 세션의 불투명 토큰을 원문으로 복원할 수 없습니다. 존재하지 않거나 이미 종료된 세션의 handle을 전달하면 오류가 발생합니다.

tokenizeValueTree()detokenizeValueTree() 메서드는 JSON과 호환되는 MapList 구조를 처리합니다. 값으로는 null, 불리언, 문자열과 Byte, Short, Integer, Long, BigInteger, BigDecimal, 유한한 Float·Double 값을 사용할 수 있으며, Map의 키는 문자열이어야 합니다.

이 메서드들은 입력 객체를 직접 수정하지 않고 변환된 새로운 MapList를 반환합니다. 지원하지 않는 값이나 문자열이 아닌 Map 키, 순환 참조가 있으면 TRANSFORMATION_CONFLICT가 발생하며, 처리 가능한 크기 제한을 초과하면 PAYLOAD_LIMIT_EXCEEDED가 발생합니다.

일반 Java 객체나 Jackson JsonNode를 이 두 메서드에 직접 전달할 수는 없습니다. 직접 사용하는 경우에는 먼저 지원되는 Map/List 구조로 변환해야 합니다.

테스트 지원

spring-ai-privacy-guardrails-test는 JUnit 같은 자동화 테스트에서 사용하는 유틸리티 모듈입니다. 모델에 개인정보 원문이 전달됐는지, 도구가 허용된 원문을 받았는지, 요청이 끝난 뒤 개인정보 보호 세션이 정리됐는지 테스트 코드로 검증할 수 있습니다.

dependencies {
    testImplementation "io.github.ultramancode:spring-ai-privacy-guardrails-test:0.3.0"
}

테스트에서는 이 모듈이 제공하는 PrivacyTestProbe로 모델과 도구에 전달되는 값을 기록합니다. 요청 실행 후 PrivacyTestAssertions.assertThatPrivacy(...)로 그 기록을 검증합니다.

아래는 JUnit 테스트 메서드 예시입니다. 이름(PERSON)과 이메일(EMAIL_ADDRESS)을 탐지하도록 분석기를 구성하고, customerLookup 도구에는 PERSON의 원문 공개를 허용했다고 가정합니다. privacyService, privacyConfigurer, privacyToolCallbackFactory는 앞에서 설명한 스타터 구성의 Bean을 테스트에 주입받아 사용합니다.

예시에서 사용하는 값과 객체의 의미는 다음과 같습니다.

값 또는 변수 테스트 코드에서 준비할 내용
testModel 첫 응답에서 customerLookup 도구를 요청하고, 도구 실행 후 최종 응답을 반환하도록 준비한 ChatModel입니다. 테스트용 구현이나 mock을 사용할 수 있습니다.
customerLookup 호출 시 전달되는 값을 확인할 원본 ToolCallback입니다. 테스트용 도구를 만들거나, 검증하려는 애플리케이션의 도구 콜백을 사용합니다.
"Alice", "alice@example.com" 개인정보 탐지와 전달 여부를 확인하기 위한 예제 이름과 이메일입니다. 테스트 입력과 검증 메서드에 사용할 값을 맞춰 지정하세요.

이 테스트에서 testModel이 만드는 도구 호출 인자에는 모델 입력에서 받은 PERSON 불투명 토큰을 사용하세요. 그러면 불투명 토큰이 도구에 전달되기 전에 "Alice"로 복원되는지 확인할 수 있습니다.

@Test
void protectsModelInputAndDisclosesAllowedToolInput() {
    try (PrivacyTestProbe privacyProbe = PrivacyTestProbe.create(privacyService)) {
        ChatModel recordingModel = privacyProbe.wrapModel(testModel);
        ToolCallback protectedTool = privacyProbe.wrapTool(
                customerLookup, privacyToolCallbackFactory);

        ChatClient client = privacyConfigurer.configure(
                ChatClient.builder(recordingModel).defaultTools(protectedTool)
        ).build();

        client.prompt()
                .user("Find Alice (alice@example.com).")
                .call()
                .content();

        assertThatPrivacy(privacyProbe)
                .modelRequestsDoNotContainRawValues("Alice", "alice@example.com")
                .modelRequestsContainOpaqueToken("PERSON")
                .toolInputsContain("customerLookup", "Alice")
                .hasNoActivePrivacySessions();
    }
}

wrapModel(...)로 기록 기능을 붙이고, privacyConfigurer.configure(...)로 모델 입력의 개인정보 보호를 적용합니다. wrapTool(...)은 전달받은 PrivacyToolCallbackFactory로 도구를 보호하고, 보호 처리 후 도구에 전달되는 값을 기록합니다.

외부 LLM 연결 없이도 테스트용 ChatModel로 개인정보 보호 동작을 검증할 수 있습니다.

이 예제는 대표적인 검증 메서드를 보여줍니다. 전체 테스트 유틸리티와 검증 메서드는 각 클래스의 Javadoc과 IDE 자동완성에서 확인할 수 있습니다.

PrivacyTestProbe에는 테스트 원문이 기록될 수 있으므로 테스트 환경에서만 사용하세요. 위 예제처럼 try-with-resources로 사용하면 종료 시 기록이 정리됩니다. 테스트 도중 기록만 초기화하려면 clear()를 사용할 수 있습니다.

개인정보 보호 런타임 관측

애플리케이션은 선택적으로 PrivacyEnforcementObserver 타입의 Spring 빈을 하나 등록해 스타터가 관리하는 개인정보 보호 경계의 처리 결과를 받을 수 있습니다.

@Bean
PrivacyEnforcementObserver privacyEnforcementObserver() {
    return event -> privacyMetrics.record(event.boundary(), event.outcome());
}

privacyMetrics.record(...)는 애플리케이션의 메트릭 기록 코드를 나타내는 예시입니다. 사용하는 모니터링 도구에 맞는 코드로 바꾸세요.

라이브러리는 개인정보 보호 처리가 끝나면 등록된 옵저버에 이벤트를 전달합니다. boundary()는 이벤트가 발생한 지점을, outcome()은 해당 지점의 처리 결과를 나타냅니다. 따라서 요청 하나에서 여러 이벤트가 발생할 수 있습니다. 요청이 특정 경계를 지나지 않으면 해당 경계의 이벤트는 전달되지 않습니다. 출력 정책에 따른 차단은 BLOCKED로 알리지만, 그 밖의 처리 실패를 알리는 이벤트는 제공하지 않습니다.

PrivacyEnforcementEvent에는 의도적으로 boundary()outcome()만 포함됩니다. 개인정보 원문, 불투명 토큰, 엔티티 유형, 페이로드, 도구 이름, 요청 식별자와 상관관계 데이터는 전달하지 않습니다.

경계 (boundary) 이벤트 발생 시점 결과 (outcome)와 의미
MODEL 모델에 전달할 요청의 보호 처리가 완료된 뒤 PROTECTED — 모델 요청 보호가 완료됨
TOOL_INPUT 도구 입력 처리가 완료된 뒤 DISCLOSED — 정책에 따라 개인정보 원문을 하나 이상 복원함
PROTECTED — 도구에 전달하기 위해 복원된 개인정보 원문이 없음
TOOL_RESULT 도구 결과의 보호 처리가 완료된 뒤 PROTECTED — 도구 결과 보호가 완료됨
APPLICATION_OUTPUT 최종 응답에 출력 보호를 적용할 때 PROTECTED — 출력 보호가 완료되어 응답을 반환할 수 있음
BLOCKEDBLOCK 정책이 개인정보를 탐지해 응답 대신 차단 예외를 발생시킴

PROTECTED는 해당 경계의 보호 처리가 정상적으로 완료됐다는 뜻입니다. 개인정보가 있었는지 또는 실제 내용이 변경됐는지는 나타내지 않습니다. TOOL_INPUT에서 PROTECTED는 도구에 전달하기 위해 복원된 개인정보 원문이 없다는 뜻입니다.

스트리밍 애플리케이션 출력은 버퍼링된 전체 응답의 보호 처리가 끝난 뒤 이벤트를 한 번만 전달합니다. 옵저버 콜백은 여러 요청에서 동시에 실행될 수 있습니다. 스트리밍 출력에서는 Reactor가 응답 스트림을 처리하는 스레드에서 콜백을 실행할 수 있으므로, 요청을 처음 처리한 스레드와 같다고 가정하면 안 됩니다.

로그 기록이나 메트릭 갱신처럼 짧은 작업은 콜백에서 바로 수행해도 됩니다. 네트워크나 데이터베이스 I/O가 필요하면 작업을 별도 큐에 넣고 콜백은 즉시 반환하는 방식을 권장합니다. 옵저버 콜백에서 발생한 비치명적 오류는 무시되며 개인정보 보호 처리에는 영향을 주지 않습니다.

Spring Boot 스타터를 사용하면 등록한 옵저버 빈이 자동으로 연결됩니다. 스타터 없이 구성할 때는 PrivacyChatClientConfigurer.builder(privacyService).enforcementObserver(observer)로 옵저버를 지정한 뒤 configurer를 생성하세요. 모델 요청의 개인정보 보호 처리 결과를 받을 수 있고, 출력 보호를 활성화하면 출력 처리 결과도 받습니다. 도구 이벤트를 받으려면 PrivacyToolCallbackFactory의 생성자에도 옵저버를 별도로 전달해야 합니다. PrivacyOutputAdvisor를 직접 생성한다면 옵저버를 받는 생성자를 사용하세요. 옵저버를 지정하지 않은 configurer와 구성 요소는 관측 이벤트를 전달하지 않습니다.

저장 데이터와 진단 정보

이 라이브러리는 모델에 전달되는 메모리와 검색 문서의 개인정보를 보호하지만, 이미 저장된 데이터 자체를 찾아서 수정하지는 않습니다. ChatMemory, 벡터 저장소, 데이터베이스, 로그와 추적 정보 등에 저장된 개인정보는 애플리케이션에서 별도로 보호해야 합니다.

추론 텍스트 보호에 명시한 필드 외의 응답 메타데이터와 비텍스트 미디어는 자동으로 보호하지 않습니다.

PiiAnalyzerFailureObserver에는 개인정보나 상세 예외 내용 대신 분석기 ID, 실패 코드, 처리 단계와 시도 횟수처럼 정제된 실패 정보만 전달됩니다. 분석기나 원문 공개가 허용된 도구의 상세 진단 정보에는 개인정보가 포함될 수 있으므로, 애플리케이션의 안전한 로그 또는 모니터링 시스템에서 관리하세요.

개인정보 보호 오류 처리

PrivacyGuardrailException은 이 라이브러리의 개인정보 보호 처리 과정에서 발생한 오류를 나타냅니다. code()로 오류 유형을, phase()로 오류가 발생한 처리 단계를 확인할 수 있습니다.

PrivacyFailureCode는 이 라이브러리에서 발생한 오류에만 사용합니다. 모델 제공자나 애플리케이션 도구 자체에서 발생한 예외는 기존 예외를 그대로 전달합니다.

사용 가능한 오류 유형과 자세한 의미는 PrivacyFailureCode의 Javadoc에서 확인할 수 있습니다.

phase() 의미
ANALYSIS 개인정보 탐지 및 분석
TOKENIZATION 개인정보 토큰화
REDACTION 개인정보를 마스킹
DETOKENIZATION 허용된 원문 복원
SESSION 개인정보 보호 세션 처리
OUTPUT_POLICY 최종 출력 정책 적용
TOOL_INPUT 도구 입력 검사 및 원문 공개
TOOL_EXECUTION 도구 실행 경계 검사
TOOL_OUTPUT 도구 실행 결과 보호