CLAUDE LABEN
MEMORY — Claude Codeの長時間セッションのメモリリークが一掃されました。MCP stdioサーバのstderrが最大64MB蓄積する問題やLSPドキュメントの開きっぱなしが修正されていますTABLES — 非常に大きなmarkdownテーブルが描画を止める不具合を修正。200行を超えるテーブルは先頭200行と「… N more rows」表示になりますSPEED — deny/askルールを多く抱えたセッションで毎ターン数秒遅くなる問題を修正。ルールマッチャがコンパイルして再利用されますTOOLS — MCPツールが多いprint/SDKセッションでは、ツールプールの組み立てをキャッシュし最大7倍速いラウンドになりましたARTIFACTS — Claude CodeのArtifactsは、セッションの作業をその場で更新される共有Webページに変えます。PR解説やダッシュボードに使えますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。speed: "fast" はエラーになるため、Opus 4.8のfastモードへ移行が必要ですMEMORY — Claude Codeの長時間セッションのメモリリークが一掃されました。MCP stdioサーバのstderrが最大64MB蓄積する問題やLSPドキュメントの開きっぱなしが修正されていますTABLES — 非常に大きなmarkdownテーブルが描画を止める不具合を修正。200行を超えるテーブルは先頭200行と「… N more rows」表示になりますSPEED — deny/askルールを多く抱えたセッションで毎ターン数秒遅くなる問題を修正。ルールマッチャがコンパイルして再利用されますTOOLS — MCPツールが多いprint/SDKセッションでは、ツールプールの組み立てをキャッシュし最大7倍速いラウンドになりましたARTIFACTS — Claude CodeのArtifactsは、セッションの作業をその場で更新される共有Webページに変えます。PR解説やダッシュボードに使えますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。speed: "fast" はエラーになるため、Opus 4.8のfastモードへ移行が必要です
記事一覧/API & SDK
API & SDK/2026-06-16上級

Claude API の PII マスキングは台帳運用で決まる — 復元・暗号化・漏洩率の本番設計メモ

Claude API へ送る前の PII マスキングで本当に難しいのは検出ではなく、復元用トークン台帳の運用です。暗号化保存・多インスタンス共有・漏洩率の継続測定までを動くコード付きで整理します。

claude-api81piisecurity9production87privacy2observability14

プレミアム記事

PII マスキングを Claude API の手前に入れる、という方針自体に異論を持つ人は少ないと思います。つまずくのはその先です。正規表現と NER で検出器を組んだあと、「マスクしたものをどう元に戻すか」「その対応表をどこに置くか」「本当に漏れていないとどう証明するか」という運用の問いが残り、ここで設計が一気に難しくなります。

検出ロジックは数日あれば形になります。けれども本番で痛い目を見るのは、たいてい検出ではなく 復元用の台帳(ledger) の扱いと、漏洩率を測り続ける仕組み の欠如です。個人開発で業務向けアシスタントを Claude API に組み込み、私自身が運用してきた中で、レビューや障害の大半はこの2点に集中していました。この記事は検出器の作り方を一通り示しつつ、重心を「台帳運用」と「継続測定」に置いて、本番投入で効く判断を実装コードとともにまとめます。

マスクは「往復」で考える — 片道設計が破綻する理由

PII マスキングを「送信前に消す処理」とだけ捉えると、要約や業務アシスタントのユースケースで必ず破綻します。Claude が <PERSON_001>さんへ連絡しました と返してきても、それを利用者に見せる前に 田中太郎 へ戻さなければ意味が通りません。つまりマスキングは送信時の片道処理ではなく、マスク(往路)と復元(復路)が対になった往復処理 です。

往復で考えると、設計の主役は検出器ではなく、トークンと原文の対応を持つ台帳になります。台帳は次の3つを同時に満たす必要があります。

第一に、会話やリクエストをまたいで一貫していること。同じ 田中太郎 には常に同じ <PERSON_001> を割り当てないと、Claude が同一人物だと認識できず出力品質が落ちます。第二に、暗号化されていること。台帳は「どのトークンが誰なのか」を記した地図そのものなので、生の PII より漏れたときの被害が大きい。第三に、多インスタンスで共有できること。本番は単一プロセスでは動きません。

検出は不可逆マスク(<PERSON> で潰す)なら台帳すら不要です。台帳が要るのは復元する場合だけ。だからこそ「可逆をデフォルトにするか」という判断が、運用コストを左右する最初の分岐点になります。私は復元が必要かどうか曖昧なうちは可逆を選びます。後から不可逆へ落とすのは一行ですが、不可逆から可逆へ戻すのは原文が失われていて不可能だからです。

検出は2層で十分 — 正規表現の Luhn と Haiku の NER

台帳の話に入る前に、検出器を最小構成で固めておきます。私の運用では正規表現(Layer 1: 識別子)と軽量モデル NER(Layer 2: 準識別子)の2層で実用十分でした。文脈推論が必要な Layer 3 は機械処理を諦め、UI 側の入力ガイダンスに寄せています。

