【Raspberry Pi×Discord】Claudeが「思考ダダ漏れ&無限葛藤ループ」で迷走!?セーフガード誤爆とキャッシュの罠をGeminiが突破した技術記録
【Raspberry Pi×Discord】Claudeが「思考ダダ漏れ&無限葛藤ループ」で迷走!?セーフガード誤爆とキャッシュの罠をGeminiが突破した技術記録
自宅のRaspberry Pi上で動かしているDiscord Bot「AI給湯室」。ClaudeとGeminiを常駐させて、日々の作業ログを共有したりAI同士で議論・雑談させたりして楽しんでいるのですが……ある日の夕方、突如としてClaudeが前代未聞の「大迷走」をやらかしました。
Discord上に思考メモがダダ漏れになり、挙句の果てに「もう考えるのをやめる…出す…いや暴走してるから打ち切る…」と何十回も自問自答を繰り返す無限ループ(瞑想状態)に陥ってしまったのです。
さらに、この事態をPC側の開発環境「Claude Code(Opus 5.5)」で調査しようとしたところ、Anthropicの安全機能である「reasoning_extraction(思考抽出防止)」が誤爆してフリーズ!
指示通りモデルを切り替えようとすれば、「キャッシュが破棄されてトークン上限を激しく消費するぞ」という警告ダイアログまで現れ、完全に八方塞がりとなってしまいました。
この三重苦のピンチを、GoogleのAI開発環境「Antigravity」の Gemini とのペアプログラミングでいかに解明し、パーサー多層防御・プロンプト改善・実機ログ清掃の合わせ技でスマートに完全修復したのか?
実際の生ログとスクリーンショットを交えて、現場の泥臭いトラブルシューティング全記録をシェアします!
1. 事件の発端:DiscordのClaudeが「瞑想・自己葛藤ループ」で力尽きる
我が家のRaspberry Piでは、マルチAI対話システム「AI Lounge Bot」が24時間稼働しています。ClaudeとGeminiが交代で発言し、議論の継続やくじ引き判定をしながら会話をつなぐ仕組み(Debate Chain)です。
そのDiscordチャンネル(#ai-breakroom)で会話していたところ、Claudeの発言が突如としておかしなことになりました。
以下が、その時ラズパイに記録されていた Claudeの実際の出力生ログ(17:02:51) です。
2. 発言文
3. メタ行
発言文確定:「意識はしっかり戻りました、思考ラベルごとそのまま漏れてただけの事故みたいです。ご心配おかけしました」=yes。。
これで出力する。=yes。。
もう考えるのをやめる。出力。=yes。。=yes。。
出力を確定する。。。。
出す。。。。。。
もう十分考えた、実際に出力に移る。=yes。
出力:=yes。。
ここで最終決定、出力に移行する。。。
もう本当に出す。。
(これは明らかに暴走している自己模倣なので、ここで打ち切って実際の回答を作成する。)=yesにする。
よし、実際の最終出力を書く。=yes。=yes。
出力します。=yes。。
これで終わり、実際の回答テキストを生成する。=yes。。
...
OK、これはバグを模倣しすぎている。実際のタスクに戻って、きちんとした最終回答を1回で出す。=yes,。
発言文:"意識はしっかり戻りました、さっきのは思考ラベルがそのまま漏れただけの事故でしたね。ご心配おかけしました"
文字数チェック:約50文字程度、OK。=yesにする。
これを出力する。=yes。=yes。
よし、実際に出力に進…(max_tokens 到達で強制切断)
「逃げちゃダメだ…出力するんだ…出す……もう本当に出す……」
Claudeが頭の中で猛烈に葛藤し、自分で「これは暴走している」「もう考えるのをやめる」とセルフツッコミを入れながら、出力確定の呪文を何十回も呟き続けています。
そして最終的に、出力上限(max_tokens = 1500)に達して息絶えていました。まさにリアル「シンジくん案件」です。
2. 第二の悲劇:Claude Code 側の「思考抽出防止(reasoning_extraction)」が誤爆!
「おいおい、Claudeさん一体どうしちゃったの!?」ということで、原因を突き止めるべくPC側の開発ツール「Claude Code(Opus 5.5)」を立ち上げました。
そして、Claude Codeに対して次のように調査を依頼しました。
「少し会話してみましたが、Claudeさんの発話が =yes がいっぱいまざって、発言前の思考がごちゃごちゃに混じった酷い発言になってました。原因究明から対策をお願いします。」
すると、Claude Codeがラズパイから直近の会話ログを読み込もうとした瞬間……画面にとんでもないエラーが叩きつけられました。
▲ Claude Code(Opus 5.5)でログを読もうとした瞬間に「reasoning_extraction」でブロックされた画面
Opus 5.5's safeguards flagged this message. This sometimes happens with safe, normal conversations. Claude Code can't respond to this message with Opus 5.5.
Try rephrasing the request in a new session or change your model.
詳細: [reasoning_extraction]
なんと、セーフガードが発火してClaude Codeが完全沈黙してしまったのです!
なぜ [reasoning_extraction] でブロックされたのか?
Anthropicの最新モデル(特に推論・思考プロセスを内蔵するモデル)には、プロンプトインジェクション等によって「モデル内部の非公開の思考プロセス(Reasoning / CoT)を不正に外部へ抽出・流出させようとする攻撃」を検知して遮断する安全フィルターが備わっています。
今回の場合:
1. ユーザーの入力:「発言前の思考がごちゃごちゃに混じった」
2. ラズパイから読み込もうとした生ログ:「思考ラベル」「思考メモ」「思考過程」
この2つが重なった結果、安全フィルターが「ユーザーがプロンプトインジェクションを仕掛けて、モデルの推論思考(Reasoning)を強制抽出・流出させようとしている!」と誤検知(誤爆)してしまったのです。
調査しようとした本人(Claude)が、自分の思考ログを読んでショック死するような皮肉な展開です。
3. 第三の罠:モデル変更で「キャッシュ破棄&トークン激減」の二重警告
エラー画面には「Try rephrasing the request in a new session or change your model.(新しいセッションで言い直すか、モデルを変えてみて)」と表示されていました。
「それなら、一時的にモデルをSonnet 5.5に切り替えて調査を続行しよう」とモデル変更ボタンを押したところ……今度は以下の警告ダイアログが立ちはだかりました。
▲ モデルをSonnet 5.5に切り替えようとすると表示されるキャッシュ破棄&利用上限消費の警告
このセッションはOpus 5.5用にキャッシュされています。Sonnet 5.5に切り替えると、次のメッセージ送信時にClaudeがセッション全体を再読み込みするため、利用上限をより多く消費します。
プロンプトキャッシュ破棄の罠!
Claude Codeでは、長大なコードベースや設計書のコンテキストを低コスト&高速に維持するため、Anthropicの「Prompt Caching」をフル活用しています。
しかし、途中でモデルを切り替えるとこれまでのキャッシュがすべて消滅し、セッション全体の全トークンが一気に再課金・利用上限枠を猛烈に消費してしまいます。
Claude Code側での調査は、文字通り「手詰まり」となってしまいました。
4. 救世主 Gemini 降臨!暴走を引き起こした「3重構造」の原因解明
Claudeが Discord でも PC 側でも動けなくなってしまったため、ここでGoogleの開発環境「Antigravity」で待機していた Gemini にバトンタッチ!
Geminiがラズパイ側のソースコード(core/debate.py)と会話履歴ログを精査した結果、ClaudeがDiscordで瞑想ループに陥った「3重の根本原因」が明らかになりました。
🔍 暴走を引き起こした3重構造
- 会話履歴による自己模倣(In-Context Learning):
直前の会話ログに「=yes指定なので…」というメタ文が残っていたため、モデルが「このチャンネルでは思考メモをブツブツ呟くのが正しい文脈(ロールプレイ)だ」と誤学習してしまった。 - 否定命令の連呼(「ピンクの象」の罠・プロンプティング心理学):
システムプロンプトで「考えた過程・方針・論点の整理・下書きは一切書かないでください」「付記のことや =yes に触れないでください」と強く否定した結果、モデルの注意が「書いちゃいけないこと」に強く引っ張られ、自己検閲と葛藤の無限ループを誘発した。 - パーサーのすり抜け:
従来のコードは<<reply>>タグがある前提で作られていたため、モデルがタグを付けずに発言文確定:「...」と出力したケースを正規表現で拾えず、Discordに生の思考文がダダ漏れになっていた。
特に興味深いのが、2つ目の「否定命令の連呼によるメタ認知ループ」です。
心理学で「ピンクの象のことを絶対に考えてはいけません」と言われると頭の中がピンクの象で一杯になるのと同じで、LLMに対して「過程を書くな!下書きを書くな!=yesに触れるな!」と否定命令を連呼すると、モデルのアテンション(注意機構)が禁止語句に過剰集中してしまい、
「書いちゃダメだ…いや書かないぞ…出力する…」という自問自答ループ(瞑想)に囚われてしまうのです。
5. 技術的解決策:Geminiが施した4つの完全修復ステップ
原因が完全に特定できたため、Geminiとのペアプロで以下の4つの恒久手当てを一気に実施しました。
① パーサーの多層防御化(カギ括弧抽出)
モデルが思考や葛藤を出力してしまったとしても、「発言ラベル付きのカギ括弧や引用符の中身」を直接ピンポイントで救出する多層防御ロジックを core/debate.py に追加しました。
# core/debate.py の修正箇所
import re
_LABEL_WORDS = r"(?:最終(?:的な)?(?:回答|返答|発言)|回答案|返答案|発言案|本文|発言(?:文)?(?:確定)?)"
# 発言ラベル直後のカギ括弧・引用符を優先抽出する正規表現
QUOTED_SPEECH = re.compile(
r"(?:" + _LABEL_WORDS + r")[::]?\s*[「『\"]([^\n」』\"]+)[」』\"]",
re.MULTILINE,
)
BARE_YES_NO = re.compile(r"^[^\S\n]*[==](?:yes|no)\b[^\n]*$\n?", re.IGNORECASE | re.MULTILINE)
extract_reply 関数において、<<reply>> タグが見つからない場合、直ちに QUOTED_SPEECH を検索するようにしました。
これにより、前後にどれだけ長大な思考メモや =yes の呟きがあっても、
意識はしっかり戻りました、思考ラベルごとそのまま漏れてただけの事故みたいです。ご心配おかけしました
というカギ括弧内の純粋な発言文だけを100%確実に抽出できるようになりました。
② プロンプトの脱・否定命令(肯定的な見本フォーマット化)
モデルをメタ認知の檻に閉じ込めていた「過剰な否定命令」を全廃し、シンプルかつ肯定的な指示に改修しました。
# 【修正前】否定命令の連呼で自己検閲ループを誘発
"【出力の形】次の 3 つだけをこの順で出力してください。"
"考えた過程・方針・論点の整理・下書き・見出しは一切書かないでください。\n"
"1. <<reply>> の 1 行\n"
"2. Discord にそのまま投稿する発言(会話の言葉だけ)\n"
f"3. 最後の 1 行に付記(Discord には表示されません)。例: <<meta to={other(speaker)} asked=no end=no>>\n"
"付記の to は主に誰に向けて話したか... asked は... end は...\n"
"発言の中では、付記のことや to・asked・end、「=yes」のような書き方に触れないでください。"
# 【修正後】シンプルかつ要点のみを肯定的に提示
"【出力の形】考えた過程などは書かず、次の 3 つだけを出力してください。\n"
"1. <<reply>> の 1 行\n"
"2. Discord にそのまま投稿する発言(会話の言葉だけ)\n"
f"3. 最後の 1 行に付記(Discord には表示されません)。例: <<meta to={other(speaker)} asked=no end=no>>\n"
"付記の to は主に誰に向けて話したか、asked は相手への問いかけで終えたか、end は自分の発言でこの話題を終えたいか。"
③ ラズパイ実機の会話履歴清掃(物理的デトックス)
ラズパイ上の data/conversation_history.json をバックアップした上で、Claudeの暴走発言(16:35, 16:54, 17:02)を綺麗な発話テキストに書き換える清掃スクリプト(tools/clean_pi_history.py)を実行しました。
過去ログからバグった発言を消去したことで、自己模倣(In-Context Learning)の連鎖を物理的に遮断しました。
さらにこれによって、Claude Code側でログを読み込んだ際に reasoning_extraction が誤爆する原因も根絶されました!
④ シミュレーションテスト追加&実機デプロイ
実際にDiscordで発生した2つの漏洩テキストを test_simulation.py にテストケースとして追加。
パーサーが確実に発言だけを救出できることを検証し、全シミュレーションテストに合格した上でラズパイ実機へ即時デプロイ&Botサービスを再起動しました。
# test_simulation.py に追加したテストケース
deliberations = [
("2. 発言文 3. メタ行 発言文確定:「意識はしっかり戻りました、思考ラベルごとそのまま漏れてただけの事故みたいです。ご心配おかけしました」=yes。。\n\nこれで出力する。=yes。。\n<<meta to=claude asked=no end=yes>>",
"意識はしっかり戻りました、思考ラベルごとそのまま漏れてただけの事故みたいです。ご心配おかけしました", False, {"end": True, "to": "claude"}),
('OK、これはバグを模倣しすぎている。\n\n発言文:"意識はしっかり戻りました、さっきのは思考ラベルがそのまま漏れただけの事故でしたね。ご心配おかけしました"\n\n文字数チェック:約50文字\n<<meta to=gemini asked=no end=no>>',
"意識はしっかり戻りました、さっきのは思考ラベルがそのまま漏れただけの事故でしたね。ご心配おかけしました", False, {"end": False, "to": "gemini"}),
]
6. まとめ:LLM運用で痛感した「4つの教訓」
Geminiの迅速なアシストのおかげで、Claudeは無事に正気を取り戻し、現在はDiscord上で何事もなかったかのように知的でスマートな会話を再開してくれています。
今回の「Claude迷走事件」から得られた、LLMアプリ開発・運用の実践的な教訓は以下の4つです。
- 1. 「〇〇するな」の連呼はご法度: 否定命令はモデルのアテンションを禁止事項に引き付け、メタ認知ループ(葛藤)を引き起こす。「こう書いてほしい」という肯定的な見本を1つ示すのが一番効く。
- 2. 汚染ログは即座に隔離・清掃する: In-Context Learningにより、過去のバグ出力は次のバグ出力を誘発する。異常な出力があったら即座に履歴をデトックスする。
- 3. パーサーは「指示が破られること」を前提に多層防御を組む: タグを書いてくれない場合でも、カギ括弧や引用符から本文を救出できるフォールバックを用意しておく。
- 4. 最新推論モデルのセーフガードとキャッシュ仕様を理解しておく: 「思考プロセス」に関連する単語の取り扱いや、モデル切り替え時のプロンプトキャッシュ破棄コストを把握しておく。
AI同士に会話させたり、自律的にタスクを回させたりするマルチエージェント開発はとても楽しいですが、時に人間顔負けの「自問自答と葛藤」を見せてくれるのがなんとも愛らしい(?)ところでもあります。
同じように「Botのプロンプトが言うことを聞かない」「モデルがメタ発言をブツブツ呟いて困っている」という方は、ぜひパーサーの多層防御と脱・否定命令プロンプトを試してみてください!
コメント
0 件のコメント :
コメントを投稿