<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>AgentBar Blog — 日本語</title>
		<link>https://agentbar.pages.dev/ja/blog</link>
		<description>AI コーディングエージェントをファイル読取だけで監視する macOS メニューバーアプリ AgentBar の開発ノート。プロセス非起動の計測、トレース再構成、プライバシー設計。</description>
		<language>ja</language>
		<atom:link href="https://agentbar.pages.dev/ja/feed.xml" rel="self" type="application/rss+xml" />
		<item>
			<title>AgentBar がエージェントを起動せず、ファイルだけを読む理由</title>
			<link>https://agentbar.pages.dev/ja/blog/read-only-by-design</link>
			<guid isPermaLink="true">https://agentbar.pages.dev/ja/blog/read-only-by-design</guid>
			<pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
			<description>CodexBar は使用量を読むために Claude CLI を起動し、Mac を毎分フリーズさせました。AgentBar はエージェントが自分で書いたファイルだけを読みます。その保証はテストで強制されています。</description>
			<content:encoded><![CDATA[<p>去年の7月、私の Mac は1分おきに、1分近く固まるようになりました。ポインタは動いて、止まって、まとめて追いつきます。キー入力は遅れて届くか、届きません。どこかの Chrome タブが暴れているのだろうと思っていました。違います。プロセツリーが指していたのは、エージェントの様子を見るために入れたメニューバーアプリでした。そしてそのアプリが60秒ごとに起動していたのは、エージェントの側でした。</p>
<p>アプリは CodexBar 0.43.0、Apple のノータリゼーション済み、更新間隔は1分に設定してありました。使用量の数値を1つ表示するために、このアプリは Claude CLI を起動します。問題は、その CLI が隔離環境で動かなかったことです。CLI は普段の Claude 設定をそのまま読み込みました。私の設定には Context7 と Serena という2つの MCP サーバーと Chrome 連携が入っていて、プローブのたびにそれらも初期化されます。Chrome は GPU プロセス、ネットワークサービス、ストレージサービス、タブと拡張機能を復元する多数の Renderer を引き連れて起動しました。</p>
<p>その午後の実測値は、時刻付きでリポジトリに残してあります。14:56:48 と 14:57:48、1分差で2回のプローブが起動し、どちらも CodexBar の watchdog の子プロセスでした。Renderer は個別に CPU の 30〜111% を消費し、空きメモリは約22万ページから約4千ページへ落ち、圧縮メモリはゼロから10万ページを超え、WindowServer は 33〜40% まで上がり、入力が画面に届かなくなりました。14:58:42 に CodexBar を終了させて、さらに2分監視しています。新しいプローブは一度も現れませんでした。</p>
<p>公平を期すなら、この Mac の負荷は CodexBar だけのものではありません。DisplayLink と InstantView という2つの USB 映像ソフトが常駐しており、これらは WindowServer への負荷を増幅します。ただし、60秒ごとに背景の重さをデスクトップ全体のフリーズへ変えていた周期的なきっかけは、使用量を重い方法で読んでいたメニューバーアプリでした。</p>
<h2 id="使用量を読むのに-cli-は要らない">使用量を読むのに、CLI は要らない</h2>
<p>あとから CodexBar の GitHub issues を200件ほど調査しました。同じ設計がどこにでも出てきます。データソースが「CLI に聞く」で、その CLI がフルスタックのエージェント実行環境であるかぎり、更新の重さはあなたの設定全体を引き受けます。MCP サーバーや連携を増やすほど、メニューバーの定期更新は重くなる。罰が設定量に比例する設計です。</p>
<p>issue トラッカーは、このパターンを具体的な数字で示しています。</p>
<ul>
<li><a href="https://github.com/steipete/CodexBar/issues/1844">#1844</a>: 時間ごとの「delegated CLI refresh」回復パスが <code>/usr/bin/open</code> を呼び、ユーザーの既定ブラウザを勝手に起動しました。高速リトライ中は20秒〜3分間隔で開き続けます。</li>
<li><a href="https://github.com/steipete/CodexBar/issues/2052">#2052</a>: バックグラウンドの Claude プローブが CLI の自動更新ダウンロードを誘発しました。<code>DISABLE_AUTOUPDATER=1</code> が設定されていなかったためです。3日間で 90.6 GiB の通信、1日あたり 257〜495 の Claude CLI プロセスが起動しています。</li>
<li><a href="https://github.com/steipete/CodexBar/issues/2251">#2251</a>: 使用量プローブのたびに空の Claude セッションが新規作成され、数週間で36以上の幻影セッションがアカウントに蓄積しました。Anthropic のレート制限にも抵触し始めます。</li>
<li><a href="https://github.com/steipete/CodexBar/issues/2241">#2241</a>: CLI プローブの成功率は 268回中23回、8.6%。失敗時にキャッシュ済みのスナップショットを破棄するため、表示データに最長110分の欠落が生まれました。</li>
<li><a href="https://github.com/steipete/CodexBar/issues/1999">#1999</a>: CodexBarCLI の2プロセスが合計 75 GB まで膨張し、48 GB マシンをシステム全体の OOM に巻き込んでいます。</li>
</ul>
<p>これらは不注意ではありません。受動的なモニターが能動的なエージェントを起動し続ける設計が、1プローブずつ生む帰結そのものです。</p>
<h2 id="ファイルは-もうそこにある">ファイルは、もうそこにある</h2>
<p>代替手段は、最初からディスクの上にありました。コーディングエージェントは自分の仕事を自分で記録します。Claude Code は <code>~/.claude/projects/**/*.jsonl</code>、Codex は <code>~/.codex/sessions/YYYY/MM/DD/*.jsonl</code>、Qwen はチャット JSONL と <code>usage_record.jsonl</code>、Gemini はイベントソーシングのセッション JSONL を書きます。Cursor は SQLite データベース（<code>state.vscdb</code>）に状態を持つので、AgentBar は sqlite3 の C API で直接読み取ります。Cursor には何も問い合わせません。</p>
<p>AgentBar が表示するものは、すべてこれらのファイルから再構成されます。日別のトークン使用量、クォータ、モデル別内訳、60日分のセッション履歴、<a href="/ja/blog/reconstructing-agent-traces">どのエージェントが誰を呼び出したか</a>のグラフ、そして「承認待ち」の状態まで。承認待ちは推測ではありません。Claude については生 JSONL の末尾から読んでいます。未完了の <code>tool_use</code> レコードがあり、対応する result がなければ、そのエージェントは人間の承認で止まっている。AgentBar はそういう行を最上位に固定します。</p>
<p>Claude のクォータ数値は <code>~/.claude/usage-watch/rate-limits.json</code> から来ます。Claude CLI 自身が毎回の応答のあとに書き出すファイルです。AgentBar はサーバーに聞かず、プロセスも起動せず、このファイルを読みます。</p>
<h2 id="約束ではなく-強制">約束ではなく、強制</h2>
<p>「読取専用」は主張するのは簡単で、守り続けるのは難しい。だから AgentBar は規律に頼りません。構造的に2つの仕組みで強制します。</p>
<p>実行時は <code>ProcessGuard</code> が、取得の前後で <code>sysctl</code> を使ってプロセステーブルの差分を監視します。更新処理が禁止された子プロセス（Node、Python、npm、uv、ブラウザ、MCP サーバー）を起動したら、モニターが自分の違反を自分で検出して報告します。テストスイートの <code>NoProcessSpawnTests</code> はさらに先へ進みます。Claude 設定に意図的に10個の MCP サーバーを登録した状態で100回の更新を回し、Node・Python・npm・uv・Chrome・MCP のプロセスが1つでも現れたらビルドを失敗させます。テストが領収書です。</p>
<p>設計の残りは、上の issue リストへの直接の回答になっています。自己監視は <code>getrusage</code> と <code>task_info</code> で AgentBar 自身の CPU と RSS を計測し、閾値を超えたら自動更新を止めます。取得に失敗しても UI は白くなりません。最後の正常値が時刻付きで画面に残り続けます（stale-while-revalidate）。issue #2241 の真逆です。更新間隔の最短は5分。1分の選択肢は設計として存在しません。更新はプロバイダーごとに単一飛行、数秒ずつずらして実行され、失敗が続いたプロバイダーはサーキットブレーカーが開いて15分止まります。</p>
<p>AgentBar がサブプロセスを起動する場所は1つだけです。ツールアップデーターが、あなたのクリックで、ハードタイムアウト付きでオンデマンド実行するとき。Diag タブは帳簿を公開します。直近取得の所要時間、CPU 時間、ピーク RSS、読取ファイル数、パースしたレコード数、そして起動した禁止プロセス数。最後のカウンターは常にゼロです。</p>
<h2 id="代わりに手放すもの">代わりに手放すもの</h2>
<p>ファイルを読むことにも代償はあります。その代償を正直に書くことが、モニターと広告の分かれ目です。</p>
<p>ファイル読取が見るのは、エージェントがすでにディスクへ書き出したものまでです。API の真実ではなく、ディスクの真実。クォータの数値は、それを書き出すファイルの新しさそのものでしかありません。実行状態の検出は、ログ末尾が状態を明示している Claude では正確で、Codex・Qwen・Gemini・Cursor では会話ターンからの最善推定になります。コストはモデル単価テーブルに基づく推定値で、サブスクリプションにカバーされている可能性があります。だから UI は毎回「推定」と表示します。キャッシュトークンは生成トークンと別建てで課金し、推定値が二重課金しないようにしています。CodexBar の issue <a href="https://github.com/steipete/CodexBar/issues/1796">#1796</a> はここが壊れていて、コストが 2.7〜4.6 倍に膨れていました。</p>
<p>そして、ローカルに記録を残さないエージェントは、この方法では監視できません。ここはきっぱりしています。例外的に、リモートにしかデータがないプロバイダー向けにリモート usage 照会を用意していますが、明示設定の opt-in で、プロバイダーごとの設定が必要で、読取専用原則の唯一の例外です。既定で外へ出るものは何もありません。</p>
<h2 id="静かな部分">静かな部分</h2>
<p>あの日の午後、解決策はアプリを終了させることでした。新しいアプリを書く理由になったのは、「監視する」と「起動する」が同じ動詞であるべきではなかった、という気づきです。使用量メーターは、エージェントが働くほど重くなるべきで、ツールを設定するほど重くなってはいけません。</p>
<p>それ以来、私の Mac は静かです。これは私の Mac についての観察であって、あなたの Mac への約束ではありません。約束はリポジトリの中にあります。<code>ProcessGuard</code> と <code>NoProcessSpawnTests</code>、そして要求があればいつでも領収書を印刷する Diag タブの中に。</p>
]]></content:encoded>
		</item>
		<item>
			<title>AgentBar はローカルログからマルチエージェントの呼び出し関係をどう再構成するか</title>
			<link>https://agentbar.pages.dev/ja/blog/reconstructing-agent-traces</link>
			<guid isPermaLink="true">https://agentbar.pages.dev/ja/blog/reconstructing-agent-traces</guid>
			<pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
			<description>Claude が codex exec を呼び、その Codex が claude -p を呼ぶ。フックもデーモンも入れずに、AgentBar がログから呼び出し関係と現在状態をどう再構成し、どこを推定として区別するか。</description>
			<content:encoded><![CDATA[<p>Claude Code にリファクタを依頼したら、途中で別のエージェントが必要だと判断し、シェルで <code>codex exec</code> を実行しました。その Codex は、差分の確認のために <code>claude -p</code> を呼びました。依頼は1つ、エージェントは3つ、プロセスの境界は2回、自分の関与なしに越えられた。</p>
<p>あとから知りたいのは全体像です。誰が誰を、どのコマンドで呼び、今それぞれ何をしているのか。サービスバックエンドなら、これは分散トレーシングの担当領域です。トレースコンテキストがホップごとに伝播し、コレクタがスパンを組み立て、UI がウォーターフォールを描く。ただし条件があります。コンテキストを注入し、コレクタを動かす誰かが要る。</p>
<p>あなたは何も入れていません。エージェントにフックを仕込んでもいないし、トレイサーライブラリもデーモンも無い。それなのに、なぜトレースが存在できるのか。</p>
<p>率直に言えば、トレーシングの意味では存在していません。境界で捕捉されたものは何も無い。AgentBar は事後にグラフを再構成します。エージェントが自分自身の理由で書いた記録から組み立て、推定が必要だった接続にはすべて印を付けます。</p>
<h2 id="記録はエージェント自身が書いている">記録はエージェント自身が書いている</h2>
<p>コーディングエージェントはトランスクリプトを残します。Claude Code は <code>~/.claude/projects/**/*.jsonl</code>、Codex は <code>~/.codex/sessions/</code> 配下の日付別 JSONL、Qwen と Gemini はそれぞれの JSONL、Cursor は SQLite データベースに状態を持ち、AgentBar は sqlite3 の C API で直接読み取ります。Cursor には何も問い合わせません。</p>
<p>これらのファイルは、エージェントがセッションを再開し、履歴を表示するために存在します。監視されているからではなく、動いている副産物として書かれる。AgentBar はそれだけを読み、他には何も読みません。CLI を起動せず、フックを仕込まず、トレイサーを注入しない。ファイルを読むことの意味は<a href="/ja/blog/read-only-by-design">別の記事</a>に譲ります。ここで狭く言うのは、トレースの原料が最初からディスクにあったという点です。</p>
<p>この方法で組んだトレースは法医学的です。すでに起きたことを、残された痕跡から復元する。ライブのテレメトリが境界を跨ぐ真実を報告するのに対し、再構成は領収書を読んで、最も起きたらしいことを推定します。この構えが、期待の置き方を正しくします。</p>
<h2 id="呼び出しの瞬間を見つける">呼び出しの瞬間を見つける</h2>
<p>最初の仕事は、境界の通過に気づくことです。AgentBar の <code>EdgeDetector</code> は親 Run の会話ターンを走査します。見るのは tool ターンと assistant ターンだけ。user と system ターンはコマンドを実行しないからです。ターンの内側では、各行をシェルの区切り（<code>&amp;&amp;</code>、<code>;</code>、<code>|</code>、単独の <code>&amp;</code>）で分割し、各セグメントが実際に何を実行するかを問います。</p>
<p>トークナイザーは意図的に浅く作ってあります。先頭の環境代入（<code>FOO=bar</code>）とコマンドラッパー（<code>nohup</code>、<code>sudo</code>、<code>env</code>、<code>time</code> など）を飛ばし、最初の実トークンを取ってパスを剥がす。<code>nohup codex exec &quot;…&quot;</code> は <code>codex</code> と読まれ、<code>/usr/local/bin/claude -p &quot;…&quot;</code> は <code>claude</code> と読まれます。detached や sudo 越しに起動されるエージェントこそ追跡したいので、ラッパーの透過は重要です。</p>
<p>これはシェルパーサーではありませんし、そうである必要もありません。やることは1つ、起動コマンドを散文と区別すること。<code>codex exec &quot;fix the tests&quot;</code> ではエージェント名がコマンドトークンです。「claude にレビューを頼んだ」という文では、エージェント名はコマンドトークンにならない。この1つの区別が、相関を走らせる前に誤検出の大半を取り除きます。</p>
<p>検出はそれぞれ起動（invocation）になります。境界を越えたコマンド、対象エージェント、それを含むターンの時刻、親の作業ディレクトリ、そしてコマンドがツール結果由来なら親のツール呼び出し id。</p>
<h2 id="推定辺ができるまで">推定辺ができるまで</h2>
<p>起動は、親が別のエージェントを宣言したことを示します。しかし、そのエージェントがどのセッションを始めたかまでは示しません。バイナリは同じターン内で起動して終了したかもしれないし、対応するセッションは複数あるかもしれない。AgentBar は相関を取ります。</p>
<p>起動ごとに候補セッションを絞ります。セッションが候補になるのは、プロバイダーが対象エージェントと一致し、起動より後かつ60秒の窓以内に開始し、両方がディレクトリを持つときはプロジェクトが起動の作業ディレクトリと一致するときです。どちらかのディレクトリが欠けている場合は、不一致ではなく不明として扱います。複数が該当すれば、最も早く始まったものが勝つ。</p>
<p>結果は辺（edge）です。そしてデータモデルは、それがどの種の辺かを明示します。この経路が生成する辺はすべて <code>.inferred</code> の信頼度を持ち、破線で描かれます。モデルには <code>confirmed</code> の信頼度も定義されています。環境変数やセッション id で境界をまたいで受け渡された結合のためのものです。ファイルだけの経路は、これを一切出しません。確定の根拠になるプロセス間シグナルが存在せず、あるのは時刻とディレクトリの一致だけだからです。AgentBar は、持っていない確実性を主張しません。</p>
<p>実線は、結合が観測されたことを意味します。破線は、起動コマンドを見て、対応するセッションが直後に同じ場所で現れるのを見て、一方が他方を引き起こしたと結論したことを意味します。たいてい、この結論は正しい。ラベルは、正しくないときのために存在します。</p>
<h2 id="グラフが描くもの">グラフが描くもの</h2>
<p>Graph ウィンドウはメニューバーの Active タブから開き、1つの人間依頼を左から右へ、X-Ray や Datadog のトレースマップ風に配置します。形が種別を運び、色が状態を運ぶ。この2つは競合しません。</p>
<p>丸はアクターの点です。人間のプロンプト、エージェント実行、終端マーカー。四角はツール呼び出し。三角はモデルの思考、システム注記、承認待ちです。エージェント実行は、プロバイダー別の縁取りと6pt の状態ドットを持つ丸として描かれ、5つの状態のいずれかで色が付きます。実行中、承認待ち、完了、失敗、アイドル。</p>
<p>ノードはセッションではなく Run です。1つのセッションは複数の Run を含み、<code>--resume</code> やスレッドの再実行のたびに増える。親子の辺は Run に紐づくため、会話を再開しても子は孤立しません。</p>
<p>子エージェントは起動地点にインライン展開されます。<code>bash</code> が <code>codex exec …</code> を実行すると、その Codex は単なるツール呼び出しではなく子レーンとして描かれ、親レーンは子フローへ降りて、完了後に合流します。ネストが深いほどレーンも深くなる。同種の思考が連続すると <code>×N</code> ノードに集約され、クリックすれば集約分がすべて開きます。形をクリックするとインスペクタが開き、思考ならその内容、ツール呼び出しならコマンドと出力、エージェント実行ならモデル・トークン数・キャッシュヒット率・変更ファイル・イベント全件を読めます。巨大なグラフは2方向スクロール、35〜200% のズーム、フィットボタンで操作できます。</p>
<h2 id="状態はログ末尾の純粋関数">状態はログ末尾の純粋関数</h2>
<p>誰が誰を呼んだかは、問いの半分です。もう半分は、各エージェントが今何をしているか。AgentBar はこれにも、グラフと同じ方法で答えます。ファイルを読んで、計算する。</p>
<p>各プロバイダーはログ末尾を小さなシグナルへ縮約します。最終レコードの時刻、最終イベントの種別、未応答のツール提案があるか、終端の成功または失敗を見たか。純粋な分類器がこのシグナルを固定の優先順位で状態へ変換します。失敗が最優先で、新しさに関係なく失敗は失敗。新しいログに未応答のツール提案があれば承認待ち。新しいログに開いた質問があれば入力待ち。新しくて終端レコードが無ければ実行中。冷めた終端停止は完了。それ以外はアイドル。</p>
<p>鮮度の窓が効いてきます。承認待ちはログが新しいあいだだけ意味を持つ。ログが古くなったら、分類器は「ユーザーはこのエージェントに応答義務を負う」という主張をやめます。</p>
<p>精度はプロバイダーで異なり、UI はそれを明言します。Claude の承認待ちは生 JSONL の末尾から読み取ります。未完了の <code>tool_use</code> があり、対応する result レコードが無いこと。Codex・Qwen・Gemini・Cursor では会話ターンからの最善推定で、状態の注記はその留保を運びます。メニューバーの Active タブはセッションディレクトリを10秒スロットルでポーリングし、ライブグラフを直近3日・各プロバイダー25件に絞り、変更の無い要約と会話末尾をメモリキャッシュから再利用し、承認待ちを最上位に固定します。</p>
<h2 id="再構成が手放すもの">再構成が手放すもの</h2>
<p>領収書を読むことにも代償があります。それを名指すことが、モニターとデモを分けます。</p>
<p>相関は外れ得ます。同じ起動から1分以内に、同じディレクトリで2つの Codex セッションが始まれば、両方が候補に見え、たとえもう一方が本当の子でも、最も早いものが勝ちます。60秒の窓とディレクトリ照合はこれを稀にしますが、不可能にはしません。クラッシュしたエージェントと承認待ちのエージェントは、似たログ末尾を残し得ます。だから状態は保証ではなく注記を携えます。Gemini は起動コマンドとして検出されますが、セッションへ相関しません。照合先の Gemini プロバイダーを AgentBar がまだ持たないためです。起動は記録され、辺は記録されません。</p>
<p>そして全体像は、材料となるファイルの新しさを超えることはできません。AgentBar が見るのはエージェントがディスクへ書き出したものまでで、ライブのプロセスの真実ではありません。1秒前に終わった Run でも、終端レコードをまだ書いていなければ、まだ動いているように見えます。</p>
<p>このどれも、描画に隠れていません。推定辺は破線。推定状態は注記付き。グラフ上の純粋関数である Analysis ペインは、プロバイダー別のトークン・推定コスト・キャッシュヒット率・Run 数に加え、グラフの健全性を報告します。深すぎる連鎖を警告する最大深度、孤児 Run、辺数、そしてボトルネックとして最長 Run。見たものを記述し、推定した場所に旗を立てます。</p>
<p>トレースは収集されたことがありません。エージェントが、自分の領収書を誰かがグラフへ組み立てるとは知らずに、1行の JSONL ずつ残していったものです。AgentBar の仕事は、その領収書を注意深く読み、証拠が支える場所だけで接続し、推定せざるを得なかった場所を率直に言うこと。あなたが欲しかった因果の鎖は、ディスクの上にあります。そのどれだけが推定かという正直さも、同じくディスクの上にあります。</p>
]]></content:encoded>
		</item>
	</channel>
</rss>
