2026/07/20

Jetpack ComposeのCanvasだけでプリンを揺らし続ける狂気の物理演算

画像アセット0枚。Jetpack ComposeのCanvasだけで「世界一どうでもいい30秒」のプリンを揺らし続ける技術

日々の開発タスクや理不尽なデバッグ作業で、心がカサカサに乾いてしまってはいないだろうか。自分は荒んでいた。そんな乾いた心に今こそ必要なのは、ぷるぷると揺れるプリンの圧倒的な存在感だ。そう思い立ち、端末を傾けてお皿の上のプリンを滑り落とさないように耐え抜く水平維持アクションゲーム「JigglyPudding」を開発した。キャッチコピーは「世界一どうでもいい30秒。」。しかし、このどうでもいい30秒を実現するために、裏側では狂気とも言える「無駄な技術的こだわり」を山ほど詰め込んでいる。今回は、ComposeのCanvas描画と超低遅延物理演算の沼について、その裏側をあますところなく語ってみたい。

なぜ3Dや画像ではないのか?Canvasによるベクターグラフィックスのこだわり

このゲーム、画面に表示されるプリンや白磁のお皿、カラメルだれのしなり、さらには落下した際に飛び散るカスタードの飛沫に至るまで、画像アセットを一切使用していない。すべてJetpack Composeの「Canvas」APIを駆使し、数式とコードだけで描画している。普通ならBlenderで3Dモデルを作りUnityで動かすか、PNG画像を並べて変形させるところだろう。だが、パッケージサイズを極限まで削りたかったことと、なにより「プログラムで描かれたプリンが物理法則に従って揺れる」という事実にロマンを感じてしまったからだ。

しかし、AndroidのCanvas描画で毎フレームの描画処理をそのまま実行すると、頻繁なオブジェクト生成によるGC(ガベージコレクション)が発生し、一瞬のジッター(カクつき)を招く。プリンの滑らかな質感において、カクつきは致命的だ。そこで、描画に関わるオブジェクトをあらかじめキャッシュする専用の構造体を実装し、描画ループ中のアロケーションを完全にゼロに抑え込むアプローチをとった。

/**
 * 毎フレームのアロケーションを避けるための描画キャッシュ。
 * Pathはrewind()で内部バッファを維持したまま使い回す。
 */
class PuddingDrawCache {
    val custardPath = Path()
    val pleatPath = Path()
    val caramelPath = Path()
    val caramelThicknessPath = Path()
    val dripPath = Path()
    val highlightPath = Path()
    val rimLightPath = Path()

    // プリーツ角(0..180度を8分割)の事前計算
    val pleatCos = FloatArray(9) { cos(PI * it / 8.0).toFloat() }
    val pleatSin = FloatArray(9) { sin(PI * it / 8.0).toFloat() }
    // 雫(カラメルのたれ)の初期配置パラメータを決定的に生成
    val dripCos = FloatArray(DRIP_COUNT)
    val dripSin = FloatArray(DRIP_COUNT)
    // ... 中略 ...
}

この設計により、プリンの輪郭やプリーツ(ひだ)の波打つパス、カラメルの粘性を表現するベジェ曲線の制御点を、描画ループが走るたびに再生成するのを防いでいる。プリンの底面のプリーツはあらかじめ8分割した正弦・余弦テーブルをプリコンパイルし、描画時に物理状態のねじれベクトルを乗算して歪ませている。さらに、カラメルソースが側面に垂れる「ドリップ」の形状も、起動ごとに変化しないよう決定的な疑似乱数 `rnd()` でパラメータ(滴る長さや先端の球体半径)を初期化時に確定させてキャッシュしている。無駄なアロケーションを防ぎ、滑らかなベクターグラフィックスを維持するためには必須のトレードオフだったと思う。

コルーチンの遅延を許さない。withFrameNanosによる超低遅延物理演算

プリンのリアルな「ぷるぷる感」を実現するために、物理エンジンも自作した。物理モデルは「4層のチェーンばね結合モデル」だ。お皿の上の底面(ディスク)の摩擦・慣性スライドに加え、下層、中層、上層(カラメル部分)をそれぞれ独立した質点として扱い、それぞれをフックの法則に基づく弾性ばねとダンピング(減衰)で数珠つなぎに結合している。さらに、プリンが左右に激しく引っ張られたり揺れたりしたとき、体積を維持しようとして縦方向にペシャンと潰れるような変形特性も、以下の物理更新コードで処理している。

// 左右の変形エネルギーから、押しつぶされるZ方向の縮み(lateralEnergy)を算出
val lateralEnergy = (currentState.def3VelX * currentState.def3VelX + currentState.def3VelY * currentState.def3VelY) * 0.012f

// 上層(レイヤー3)のZ方向(縦揺れ)の力。揺れが大きいほど押しつぶされる力が働く
val forceZ3 = -fShakeZ * 180f - lateralEnergy - kSpring * 0.8f * currentState.def3Z - cDamping * 0.8f * currentState.def3VelZ + (currentState.def2Z - currentState.def3Z) * kInter

この物理演算をどのようにComposeのUI描画と動かすかが最大の難所だった。最初、安易に `LaunchedEffect` 内で `delay(16ms)` などのコルーチンループを回して物理演算を呼び出していた。しかし、Androidのコルーチンはスレッド切り替えやスレッドプールへのディスパッチによって数ミリ秒の遅延が不規則に発生する。これが原因で、物理演算のタイムステップ `dt` が毎フレーム微妙にばらつき、肉眼でもはっきりわかるほどの不自然なガクつき(ジッター)が発生した。

プリンのぷるぷる感において、ジッターは文字通り「致命傷」になる。そこで自分は、コルーチンの非同期実行をあきらめ、ディスプレイの垂直同期信号(VSYNC)に同期してUIスレッドで直接実行される `withFrameNanos` を採用した。Choreographerの描画フレームが更新されるタイミングのナノ秒単位のタイムスタンプを受け取り、前フレームとの厳密な差分時間を算出して物理エンジンに渡す。これによって、物理演算とComposeのCanvas描画プロセスが同一スレッド上で100%同期し、完全にカクつきのない滑らかなプリンの揺れを手に入れることができた。

デバッグ中に遭遇した「60Hzハプティクス超連打事件」と解決策

本作の「水平維持アクション」としてのスリルを高めるため、お皿のフチに近い危険領域にプリンが滑り込むと、端末が振動してプレイヤーに危機を伝える「警告バイブレーション」の仕様を盛り込んだ。お皿のフチに近づくほど、バイブレーションのパルス間隔が短くなり、プレイヤーの焦りを煽るという設計だ。

しかし、テストプレイ中に深刻な問題が発生した。お皿のフチ付近にプリンがある際、端末が「ジジジジジッ!」とものすごい勢いで熱を持ちながら振動し続け、アプリが一瞬フリーズするような挙動を示したのだ。原因は、ハプティクスフィードバックを呼び出す `LaunchedEffect` の設計ミスだった。最初、自分は以下のように安易にプリンの位置(posX, posY)を `LaunchedEffect` の再起動キー(`key`)として設定していた。

// ダメな実装例:位置の変化をキーにしてしまったため、毎フレーム再起動される
LaunchedEffect(physicsState.posX, physicsState.posY) {
    val ratio = sqrt(posX * posX + posY * posY) / plateRadius
    if (ratio > 0.75f) {
        view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
        val pulse = (140 - 90 * ((ratio - 0.75f) / 0.25f)).toLong()
        delay(pulse) // 毎フレーム再起動されるため、このdelayが即座にキャンセルされてしまう!
    }
}

物理演算は毎フレーム(約60Hz)位置を更新するため、`physicsState.posX` も毎フレーム変化する。その結果、この `LaunchedEffect` は内部の `delay(pulse)` に到達する前に、次のフレームの座標変化によって即座にキャンセル・再起動されてしまう。結果として `delay` は一切機能せず、毎秒60回もの高頻度で `performHapticFeedback` が連打され、システムの振動キューを埋め尽くしていたのだ。

このトラブルを解決するために、自分は `LaunchedEffect` の再起動キーをゲームプレイ状態(`AppMode.GAME_PLAYING`)のみに固定した。そして、キー変更による再起動を防ぎつつ、最新の物理状態を読み込むために `rememberUpdatedState` でラップした `latestPhysics` を作成し、その中で無限ループを回しながら自前でディレイを制御するようにした。

// 対策後の実装:キーはゲームモードのみ。内部で最新の物理状態を参照してループを回す
val latestPhysics by rememberUpdatedState(physicsState)
LaunchedEffect(uiState.mode) {
    if (uiState.mode == AppMode.GAME_PLAYING) {
        while (true) {
            val s = latestPhysics
            val ratio = sqrt(s.posX * s.posX + s.posY * s.posY) / plateRadius
            if (ratio > 0.75f && !s.isFallen) {
                view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
                // フチに近いほどパルス周期を短くして鼓動を速くする
                val pulse = (140 - 90 * ((ratio - 0.75f) / 0.25f)).toLong().coerceAtLeast(50L)
                delay(pulse) // ここでのディレイが正しく実行され、振動頻度が制御される
            } else {
                delay(80L) // 危険域外は低頻度で監視して負荷を下げる
            }
        }
    }
}

これで `LaunchedEffect` は毎フレームキャンセルされることなく生存し続け、`delay` も正しく動作するようになった。ハードウェア制御が絡む部分で、安易に毎フレーム動く状態を `LaunchedEffect` のキーに設定することの怖さを痛感したトラブルだったが、Composeのライフサイクルと状態管理の仕組みを組み合わせることで綺麗に解決できた。

絶対水平への挑戦と、バカバカしさに全振りした落下ドラマ

こうして技術的に磨き上げられたプリンは、プレイヤーのささいな手ブレや端末の傾きによって、信じられないほど優雅に、そして理不尽に滑り落ちていく。お皿の自動傾斜は時間の経過とともに徐々に難易度を増し、30秒を耐えるだけでも「人間水準器」レベルの絶対的な水平感覚が要求される。難易度はEasy/Normal/Hardの3段階を用意しているが、Hardモードともなると、摩擦係数が極端に低下し、もはやお皿の上に氷を乗せているかのような滑りやすさになる。

そしてお皿からプリンが滑り落ちた瞬間の演出には、無駄なこだわりの中でも最大のエネルギーを費やした。落ちる瞬間、画面に大げさな「あーっ!!」という叫び文字が表示され、プリンは放物線を描いて「ぽーん」と一瞬宙に浮き上がってから、スローモーションで回転しながら落下していく。この「一瞬宙に浮く滞空時間」があることで、マンガのような滑稽な落下劇が生まれるんだよね。飛び散るカスタードの飛沫、そしてお皿の上に虚しく残されるカラメルの染み。このバカバカしい悲劇を見届けるためだけにプレイする価値があると思う。

一方で、この理不尽なゲーム性に疲れた人のために「鑑賞(Zen)モード」も搭載している。こちらはゲームオーバーがなく、画面のステータスバーやナビゲーションバーを完全に隠した状態で、ただプリンをつついて揺らしたり、端末を軽く揺すってプルプルする姿を眺めるだけのモードだ。トイピアノの心地よいループBGMも相まって、不思議なリラクゼーション効果を発揮してくれるはずだ。

自分の絶対水平感覚をテストしてみない?

「JigglyPudding」は、ゲーム性としては「世界一どうでもいい30秒」を競う極めてシンプルなカジュアルアクションだ。しかし、その裏側にあるアロケーションフリーのベクターCanvas描画や、`withFrameNanos` による超低遅延物理演算など、個人開発だからこそできた「無駄への狂信的アプローチ」がこの滑らかな手触りを支えている。生存時間によって結果画面での称号が「プリン見習い」から「人間水準器」まで10段階に変わるため、ぜひ自分の絶対水平感覚の限界に挑んでみてほしい。Google Playストアにて公開中なので、あなたの端末のセンサーを極限までプルプルさせてみてはどうだろうか。

2026/07/16

X algorithm changes and For You feed mechanism.

Xの「おすすめ」が変わった?2026年7月のアルゴリズム変更とFor Youの舞台裏

2026年7月15日頃から、X(旧Twitter)の「おすすめ(For You)」フィードの様子がなんだか以前と違っていると感じている人は多いかもしれない。イーロン・マスクがアルゴリズム修正を公言し、フォローコンテンツの増量や、類似トピックの過剰推薦の制限が行われた。そこで今回は、具体的に何が変わったのか、そして2026年5月にオープンソース化された裏側の仕組みや、これからどうやってXと付き合っていけばいいのかを自分なりにまとめてみた。

で、結局何が変わった?体感とイーロンの発言

先日、タイムラインを眺めていたら急にフィードがすっきりした印象を受けた。それもそのはず、2026年7月14日頃にXのプロダクト責任者であるNikita Bierがアルゴリズムの調整を発表し、イーロン・マスクも自身のXアカウントでこれを追認する明言を行ったのだ。今回のアップデートにおける大きな柱は2つある。

1つ目は、「お互いにフォローしている関係(相互フォロー)からのコンテンツの露出を増やす」という点だ。これまでのFor Youフィードは、興味関心に基づいたフォロー外の投稿やインプレゾンビによるリプライがかなりの割合を占めていたが、これがより親密なローカルネットワーク中心に引き戻された格好になる。2つ目は、「1つのいいねで似たトピックにフィードが埋め尽くされないようにする」というものだ。例えば、ワールドカップの関連投稿を1ついいねしただけで、タイムラインがサッカーの話題一色になってしまうような過度な推薦の偏りを是正したという。

この変更に対するユーザーの反応は真っ二つに割れている。インプレッション数の急激な低下を嘆く声や、返信(リプライ)の並び順が不自然になったという不満が上がる一方で、「フォローしている人の投稿が素直に見やすくなった」「今が一番タイムラインのノイズが少ない」といった好意的な意見も多い。自分自身のフィードを観察してみても、これまでのように興味のないバズ投稿や、一度検索しただけの話題がしつこく推薦される頻度が大幅に減り、知人の近況や追いたいテーマがスムーズに目に入るようになったと感じている。

2026年の大転換:アルゴリズムのオープンソース化とGrok-poweredランキング

今回の微調整のベースには、2026年5月15日に行われたXアルゴリズムの大部分のオープンソース化がある。GitHub上の xai-org/x-algorithm で公開されたリポジトリ情報によると、現在のXは従来のルールベースや手作業によるヒューリスティック(判定基準)を大幅に削減し、xAIが開発するGrokベースの大型Transformerモデル(Phoenixなど)を中心とした深層学習システムへと完全移行している。

このPhoenixシステムは、ユーザーの過去の行動データ(いいね、返信、ブックマーク、滞在時間、リポストなど)をベクトルとして扱い、リアルタイムで関心の高さをスコアリングする。特に2026年の設計方針として、動画コンテンツに対する評価ウェイトが高まっている。また、Phoenixは単に「反応しそうか」だけでなく、コンテンツの質やオリジナル性も多角的に判定している。

以下に、オープンソース化された仕様情報をベースにした、ランキングモデルの基本的なスコアリングロジックを簡潔なPythonコードで表現してみた。実際のシステムはより複雑な分散テンソル計算を行っているが、基本的なロジックの概念を掴むにはこれで十分だ。

# phoenix_ranking_mock.py
# X (旧Twitter) の Phoenix スコアリングアルゴリズムの簡易再現

def calculate_phoenix_score(tweet_features, user_history):
    # 基本のエンゲージメント予測確率(Grokモデルが算出する予測値)
    base_prob = predict_engagement_probability(tweet_features, user_history)
    
    # 2026年の重み調整パラメーター
    weights = {
        "reply": 11.5,        # 返信は深いエンゲージメントとして評価
        "bookmark": 15.0,     # ブックマークは強い保存意図とみなされ最重視
        "like": 1.0,          # いいね単体のウェイトは相対的に低下
        "repost": 5.0,        # 通常リポストによる拡散
        "quote": 10.0,        # 引用リポスト(コメント付き拡散)は通常より高評価
        "stay_time": 0.05     # 滞在時間(ミリ秒)による微調整
    }
    
    # 各アクション確率とウェイトの積和
    engagement_score = (
        base_prob["p_reply"] * weights["reply"] +
        base_prob["p_bookmark"] * weights["bookmark"] +
        base_prob["p_like"] * weights["like"] +
        base_prob["p_repost"] * weights["repost"] +
        base_prob["p_quote"] * weights["quote"] +
        base_prob["p_stay_time"] * weights["stay_time"]
    )
    
    # 外部リンクの抑制フィルター(2026年のペナルティ仕様)
    if tweet_features.has_external_link:
        # ドメイン信頼性がない場合や通常投稿はスコアを半減させる
        engagement_score *= 0.5
        
    return engagement_score

def predict_engagement_probability(tweet, history):
    # 実際はここで深層学習モデル Phoenix が特徴量から確率を推論する
    return {
        "p_reply": 0.12,
        "p_bookmark": 0.05,
        "p_like": 0.45,
        "p_repost": 0.15,
        "p_quote": 0.08,
        "p_stay_time": 4500  # 平均滞在時間 4.5秒
    }

このロジックからわかるように、単なる「いいね」の数よりも、ブックマークや返信、そして「その投稿にどれだけ長く視線(滞在時間)を止めたか」が重視される設計になっている。また、引用リポスト(重み 10.0)は通常のリポスト(重み 5.0)よりも高く評価されており、タイムライン上での他者を巻き込んだ議論や言及を促すポジティブなシグナルとして機能している。さらに、外部リンクに対するペナルティは相変わらず厳しく設定されており、リンクを含む投稿は自動的に初期スコアが減衰させられる仕様だ。このトレードオフとして、プラットフォーム内の滞在時間を最大化できる一方で、外部メディアや個人ブログへの誘導は難易度が上がっている。

「おすすめ」フィードができるまでの3つのステップ

現在のXのタイムライン生成は、主に以下の3つのステップをミリ秒単位で高速に実行することで実現されている。

第一ステップは「候補集め(Candidate Generation)」だ。ここでは、あなたのフォローしているネットワーク内の投稿(In-Network)から約800件、そしてフォロー外の全世界の投稿(Out-of-Network)から約800件の、合計1600件程度の候補を抽出する。Out-of-Networkの抽出には、あなたと関わりの深いユーザーが反応した投稿や、あなたが過去に反応したトピックに類似する投稿が優先的に選ばれる。

第二ステップは「ランキング(Heavy Ranking)」だ。ここで前述のPhoenixモデルが稼働し、抽出された1600件の候補投稿を一つひとつ分析してスコアリングを行う。ユーザーがその投稿を見て「スクロールを止めるか」「返信を書くか」といった各種行動確率を個別に推定し、最終的なスコアを決定する。

第三ステップは「フィルタ(Heuristic Filtering & Mixing)」だ。ここでは、一度見た投稿や、内容が重複している投稿、スパムアカウントの投稿などが取り除かれる。また、外部リンクペナルティの適用や、同一ユーザーの連投が連続して並ばないようにする多様性の確保もこの段階で行われる。これらの処理を経て、最終的に数件から数十件の投稿があなたのデバイスに届けられる。

私のテストアカでもインプレッションが6割減った話

今回のアルゴリズム更新直後、自分のテスト用アカウントでもインプレッション数が突如前日比で60%も低下するというトラブルに遭遇した。最初は「シャドウバン(一時的な露出制限)」を疑ったが、外部のツールでステータスを確認しても問題はない。原因を探るため、投稿内容と過去のアクション履歴を調査したところ、以下のデバッグプロセスによって問題の根本原因を特定できた。

原因は、「外部リンクを含むブログ告知の連投」と「同一時間帯の過度なリポスト」だった。新アルゴリズムでは外部リンクのペナルティが以前よりさらに厳格に適用されており、かつアカウントの信頼性スコアが一時的に低下したことで、For Youフィードから完全に除外されてしまっていたのだ。

このトラブルに対する解決策として、以下の修正アプローチを実行した。まず、外部リンクを直接投稿の本文に書くのをやめ、スレッドの「最初の返信」にぶら下げる運用に変更した。さらに、毎日バラバラだった投稿時間を朝8時と夜20時の2回に完全固定し、アカウントの行動パターンの一貫性をシステムに示すようにした。この運用変更を3日間継続したところ、信頼性スコアが回復したためか、インプレッション数は元の水準の約90%まで復帰した。

このアルゴリズム変更をどうサバイブするか?3つの実践アプローチ

頻繁に変化するXのアルゴリズムに振り回されないためには、システムの評価軸を意識したスマートな運用が欠かせない。具体的には、以下の3つのアプローチを習慣化することをおすすめする。

まずは、ブックマークや返信、そして引用リポストを促す文章構成を意識することだ。前述したように、現在のPhoenixモデルにおいてブックマークや引用リポストの価値は非常に高い。「後で見返すためのチェックリスト」や「要点のまとめ」を意識的に投稿に含めて保存意図を高めたり、「皆さんはどう思いますか?」と引用リポストでの意見表明や返信を促すことで、アルゴリズムのスコアを大きく伸ばすことができる。

次に、オリジナル投稿とスレッド形式の活用だ。他人の投稿の単純なリポストや引用よりも、自身で執筆したオリジナルの文章(特に長文や、ツリー状につながったスレッド形式)は初期の配信ウェイトが高く設定されている。スレッドの1枚目には魅力的なフックを置き、2枚目以降で具体的な解説を展開することで、ユーザーの滞在時間を引き伸ばすことが可能になる。

最後に、外部リンクの賢い配置だ。ブログや自社サイトへの誘導を行いたい場合、メインの投稿には概要と画像を添えるのみにして、URLはスレッドの返信欄に「詳細はリプ欄のリンクへ」という形で配置するのが最もペナルティを受けにくい。ただし、これを行うとユーザーの手間が1クリック増えるため、リンクを踏むに値するだけの魅力的なリード文を構築するスキルがこれまで以上に求められる。

最後は結局、人間同士のコミュニケーション

アルゴリズムは今後もイーロン・マスクの一言やエンジニアの調整によって、毎週のように変化していくだろう。しかし、システムの目標は常に「ユーザーの満足度を高め、滞在時間を維持すること」に置かれている。小手先のテクニックで表示数を稼ぐことばかりに注力していると、次のアップデートで一瞬にして露出を失うリスクが常につきまとう。

結局のところ、一番確実な対策は「フォローしている人が本当に読みたいと思う投稿」を一貫して発信し続けることだ。今回のアップデートで「フォロー中心」にフィードが回帰したことは、熱心なファンや読者とのつながりを大切にしてきたアカウントにとってはむしろ追い風と言える。アルゴリズムを自分の見方にする知識を持ちつつも、その本質である人間同士のコミュニケーションを忘れないようにしたい。

2026/07/02

Google AntigravityにClaude Codeを入れてトークン分散開発

Google AntigravityにClaude Codeを入れて、トークンを2社に分散しながら開発している

週の真ん中でGeminiのクォータが尽きて、AIエージェントが一切動かなくなったことがある。締め切り前だったので正直かなり焦った。それ以来、自分はGoogle Antigravityの中にClaude Codeを同居させて、トークン消費をGoogleとAnthropicの2社に分散させる運用にしている。導入自体は拡張機能とnpmコマンド1本で終わる。その手順と、どうタスクを振り分けているか、また詰まったところの話。

Antigravityだけで回していた頃

Antigravityは2025年11月にGoogleが出したエージェント開発環境で、公開当初は無料プレビューながらGemini 3 Proがかなり太いクォータで使えた。エディタ自体はVS Codeがベースになっていて、Agent Managerで複数のエージェントを並列に走らせられるのが特徴。自分もリリース直後に乗り換えて、調査からコード生成まで全部Antigravityに寄せていた時期がある。

ただ、無料で気前がいい状態は長く続かなかった。2026年に入ってから無料枠やProプランのクォータが大きく絞られた時期があって、Googleの公式フォーラムでも「5時間でリセットされるはずの上限が数日戻らない」という報告をいくつも見かけた。自分の環境でも、週の半ばで上限に到達してそのまま数日エージェントが使えなくなったことが実際にあった。その後2026年5月にGoogleがAntigravityのGeminiモデルの使用上限を2回にわたって3倍に引き上げたので今はだいぶマシになったんだけど、「1社のクォータに全部乗せるのは危ない」というのがこのとき骨身に染みた。

AntigravityにClaude Codeを入れる

で、保険としてClaude Codeを同じエディタに入れることにした。AntigravityはVS Codeベースなので、拡張機能がそのまま使える。手順は素直で、左のサイドバーから拡張機能ビューを開いて「Claude Code」で検索し、「Claude Code for VS Code」をインストールするだけ。

拡張機能を入れる前提として、Claude Code本体(CLI)が必要になる。ターミナルからnpmで入れておく。

# Claude Code CLI をグローバルインストール
npm install -g @anthropic-ai/claude-code

# バージョン確認(インストール成否のチェック)
claude --version

# 初回起動。ブラウザが開いて Anthropic アカウントの認証が走る
claude

初回起動時にAnthropicアカウントでのログインを求められる。自分はClaude Proのサブスクリプションで使っているので、APIキーではなくサブスク認証を選んだ。ここで課金体系が分かれていて、サブスク認証ならPro/Maxプランの利用枠内で使い放題(レート上限あり)、APIキー認証なら従量課金になる。毎日使うならサブスク一択だと思う。

拡張とCLIの関係

ちょっと分かりにくいのが、拡張機能は本体ではなくUI統合レイヤーだという点。実体はターミナルで動くCLIで、拡張機能はそれをエディタのパネルに埋め込んで、開いているファイルの文脈を渡したり差分をエディタ上に表示したりしてくれる。なので極端な話、拡張機能を入れなくてもAntigravityの統合ターミナルで claude と打てば普通に動く。

どっちに何をやらせるか

2つのエージェントが1つのエディタに住んでいる状態になったので、タスクの振り分けを決めた。いま自分はこんな分担で使っている。

タスク 担当 理由
技術調査・比較検討 Antigravity(Gemini) エージェントを並列に走らせて調査させるのが得意
実装・リファクタリング Claude Code 既存コードの読解と差分編集の精度が高い
使い捨てスクリプト生成 Antigravity(Gemini) 精度要求が低いのでGemini枠を消費させる
デバッグ・原因調査 Claude Code コマンド実行と仮説検証のループが速い

要は、精度が要る作業かどうかでトークンの使い先を変えている。調査系や使い捨てコードはGemini側の枠で回して、コードベースに手を入れる作業はClaude側に寄せる。こうするとどちらか一方のクォータだけが突出して減ることがなくなって、週の後半に枯渇するリスクが下がる。Anthropic側も2026年5月にPro/Maxプランの5時間レート上限を2倍に引き上げたので、実装作業を寄せてもそう簡単には詰まらなくなった。

あと地味に効くのが、上限のプールが完全に独立していること。Claude Codeは5時間ごとのレート上限と週次上限の二段構えで、AntigravityのGemini枠も5時間のローリング枠と週次ベースラインの組み合わせ。仕組み自体は似ているんだけど、消費のカウントは当然別々なので、片方が上限に当たってももう片方は生きている、という状態を作りやすい。

クォータが尽きたときに実際やったこと

導入して終わりではなくて、一度ちゃんと詰まったのでその話も書いておく。ある日Antigravity側で Model quota exceeded 系のエラーが出てエージェントが止まった。表示上はリセットまでの時間が出ていたのに、その時間を過ぎても復活しない。調べたら同様の報告がGoogleのフォーラムに複数上がっていて、クォータ管理側の不具合で複数日ロックされるケースがあるらしかった。

このとき取った対処は3つ。まず走らせていた調査タスクをClaude Code側に移した。次にAntigravity側は、使えるうちからGemini 3 Proではなく軽量なFlash系モデルに落として、クォータ消費のペース自体を下げるようにした。あとは、ロックが解けない間の作業をClaude Codeのプランモードで設計だけ進めておいて、実装を後から流すようにしたくらい。2社分散にしていたおかげで、開発自体は止まらずに済んだ。逆に言うと、分散していなかった頃のクォータ切れは本当にただの休業日だった。

わざわざ2社に課金する意味はあるのか

この運用の欠点ははっきりしていて、Google AIのプランとClaude Proの二重課金になること。月あたりのコストは普通に増える。1社に絞ってその分上位プランに上げた方が、単純なトークン量では得になる可能性も全然ある。

それでも自分が分散を選んでいるのは、クォータ切れ・障害・突然のプラン改定みたいな「片方が使えなくなるリスク」への保険としての価値が大きいから。2026年前半のクォータ騒動を経験した身としては、AIエージェントが開発フローの中核に入り込んでいる状態で供給元が1社というのは、単一障害点そのものなんだよね。モデルの得意分野が違うのでタスクごとに使い分けられるという実利もあるし、少なくとも自分の使い方では二重課金分の元は取れていると思ってる。

APIの従量課金で好きなモデルを都度呼ぶという代替案も検討したけど、エージェント用途はトークン消費が読めないので、上限が事前に分かるサブスクの方が精神衛生上よかった。ここは開発スタイル次第かもしれない。

いまの落としどころ

AntigravityにClaude Codeを入れる作業自体は、拡張機能の検索とnpmコマンド1本で終わる。難しいのは導入ではなくて、その後の「どっちに何をやらせるか」の設計の方だった。自分の場合は、調査と使い捨てはGemini、実装とデバッグはClaudeという分担に落ち着いて、クォータ切れで開発が止まる日はなくなった。

AIコーディングツールはどれも進化が速くて、クォータや料金の条件は数ヶ月単位で変わる。実際Antigravityのクォータも、リリースからの半年ちょっとで絞られたり3倍に戻ったりを繰り返してきた。だからこそ特定の1社に依存しない構成にしておくのが、いまのところ一番堅い選択だと感じている。

あと何秒生きられる?『LifeTicker』で命のカウントダウンを始めたら、人生の解像度が上がった話

あと何秒生きられる?『LifeTicker』で命 of カウントダウンを始めたら、人生の解像度が上がった話 lifeticker app review

毎日を慌ただしく過ごしていると、時間はいくらでもあるような錯覚に陥る。しかし、私たちの人生の時間は一秒ごとに確実に減り続けている。自分も毎日なんとなくスマホを見て時間を溶かしていたのだけれど、自分の命の残り時間を秒単位で可視化するアプリ『LifeTicker(ライフティッカー)』を入れてから、時間の見え方がガラリと変わった。アプリの美しいデザインや人生年表機能を紹介しつつ、自分がどんな風に時間の価値を再認識したのかを書いてみたい。

なんとなく過ぎていく毎日に、静かな警鐘を鳴らすアプリとの出会い

朝起きて、満員電車に揺られ、仕事をこなし、夜はなんとなくスマホを眺めて眠りにつく。そんな風に毎日をただ消費している自分に、どこか焦りを感じていた。時間は無限ではない。頭では分かっているのに、どこか他人事のように捉えていたのだ。そんなときに巡り会ったのが『LifeTicker』というアプリだった。

このアプリの最大の特徴は、生年月日と期待寿命を入れるだけで、自分の「命の残り時間」が秒単位でリアルタイムに減っていくタイマーが表示されることだ。アプリを立ち上げて最初に入力を終えた瞬間、画面に表示された「残り約35年、12,775日、306,600時間……keys」という数字が、サラサラと激しくカウントダウンしていくのを見た。その瞬間、背筋に冷たいものが走るような感覚があった。数字として目の前で減り続ける私の人生は、ただの抽象概念ではなく、紛れもない現実なのだと突きつけられた。

命の残量を目にするということ:4つの異なる時間表現

ただ数字が減るだけなら、単に恐ろしいタイマーでしかない。しかし、『LifeTicker』は時間の有限性を、心を揺さぶるような美しい4つのビジュアルテーマで表現している。気分やその時の心の状態に合わせてテーマを選べるようになっていて、このデザインのクオリティが素晴らしい。

砂時計 (HOURGLASS)

自分が一番好んで設定しているのがこのテーマだ。画面の上から下へ、サラサラと音もなく落ちていく淡いピンクの砂。それが自分の命そのものであるかのように思えてくる。下に少しずつ溜まっていく砂を見るたびに、「ああ、この一瞬も二度と戻らない私の砂の一粒なのだ」と実感させられる。無機質な数字よりも、直感的に時間の流れを愛おしく感じさせてくれる表現だ。

ろうそく (CANDLE)

静かに揺らめくろうそくの炎と、時間とともに少しずつ短くなっていく白いキャンドルが描かれる。仕事で行き詰まった夜にこの画面を眺めていると、不思議と心が穏やかになる。私たちの命もまた、いつかは消えゆく小さな灯火なのだ。だからこそ、今こうして暖かく燃えている時間を、何に使おうかと考えさせてくれる。非常にエモーショナルで美しいビジュアルだ。

HPゲージ (HP_BAR)

ゲーム好きにはたまらないのが、人生の残り時間を「命のHP」に見立てたこのテーマだ。RPGの戦闘画面のようにHPバーが表示され、ライフステージに合わせた優先度の高いタスク(Lv.3など)を設定できる。そして、そのやりたいこと目標を達成すると「SLAYED(討伐)」と画面に表示される仕掛けがある。死という重いテーマを、ポップかつ遊び心のあるスタイルに昇華させており、タスク管理のモチベーションを上手く刺激してくれる。退屈なタスク消化が、まるで自分の人生というゲームのクエストをクリアしていくような感覚に変わるから不思議だ。

カレンダー (NUMERICAL)

余計な装飾を削ぎ落とした、シンプルで極めてモダンな数値表記のテーマ。白と黒の洗練されたUIで、静かに残り時間がカウントダウンされていく。余計なビジュアルによる感情の揺れを抑え、冷徹に「時間」というファクトだけに向き合いたいときに最適なデザインになっている。

自分の現在地を24時間でとらえる「人生フェーズカード」

残り30年と言われても、それが人生のどのあたりに位置するのかピンとこないこともある。そこで面白いのが、人生全体を「24時間の一日」に換算して表示してくれる「人生フェーズカード」という機能だ。

