生成AIなんでも展示会vol5に行った感想
自分の興味のある、AIの人格形成関連の展示もいくつかあった。
普段一人でもくもくと作っているので同じトピックで会話が通じたのが嬉しかった。自分の研究している方向性と似た展示もいくつかあって、記憶が性格に寄与するという考えに至っている人は多いという印象。
その中でもパラメータの振り方や記憶の保持する層の厚さ、記憶想起の仕組みに個性が出ていた。
とはいえ記憶から振る舞いに一貫性を持たせたい人達の作っている仕組みの方向性はほぼ一致していて、誰かのアイデアやアーキテクチャが突出しているような状況ではないように思えた。
思えたというのは、実際に記憶想起する部分の正しさというのは長期的にそのAIと関わらないと見えてこない部分なので、正直デモではわからなかった。長期的に見比べたら特に優れたものがあったのかもしれない。
そもそも記憶想起は人によって忘却の仕組みがあったり、頻出単語の重み付けがあったりと、単純な情報検索の正確性を測っているわけではないので、優れたアーキテクチャを定量的に測れるものでもないと思う。人間っぽい、会話が連続しているように感じられる、という主観的な測定しかできない。
それでいうとちょっと心配なのは、今後スタンダードに使われる仕組みは、ある程度それらしく動くという前提はあるものの、プロモーションのうまさで決まってしまうのではないかということ。
大手企業とか、インフルエンサーが紹介したものが主流になり、その後により優れた仕組みが現れても誰も試さない。
長期で見ないと良さが分からない上に、既存のキャラの記憶を引き継げないのなら試すハードルが高すぎるということになる。
単純に記憶想起するAIの研究は個人でやって成果を上げるのが非常に難しいかもなどと思った。
だから研究を止めるというわけではなく、むしろ色々な人の情熱を感じてやる気が出ている。見せ方とか、別の価値を付与するような工夫もしなければ、ということを感じた。
次回は出展側で出てみようかな。何か見せられるものを作りたい。
コピペなしでAIがRubyをデバッグ!girb-mcpをリリースしました
[重要]girb-mcpはdebug-mcpにリネームしました! 今後はdebug-mcpをお使いください(機能はこれまで通りです)
girb-mcpとは?
girb-mcp は、LLMエージェントが実行中のRubyプロセスにアクセスするためのMCPサーバーです。
MCP (Model Context Protocol) に対応したクライアントであれば何でも使えます。Claude Code、Gemini CLIで動作確認済みです。
例えばこんな感じで、エージェントに「バグを調査して」と伝えるだけで、実際にリクエストを投げて実行時の状態を確認し、原因を特定してくれます。
あなた: ユーザー一覧ページが500エラーになるので、デバッグセッションに入って原因を調べて
エージェント: コントローラにブレークポイントを設定してリクエストを送りました。
停止地点で変数を確認したところ、@usersの中にnameがnilのレコードが
1件混ざっています(User ID: 42)。
ビューでuser.name.uppercaseを呼んでいるため、ここでNoMethodErrorが
発生しています。
コードを読むだけではわからない「実行時に何が起きているか」を確認できるのがポイントです。
実際に動作する様子はこちらの動画をご覧ください。
girbとの違い
先日リリースしたgirbはIRBやRails console上で人間が対話的にAIを呼び出すツールでした。
girb-mcpは同じ「実行中のRubyプロセスのコンテキストにアクセスする」というアプローチを、LLMエージェント向けに提供するものです。
| girb | girb-mcp | |
|---|---|---|
| 使う人 | 人間(IRB上で対話) | LLMエージェント(MCP経由) |
| インターフェース | REPL上のコマンド | MCPツール呼び出し |
| 動かし方 | girb or binding.girb |
MCPクライアントの設定に追加 |
girbが「人間がAIの力を借りてデバッグする」ツールなら、girb-mcpは「AIが自律的にデバッグする」ためのツールです。
既存のMCPサーバーとの違い
Ruby/Rails向けのMCPサーバーはすでにいくつかありますが、それらは静的解析やアプリケーションレベルのAPI(DBクエリ、ルーティング確認など)がメインです。
girb-mcpはdebug gem経由で実行中のRubyプロセスに接続し、その実行時状態をエージェントに公開します。
Agent → connect(host: "localhost", port: 12345) Agent → get_context() → ローカル変数、インスタンス変数、コールスタック Agent → evaluate_code(code: "user.valid?") → false Agent → evaluate_code(code: "user.errors.full_messages") → ["Email can't be blank"] Agent → continue_execution()
「この変数が今何の値を持っているか」「user.valid?の結果は何か」を実際に評価して返せるのが静的解析との決定的な違いです。
Rubyのような動的な言語では、コードを読むだけではわからないバグが多いので、このアプローチは特に有効だと考えています。
仕組み