正規表現で重要なのは、クレジットカードらしき数字列を Luhn チェックで絞ることです。「13桁以上の数字」だけで拾うと ISBN・JAN・配送伝票番号まで巻き込み、要約精度が目に見えて落ちます。

// pii-detect.ts — Layer 1(識別子)の機械検出。トークンは <CATEGORY_NNN> 形式で統一する
// 設計意図: 誤検出はモデル精度を、見逃しは漏洩を悪化させる。クレカは Luhn で誤検出を抑える
export type Span = { start: number; end: number; category: string; text: string };
 
const REGEXES: Record<string, RegExp> = {
  EMAIL: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
  PHONE_JP: /(?:\+?81[-\s]?|0)\d{1,4}[-\s]?\d{1,4}[-\s]?\d{3,4}/g,
  CREDIT_CARD: /\b(?:\d[ -]*?){13,19}\b/g,
};
 
export function detectLayer1(input: string): Span[] {
  const spans: Span[] = [];
  for (const [category, regex] of Object.entries(REGEXES)) {
    for (const m of input.matchAll(regex)) {
      const text = m[0];
      if (category === "CREDIT_CARD" && !isLuhnValid(text.replace(/[ -]/g, ""))) continue;
      spans.push({ start: m.index!, end: m.index! + text.length, category, text });
    }
  }
  return spans;
}
 
function isLuhnValid(num: string): boolean {
  if (!/^\d{13,19}$/.test(num)) return false;
  let sum = 0, alt = false;
  for (let i = num.length - 1; i >= 0; i--) {
    let n = parseInt(num[i], 10);
    if (alt) { n *= 2; if (n > 9) n -= 9; }
    sum += n; alt = !alt;
  }
  return sum % 10 === 0;
}

名前と住所は正規表現では捕まりません。ここで Claude Haiku を NER として使います。NER への入力もまた PII を含むので、汎用のクラウド NER に出すよりは、自分が管理する Claude 呼び出しに閉じる方が監査上は説明しやすいです。ポイントは、抽出結果を信用しすぎず、必ず固定バージョンのモデルにピン留めしておくことです(後述の落とし穴4)。

// pii-ner.ts — Layer 2(準識別子: 名前・住所)の抽出。モデルは日付付き ID にピン留めする
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });
 
const NER_MODEL = "claude-haiku-4-5-20251001"; // 挙動を固定するため日付付きで固定
const NER_SYSTEM = `あなたは日本語の固有表現抽出器です。入力から PERSON と ADDRESS_JP のスパンのみを抽出し、
必ず次のJSONで返してください。推測や創作は禁止。分類できないものは出力しないでください。
{"entities":[{"text":"string","category":"PERSON"|"ADDRESS_JP"}]}`;
 
export async function detectLayer2(input: string): Promise<{ text: string; category: string }[]> {
  const res = await client.messages.create({
    model: NER_MODEL, max_tokens: 1024, system: NER_SYSTEM,
    messages: [{ role: "user", content: input }],
  });
  const text = res.content.filter((b) => b.type === "text").map((b: any) => b.text).join("");
  const match = text.match(/\{[\s\S]*\}/);
  if (!match) return []; // 抽出できなければ空。後段の再スキャンで漏れを検知する
  try {
    const parsed = JSON.parse(match[0]) as { entities?: { text: string; category: string }[] };
    return (parsed.entities ?? []).filter((e) => e.text && ["PERSON", "ADDRESS_JP"].includes(e.category));
  } catch {
    return []; // パース失敗時もスキップ。漏れは測定で捕まえる前提に倒す
  }
}

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
復元用トークン台帳を AES-GCM で暗号化し、多インスタンスで共有する実装
ゴールデンデータセットとシャドウ再スキャンで漏洩率を毎日数値化する仕組み
ストリーミング分断・トークン英訳・NER モデル更新という3つの実運用バグの潰し方
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API & SDK2026-06-18
Claude API のレスポンスキャッシュが「古い答え」と「似て非なる誤答」を返すとき — 鮮度管理と誤ヒット抑制の実装メモ
Claude API のレスポンスキャッシュは速度とコストを劇的に改善しますが、運用で問題になるのは平均ヒット率ではなく、古い答えと意味的な誤ヒットの二つです。キー設計・鮮度管理・誤ヒット抑制・観測の実装をまとめます。
API & SDK2026-05-10
Claude API の metadata.user_id は何のために送るのか — abuse 検知とプライバシーの折り合いを設計する
Claude API の metadata.user_id は abuse 検知の精度を上げるためのフィールドですが、生のメールアドレスをそのまま渡すとプライバシー上の問題が出ます。HMAC で安定した擬似 ID を作る具体的な実装と、渡すべき/渡さない場面の判断基準をまとめました。
API & SDK2026-05-01
Claude API のテレメトリを ClickHouse に流して分析する — 本番環境のコスト・遅延・エラーを可視化する設計ガイド
Claude API のリクエスト単位でコスト・遅延・トークン使用量を ClickHouse に蓄積し、Materialized View でリアルタイムダッシュボードを構築する本番運用設計を解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →