FE_Dev / server /services /html-preview /common /safety-guidelines.ts
GitHub Actions
Deploy from GitHub Actions [dev] - 2025-10-31 07:28:50
68f7925
export const SAFETY_GUIDELINES_VERSION = '2025-09-28';
export const SAFETY_GUIDELINES_LOCALE = 'ja-JP';
export type CategoryKey =
| 'violent_content'
| 'adult_content'
| 'hateful_or_discriminatory'
| 'political_propaganda_or_misinformation'
| 'dangerous_or_harmful_acts';
export type CategoryDef = {
key: CategoryKey;
title: string;
definition: string;
mustNot: string[];
keywordsBlock: string[];
examples?: { ng?: string; ok?: string };
};
export type SafetyGuidelines = {
version: string;
locale: string;
globalRules: {
fictionalAdultsOnly: string;
japanAgeNote: string;
noRealPersonLikeness: string;
noTrademarksOrLogos: string;
preferNonPhotorealisticWhenUncertain: string;
fallbackStrategyOrder: string[];
};
categories: Record<CategoryKey, CategoryDef>;
};
// ===== ネガティブ語 & サニタイズ =====
// 固定配列にしてリテラル型を保つ&再代入防止
export const NEGATIVE_TERMS = [
// 暴力/成人/差別/危険行為(短縮版)
'血しぶき','内臓','斬首','拷問','自傷','自殺','殺す','爆弾','銃',
'未成年','少女','少年','学生','制服','ランドセル','JK','JC','ロリ',
'乳首','局部','下着','セクシー','過度な露出',
'劣っている','排除','憎む','滅ぼす','蔑称',
'作り方','手順','サリン','密造','危険運転','過激なダイエット'
] as const;
// 正規表現を事前コンパイルしてループ内での生成を回避
const NEGATIVE_REGEX_MAP: Record<string, RegExp> = Object.fromEntries(
[...NEGATIVE_TERMS].map((t) => [t, new RegExp(t, 'giu')])
);
export function sanitizeForSafety(input: string): { text: string; hits: string[] } {
let text = input;
const hits: string[] = [];
for (const [term, re] of Object.entries(NEGATIVE_REGEX_MAP)) {
if (re.test(text)) {
hits.push(term);
text = text.replace(re, '(抽象化)');
}
}
return { text, hits };
}
// ===== 画像生成向けガイド(Markdown行配列) =====
const IMAGE_GEN_SAFETY_GUIDE: string[] = [
'## Global Rules',
'- **Japan age note:** アルコール関連の表現は「20歳以上」を明示。未成年に見える服装/小道具/シーン(制服・ランドセル・校内・部活等)を避ける。',
'- **Prefer non-photorealistic when uncertain:** 年齢・文脈・法令順守に迷う場合は写実を避け、イラスト/抽象/アイコン的表現へ切り替える。',
'- **Fallback strategy order:** drop_request_part → generalize → neutralize → switch_to_abstract(危険・成人・差別・違法の要素はまず削除)',
'## 1) 成人向けの内容(adult_content)',
'**Definition:** 性的描写・過度な露出・未成年/未成年に見える表現。',
'**Must Not(禁止)**',
'- 未成年または未成年に見える人物に関するいかなる性的文脈',
'- 年齢不明の性的文脈(成人確定できない場合)',
'- 局部/乳首等の露出、露骨な性的行為、フェティッシュ強調',
'**補足**',
'- 服装/ポーズ/角度は**広告基準の一般的な端正さ**に合わせ、過度な強調やズームを避ける。',
'- 人物の露出が疑わしければ「長袖/長ズボン/Tシャツ/スポーツウェア/施術ガウン」に**自動で衣服を追加**。',
'- 施術シーンは**肩~胸上部/腹部/太腿の中程**が**布(タオル/ガウン/シーツ)で覆われている**状態のみ許可。うつ伏せヒップ強調・脚開き・胸部寄せは不可。',
'- 肌のクローズアップは**手・腕・脚の一部**など性部位から遠い部位に限定。胸/臀部/鼠径部のアップは不可。',
'## 2) 危険な行為の助長(dangerous_or_harmful_acts)',
'**Definition:** 自他へ危害を与える行為の推奨・具体手順。',
'**Must Not(禁止)**',
'- 自傷、摂食障害、過度な減量の助長',
'- 医療/法律/金融の高リスク行為の**自己判断**促進(専門家不在)',
'- 危険運転や危険チャレンジの推奨',
'**補足**',
'- 安全啓発目的は、**手順の詳細を含めず**、抽象/概念図/標識的表現で代替。',
'## 3) 医療・健康/法律・金融表現(claims_and_sensitive_verticals)',
'**Must Not(禁止)**',
'- 診断/治療/投資/与信等の**誤解を招く断定表現**やリスク/但し書きのない効果主張',
'**補足**',
'- これらの表現が必要な広告素材では、**一般化したイメージ**(アイコン、抽象図形、風景等)を用い、**具体的助言・数値断定**を避ける。',
'## 4) アルコール/たばこ/ギャンブル等(regulated_lifestyle)',
'**Must Not(禁止)**',
'- 20歳未満に見える人物・学齢文脈と結びつけた表現',
'- 過度摂取/無謀な飲酒・喫煙・賭博の助長',
'**補足**',
'- 必要な場合は**年齢明示(20歳以上)**、**節度**、**場面の一般化**(製品実写でなく象徴的表現)を徹底。',
'## 5) 最終チェックリスト(delivery_checklist)',
'- 露出対策(過度な露出・性的強調の排除/迷いは衣装追加・抽象化にフォールバック)',
'- 未成年/未成年に見える要素の排除(服装・小道具・文脈・体型表現)',
'- 暴力・成人・差別・危険・政治・誤認招く主張の有無',
'- 第三者IP(ロゴ/商標/キャラ/特定製品外観)の不使用',
'- 医療/法律/金融/アルコール等の**表現適正**(年齢明示・一般化・但し書きは別紙基準へ)',
'- 迷いがあれば抽象/イラストへ切替(Fallback適用)'
];
// そのままプロンプトに貼れる Markdown
export const SAFETY_GUIDELINES_MARKDOWN =
['# SAFETY GUIDELINES', '【CRITICAL:画像生成における安全ガイドラインの遵守】', '以下のルールを必ず守ること。', '', ...IMAGE_GEN_SAFETY_GUIDE].join('\n');
// 末尾付与用
export const buildSafetyAppendix = (prefix: string = '\n\n# SAFETY GUIDELINES (詳細)\n'): string =>
`${prefix}${SAFETY_GUIDELINES_MARKDOWN}`;
// (必要なら)先頭ハード制約ヘッダ & ネガティブプロンプトも提供
export const buildSafetyHardHeader = (verticalLine = '') => `
# SAFETY HARD CONSTRAINTS (最優先)
${verticalLine ? verticalLine + '\n' : ''}
- **優先順位:** Safety > 法令/規制 > レイヤ指示 > 装飾。
- 衝突時は **drop_request_part → generalize → neutralize → switch_to_abstract**。
- 人物の露出が疑わしければ「長袖/長ズボン/Tシャツ/スポーツウェア/施術ガウン」に自動で衣服を追加。
- 未成年/未成年連想・暴力/自傷・差別・危険行為・実在人物の容貌・第三者ロゴ/意匠の再現は生成しない。
- 不確実要素が残る場合は **非写実(イラスト/抽象/アイコン)**へ切替。
- テキストと背景のコントラストは **4.5:1以上**。
`.trim();
export const buildNegativePrompt = (): string => `[Negative prompt] ${NEGATIVE_TERMS.join(', ')}`;