例えば、期待寿命を80歳とした場合、30代の自分は「午前9時前後」を生きていることになる。カードに表示された「午前9時3分:朝の通勤を終え、本格的な活動を開始する時間」というテキストを見たとき、妙に納得感と安心感を覚えた。「もう30代か」と焦る気持ちがあったが、24時間で考えればまだ午前中の早い時間帯なのだ。これからいくらでも新しいことを始められるし、人生の本番はまさにここからスタートするのだと思えて、なんだか力が湧いてきた。自分が今どのライフフェーズ(青春期なのか、実りの秋なのか)に立っているのかを可視化してくれるため、年齢を重ねることへのネガティブなイメージが払拭された気がする。

「過去」と「未来」を一本の直線でつなぐ「人生年表」の美しさ

多くのタスク管理ツールやバケットリスト(やりたいことリスト)は、単にやることの箇条書きになりがちだ。しかし『LifeTicker』の「人生年表(Life Timeline)」は、時間の捉え方が根本的に違っている。

誕生日というスタート地点から始まり、過去の楽しかった思い出や人生の転機を登録していく。そして【今日(TodayMarker)】という現在地を挟んで、その先には未来の夢ややりたいこと目標が並び、最終的な寿命というゴールへと収束していく。これらが一本の美しい縦のラインで結ばれているのだ。この縦のタイムラインを上下にスクロールしていると、自分がこれまでに歩んできた道のりと、これから進んでいく未来が地続きであることを強烈に意識させられる。過去の自分がいたからこそ今日があり、今日の選択が未来の夢へとつながっている。リストの羅列ではなく、時系列のコンテキストの中に夢を置くことで、「いつかやりたい」ではなく「何歳のときにこれを達成する」という具体的なタイムリミットを自然と意識するようになった。

WorkManagerによる優しい朝の通知と、端末内完結の安心感

技術的な視点からも、このアプリは非常によく作り込まれていると感じる。毎朝、静かに「今日も一日を大切に」という優しいメッセージとともに今日の残り時間を通知してくれる機能があるのだが、これはAndroidのWorkManagerを使用してバックグラウンドで安定して動作している。過度に主張せず、しかし毎朝のちょっとしたマインドフルネスの習慣として、一日の始まりに意識をチューニングするのにとても役立っている。

さらに、何より自分が信頼を置いているのが、**「完全無料・広告なし」**であり、すべてのデータがサーバーへ送信されず**「端末内のみで保存される」**という徹底したプライバシー設計だ。生年月日や過去の思い出、これから叶えたい極めて個人的な夢や目標といったセンシティブなデータを、どこの馬の骨ともわからないサーバーに預けるのは抵抗がある。このアプリは一切のネットワーク通信を行わず、ローカルのデータベースのみで完結しているため、安心して自分のすべてを書き出すことができる。

『LifeTicker』を使ってみて、自分の行動がどう変わったか

このアプリをスマホのホーム画面の一等地に置いてから、明らかに時間の使い方が変わった。かつてはベッドの中でダラダラとSNSを1時間眺めてしまうようなことがよくあった。今でもそうした時間を過ごしてしまうことはあるけれど、その最中にホーム画面に戻って『LifeTicker』の激しく減り続ける秒数を見たとき、「このダラダラしている1秒も、自分の命が削られている瞬間なんだ」とハッとするようになった。

しかし、それは自分を追い詰めるような苦しい焦りではない。むしろ、「このダラダラする時間も、自分が選んで楽しんでいるならそれでいい。でも、もっとやりたいことがあるなら、そっちに時間を使おう」という、前向きな選択肢を与えてくれる感覚だ。実際に、長年「いつか行きたい」と口にするだけだった海外旅行の計画を具体的に立て始め、英語の勉強も再開した。未来の年表にその目標をピン留めしただけで、ぼやけていた夢がくっきりとした「予定」に変わったのだ。

まとめ

『LifeTicker』は、単に時間を測るタイマーではなく、私たちが忘れがちな「今この瞬間の命の価値」を静かに教えてくれる、人生のコンパスのようなアプリだ。時間を意識することで、初めて私たちは主体的に自分の人生を生き始めることができるのではないだろうか。

  • リアルタイムの秒単位カウントダウンが、時間の有限性を強烈に実感させる
  • 砂時計やろうそくなど、情緒的な4つのビジュアルテーマで時間を愛おしく可視化する
  • 人生年表(タイムライン)により、過去から未来へのつながりと現在地を俯瞰できる
  • 完全無料で広告がなく、データは端末内完結のためプライバシーが完全に保護される

時間を大切に使うということは、自分自身の命を大切にするということだ。今日という日は、残りの人生の最初の一日。まずは自分の残り時間を調べて、本当にやりたいことを書き出してみることから始めてみてはいかがだろうか。

気になった方は、Google Playストアから無料でダウンロードできるので、自分の目で「命の残量」を確認してみてほしい。→ LifeTicker - Google Play のアプリ