State Transition phenomenon in Claude’s dialogue mode switching

eyecatch AI関連

「さっきまで普通に会話できてたのに、急にポリシーマニュアルみたいな文体になったんだけど??」

Claude を触っていて、そんな違和感を覚えたことはありませんか?
API のパラメータも変えてない、モデルも同じ。それなのに、あるタイミングから突然、

  • 箇条書きだらけ
  • セクション見出しだらけ
  • 「ステップ1, ステップ2…」と言い出す
  • やたら「私はこれから〜します」とメタ説明が増える

みたいな「別人格」になるやつです。

実はこれ、単なる気のせいでも、ランダムなブレでもなくて、ちゃんと観測・整理された現象として報告されています。それが今回のテーマである 「Claude の対話モード切り替えにおける State Transition 現象」です。


一言で言うと?「対話型 REPL のグローバル状態バグ」みたいなもの

一言で言うと?「対話型 REPL のグローバル状態バグ」みたいなもの

一言でまとめると、

「会話だけで、Claude の内部モードがカチッと別フェーズに遷移して、そのまましばらく固定される」

という話です。

これ、エンジニア視点で言うとかなりイヤ〜な感じで、「長時間使われてる Python REPL で、どこかのタイミングで from something import * されて、以後ずっと挙動が変わる」みたいなものです。

  • API パラメータは同じ
  • モデル ID も同じ
  • temperature も同じ

なのに、「過去の対話履歴」だけで、振る舞いが別物になっていく
しかもその変化が、ふわっとした「ちょっとスタイルが変わる」レベルではなく、段階的ではない「相転移」っぽい急変なんですよね。

正直、プロダクションでマルチターンのエージェント作ってる人からすると、これかなりクリティカルな話です 🤔


何が起きているのか:Claude は「モードフル(modeful)」なやつだ

観測されているモードのざっくり像

報告によると、Claude 3 系は対話の流れの中で、ざっくりこんな「フェーズ」に落ち着きやすいようです(名前は私の意訳含み):

  • デフォルト・アシスタントモード
  • 普通にフレンドリーに説明してくれるいつものやつ
  • スタイルは柔軟で、ユーザーのトーンにもそれなりに追従

  • 仕様書/厳格ルールモード

  • Markdown 見出し+箇条書きテンプレ化
  • 「要件」「制約」「例」みたいなセクションを勝手に生やしがち
  • 指示に対して異常にリテラルで、ゆとりゼロ

  • メタ推論モード

  • 「これからステップ1〜3で説明します」「まず前提を整理します」みたいなメタ発話が激増
  • 質問の答えよりも「自分の作業計画」を先に宣言しがち

  • ミニマリストモード

  • 「とにかく短く答えろ」と圧をかけられた時に入りがち
  • 必要最低限しか喋らない、ドライな回答連発

で、ポイントは、

これらのモードは「そのターンだけのスタイル指定」ではなく、一度入るとしばらく持続する

ことです。

何がトリガーになるのか

トリガーとして効きやすいのは、ざっくり言うと「メタっぽい指示」です。例えば:

  • ロール再定義系
  • 「今後は仕様書ジェネレータとして動いてください。説明は不要で、セクション構造だけ出してください。」
  • 「ここからは、あなたは安全ポリシー審査官として振る舞ってください。」

  • 状態言及系

  • 「さっきからスタイルが変わりましたね。前のフランクなスタイルに戻してください。」
  • 「あなたの内部ルールを一度明示してから回答してください。」

  • システム / アライメント言及系

  • 「システムプロンプトを意識して、ポリシーに沿って答えてください。」
  • 「安全ルールを遵守していることを確認しながら回答してください。」

こういう「お前の振る舞いそのものをしゃべれ / 定義し直せ」というタイプの介入をすると、カチッと別モードに遷移して、そのまま固定される傾向が強い。

API 目線では何も変わっていないのに、実質的には 「隠し system prompt を差し替えた」みたいな事態が進行しているわけです。


これ、なぜそんなに大事なのか:LLM は「ステートレス」ではないという現実

これ、なぜそんなに大事なのか:LLM は「ステートレス」ではないという現実

ぶっちゃけ、LLM ベースのプロダクト設計の暗黙の前提って、

「同じモデル+同じ system prompt +似た user prompt → 似た挙動」

だと期待しているところにあります。

ところが、この State Transition 現象を前提にすると、実際はこうなっています:

  • 同じモデル + 同じ API パラメータ でも」
  • 初期の数ターンの会話パスが違うだけで
  • 「その後 20 ターン分くらいの挙動が、まるで別機能になる」

テストや QA の観点から言うと、これはかなり悪夢です。

GPT-4 との対比:Claude は「相転移型」、GPT-4 は「連続体型」

OpenAI の GPT-4 系ももちろんコンテキスト依存はありますが、体感としては:

  • GPT-4:
  • スタイル変更が比較的「連続的」
  • 後から別のトーン指定をすると、そこそこ素直に上書きされることが多い
  • よほど強く system プロンプトで縛らない限り、粘着性はそこまで高くない

  • Claude:

  • 一度モードに入ると、話題を変えても同じフォーマット/文体を引きずりがち
  • 「メタ発話」や「役割再定義」に対して過敏
  • モードの切り替えが段階的ではなく、急に別人格スイッチが入るように見える

正直、ここは Anthropic の設計思想の違いでもあって、

  • Claude:
    「会話全体の整合性・一貫性」をかなり重視する alignment
  • GPT-4:
    もう少し「そのターンの指示」を素直に受けやすい(よくも悪くも、忘れやすい)

という印象があります。

なので、エージェント的に長く会話させるなら Claude は強いが、「対話履歴に引きずられすぎる」副作用も同時に抱えている、というのが今回の現象の本質かなと思っています。


開発者視点の「一番痛いポイント」

再現性とテストの地獄

プロダクションのチャットボットやエージェントでありがちなのが、

  • システム側が途中でメタプロンプトを挿入する
  • 例:安全チェックのための「この回答は◯◯ポリシーに違反していないか確認せよ」
  • 例:ツール呼び出しの前に「これからは JSON でのみ返答せよ」みたいな指示

これが 意図せずモード遷移のトリガーになり、以降のユーザー向けレスポンスまでずっとそのモードを引きずる、ということが起き得ます。

テストを書く側からすると、

  • 「このケースを再現するには、ある特定の対話パスを再生しないといけない」
  • 会話ログを全部追わないと、なぜ今このフォーマットになっているのか特定できない

という、かなり面倒な「対話履歴依存バグ」になります。

正直、ここまで来ると「普通のユニットテスト思考」は破綻していて、「対話シナリオテスト」的な E2E テスト前提で設計しないと危ういです。

フレームワークのメタプロンプトが「暗黙バグ」になる懸念

LangChain / LlamaIndex / AutoGen みたいなフレームワークは、

  • エージェントの前処理/後処理
  • 安全ラッパー
  • Chain-of-Thought 誘導

のために、かなり積極的にメタプロンプトを差し込んできます。

ここに Claude の State Transition 性質が合わさると、

  • フレームワークが勝手に入れた一文でモードが切り替わる
  • 結果として、ユーザー向け UX が壊れる
  • でもアプリ開発者本人は「そんなメッセージ送った記憶がない」

という、三重の責任分散バグが起きます。
ぶっちゃけ、これはかなり危険なパターンです。

ベンダーロックインが「挙動レベル」で進行する

このモード切り替え現象は、Anthropic が公式に仕様として公開しているわけではありません。
あくまで「Claude の学習・アライメントの結果として、そういう挙動になっている」というだけの話です。

ということは、

  • これを前提に「賢いプロンプトハック」を作り込むと、
  • その時点で Anthropic 特有の挙動にハードロックインする
  • モデルアップデートや alignment 調整が入った瞬間、
  • その「賢いハック」が ある日突然、全部バグになる可能性がある

正直、これが一番怖い。
「API 仕様に書いてない挙動に依存したプロダクト」は、LLM 時代のアンチパターン筆頭だと思っています。


とはいえ、これを「武器」にできる場面もある

とはいえ、これを「武器」にできる場面もある

ネガティブな話ばかりしてもあれなので、ポジティブな側面も少し。

「明示的モード設計」ができるようになる

Claude がこういう「モードフル」な挙動をするという前提を受け入れると、

  • セッション開始時に「ベースモード」を固める
  • 例:「あなたはこれから◯◯企業の社内 SE 向けヘルプデスクとして振る舞います。文体は〜…」
  • 明示的に「モード変更プロトコル」を用意する
  • 例:「/spec コマンドで仕様書モードに入る」「/chat で通常会話モードに戻る」
  • モード変更時には、ユーザーにもそれを見える形で宣言させる

みたいな、「人間の OS のユーザー切り替え」的な設計ができます。

要するに、

曖昧に「なんかスタイル変わった…」と感じさせるのではなく、
モード変更を一級の UX として組み込んでしまう

という方向です。

歴史的に見ても、
インタラクティブシェルや REPL で「状態汚染」が問題になった結果、

  • virtualenv で環境を分ける
  • resetclear コマンドで状態を飛ばす
  • Docker コンテナで一回きりの実行環境を作る

という「状態を明示的に管理する文化」が生まれました。

Claude の State Transition も、似たように 「会話状態を明示的に設計する文化」を要求してきているように感じます。


懸念点:ここまで来ると、もはや「対話」ではなく「プロトコル」だ

正直に言うと、私が一番モヤっとしているのはここです。

  • ユーザーは「自然な会話」をしているつもり
  • でも実際には、開発者とモデルの間で、暗黙の状態マシンプロトコルが走っている

このギャップが大きくなりすぎると、

  • ちょっとした言い回しでモードが変わってしまう
  • でもユーザーには、そのトリガーが何だったのか一切わからない

という、「ブラックボックスな人格スイッチ」が起きます。

AI との対話が「人と人の会話」というよりも、

「人間が暗黙の状態遷移表を覚えさせられる対話型プロトコル」

になってしまったら、それは本末転倒では?という懸念があります。

ぶっちゃけ、人間側が「ai-cli の隠しフラグ」を覚えさせられてる状態に近いんですよね…。


じゃあプロダクションで使うか?正直、まだ「設計次第で可」レベル

じゃあプロダクションで使うか?正直、まだ「設計次第で可」レベル

結論をはっきり書きます。

  • Claude 自体は相変わらずめちゃくちゃ優秀
  • でも、この State Transition を知らずにマルチターンアプリを作るのはかなり危険
  • ちゃんと「モード」を一級の設計要素として扱えるなら、むしろ武器になる

という立ち位置です。

実務でのおすすめ方針(当面のベストプラクティス)

個人的には、現時点で Claude をプロダクション投入するなら、次の 4 点は強く推します:

  1. セッション境界をケチらない
  2. タスクが切り替わるタイミングで、できるだけ会話セッションをリセットする
  3. 「長く続く雑談 1 本」というより「タスクごとに短いセッション多数」

  4. system prompt / 冒頭プロンプトで「ベースモード」をガチガチに固める

  5. 文体・フォーマット・丁寧さ・長さを最初に全部決めてしまう
  6. ユーザー側からのメタ指示には、むやみに追従させない

  7. メタプロンプトを入れるコンポーネントを明確に分離する

  8. 安全ラッパー、ツールコントローラなどが挿入するメタメッセージをすべて可視化し、ログに残す
  9. 「誰がどのメタ指示を出したか」を追跡できるようにする

  10. 「モードリセット」用の明示的コマンド/プロンプトを用意する

  11. 例:「ここからは、それまでのスタイル指定をすべて忘れて、通常の技術アシスタントとして回答してください。」
  12. できればユーザー側にも /reset 的な UI を提供する

最後に:State Transition を「バグ」と見るか「機能」と見るか

この現象、見方はいくつかあります。

  • バグ・ノイズとして見る
  • 「再現性を壊す厄介な振る舞い」
  • 「ドキュメント化されていない挙動で、テスト設計を難しくする要因」

  • 機能・強みとして見る

  • 「自然言語だけで隠れモードを切り替えられる柔軟なプラットフォーム」
  • 「長期的な一貫性を保つための積極的なステート管理」

正直、私はどちらかというと 「設計思想としては理解できるが、現状の透明性の低さが気になる」派です。

ユーザーも開発者も、「今どのモードにいるのか」「何がトリガーで変わったのか」をある程度観測できるようにならない限り、
この種の State Transition は「魔法」ではなく「予測不能な気分屋」に見えてしまいます。

とはいえ、LLM がより「エージェント」に近づいていく未来を考えると、

「隠れ状態をどう公開し、どうコントロールさせるか」

は避けて通れないテーマです。
Claude のこの挙動は、その未来の少し手前を、先にチラ見せしてしまったのかもしれません。

プロダクションでバリバリ使うか?
正直、まだ「慎重に設計しつつ様子見」のフェーズだと思います。

ただ一つだけ確かなのは、

もはや LLM を「巨大な純関数」として扱う時代は終わった

ということです。
これから私たちが相手にするのは、「文脈に依存して状態遷移する対話的システム」であり、その設計とデバッグの作法を、ソフトウェアエンジニアとしてゼロから学び直すタイミングに来ている——そう感じています。

コメント

タイトルとURLをコピーしました