はじめに
皆さん、Claude Code と仲良くできていますか?出力にイラッとするときないですか?私はあります。
今回は、その苛立ちを軽減するかもしれない、Claude Codeの顔が見えるツールを簡単に作ってみました。
Claude Code の出力テキストを感情分析して、デスクトップマスコットのように映すツールです。

出力テキストの感情分析と、デモには映していませんがコンテキストの使用率に応じて表情が変わるようになっています。
ちなみに見た目はプリンタニア・ニッポンのコンサルをちょっと意識しました。プリンタニア・ニッポンはいいぞ。
仕組みの概要
大まかな流れはこうなっています。
Claude Code がターンを終えるたびにステータスラインスクリプトが呼ばれ、出力テキストを抽出する
↓
テキストをファイルに書き出す(state.json)
↓
マスコット(PySide6 のウィンドウ)がファイルの変化を検知する
↓
感情分析サービス(Docker コンテナ)にテキストを送る
↓
8 感情の強度が返ってくる
↓
強度をもとにマスコットの顔を決めて表示する
Claude Code の出力を取得する
今回の肝は「Claude Code がターンを終えるたびに出力テキストを受け取る」部分です。Claude Code にはそのための仕組みが 2 種類あります。
フックは、Claude Code の各イベントに外部スクリプトを割り込ませる仕組みです。Stop(ターン終了)や PostToolUse(ツール呼び出し後)などのタイミングで任意のスクリプトを実行できます。ただし渡される情報は主に transcript ファイルのパスで、context の使用率などは含まれません。
ステータスラインスクリプトは、画面下部の 1 行ステータス表示をカスタマイズする外部スクリプトです。ターン終了のたびに Claude Code から呼び出され、stdin に JSON が届きます。
{
"session_id": "...",
"transcript_path": "/path/to/transcript.jsonl",
"context_window": {
"used_percentage": 42.3,
"exceeds_200k_tokens": false
}
}
今回はこちらを使いました。transcript のパスに加えて context 使用率や 200k 超えフラグも一緒に取れるのが決め手です。「context が逼迫したらぐったり顔を出す」機能もこの値で実現しています。
スクリプトは受け取った情報から以下の 3 つを取り出して、state.json に書き出して終わります。
- context の使用率と 200k 超えフラグ
- transcript の末尾から Claude の発言テキスト
- そのターンにツールが失敗したかどうかのフラグ
テキストから感情を分析する
感情分析には、WRIME という日本語感情データセットでファインチューニングされた BERT モデル(patrickramos/bert-base-japanese-v2-wrime-fine-tune)を使用させてもらいました。WRIME は「喜び・悲しみ・期待・驚き・怒り・恐れ・嫌悪・信頼」の 8 感情をそれぞれ強度で表せるデータセットです。
このモデルを FastAPI + Docker で API 化して常駐させています。マスコットがテキストを送ると、8 感情の強度が数値で返ってきます。
CPU 推論での実測です。
| 入力長 | レイテンシ |
|---|---|
| 短文 | 52ms |
| 長文 | 149ms |
常駐メモリは 718MiB。Claude Code を使いながら並走させても体験を壊さない範囲に収まることを確認できたので、量子化などはせずこのまま確定しました。
マスコットの顔を決める
感情の強度が返ってきても、そのまま顔に変換すると誤爆が多くなります。WRIME はツイートで学習しているため、「ツールが失敗した」「謝罪している」といったケースを文章から拾いにくいからです。
そこで、テキスト解析の前に事実として確認できる状態を優先するルールを挟んでいます。
- そのターンにツールが実際に失敗していたら → しょんぼり顔
- 謝罪語が含まれていたら → しょんぼり顔
- それ以外は 8 強度の最大値で顔を決める
- 強度が全体的に低い(感情が読み取れない)→ 通常顔
加えて、context の使用率に応じて顔に汗などのオーバーレイを重ねます。
| context 使用率 | オーバーレイ |
|---|---|
| 60% 未満 | なし |
| 60〜80% | 汗 1 滴 |
| 80〜95% | 汗増し+半目 |
| 95% 以上 / 200k 超 | ぐったり+/compact 推奨 |
頻繁に更新されるため顔がパタパタしやすいのですが、最小表示時間を設ける・切り替え閾値をずらす・しばらく更新がなければ通常顔に戻す、の 3 つで落ち着かせています。
描画は PySide6 で、枠なし・背景透過・最前面で表示しています。state.json の変化検知は QFileSystemWatcher、感情分析の HTTP 通信も QtNetwork を使い、PySide6 だけで完結しています。
まとめ
AIに実際に感情があるわけではないとわかっていても、表情があるだけでなんとなく愛着が湧いてくるものですね。
感情分析の精度はまだ改善の余地がありそうなので、引き続きどうやって育てるか考えていきたいと思います。
参考
- WRIME: https://github.com/ids-cv/wrime
- 採用モデル: https://huggingface.co/patrickramos/bert-base-japanese-v2-wrime-fine-tune
- Claude Code statusline: https://code.claude.com/docs/en/statusline