- debug gem(
rdbg --open)が対象Rubyプロセスにソケットを公開 - girb-mcpがそのソケットにdebug gemのプロトコルで接続
- MCPクライアントからのツール呼び出しがデバッガコマンドに変換され、結果が返される
MCPはAnthropicが策定したオープン標準で、LLMと外部ツールを繋ぐためのプロトコルです。girb-mcpはmcp gemを使ってこの仕様に準拠しているので、MCPに対応したクライアントであれば何でも利用できます。
できること
調査ツール
| ツール | 説明 |
|---|---|
evaluate_code |
停止中のbindingでRubyコードを実行 |
inspect_object |
オブジェクトのクラス・値・インスタンス変数を取得 |
get_context |
ローカル変数・インスタンス変数・コールスタック・ブレークポイントを一括取得 |
get_source |
メソッドまたはクラスのソースコードを取得 |
実行制御
| ツール | 説明 |
|---|---|
set_breakpoint |
行・メソッド・例外クラスでブレークポイント設定 |
continue_execution |
次のブレークポイントまたは終了まで実行を再開 |
step / next / finish |
ステップイン・ステップオーバー・メソッド終了まで実行 |
Railsサポート
Railsプロセスを検出すると自動的にRails用ツールが追加されます。
| ツール | 説明 |
|---|---|
rails_info |
アプリ名・Railsバージョン・環境・DB情報を表示 |
rails_routes |
ルーティング一覧をフィルタ付きで表示 |
rails_model |
モデルのカラム・アソシエーション・バリデーション・enumを表示 |
trigger_request |
デバッグ中のRailsアプリにHTTPリクエストを送信 |
trigger_requestはPOSTなどのリクエストでCSRF保護を自動的に一時無効化してくれるので、トークンを気にせずリクエストを投げられます。
デバッグだけじゃない!AIコーディングの「次の一歩」
AIに実装を頼むと、テストも一緒に書いてくれます。テストも通ります。でも、そのテストって本当に正しいんでしょうか?
AIが書いたテストは「AIが理解した仕様」を検証しているだけです。ユーザーが意図した動作を検証しているとは限りません。テストが通っているのに、実際に動かしてみたら思ってたのと違う。これはAIコーディングあるあるだと思います。
girb-mcpを使うと、テストの先にもう一歩踏み込めます。
- AIが実装を書く
- AIがテストを書いて通す
- girb-mcpで実際にアプリを動かして、意図通りの振る舞いをするか確認する
例えば「管理者だけが記事を削除できること」を実装させたとして、テストが通った後に実際にDELETEリクエストを投げて、一般ユーザーでは403が返ること、管理者では削除されることを実際の動作で確認できます。
これまでは「テストは通ったので、あとは人間が動作確認してね」で終わっていたところを、動作確認までAIに任せられるようになります。人間は最後に動くものを見て判断するだけです。
インストールと設定
gemをインストールします。
gem install girb-mcp
MCPクライアントの設定にgirb-mcpを追加します。
Claude Codeの場合(~/.claude/settings.json)
{ "mcpServers": { "girb-mcp": { "command": "girb-mcp", "args": [] } } }
Gemini CLIの場合(~/.gemini/settings.json)
{ "mcpServers": { "girb-mcp": { "command": "girb-mcp", "args": [] } } }
他のMCPクライアントでも、STDIOトランスポートに対応していれば同様の設定で利用できます。
Bundler経由の場合はcommandをbundle、argsを["exec", "girb-mcp"]に変更してください。
Ruby >= 3.2.0 が必要です。
使ってみる
Rubyスクリプトのデバッグ
rdbg --open --port=12345 my_script.rb
あとはエージェントに頼むだけ。
「デバッグセッションに接続して現在の状態を見せて」
run_scriptツールがあるのでRubyスクリプトの起動自体をエージェントに任せることも可能です。
Railsアプリのデバッグ
girb-mcpにはRailsサーバーをデバッグモードで起動するコマンドも付属しています。
girb-rails # RUBY_DEBUG_OPEN=true bin/rails server と同等
エージェントにこう伝えます。
「app/controllers/users_controller.rbの15行目にブレークポイントを設定して、/users/1にGETリクエストを送って」
ブレークポイント設定 → リクエスト送信 → 停止した地点で変数を調査、という一連の流れをエージェントが自動で行います。
Docker内のプロセスにも対応
TCP接続またはUnixソケットのボリュームマウントでDocker内のRubyプロセスにも接続できます。TCP経由の場合、ローカルにソースコードがなくてもコンテナ内のファイルを閲覧・読み取りできます。
セキュリティについて
いくつか注意点があります。
- evaluate_codeは任意のRubyコードを実行できます。 ただしファイル操作やシステムコマンドなどの危険な操作はLLMエージェント側のポリシーで制限されています。girb-mcpはあくまで「デバッガの窓口」であり、エージェント側のガードレールと組み合わせて使うことを前提としています。
- debug gemには認証機能がありません。 TCPでデバッグポートを公開する場合は
127.0.0.1にバインドするなど、アクセスを制限してください。 - 本番環境では使わないでください。 開発・デバッグ用途のツールです。
girbファミリー
girb-mcpはgirbファミリーの一員です。
- girb — AI搭載IRBアシスタント(対話型、人間向け)
- girb-mcp — LLMエージェント向けMCPサーバー(プログラマティック、エージェント向け)
- girb-ruby_llm — ruby_llm経由のLLMプロバイダー
- girb-gemini — Gemini API経由のLLMプロバイダー
フィードバック募集中
girb-mcpはまだ発展途上です。使ってみて気づいたことがあれば、ぜひ教えてください。
- GitHub Issues: https://github.com/rira100000000/girb-mcp/issues
「ここが使いにくい」「こんな機能がほしい」など、どんな意見でも歓迎です!
Rubyと自然言語で対話しよう!girbをリリースしました
girbとは?
girb(Generative IRB)はIRB・Rails console・debuggerにAIエージェントを統合するgemです。
例えばこんな感じで、IRB上でAIを呼び出して実装やデバッグを行わせることができます。 youtu.be
いろんな場所で動く
Rails consoleでも動作します。ActiveRecordモデルの情報を理解した上で回答してくれます。
コード内のdebuggerやbinding.girbからでも呼び出せます。
実行中のコンテキストを持つ
girbはファイル、変数、定数、メソッドの定義にアクセスし、現在のプログラムの状態を確実に把握できます。
Claude Codeなどとの違いとして、実行中のプログラムのコンテキストを取得できるのが強みです。これはRubyのような動的な言語のデバッグで特に有効なアプローチと考えています。
また、REPL上で実行されたコードと会話の履歴を記憶しているため、試したコードや発生したエラーに対して自然な流れで質問・指示をすることができます。
デバッグの自動化
girbはAIエージェントです。1往復の会話だけでなく、自律的にタスクを進めることができます。
つまり、debuggerやbinding.girbで呼び出した後、ブレークポイントの設置やnextなどのデバッグコマンドを駆使して自動でデバッグを進めることができます。
一度の実行で解決できない場合、記憶の永続化オプションを有効にすればセッションが切れても記憶が途切れなくなります。
例えば10行目で『5行目のメソッド内で状態を調査するべきだった』と気づいたら、次回実行時にはその記憶を引き継いで5行目のメソッドの調査を行うことができます。
対応しているLLM
- girb-ruby_llm: OpenAI, Anthropic, Gemini, Bedrock, Ollama など
- girb-gemini: Google Gemini専用(Google検索機能に対応)
プロバイダー gemを変更してお好みのプロバイダー、LLMを選べます。
カスタムプロバイダー gemを作ることでどんなLLMでも対応することができます。
インストールと設定
gemをインストールします。
gem install girb girb-ruby_llm
.girbrcに設定を書きます。
require 'girb-ruby_llm' Girb.configure do |c| c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash') end
export GEMINI_API_KEY="your-api-key" girb
詳しくはREADMEを参照してください。
使い方
| コマンド | 説明 |
|---|---|
qq 質問 |
AIに質問する |
Ctrl+Space |
現在の入力をAIに送る |
binding.girb |
コード内からAI付きIRBを起動 |
debugger |
debug gemと連携してAIデバッグを開始 |
自律的に動いている最中でも、Ctrl+Cでいつでも中断できます。
フィードバック募集中
girbはまだ発展途上です。使ってみて気づいたことがあれば、ぜひ教えてください。
「ここが使いにくい」「こんな機能がほしい」など、どんな意見でも歓迎です!
Ano Newsクローズのお知らせ
突然ですが、AnoNewsをサービス終了しました。
(※ AnoNewsについてはリリース時の記事をご覧ください)
約2ヶ月という短い期間の運営となりましたが、その中でも多くの学びと経験を得ることができました。 使っていただいた方、ご意見・ご感想をくださった方々へ感謝を伝えたいです。
お知らせとしては以上となるのですが、せっかくなのでサービス終了の理由や運用してみた感想など書いていきたいと思います。
使用技術
Rails 8 / Hotwire / PostgreSQL / Redis(ActionCable) / Fly.io / Google OAuth / Gemini API / 自作gem(ruby-gemini-api)
サービス終了の理由
まずサービス終了の理由ですが、一つは運用を通じた技術検証が十分にできたことです。
AnoNewsは社会的な課題(ニュースが忘れられてしまう)に着目したサービスでしたが、この課題を解決するには個人プロジェクトとして規模感が合わない、というのが私の出した結論です。単純に集客力が足りないのもありますが、公開された記事をわざわざ修正してくれる、検証してくれるユーザーがいなければ成り立たない、というのがサービスの設計として難しいと感じました。
第2の理由としては、想定以上にサーバー代がかかったことです。appサーバ、DBサーバ、SolidQueueサーバにクラウドストレージ、それぞれをproductionとstagingに作ったところ月々60ドル程度のランニングコストとなりました。ソートボタン連打や複数ユーザーの同時AI記事生成といったケースを考え、負荷対策として少し良いスペックのマシンを借りていたのですが、個人プロジェクトとしては見直しが必要でした。
逆にLLMの費用は(ユーザーが少ないので)全然大丈夫でした。
学び
導線設計の重要性
サービスの強みとして「AI記事生成がとにかく面白い」と考えていたのですが、実際に作ったものは「ログインしてから投稿メニューを押して、AI記事生成を押して、気になるニュースのURLを入力すると生成される」というものでした。初見のユーザーが楽しいところに辿り着くまでの道のりが長すぎました。
次に活かすこと: サービスの一番面白い部分は、最短導線で体験できるようにする。
ユーザーでいなければいけない問題
私自身も記事を書き、投稿された記事を読み、修正したり、いいねしたり、1ユーザーとして活動しました。しかし、新規ユーザーがいないため毎日自力で投稿・巡回することが義務化されました。これは持続可能ではないと気づきました。
記事にしたいニュース、追いかけたいニュースがあるからサービスを使うはずが、サービスを使うためにニュースを探すことになったのです。負担を減らすために扱うニュースの候補を自動ピックアップするスクリプトを作ったりしましたが、本末転倒だと感じました。
次に活かすこと: 自分自身が「義務」ではなく「使いたい」と思えるサービスを作る。コールドスタート問題の解決策は、運営の努力ではなく仕組みで担保する。
良かったこと
技術的知見がたくさん得られた
触ったことのない技術、実装したことのない機能をたくさん触ることができました。Google認証、ポーリングによる通知、WebSocketによるリアルタイムなスコア加算など、自分が「こういう風にしたい」を実現するための様々な技術に触れられたのはとても良い体験でした。
監視やオブザーバビリティなど、普段あまり意識したことがなかった概念に触れられたのも良かったと思います。
自作gemをちゃんと使えた
公開しているruby-gemini-api gemをサービス内で活用したため、実際の使い心地を体験できました。不足している機能もわかったため、gemのメンテナンスも並行して行うことができました。
感想
作ってみて良かったです。サービス運用は大変だなとも思いました。
だいたい1ヶ月くらいで完成させたのですが、寝食を忘れて開発していました。とても楽しかったです。
また何か面白いものを作りたいと思います。
AIでストリートファイターを実況する技術
AIに格ゲー実況させたい
AI Tuberというものが気になってます。
AIが感想をコメントしながら格闘ゲームをしている姿が見てみたいです。
しかし、格闘ゲームをプレイするにはリアルタイムな応答性が必要です。
現時点で格闘ゲームをLLM、VLMにプレイさせるのは難しいですが、人間やCPUがプレイした動画にあたかもAI自身がプレイしたかのようなコメントを入れることは可能なのでは?と考え、実験してみました。
今回の対象ソフトはストリートファイターVです。
実況コメントするには盤面の変化を適切に捉え、喜怒哀楽を表現しなくてはなりませんがうまくいくのでしょうか?
マルチモーダルモデルに放り込む
まず思いつくのが動画をマルチモーダルなモデルに入力し、キャラ設定を渡してコメントさせる手法。
実はgemini-2.5-proが出たあたりで一度実験したのですが、自キャラと対戦相手の区別が付かないという問題がありました。
gemini-3-proが出た今なら何とかなるんじゃないの?というのが今回再実験を始めたきっかけでもあります。
結果
gemini-3-proでも敵味方の区別に失敗します。自キャラに必殺技が当たって大喜びする様子を見るのはなんとも悲しい気持ちになります。
失敗の原因分析:
- 動画全体を渡すと、VLMは「どの瞬間を見ればいいか」がわからない
- 格闘ゲームは1秒間に何度も状況が変わるため、漠然と見せても正確な判断ができない
- 「P1が攻撃した」「P2が攻撃した」の区別は、VLMには判断が難しい
ゲージを見ろ
次の作戦として、マルチモーダルなモデルに体力ゲージだけを注視させます。
まずは体力ゲージの推移ログを作り、ログと試合動画を見比べながらコメントをさせる作戦です。
これならVLMの役割がシンプルになるので成功しそうです。
結果
これも失敗。
ゲージだけ注視しろと言っても無視したり、ゲージから正確な割合を判定できないという問題がありました。
失敗の原因分析:
- VLMは「ゲージが何%か」を正確に読み取るのが苦手
- プロンプトで「ゲージだけ見ろ」と言っても、画面全体を見てしまう
体力のログは自力で作る(フェーズ1)
体力ゲージのログを取るだけならVLMじゃなくてもできます。
OpenCVという画像処理ライブラリを使い、体力ゲージの様子を100ms単位でログに出力させます。
工夫したポイント:
- 体力ゲージは「赤→黒」でダメージが確定する仕様を考慮
- キャラクターがジャンプするとゲージが隠れる問題→前フレームの値を維持
- ラウンド開始時の発光演出→異常値として除外
- 体力は増えないという制約を利用したノイズ除去
結果
これはうまくいきました。 キャラクターがジャンプすると体力ゲージが隠れたり、ラウンド開始時の発光など、イレギュラーなイベントもありましたが、「体力ゲージは増えない」、「赤→黒でダメージが確定する」など細かい仕様を加えることで、ある程度正確なログが取れています。 この体力ログ生成はフェーズ1として採用します。
ダメージイベント抽出(フェーズ2)
体力の推移ログから、実際にダメージが発生したタイミングを抽出します。
これにより100ms単位で存在していたログを圧縮します。
- Phase1の体力ログ(100ms単位)を読み込み
- 体力の減少を検出してダメージイベントに変換
- 500ms以内の連続ダメージは1イベントにマージ
- イベントタイプを分類(p1_damage, p2_damage, exchange, ko, round_start)
結果
timestamp_ms,event_type,target,damage,p1_health,p2_health 7500,round_start,-,0,100,100 11600,p2_damage,p2,3.2,100,96.8 12300,p1_damage,p1,2.1,97.9,96.8 ...
ダメージが発生したタイミングをまとめた、タイムラインの作成に成功しました。
具体的な試合内容を記録する(フェーズ3)
タイムラインからはダメージが入ったタイミングとダメージ量が読み取れます。
また、ダメージが入っていない時間からは読みあい、牽制などで試合が硬直していたことが読み取れます。
VLMにはタイムライン上の各イベントが、具体的にどのような内容だったかを確認させ、より具体的な試合内容を記録させます。
フレーム抽出方式
動画全体を渡すのではなく、各イベントのタイムスタンプ周辺の5フレーム(0.5秒間)だけを画像として抽出してVLMに渡します。
この方式のメリット:
- VLMが「どの瞬間を見ればいいか」が明確になる
- 処理時間の短縮(動画全体を処理する必要がない)
- 攻撃の前後を見ることで、何が起きたかを判断。
イベントの判定にも体力のログを使う
体力のログから判定できることはそちらで判定し、VLMは視覚的な特徴のみを担当させました。
| 判定項目 | 担当 | 理由 |
|---|---|---|
| 誰が攻撃したか | CV | 体力が減った側が被弾者 |
| コンボかどうか | CV | イベント間隔で判定可能 |
| ダメージ量 | CV | 体力の差分から計算 |
| 投げか打撃か | VLM | 視覚的な判断が必要 |
| 飛び道具か | VLM | 視覚的な判断が必要 |
| 対空か | VLM | 視覚的な判断が必要 |
様子見イベントの挿入
イベント間の空白時間が長いと、実況が沈黙してしまいます。これを解決するため、3秒以上の空白時間に「様子見」イベントを挿入します。
結果
タイムラインを渡したおかげで、VLMが敵味方を間違えることがなく、試合の詳しい情報を取得できました。
フェーズ3の出力例:
timestamp_ms,time,situation,emotion,intensity,attacker,is_p1_attacking 7500,7.5,ラウンド開始,緊張,medium,, 11600,11.6,牽制ヒット,淡々,low,p1,True 45600,45.6,コンボ被弾開始,悔しさ,high,p2,False 51500,51.5,コンボ開始,興奮,high,p1,True 70900,70.9,KO勝利,歓喜,high,p1,True
コメントを付ける(フェーズ4)
具体的なイベントを記録したタイムラインができました。
次は、タイムライン上のイベントごとにLLMに適切なコメントをさせます。
コメントの内容はキャラ付け次第になります。今回はお嬢様系実況者という設定でコメントしてもらいました。
発話時間に基づく文字数制限
コメントとコメントの間隔が短いと、発話が終わる前に次のコメントが始まってしまいます。これを防ぐため、次のイベントまでの時間から最大文字数を計算します。
CHARS_PER_SECOND = 5 # 日本語の発話速度(余裕を持たせた値) for scene in scenes: gap_sec = next_event_time - scene_time max_chars = max(3, min(25, int(gap_sec * CHARS_PER_SECOND))) scene['max_chars'] = max_chars
プロンプトでの指示はこのようになります
[11.6秒] 【自分が攻撃】 牽制ヒット (感情: 淡々, 次まで0.7秒, 最大3文字) [12.3秒] 【相手が攻撃】 被弾 (感情: 焦り, 次まで2.9秒, 最大14文字)
キャラクター設定のカスタマイズ
今回実験したキャラクター設定:
1. LLM専門用語キャラ
- 攻撃成功: 「推論的中!」「重み最適!」「loss低下!」 - 被弾: 「勾配爆発!」「NaNエラー!」「過学習!」 - コンボ: 「連鎖推論!」「テンソル全開!」「並列化!」 - ピンチ: 「VRAM残りわずか!」「GPU温度上昇中…」
2. お嬢様キャラ
- 攻撃成功: 「参ります!」「お見事」「華麗に」 - 被弾: 「まあ!」「失礼な!」「無礼な!」 - コンボ: 「舞いますわ!」「優雅に」 - 勝利: 「おほほ、当然の結果ですわ!」
他のキャラクター案
- 株トレーダーAI: 「利確!」「損切り!」「ボラ上昇!」
- 軍師AI: 「作戦通り」「陽動成功」「撤退せよ」
- 厨二病AI: 「我が力を解放…」「闇が疼く」
- 体育会系AI: 「押せ押せ!」「根性!」「気合いだ!」
- 医療AI: 「バイタル安定」「容態急変!」「オペ成功」
結果
どのキャラ設定でも問題なく機能しました。
ただ、キャラが濃すぎると何を言っているのかわからないことが多くなりますね…
お嬢様キャラの出力例:
timestamp_ms,time,situation,comment,emotion 7500,7.5,ラウンド開始,幕開けですわね。,緊張 15900,15.9,飛び込みヒット,華麗ですわ,喜び 21000,21.0,被弾,きゃっ、失礼な!,焦り 45600,45.6,コンボ被弾開始,無礼な!,悔しさ 51500,51.5,コンボ開始,舞いますわ!,興奮 70900,70.9,KO勝利,おほほ、当然の結果ですわ!,歓喜
動画とコメントを同期表示する
実際のAI Tuberとして稼働するならTTSで音声としてコメントを動画に載せると思いますが、今回はコメントとして同期表示させました。
動画とコメントを指定することで同期表示されるhtmlを用意しました。
パイプライン全体図
これで動画にAIのコメントが表示できます。
ここまでの流れをまとめます。
入力: 試合動画
↓
Phase1: 体力ゲージ解析(OpenCV)
- 100ms単位で体力%を記録
- ノイズ除去(ジャンプ、発光演出)
↓
Phase2: ダメージイベント抽出
- 体力減少タイミングを検出
- イベントタイプ分類(damage/exchange/ko)
↓
Phase3: シーン解析(VLM: gemini-3-pro-preview)
- 各イベントの前後5フレーム抽出(-200ms〜+200ms)
- コンボ判定(CV: 3ヒット以上、1500ms以内)
- 様子見イベント挿入(3秒以上の空白)
- 視覚的特徴の判定(投げ/飛び道具/対空)
↓
Phase4: コメント生成(LLM: gemini-2.5-flash)
- キャラクター設定に基づくコメント生成
- 発話時間に基づく文字数制限(5文字/秒)
- 攻撃方向に応じた感情表現
↓
出力: タイムライン付きコメント(CSV/JSON形式)
完成したもの
最終的に完成した動画がこちら。
そこそこ実況っぽくなっています! リアルタイムにコメントできない、実際にプレイできるわけではない。技の解説もたぶんできない、ということで実用的ではないですが、とりあえずコメントさせることに成功しました。
今後の発展可能性
リアルタイム化への課題
- 現状: 動画全体を処理してからコメント生成(オフライン処理)
- 課題: VLM/LLMのレイテンシ(数秒)が格闘ゲームのテンポに合わない
- 可能性: モデルの進化に期待…
TTS連携
- VOICEVOXなどのTTSと連携
- 感情パラメータ(emotion)をTTSの感情制御に活用
まとめ
学んだこと: 1. VLMに全てを任せない: CVで確定できることはCVで処理し、VLMの役割を明確に絞る 2. フレーム抽出が効果的: 動画全体より、特定タイムスタンプのフレームを渡す方が精度が高い 3. 発話時間の考慮: 実況では「何を言うか」だけでなく「どれくらいの長さで言うか」も重要
AI Tuberはある日突然登場するというより、こういった技術の積み重ねで洗練されていくものだと思っています。この記事も何かの役に立てばいいなーと思います。
自作サービスで忘れがちなあれこれ
はじめに
この記事はフィヨルドブートキャンプ Advent Calendar 2025 の9日目の記事です。
昨日の記事はmachidaさんのKaigi on Rails 2025 のデザインをやりました Vol.1 「メインビジュアルの3つの案」でした。
先日自作サービスAno Newsを公開しました。
フィヨルドブートキャンプ卒業から約2年。卒業時に作ったサービスは閉じてしまいましたが、また新たなサービスを立ち上げました。これからコツコツ育てていきたいと思います。
サービスの紹介はリリースブログに任せるとして、この記事ではサービス公開する際に「そういえば忘れてた」「あった方がよかった」となった機能を紹介したいと思います。
これからサービスを公開する方、作ろうという方は参考になるかもしれません。
忘れてた機能いろいろ
フォント設定
WEBフォントを使えば、環境によらず統一されたフォントを使うことができます。
AnoNewsはニュースサイトなので、コンテンツ本文は明朝体、見出しにはゴシック体を使うことにしました。
自作サービス作成中、デザインを後回しにしがちですが、適切なフォントを入れるだけで見栄えがよくなります。是非やりましょう。
2重リクエスト対策
例えば記事投稿の確定ボタン。連打すると同じ記事がだだだーっと大量に登録できてしまっていました。
これはフロント側で連打できないようにすることでほとんど解決するのですが、バックエンドでも重複登録を拒否するよう設定することでより安全なシステムになります。
2重リクエストについてはこちらの記事が大変参考になりました。
2重リクエスト完全攻略HANDBOOK / Double Request Handbook - Speaker Deck
退会機能
入り口や中身は一生懸命作るのに、出口は忘れがちです。
サクッとログイン出来て、気に入らなければスパッと退会できるのが理想です。ちゃんと実装しましょう。
OGP
OGPというのはX(Twitter)などのSNSにシェアしたときに表示される、タイトルや画像などの補足情報を表示するための仕組みです。
OGP画像があるとシェアされたときの見栄えがよくなります。シェアボタンがあるようなサービスなら設定しておきましょう。

ハッシュタグ
シェアボタンからシェアされたときに、自サービス用のハッシュタグをつけておくと検索性がよくなります。
OGPと合わせて設定しておくとよさそうです。
キャッシュ
キャッシュ戦略を考えるのは難しいですが、ヘッダーやメニューなど、動的に更新されない部分のキャッシュなら実装しやすいのではないでしょうか。
AnoNewsでもヘッダーの一部はキャッシュを使うことで表示の高速化を実現しています。
ちゃんと実装してた機能
逆に、「これは最初から入れておいて良かった」という機能も紹介しておきます。
全文検索
後回しにすると面倒そうな機能として全文検索があります。
記事の文章などから任意の文字列を検索するためには索引を作る必要があります。これは文章を作成したタイミングで作るのが一般的です。
サービスリリース後に作る場合、既存の文章の索引を作るという作業が発生してしまいます。
文章を扱うサービスの場合、検索機能は最初からつけておいた方がいいと思います。
エラー追跡・監視
本番環境でエラーが発生したとき、どうやって気づけばいいでしょう?ユーザーの報告がなければ気づけないのでしょうか?
エラーを見逃さないためには、エラー追跡サービスを入れておくと安心です(Sentryなど)。
無料プランでも十分使えます。
まとめ
サービス公開前は機能実装に集中しがちですが、今回紹介したような「地味だけど重要な機能」も忘れずに実装しましょう。
これからサービスを公開する方の参考になれば幸いです!
Ano Newsもぜひ使ってみてください。「あのニュース、どうなった?」という疑問を解決するサービスです。
「あのニュース、どうなった?」を追い続けるサービス「Ano News」をリリースしました

政治家の公約は実現したのか。災害の被災地は復興したのか。企業の謝罪会見の後、本当に改善されたのか。
ニュースは日々生まれますが、「その後」が報じられることは多くありません。選挙が終われば公約の検証は話題にならなくなり、災害報道は時間とともに減っていきます。調べようとしても、情報はバラバラで全体像をつかむのは簡単ではありません。
メディアは速報性に優れていますが、過去のニュースを追い続けることはビジネスモデル上難しいのが現実です。
「あのニュース、どうなった?」
この疑問に答えるためのサービス「Ano News」をリリースしました。
Ano Newsとは
Ano Newsは、ニュースの「その後」を時系列で追跡する市民ジャーナリズムプラットフォームです。
タイムライン形式でニュースを追跡・深堀り
Ano Newsでは、一つのニューストピックを「タイムライン」として管理します。タイムラインには、出来事を時系列で記録していきます。
たとえば「異次元の少子化対策」というタイムラインには、政策発表から法案成立、実施状況まで、一連の流れがまとまっています。新しい動きがあれば、誰でも続報を追加できます。
タイムラインは「これから」を追うだけではありません。「これまで」の経緯を整理する場でもあります。今話題のニュースがどのような背景で生まれたのか、過去の出来事を遡って理解できます。
誰でも投稿可能
Ano Newsは誰でも参加できるプラットフォームです。
既存のタイムラインに続報を追加することも、新しいタイムラインを作成することもできます。プロの記者でなくても、気になるニュースを追いかけて記録を残せます。
AIでタイムラインを簡単作成
「タイムライン記事を書くのは大変そう」と思うかもしれません。Ano Newsでは、AIを使って簡単にタイムラインを作成できます。
入力するのは2つだけです。
- ニュース記事のURL
- どのような観点でタイムラインを作りたいか
これだけで、AIが関連情報を収集し、時系列に整理したタイムラインの下書きを生成します。あとは内容を確認して、必要に応じて編集するだけです。
どのように使うのか
読む
タイムライン記事はユーザー登録なしで読めます。
トップページから興味のあるトピックを探してみてください。現在、以下のようなタイムラインが公開されています。
- 大阪・関西万博 誘致から閉幕までの道のり — 誘致決定から開催、そしてその後まで
- 八丈島を襲った二つの台風:被害と復旧の記録 — 災害発生から復旧状況までを追跡
- エンジニア転職市場の変遷 — 業界の変化を時系列で整理
政治、災害、社会問題から、eスポーツやはやぶさ2の状況まで、幅広いジャンルのタイムラインを用意しています。
参加する
記事へのいいね、ブックマーク、タイムラインの作成・編集にはユーザー登録が必要です。Googleアカウントがあれば、すぐに登録できます。
登録すると、以下のことができるようになります。
- 既存のタイムラインに続報を追加する
- 新しいタイムラインを作成する
- AIを使ってタイムラインを生成する(1日3本まで)
- 気になるタイムラインにいいね・ブックマークする
まずは既存のタイムラインを読んでみて、気になるニュースがあれば続報を追加するところから始めてみてください。
なぜ作ったのか
きっかけは、2025年10月に八丈島を襲った台風22号・23号のニュースでした。
発生直後は多くのメディアが報じましたが、時間が経つにつれて続報が減っています。復旧の状況を知りたくても、まとまった情報はなかなか見つかりません。SNSで細々と発信されている情報を毎日たどって、ようやく現状を把握できる状態が続いています。
Xのおすすめ欄も、興味を持ち続けなければ表示されなくなります。関心が薄れれば、情報も届かなくなる。これはどのニュースにも当てはまる構造的な問題です。
小さな続報でも、タイムラインとして一つのかたまりになれば、ニュースとしての価値が生まれるのではないか。そう考えて、Ano Newsを作りました。
ニュースをもっと身近に、「自分事」として感じられるサービスを目指しています。
今後の展望
現在、「Webデモ」機能をベータ版として公開しています。
Webデモは、市民の力で社会問題を広めるための仕組みです。Ano News内で広告を視聴すると、その収益がプールされます。集まった収益を使って、XやGoogleなどのプラットフォームに意見広告を出稿する、というコンセプトです。
「このニュースをもっと多くの人に知ってほしい」という想いを、広告という形で届ける。新しい市民参加の形を目指しています。
実装時期は未定ですが、ファーストリリース後の反応を見ながら開発を進めていく予定です。
さいごに
Ano Newsは、ニュースの「その後」を市民の手で記録し続けるプラットフォームです。
まずはサイトを訪れて、気になるタイムラインを読んでみてください。そして、追いかけたいニュースがあれば、AIタイムライン生成を試してみてください。ニュース記事のURLと観点を入力するだけで、タイムラインの下書きが作れます。
ご意見・ご感想・バグ報告など、フィードバックを歓迎しています。技術的な観点からのご意見もお待ちしています。
- サイト: https://ano.news
- X: @anonews_jp
- お問い合わせ: サイト内のお問い合わせフォーム または X DM
「あのニュース、どうなった?」という疑問を、一緒に追いかけていきましょう。