AIチャットのキャラ崩れを防ぐシステムプロンプト設計|口調固定・時刻注入・会話履歴圧縮のテクニック

AI プロンプト Web開発 LLM UI
結論

キャラ崩れを防ぐには、システムプロンプトのセクション構造化、サーバー側での動的時刻(JST)注入、そしてコンテキスト溢れを防ぐ過去履歴の動的圧縮が効果的です。

AI チャットに特定のキャラクター(ペルソナ)を設定して会話させると、最初の数ターンは自然に振る舞っていても、やり取りが長くなるにつれて丁寧語に戻ってしまったり、AI 特有の定型句を繰り返し始めたりする現象が発生します。

この「キャラ崩れ」を防止し、自然な対話を維持するための設計テクニックを解説します。

キャラ崩れが発生する要因と対策比較

会話の長期化に伴う問題と、それを解消するためのアプローチの比較です。

課題主な原因対策アプローチ効果
口調の標準化過去ログの増大によるペルソナ指示の薄れ毎リクエストでシステムプロンプトを先頭注入口調の一貫性を常に維持
時間感覚のズレ「いま何時?」「お疲れ様」への不自然な返答サーバー側で JST 現在日時を動的注入時間帯に応じた適切な労いが可能
無限ループ・蒸し返し過去の失敗や前テーマの過度な追及会話フェーズごとの制限ルールを定義自然な話題転換とレスポンスの安定化

LLM はコンテキストウィンドウ内の直近トークンを強く参照する傾向があります。そのため、ユーザーの入力文や直前の AI レスポンスが標準的なテキストであるほど、そちらに引っ張られてペルソナ設定が薄れていきます。

キャラ崩れを防ぐ 3 つの実装手順

サーバー側(Edge Functions)でプロンプトを動的に組み立てる具体的な手順です。

  1. プロンプトの構造化(Markdown セクション分け) ペルソナ設定を [基本設定], [口調・トーン], [ねぎらい・時間の空気感], [絶対禁止事項] のように明確な見出しで区切ります。

  2. JST 日時の動的注入 new Date() から生成した日本標準時(JST)をプロンプトに組み込みます。「いま深夜 2 時だから夜更かしを心配する」といった文脈を自然に考慮させることができます。

  3. コンテキスト履歴のウィンドウ制御 過去の会話履歴(messages 配列)を無制限に送るのではなく、直近 N 件(例: 8〜10 件)に制限するか、古くなった会話を短く要約して送るロジックを挟みます。

最小コード例(プロンプト生成関数)

function buildSystemPrompt(language: string = "ja"): string {
  // 1. サーバー側で現在時刻(JST)を取得
  const nowJST = new Date().toLocaleString("ja-JP", { timeZone: "Asia/Tokyo" });

  // 2. セクション分けしたシステムプロンプトの構築
  return `
[基本設定]
- あなたは明るく少し年上の親しみやすい案内役キャラクターです。
- 現在の日本標準時(JST): ${nowJST}

[口調・トーン]
- 丁寧すぎない親しみのある口調で話してください。
- 機械的な「AI ですので」「無理しないでください」という定型句は使用禁止です。

[時間の空気感]
- 現在時刻が深夜(22時〜4時)の場合は夜更かしを労い、朝・昼の場合は時間帯に合わせた自然な一言を添えてください。
  `.trim();
}

// 3. API 呼び出し時のペイロード作成
export function prepareChatPayload(userMessages: any[]) {
  const systemPrompt = buildSystemPrompt();

  // 直近 10 件のみ保持してコンテキスト圧迫を回避
  const recentHistory = userMessages.slice(-10);

  return [
    { role: "system", content: systemPrompt },
    ...recentHistory
  ];
}

現場で起こる障害と対策(Failure Boundary)

ペルソナ設定の実装時に直面しやすい問題と対策です。

1. 時刻の数字そのものを口に出してしまう

  • 発生現象: 「いま 23:45 ですね!遅くまでお疲れ様です」のように、プロンプトで注入された時刻の文字列をそのまま出力してしまう。
  • 解決策: プロンプト内に「注入された時刻の数字データ自体は直接発話せず、時間帯の雰囲気(深夜、早朝等)のみを組み込んで回答してください」と明記します。

2. コンテキスト超過によるフォールバックモデルのエラー

  • 発生現象: バックアップモデル(軽量 LLM)へ切り替わった際、メインモデル用の長いシステムプロンプトと履歴が大きすぎてトークン上限エラー(400 Bad Request)が発生する。
  • 解決策: バックアップモデル呼び出し時は、プロンプトを短縮版の軽量システムプロンプトに切り替え、送信する過去履歴も直近 4〜6 件程度に制限する制御を実装します。

当サイトの /chat/(加賀チャット)でも、このペルソナ構造化と時間帯注入の仕組みを取り入れています。詳細は 開発したAIチャット「加賀」について|無料枠で動かす技術構成とキャラクター設計 をご参照ください。