個人を特定できる情報(PII)を検出および編集する¶
個人を特定できる情報(PII)には、名前、住所、電話番号、メールアドレス、納税者番号、および個人を特定するために(単独または他の情報と合わせて)使用できるその他のデータが含まれます。ほとんどの組織には、PIIデータの取り扱いに関する規制とコンプライアンス要件があります。:doc:`AI_REDACT</sql-reference/functions/ai_redact>`は、大規模言語モデル(LLM)を使用して非構造化テキストデータからPIIを検出、特定、および編集するのに役立つ、完全に管理されたCortex AI関数です。
AI_REDACTは、コールセンターのコーチング、感情分析、保険および医療分析、機械学習(ML)モデルのトレーニングなど、さまざまなユースケースのためにテキストを準備するのに役立ちます。
Tip
AI_PARSE_DOCUMENT または AI_TRANSCRIBE を使用して、 AI_REDACT を適用する前に、ドキュメントまたはスピーチデータをテキストに変換します。
AI_REDACT¶
AI_REDACT関数には、detect``と``redact``という2つの操作モードがあります。デフォルトは ``redact です。``detect``モードでAI_REDACTを使用して、PIIの場所を特定し、編集するPIIをプログラムで選択します。``redact``モードでAI_REDACTを使用して、入力テキスト内のPIIをプレースホルダー値に置き換えます。
重要
AI_REDACTは、AIモデルを使用してベストエフォート方式で検出と編集を実行します。出力を常に確認して、組織のデータプライバシーポリシーに準拠していることを確認してください。AI_REDACTがデータ内のPIIの検出または編集に失敗した場合は、:doc:`Snowflakeサポートにお問い合わせ</user-guide/contacting-support>`ください。
リージョンの可用性¶
リージョンの可用性 をご参照ください。
制限事項¶
編集は AI モデルを使用して実行され、個人を特定できる情報をすべて検出しない場合があります。出力を常に確認して、組織のデータプライバシーポリシーに準拠していることを確認してください。AI_REDACT が特定の PII の編集に失敗する場合は、Snowflakeサポートにお問い合わせください。
COUNT_TOKENS および AI_COUNT_TOKENS 関数はまだ AI_REDACT をサポートしていません。
現時点では、 AI_REDACT は、文法的に正しい英語テキストで最善の機能を発揮します。パフォーマンスは、多くのスペルミス、句読点の誤り、または文法エラーのある他の言語またはテキストでは異なる場合があります。
AI_REDACTは現在、:ref:`label-ai_redact_pii_categories`に示されているように、USのPIIとUKおよびカナダの一部のPIIのみをサポートしています。
AI_REDACT は現在、入力および出力できるトークンの数が制限されています。入力と出力を合計して、最大4,096トークンを使用できます。出力は1,024トークンに制限されています。入力テキストが長い場合は、 SPLIT_TEXT_RECURSIVE_CHARACTER を使用して、小さなチャンクに分割し、各チャンクを個別に編集します。トークン制限を超えるテキストを編集する例については、:ref:`label-ai_redact_pii_example_chunking`を参照してください。
注釈
トークンは、 AI モデルによって処理される最小のデータ単位です。英語のテキストの場合、業界のガイドラインでは、1トークンは約4文字、または0.75単語と見なされます。
検出される PII カテゴリ¶
AI_REDACTは、以下のカテゴリのPIIの検出と編集をサポートしています。カテゴリ列の値は、オプションの``categories``引数でサポートされている文字列です。
カテゴリ
メモ
NAME
フルネーム、名、ミドルネーム、および姓を認識します
PHONE_NUMBER
DATE_OF_BIRTH
GENDER
男性、女性、ノンバイナリーを認識します
AGE
ADDRESS
識別:
完全な郵便番号(US、 UK、 CA)
住所(US、 UK、 CA)
郵便番号(US、 UK、 CA)
都市(US、 UK、 CA)
州(US)または県(CA)
郡、区、または町(US)
NATIONAL_ID
社会保障番号を識別します(US)
PASSPORT
パスポート番号を識別します(US 、 UK 、 CA)
TAX_IDENTIFIER
個人の納税番号( ITNs )を識別します
PAYMENT_CARD_DATA
完全なカード情報、カード番号、有効期限日、および CVV を識別します
DRIVERS_LICENSE
サポート対象(US、 UK、 CA)
IP_ADDRESS
注釈
AI_REDACT は一部の PII カテゴリの部分的な一致をサポートしています。たとえば、[NAME] プレースホルダーを使用して編集をトリガーするには、名前だけで十分です。
検出モードで特定のPIIを保持する¶
デフォルトでは、AI_REDACTは検出されたすべてのPIIをプレースホルダー値に置き換えます。場合によっては、特定のPIIを保持しつつ、それ以外については編集したいことがあります。たとえば、コールセンターのトランスクリプトや顧客レビューにおいて、既知の従業員名以外のすべての名前を編集したいことがあります。
選択的な編集ワークフローを構築するには、``detect``モードを使用します。
``mode``引数を``detect``に設定してAI_REDACTを呼び出し、入力テキスト内のPIIを特定して見つけます。
検出されたスパンを、保持したい値の許可リストと比較します。
許可リストにないPIIのみを編集します。
``detect``モードでAI_REDACTを呼び出すと、関数は``spans``配列を含むOBJECTを返します。配列の各要素は、次のフィールドをもつOBJECTです。
フィールド |
型 |
説明 |
|---|---|---|
|
VARCHAR |
``NAME``や``ADDRESS``などのPIIカテゴリ。サポートされているカテゴリについては、:ref:`label-ai_redact_pii_categories`を参照してください。 |
|
NUMBER |
入力テキストで検出されたPIIの開始インデックス。 |
|
NUMBER |
入力テキストで検出されたPIIの終了インデックス。 |
|
VARCHAR |
入力から一致したPIIテキスト。 |
``detect``モードの使用例については、:ref:`label-ai_detect_pii_examples`を参照してください。
複数行のクエリにおける行レベルのエラーを処理する¶
重要
クエリがすべての行で失敗する場合、原因は行レベルのエラーではなく、既知の制約である可能性があります。トークンの制限、言語のサポート、その他の制限について詳しくは、:ref:`label-ai_redact_pii_limitations`を参照してください。
AI_REDACTが入力テキストを処理できない場合、エラーが発生します。クエリが複数の行を編集する場合、エラーによりクエリ全体が失敗します。処理が他の行で続行するようにするには、セッションパラメーター``AI_SQL_ERROR_HANDLING_USE_FAIL_ON_ERROR``をFALSEに設定します。エラーが発生すると、クエリが停止される代わりに、NULLが返されます。
ALTER SESSION SET AI_SQL_ERROR_HANDLING_USE_FAIL_ON_ERROR=FALSE;
このパラメーターを FALSE に設定すると、 AI_REDACT の最終引数として TRUEを渡すこともできます。これにより、戻り値は編集されたテキストとエラーメッセージの個別のフィールドを含む OBJECT になります。AI_REDACT 呼び出しが正常に処理されたかどうかに応じて、これらのフィールドの1つが NULL になります。
次の例は、複数の行を処理する際にどのようにエラー処理を使用するかを示しています。
編集されていないテキストを含むテーブルを作成します。
CREATE OR REPLACE TABLE raw_table AS SELECT 'My previous manager, Washington, used to live in Kirkland. His first name was Mike.' AS my_column UNION ALL SELECT 'My name is William and I live in San Francisco. You can reach me at (415).450.0973';
セッションパラメーターを設定します。
ALTER SESSION SET AI_SQL_ERROR_HANDLING_USE_FAIL_ON_ERROR=FALSE;
``value``と``error``の列をもつ編集テーブルを作成します。
CREATE OR REPLACE TABLE redaction_table ( value VARCHAR, error VARCHAR );
``raw_table``からPIIを編集し、行を``redaction_table``に挿入して、編集されたテキストとエラーメッセージを格納します。
INSERT INTO redaction_table SELECT result:value::STRING AS value, result:error::STRING AS error FROM (SELECT AI_REDACT(my_column, TRUE) AS result FROM raw_table);
コストの考慮事項¶
AI_REDACT は他のCortex AI 関数と同様に、処理される入力と出力トークンの数に基づいてコストが発生します。詳細については、 Snowflakeの価格ガイド をご参照ください。
編集の例¶
基本的な編集の例¶
次の例では、入力テキストから名前と住所を編集しています。
SELECT AI_REDACT(
input => 'My name is John Smith and I live at twenty third street, San Francisco.'
);
基本的な編集の出力:
My name is [NAME] and I live at [ADDRESS]
次の例では、入力テキストから名前とメールアドレスのみを編集しています。テキストには名のみが含まれていることに注意してください。これは[NAME]として認識および編集されます。入力テキストにはメールアドレスが含まれていないため、出力にはメールのプレースホルダーは表示されません。
SELECT AI_REDACT(
input => 'My name is John and I live at twenty third street, San Francisco.',
categories => ['NAME', 'EMAIL']
);
選択的な編集の出力:
My name is [NAME] and I live at twenty third street, San Francisco.
エンド・ツー・エンドの例¶
次の例では、あるテーブルの行を処理し、編集した出力を別のテーブルに挿入しています。同様の方法を使用して、編集されたデータを既存のテーブルの列に格納できます。編集後、テキストは全体的な感情情報を抽出するために:doc:`AI_SENTIMENT</sql-reference/functions/ai_sentiment>`関数に渡されます。
編集されていないテキストを含むテーブルを作成します。
CREATE OR REPLACE TABLE raw_table AS SELECT 'My previous manager, Washington, used to live in Kirkland. His first name was Mike.' AS my_column UNION ALL SELECT 'My name is William and I live in San Francisco. You can reach me at (415).450.0973';
編集されていないデータを表示します。
SELECT * FROM raw_table;
編集テーブルを作成します。
CREATE OR REPLACE TABLE redaction_table (value VARCHAR);
``raw_table``からPIIを編集し、行を``redaction_table``に挿入します。
INSERT INTO redaction_table SELECT AI_REDACT(my_column) AS value FROM raw_table;
編集された結果を表示します。
SELECT * FROM redaction_table;
編集されたテキストに対してAI_SENTIMENT関数を実行します。
SELECT value AS redacted_text, AI_SENTIMENT(value) AS summary_sentiment FROM redaction_table;
チャンキングの例¶
この例では、テキストを小さなチャンクに分割し、各チャンクを個別に編集し、編集されたチャンクを再結合して最終出力を作成することによって、長いテキストから PII を編集する方法を示します。このアプローチは AI_REDACT のトークン制限で機能します。
患者データを含むテーブルを作成します。
CREATE OR REPLACE TABLE patients ( patient_id INT PRIMARY KEY, patient_notes TEXT );
テキストをチャンクに分割し、各チャンクにAI_REDACTを適用して、編集されたチャンクを連結します。
CREATE OR REPLACE TABLE final_temp_table AS WITH chunked_data AS ( SELECT patient_id, chunk.value AS chunk_text, chunk.index AS chunk_index FROM patients, LATERAL FLATTEN( input => SNOWFLAKE.CORTEX.SPLIT_TEXT_RECURSIVE_CHARACTER( patient_notes, 'none', 1000 ) ) AS chunk WHERE patient_notes IS NOT NULL AND LENGTH(patient_notes) > 0 ), redacted_chunks AS ( SELECT patient_id, chunk_index, chunk_text, TO_VARIANT(results:value) AS redacted_chunk, TO_VARIANT(results:error) AS error_string FROM ( SELECT patient_id, chunk_index, chunk_text, AI_REDACT(chunk_text,TRUE) AS results FROM chunked_data ) ), final AS ( SELECT chunk_text AS original, IFF(error_string IS NOT NULL, chunk_text, redacted_chunk) AS redacted_text, patient_id, chunk_index FROM redacted_chunks ) SELECT * FROM final;
結果をクエリします。
SELECT patient_id, LISTAGG(redacted_text, '') WITHIN GROUP (ORDER BY chunk_index) AS full_output FROM final_temp_table GROUP BY patient_id;
検出と選択的編集の例¶
基本的な検出の例¶
次の例では、入力を編集せずに、検出された各PIIインスタンスのカテゴリ、場所、およびテキストを特定して返します。
SELECT AI_REDACT(
input => 'My old manager, Washington, used to live in Washington. His first name was Mike.',
return_error_details => FALSE,
mode => 'detect'
);
基本的な検出の出力:
{
"spans": [
{
"category": "NAME",
"end": 26,
"start": 16,
"text": "Washington"
},
{
"category": "ADDRESS",
"end": 54,
"start": 44,
"text": "Washington"
},
{
"category": "NAME",
"end": 79,
"start": 75,
"text": "Mike"
}
]
}
許可リストを使用したエンドツーエンドの例¶
次の例は、``detect``モードと許可リストを使用した選択的編集ワークフローを示しています。ステージングされたファイルから保持する名前のリストをロードし、``detect``モードでAI_REDACTを使用してPIIの場所を特定し、許可リストにないPIIのみを編集するPython UDFにその結果を渡します。
ステージから仮テーブルにリストをロードすることにより、値の許可リストを保持します。
CREATE OR REPLACE TEMP TABLE string_list (value STRING); COPY INTO string_list FROM @mystage/allowlist.txt FILE_FORMAT = ( TYPE = 'CSV' RECORD_DELIMITER = '\n' FIELD_DELIMITER = '\t' -- any char NOT in file TRIM_SPACE = TRUE SKIP_HEADER = 0 );
許可リストテーブルを表示します。
SELECT * FROM string_list;
許可リストテーブルの出力:
VALUE Mike David
許可リストに基づいてPIIを選択的に編集するPython UDFを作成します。
CREATE OR REPLACE FUNCTION redact_spans_with_allowlist( SPAN_DATA VARIANT, ALLOWLIST ARRAY, ORIGINAL_TEXT STRING ) RETURNS STRING LANGUAGE PYTHON RUNTIME_VERSION = '3.8' HANDLER = 'redact_text' AS $$ def redact_text(span_data, allowlist, original_text): spans = span_data.get('spans', []) # Sort descending to maintain index integrity sorted_spans = sorted(spans, key=lambda x: x['start'], reverse=True) result = original_text for span in sorted_spans: text_val = span.get('text') if text_val in allowlist: continue start, end = span['start'], span['end'] label = f"[{span['category']}]" # Splice the string result = result[:start] + label + result[end:] return result $$;
UDFをテストします。
SELECT redact_spans_with_allowlist( PARSE_JSON('{"spans": [{"category": "NAME", "end": 26, "start": 16, "text": "Washington"}, {"category": "NAME", "end": 79, "start": 75, "text": "Mike"}]}'), ARRAY_CONSTRUCT('Washington'), -- This will NOT be redacted 'Hello, my name is Washington and his is Mike.' );
``detect``モードでAI_REDACTを実行します。
CREATE OR REPLACE TABLE raw (message TEXT); INSERT INTO raw (message) VALUES ('My old manager, Washington, used to live in Washington. His first name was Mike.'); SELECT t.message AS message, AI_REDACT(input=>t.message, return_error_details=>FALSE, mode=>'detect') AS spans, redact_spans_with_allowlist(spans, l.str_list, message) AS result FROM raw t CROSS JOIN ( SELECT ARRAY_AGG(value) AS str_list FROM string_list ) l;
許可リストを使用したエンドツーエンドの例の出力:
MESSAGE |
SPANS |
RESULT |
|---|---|---|
私の前のマネージャー、ワシントンはワシントンに住んでいました。ファーストネームはマイクでした。 |
{
"spans": [
{"category": "NAME",
"end": 26,
"start": 16,
"text": "Washington"
},
{"category": "ADDRESS",
"end": 54,
"start": 44,
"text": "Washington"
},
{"category": "NAME",
"end": 79,
"start": 75,
"text": "Mike"
}
]
}
|
私の前のマネージャー、[NAME]は[ADDRESS]に住んでいました。ファーストネームはマイクでした。 |
法的通知¶
インプットとアウトプットのデータ分類は以下の表の通りです。
入力データの分類 |
出力データの分類 |
指定 |
|---|---|---|
Usage Data |
Customer Data |
一般的に利用可能な関数は、カバーされている AI 機能です。プレビュー関数は、 AI 機能をプレビューします。[1] |
詳細については、 Snowflake AI と ML をご参照ください。