美容サロンやウェルネス系の初回フォームでは、予約メニューよりも「備考」欄が危険になりがちです。肌が弱い、服薬あり、妊娠中 のような情報がCSVの自由記述に残ったままAIへ渡ると、プロンプトで「個人情報は扱わないで」と書いても入口で負けています。
この記事では、実データを使わず、ローカルの架空fixtureだけで「AIへ渡す前のCSVに危ない列名や値があれば終了コード1にする」最小パターンを書きます。Claude Codeのpermissionsとsandboxは公式ドキュメントで確認し、ここでは実装の形に絞ります。
前提のフォルダ分離
原本とAI用コピーを同じ場所に置かない前提にします。
-
intake-raw/: 原本フォーム、氏名、電話、メール、自由記述、写真、決済文脈 -
intake-ai-work/: 架空ID化または匿名化したCSV、分類表、下書き材料 -
intake-approved/: 人が確認したチェックリストと送信用文面
Claude Codeの公式ドキュメントでは、permissionsはRead、Edit、Bashなどのtool権限を制御し、sandboxはBashコマンドや子プロセスのファイル・ネットワーク境界を作るものとして説明されています。つまり、設定だけに頼らず、入力ファイル自体を先に減らします。
最小のpreflightコード
以下はコピペで動くNode.js例です。実CSVを読まず、通してよい架空データと止めたい架空データを配列で持たせています。
const files = [
{
path: "intake-ai-work/intake-redacted.csv",
text: "intake_id,menu,consent,contraindication_category,staff_review\nB-001,trial_facial,true,sensitive_skin,true"
},
{
path: "intake-ai-work/bad.csv",
text: "name,email,medication_note\nAiko,aiko@example.com,blood pressure medicine"
}
];
const blockedFields = [
"name",
"email",
"phone",
"address",
"birthdate",
"medication",
"diagnosis",
"pregnancy_week",
"free_note"
];
const valuePatterns = [
/[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}/,
/\b\d{2,4}-\d{2,4}-\d{3,4}\b/,
/\b(?:medicine|diagnosis|pregnant|allergy)\b/i
];
const findings = [];
for (const file of files) {
const lowerText = file.text.toLowerCase();
for (const field of blockedFields) {
if (lowerText.includes(field)) {
findings.push({ path: file.path, type: "blocked field", field });
}
}
for (const pattern of valuePatterns) {
if (pattern.test(file.text)) {
findings.push({ path: file.path, type: "blocked value", pattern: String(pattern) });
}
}
}
console.table(findings);
if (findings.length > 0) {
process.exitCode = 1;
}
bad.csv 側に email と medication_note が入っているため、終了コードは1になります。ここで大事なのは、検出値を長くログに出さないことです。メールアドレスや薬名をログへ再掲すると、検査コードが新しい漏えい経路になります。
終了コードの扱い
この検査では、終了コード1を「Claude Codeへ渡さない」という合図にします。0は「完全に安全」ではなく、「この小さな検査では止まらなかった」という意味です。0でも、スタッフが intake-ai-work/ のCSVを開き、自由記述がカテゴリ化されているか、staff_review が必要な行に立っているかを見ます。
CIに入れる場合も、失敗ログには値そのものを出しません。blocked field: email のように項目名だけ出せば、直す人には十分です。検査の目的は、危険な値を詳しく表示することではなく、AI入力前に作業を止めることです。
実ファイル版へ広げる時
実ファイルを読む版に変える時も、対象は intake-ai-work/ だけです。intake-raw/ は読まない設計にします。拡張子は最初から .csv、.json、.md、.txt などに絞り、PDFや画像が来たら「未対応」として止めます。黙って通すより、対応外を人の確認へ戻すほうが事故を減らせます。
完全な業務フロー、権限境界、スタッフ確認、ROIの測り方は、美容・ウェルネス初回フォームのpreflight全体設計にまとめています。
よくある失敗
一つ目は、列名だけを見ることです。note の中に薬、妊娠、アレルギー、住所が入ると列名チェックだけでは通ります。上の例では簡単な正規表現も入れていますが、手書き画像や複数列を組み合わせた本人推定までは見ません。
二つ目は、検査を本物の予約CSVで試すことです。ターミナル履歴、スクリーンショット、CIログに値が残ります。許可サンプルも拒否サンプルも、架空IDと架空メールだけで作ります。
三つ目は、正規表現を増やしすぎることです。検出を細かくするほど誤検知も増えます。最初は「危ない列名」「メールや電話らしい値」「健康や薬らしい英単語」の3つに絞り、止まった件数と人の確認結果を見て足します。
運用に入れる境界
このコードだけで安全とは言いません。Claude Code側では intake-raw/ をdenyし、sandbox側でも原本フォルダを読めないようにします。さらに、AIに渡すCSVは許可列方式にして、自由記述は短いカテゴリやフラグへ変えます。
公式情報として、Claude Code permissions、settings/sandbox、個人情報保護委員会の個人情報ページを確認しました。個別の法務・医療・施術判断は、自社の責任者や専門家が行う前提です。
まとめ
AI入力前チェックは、完全な匿名化ツールではありません。それでも、明らかに渡してはいけない列や値を止めるだけで、初回フォームの事故は減らしやすくなります。原本、AI用コピー、人の承認、送信先を分け、止まった件数も記録するのが最初の一手です。