agentic-ledger について
Agentic Ledgerは、AIエージェントの実行状況を観測するローカル優先のプロキシです。活動やコストを調べたい開発者やチーム向けに、リクエストとレスポンスを記録し、ダッシュボードとAPIでセッション、ループ、費用、再生を確認できます。
主な機能
- 01プロキシ経由でリクエストと応答を記録
- 02セッション、費用、ループ実行を追跡
- 03トレース、フロー、呼び出し詳細を確認
- 04記録した実行を別モデルで再生
- 05実行の上限を設定して追加呼び出しを遮断
活用シーン
- 01エージェント実行の呼び出しやプロンプトを調査
- 02モデル選択ごとに記録済み実行を比較
- 03エージェントループの支出上限を設定
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Agentic Ledger
AI エージェントのランタイム可観測性を実現します。エージェントが何をしたのか、なぜそうしたのか、そしていくらかかったのかを正確に確認できます。
ウェブサイト: agentic-ledger.dev
数値はプロバイダーの請求額と一致することを想定しています。一致しない場合は、ぜひお知らせください。
あらゆるエージェントフレームワーク、あらゆる LLM プロバイダー、あらゆるモデルゲートウェイで動作します。コードの変更は不要です。エージェントの接続先をプロキシにするだけで、すべてが自動的に記録されます。
仕組み
Agentic Ledger は、エージェントと LLM プロバイダーの間で透過的なプロキシとして動作します。すべてのリクエストとレスポンスを傍受して action_id を割り当て、保存した後、上流からのレスポンスを変更せずに返します。エージェントがプロキシの存在を知ることはありません。図解とコントリビューター向けのモジュールマップを含む全体像は、
ARCHITECTURE.mdを参照してください。
Your Agent → Agentic Ledger Proxy → OpenAI / Anthropic / LiteLLM / any LLM
↓
SQLite or Postgres
↓
Live Dashboard + API
クイックスタート
ステップ 1 - プロキシを起動する
Helicone や LangSmith から移行しますか?移行ページに、2 行でできる移行方法があります。Headroom のようなコンテキストコンプレッサーを実行していますか?連携して使用できます。
コマンドは 2 つ、設定不要、ターミナルを占有しません。
uv tool install agentic-ledger # or: pipx install agentic-ledger, or pip install -U agentic-ledger
agenticledger start # runs in the background; terminal freed
ツール管理のインストール(uv tool / pipx)では、専用の隔離環境と PATH 上で明確に判別できる shim が用意されるため、別の Python のコピーによるシャドーイングがまれになり、doctor で検出できます。また、agenticledger upgrade の意味が常に一意になります。通常の pip も使えます。マシンに複数のインストールが共存するようになった場合は、agenticledger doctor --fix で整理できます。
agenticledger start はダッシュボードの URL を表示して、ターミナルを解放します。ウィンドウを閉じても停止しません。agenticledger status で起動状態と正常性を確認でき、agenticledger logs で動作内容を確認でき、agenticledger stop で停止できます。それでも設定ファイルが必要ですか?agenticledger init を実行すると、コメント付きの設定ファイルが作成されます。設定内容については設定を参照してください。
Docker を使う場合(Python は不要):
docker run -p 8000:8000 \
-e AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com \ # optional: omit to route by call format
-v $(pwd)/data:/data \
ghcr.io/shekharbhardwaj/agentic-ledger:latest
イメージはマルチアーキテクチャ(amd64/arm64)に対応し、root 以外のユーザーとして実行されます。また、すべてのリリースは Sigstore で署名され、SBOM が付属します。共有環境へのデプロイを強化する場合(TLS、認証キー、秘匿化、検証)は、 デプロイガイドを参照してください。 Anthropic / Claude をお使いですか? 設定は不要です。上流が設定されていない場合、プロキシはワイヤ形式に基づいて各呼び出しをルーティングするため、Anthropic 形式の呼び出しは Anthropic に、OpenAI 形式の呼び出しは OpenAI に送られ、1 つのプロキシを通じて両方を利用できます。明示的な
upstream_url(LiteLLM や OpenRouter などのゲートウェイ、LM Studio、または固定したプロバイダー)を設定すると、不一致のヒントも含め、従来の 1 つのプロキシにつき 1 つのプロバイダーという動作に切り替わります。
または docker compose を使用します(デフォルトは SQLite です。docker-compose.yml を参照):
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com docker compose up
Postgres の場合は、オーバーライドを重ねてください。DSN が置き換えられ、データベースサービスが追加されます。また、イメージにはドライバーが含まれています:
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up
uv を使用する場合:
uv add agentic-ledger
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com uv run python -m agenticledger.proxy
pip を使用する場合:
python -m venv venv && source venv/bin/activate
pip install -U agentic-ledger
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com ./venv/bin/python -m agenticledger.proxy
Postgres をお使いですか? 追加機能をインストールし、
AGENTICLEDGER_DSNを設定してください:pip install "agentic-ledger[postgres]" AGENTICLEDGER_DSN=postgresql://user:password@localhost/agenticledger注:Docker イメージで使用できるのは SQLite のみです。Docker で Postgres を使う場合は、代わりに
pipでインストールしてください。
OpenTelemetry をお使いですか? 追加機能をインストールし、
AGENTICLEDGER_OTEL_ENDPOINTを設定してください:pip install "agentic-ledger[otel]" AGENTICLEDGER_OTEL_ENDPOINT=http://localhost:4318
プロキシは http://localhost:8000 で起動します。agenticledger start で起動した場合、トレースは ~/.agenticledger/agenticledger.db に保存されます(バックグラウンドサービス用のホームディレクトリは、起動した場所にかかわらず共通です)。フォアグラウンドで実行した場合(agenticledger serve / python -m agenticledger.proxy)、トレースは現在のフォルダーにある agenticledger.db に保存されます。Docker では /data/agenticledger.db に保存されます。
ステップ 2 - エージェントをプロキシに接続する
Claude Code、BMAD、または OpenClaw の場合、コマンド 1 つで設定を書き込めます (バックアップ、マージ、Docker 対応):
agenticledger connect claude-code # or: bmad, openclaw
それ以外の場合は、2 か所を変更します。base_url をプロキシに設定し、呼び出しを 1 つの実行にまとめるためのセッション ID ヘッダーを追加します。API キー、モデル、メッセージなど、ほかの設定はすべてそのままです。
OpenAI:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1", # ← proxy
api_key="your-openai-key",
default_headers={"x-agenticledger-session-id": "run-1"},
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Research the top 3 AI trends in 2026"}],
)
Anthropic(上流の設定は不要です。/v1/messages の呼び出しは自動的に Anthropic にルーティングされます):
import anthropic
client = anthropic.Anthropic(
base_url="http://localhost:8000", # ← proxy
api_key="your-anthropic-key",
default_headers={"x-agenticledger-session-id": "run-1"},
)
Azure OpenAI: AzureOpenAI(azure_endpoint="http://localhost:8000") を使用して台帳に接続し、リソースを上流として設定してください。デプロイメントの料金は、応答で指定されたモデルに基づいて計算されます。Azure ガイドを参照してください。
AWS Bedrock: agentic-ledger[bedrock] をインストールし、標準の認証情報チェーンを通じて台帳に AWS 認証情報を渡してから、boto3(endpoint_url)または Claude Code(ANTHROPIC_BEDROCK_BASE_URL)を台帳に接続してください。台帳が各呼び出しを自ら再署名します。InvokeModel と最新の Converse/ConverseStream API の両方に対応しています。Bedrock ガイドを参照してください。
LiteLLM / OpenRouter / 任意のゲートウェイ:
# Point Agentic Ledger at your gateway
AGENTICLEDGER_UPSTREAM_URL=http://localhost:4000 uv run python -m agenticledger.proxy
# Then point your agent at Agentic Ledger
client = OpenAI(base_url="http://localhost:8000/v1", ...)
ステップ 3 - ダッシュボードを開く
http://localhost:8000
呼び出しが届くと、Web アプリは WebSocket 経由でリアルタイムに更新されます。再読み込みは不要です。
- Webサイトに合わせたデザイン - ダッシュボードは、agentic-ledger.dev のチャコールカラーのサーフェス、アイスブルーのアクセント、幾何学的なアライグマのマーク、タイポグラフィを採用しています。セッション概要には、記録されたコスト、呼び出し回数、トークン合計、呼び出しごとのコストグラフが追加されています。Loop Lens では、反復ごとのコストと「不在中の出来事」タイムラインを並べて表示します。不明な呼び出し価格は明示され、すべてのグラフは記録済みの台帳データを使います。Calls、Flow、Trace、リプレイ、予算管理、ライト/ダーク表示も引き続き利用できます。
- Loop Lens - すべてのループ実行について、観測されたステータス(実行中/フラグ付き/完了を宣言/終了/呼び出しをブロック)、オープンな指標ストリップ(記録済み支出、正直な計上状況を示すトラック付きの実行上限、モデル呼び出し回数)、Overview/Activity/Cache ビュー、証拠へ直接移動できる記録済みイベントのタイムライン、実行中のループによる以降の呼び出しをその場で拒否する Block calls アクション(再び許可するには Allow calls again を使います。ブロックされたエージェント自身では解除できません)、反復ごとの内訳、すべてのフラグについての平易な説明を確認できます。⇆ で任意の2つの実行を選ぶと、並べて差分を比較できます。まず アナトミーリプレイ が表示されます(記録された呼び出しを1つずつ再生し、モデルが読んだ内容までコンテキストの積み重なりを表示し、モデルのアクションがツールへ送られ、結果が会話に戻る様子、または次の呼び出しが新たに始まるときに破棄される様子を、両方の実行を同じ尺度で表示します)。続いて、コスト、反復回数、呼び出し回数、キャッシュ読み取り、フラグ、所要時間を符号付きの差分とともに表示し、実行間でシステムプロンプトと冒頭の指示が正確にどのように変わったかを示す プロンプトのドリフト 差分も表示します。
examples/loop-anatomy/には、2つの進め方を紹介できるよう、同じタスクで実行した Ralph ループと ReAct ループが記録されています。 - セッション - ひと目で確認できるフラットな行と、3つのビューがあります。呼び出し行(時刻、モデル、ステータス、レイテンシ、コスト)を展開すると、4つのタブを持つインスペクター(Response、Tools、Prompt、Raw)が開きます。Flow はエージェント間のハンドオフを示す DAG、Trace はループエンジンから取得した実際の親リンク付きウォーターフォールです。行には、チームバッジ、実際の失敗を示す赤、意図的な拒否を示すアンバー、リプレイを示す紫、各セッションをそのループにリンクする実行チップが表示され、どのチームのものかすぐにわかります。
- 実行全体をリプレイ - モデルの切り替えを決める問いは「1回の呼び出しにどう対応したか?」ではなく、「自分のループは最後まで動いただろうか?」です。実行またはセッションを選び、リプレイ先を選択すると(ローカルモデルは無料です)、各ステップが元の入力で再実行されます。必要なのは宿題ではなく、評価レポートです。「40の場面中34で一致」、失敗した場面(「ツールを見失った」など)、両方のコストが表示されます。各ステップは記録された実際の場面をそのまま正直にリプレイします。最初のステップの後は、別のモデルなら会話の進め方も変わっていたはずなので、台帳が比較するのは物語ではなく場面です。
- ポケットの中でも -
agenticledger shareを実行すると、自分が所有する HTTPS トンネルが開き(cloudflared 経由、アカウント不要)、ペアリングリンクが表示され、ターミナルに QR コードが描画されます。スマートフォンのカメラをかざせば、ダッシュボードを手元で使えます。キルスイッチ、すべての呼び出しの停止、上限管理も利用できます。同一ネットワーク用のリンクには--wifi、すべてのデバイスのペアリング解除には--rotateを指定するか、ダッシュボードの ⚿ パネルで Pair a device を押します。ローカルマシンではキーは不要です。それ以外の接続先には、自動生成されたペアリングキーが適用されます。ダッシュボードはスマートフォンに合わせてあり、一度に1つのペインを表示し、戻るボタンと実行間を切り替える前/次の矢印を備えています。 - 全エージェント共通の遮断措置 - Stop all calls は、すべてのエージェントを一度に停止する緊急停止機能です。Loop Lens に確認付きのボタンがあり、有効な間はすべてのページにバナーが表示され、解除されるまで再起動後も状態が維持されます。モデルやプロバイダーの許可リストと拒否リスト(
AGENTICLEDGER_ALLOW_MODELS、AGENTICLEDGER_DENY_PROVIDERSなど。glob も使用できます)を設定すると、許可されていないモデルはルール名とともに拒否されます。チームカードには独自のリストを設定でき、対象を全体の設定より絞り込むことのみ可能です。拒否はすべて記録されます。レート制限、ループガード、予算、上限、キルスイッチ、全呼び出しの停止は、理由付きのアンバー色のblocked:行として記録され、Reports と/metricsに集計されます。ループのブロックはダッシュボードのセッションから解除でき、再起動は不要です。台帳が行うのは呼び出しの拒否または記録だけです。呼び出しを書き換えたり、別の経路へ振り分けたり、代替したりすることはありません。 - キャッシュ監査 - 各実行で「繰り返しのテキストに定価を払っていたか?」を確認できます。受けた割引はプロバイダー独自のキャッシュレポートから正確に取得し、見逃した節約額はラベル付きの推定値として計算方法とともに表示されます。各判定には理由と、1行で読める改善策が付いています。「見逃したものはありません。問題ありません」という結果も表示されます。
GET /api/runs/{id}/cache-auditからも利用できます。 - 自分好みに - ダーク、ライト、またはシステムに合わせた表示(ブラウザー内だけで保持される設定)と、調査結果を保持する URL を利用できます。実行、セッション、個々の呼び出しへのディープリンク(
#/sessions/<id>/calls/<action_id>を開くと、その呼び出しを展開した状態でセッションが表示されます)、動作する戻る/進む操作を備え、通常のリンクに認証情報が含まれることはありません。リストには最新の50件が読み込まれ、ボタンを1回押すごとに古い項目が追加されます。フィルターは全履歴に適用され、各サイドバーの件数には実際の合計が表示されます。 - 名前付きインスタンス -
agenticledger start --name demo --port 8003を実行すると、普段使う台帳と並行して2つ目の台帳が起動します。独自の状態とデータベースを持ち、ダッシュボードにはアンバー色の名前チップが表示されるため、本番用と取り違えることはありません。stop、status、logs、share、runはすべて--nameを指定できます。 - 支出メーター - 実行の詳細では、支出額がリアルタイムで表示されます。現在までの支出、消費ペース(ドル/時)、「このペースでは午前8:00までに$Y」が確認できます。任意の実行に コスト上限 を設定すると、支出が上限に達した瞬間にプロキシが以降の呼び出しを拒否します(アンバー表示、費用は発生しません)。上限を引き上げるか解除するまで拒否は続きます。上限は再起動後も維持され、自動検出されたループにも適用されます。80%に達すると Webhook アラートが送信されます。
- 名前、ピン留め、プロジェクト、アイコン -
cc-73a26366ではなく「夜間の認証修正」のような名前を付け、重要な項目を ★ で上部にピン留めし、プロジェクトごとに作業を整理できます。Sessions ビューはセクション表示になり、各プロジェクトの見出しの下にセッションが並び、最後に未分類の項目が表示されます。プロジェクトに分類された実行では、そのセッションも同じプロジェクトに分類されます。✎ エディターのピッカーでループまたはセッションにアイコンと色を設定すると、ひと目で見分けられます。 - 設定 - ⚙ では、プロキシが実際に使用している設定を確認できます。適用中の設定ファイル、アップストリーム、予算、リプレイ先が表示され、各項目には file/env/default のラベルが付きます。シークレットは非表示になります。設定ファイルで変更できる各項目には Change リンクがあります。新しい値を選択または入力すると設定ファイルに書き込まれ、ダッシュボード上で Restart now を1回押すと、すべての変更が適用されます(台帳はその場で自分自身を再実行します)。環境変数で設定された項目にはその旨が表示されます。常に環境変数の設定が優先されるためです。
- リプレイと仮定分析 - 任意の呼び出しを開いて ↻ Replay を押すと、リプレイ先を選択できます(パネルにはローカルサーバーで実際に読み込まれているものが表示されます)。記録されたプロンプトがそのまま再実行され、同じプロバイダー、別のプロバイダー、または LM Studio 経由の無料ローカルモデル を選べます。ツール呼び出し、スキーマ、システムプロンプトは、Anthropic と OpenAI のワイヤーフォーマット間で自動的に変換されます。呼び出しが自分で設定した予算によってブロックされている場合でも動作します。遮断措置に拒否されても、何が起きたかを $0 で確認できます。リプレイから元の呼び出しには ↩ Open original で戻れます。仮定分析 ボックスでは、まずより手軽なコスト比較に答えます。API 呼び出しは一切行わず、純粋な計算で、任意の実行またはセッションを別のモデルの料金で再計算します。(
AGENTICLEDGER_REPLAY_API_KEYやプロバイダーごとのAGENTICLEDGER_REPLAY_*_KEYのリプレイ先を設定してください。) - レポート - 費用の行き先を確認できます。日ごとの支出、モデルの内訳と レイテンシ p50/p95/p99、エージェントごとの合計、各チームの支出をカードの日次上限と照らし合わせる チーム別テーブル(「どのチームが予算を使い切ったか?」がひと目でわかります)、キャッシュによる節約額(プロンプトキャッシュを使った通信に入力トークンの通常料金を適用した場合のコストと、実際のコストの比較)を確認できます。エラーとブロックは、どこでも別々に集計されます。赤=問題が発生、アンバー=台帳が意図的に拒否。遮断措置が正常に機能していても、エージェントが異常に見えることはありません。
- 検索 - プロンプト、出力、エージェント名、ユーザー ID を対象に、すべてのセッションを全文検索できます。
設定
agenticledger init は、すべてのオプションがコメントアウトされた agenticledger.toml を書き込みます。必要な項目のコメントを解除してください。設定が正しく動作している場合は、次のようになります。
[proxy]
port = 8000
upstream_url = "https://api.anthropic.com"
db = "sqlite:///agenticledger.db"
[keys]
# Prefer *_file: the file's contents are the key, so no secret lives in
# this file or your shell history (chmod 600 the key file).
api_key_file = "~/.agenticledger/api.key" # dashboard/admin access
ingest_key_file = "~/.agenticledger/ingest.key" # closes the open relay
[budgets]
daily = 25.0 # whole-ledger daily ceiling, USD
session = 5.0 # per-session ceiling
[replay]
# Free local replay via LM Studio (any key works there):
openai_url = "http://localhost:1234"
openai_key = "lm-studio"
3つのルール:
- ファイルは次の順序で検索されます:
AGENTICLEDGER_CONFIG、次に./agenticledger.toml(起動したフォルダー)、最後に~/.agenticledger/config.tomlです。最初に見つかったファイルが使われます。起動時のバナーに有効なファイルが表示されます。 - コマンドで入力した内容は、ファイルの設定より優先されます。 環境変数は設定ごとに上書きします(
AGENTICLEDGER_PORT=9000 agenticledger startは、ファイルに触れずにその実行時のポートとして 9000 を使用します)。そのため、環境変数で設定された Docker や CI の設定にも影響しません。 - 変更は再起動後に反映されます(
agenticledger stopの後にstartを実行します)。
以下の環境変数リファレンスに記載されている設定はすべて、設定ファイル内に対応する項目があります。[env] セクションを使うと、その他の AGENTICLEDGER_* 変数をそのまま渡せます。
プロバイダーの設定手順
以下のすべてのプロバイダーは、同じプロキシを経由します。変更するのは、接続先として指定するベース URL だけです。各手順では、プロキシが起動していること(agenticledger start)を前提とし、同じ方法で確認します。1回リクエストを実行し、http://localhost:8000 を開いて、Sessions に表示されることを確認してください。
OpenAI(および OpenAI 互換 API)
- クライアントがプロキシを参照するように設定します:
export OPENAI_BASE_URL=http://localhost:8000/v1 OPENAI_API_KEYはこれまでとまったく同じ状態にしておきます。プロキシは認証ヘッダーを変更せずにそのまま渡します。- リクエストを実行します。Sessions に O マーク付きで表示されます。
Anthropic
- クライアントがプロキシを参照するように設定します:
export ANTHROPIC_BASE_URL=http://localhost:8000 ANTHROPIC_API_KEYはこれまでと同じ状態にしておきます。- リクエストを実行します。A マーク付きで表示されます。上流の設定は不要です。プロキシは、ワイヤーフォーマットに基づいて Anthropic 形式のリクエストを Anthropic にルーティングします。
AWS Bedrock(直接キャプチャ)
- 標準の認証情報チェーン(環境変数、
~/.awsプロファイル、またはインスタンスロール)を通じて、Bedrock のbedrock:InvokeModelおよびbedrock:InvokeModelWithResponseStreamにスコープを限定した AWS 認証情報を台帳に付与します。次に、追加機能をインストールして再起動します:pip install "agentic-ledger[bedrock]" agenticledger stop && agenticledger start - ⚙ Settings パネルを確認します。Bedrock の行に「signing as the ledger in 」と表示されているはずです。
- クライアントがプロキシを参照するように設定します。Claude Code の場合:
boto3 の場合:export CLAUDE_CODE_USE_BEDROCK=1 export ANTHROPIC_BEDROCK_BASE_URL=http://localhost:8000boto3.client("bedrock-runtime", endpoint_url="http://localhost:8000")。 - リクエストを実行します。オレンジ色の B マーク付きで表示されます。台帳は呼び出し元の ID を取り除き、自身の認証情報で署名し直します。詳しい手順: docs/integrations/bedrock.md。
会社のゲートウェイ経由の AWS Bedrock
多くの企業では、認証を独自に処理するゲートウェイを Bedrock の前段に配置しています。その場合、通常は管理対象の設定ファイルで、CLAUDE_CODE_SKIP_BEDROCK_AUTH=1 を設定し、ANTHROPIC_BEDROCK_BASE_URL にゲートウェイを指定して Claude Code を設定します。台帳はそのゲートウェイの前段に置かれ、ヘッダーを含めて、エージェントが送信した各リクエストをそのまま転送します。署名は行わず、こちら側で AWS 認証情報を用意する必要もありません。
- ゲートウェイの場所を台帳に伝えます(以前
ANTHROPIC_BEDROCK_BASE_URLが指定していたホストです):agenticledger config set proxy.bedrock_gateway_url https://bedrock-gateway.company.example agenticledger stop && agenticledger start - 代わりに Claude Code が台帳を参照するように設定します:
ANTHROPIC_BEDROCK_BASE_URL=http://localhost:8000。この値が IT 管理の設定ファイル(/Library/Application Support/ClaudeCode/managed-settings.json)にある場合は、ほかのすべての設定より優先されるため、IT 部門による変更が必要です。~/.claude/settings.jsonにある場合は、そこで編集してください。 /healthと ⚙ Settings パネルには、「forwarding as sent to the gateway at ...」と表示されます。リクエストは Bedrock マークと、リージョンがプレフィックスとして付いたモデル ID とともに表示されます。
Azure OpenAI
- アップストリームを使用するリソースに設定します:
agenticledger config set proxy.upstream_url https://<resource>.openai.azure.com agenticledger stop && agenticledger start - クライアントの Azure エンドポイントを
http://localhost:8000に設定し、api-keyヘッダーはそのままにします。 - 呼び出しには
azure-openaiのタグが付き、RESPONSE に記載されたモデルに基づいて 料金が計算されるため、デプロイメントのエイリアスで実際のモデルを隠すことはできません。詳しいガイド: docs/integrations/azure-openai.md。
ローカルモデル(LM Studio、OpenAI API を使用する Ollama)
- アップストリームをローカルサーバーに設定します:
agenticledger config set proxy.upstream_url http://localhost:1234 agenticledger stop && agenticledger start - エージェントで
export OPENAI_BASE_URL=http://localhost:8000/v1を実行します。 - 呼び出しには紫色のマークが付き、コストは 0 ドルと表示されます。詳しいガイド: docs/integrations/lm-studio.md。
ゲートウェイ(OpenRouter、LiteLLM)
- アップストリームをゲートウェイに設定します:
agenticledger config set proxy.upstream_url https://openrouter.ai/api agenticledger stop && agenticledger start export OPENAI_BASE_URL=http://localhost:8000/v1を実行し、ゲートウェイの キーはそのままにします。- ゲートウェイのプレフィックスが付いたモデル ID(「anthropic/claude-...」)は、 部分文字列マッチングによって正しく料金が計算されます。ガイド:openrouter.md、 litellm.md。
CrewAI、LangGraph、AutoGen、Vercel AI SDK、pydantic-ai など、フレームワーク別のレシピは docs/integrations/ にあります。
コーディングエージェント - Claude Code、Ralph ループなど
Claude Code(およびほとんどのコーディングエージェント)は、環境変数を 1 つ設定するだけでプロキシを利用できます。ヘッダーもコードの変更も不要です。
agenticledger start
export ANTHROPIC_BASE_URL=http://localhost:8000
claude
上流の設定は不要です。呼び出しはワイヤ形式に一致するプロバイダーにルーティングされます。
Agentic Ledger は Claude Code のトラフィックを自動的に識別します。すべての呼び出しに framework=claude-code のタグが付けられ、区別のない 1 つの集計枠にまとめられるのではなく、各 Claude Code セッションが実際のセッション UUID(claude --resume に表示されるものと同じ ID)で表示されます。また、プロンプトキャッシュの読み書きが正確に記録され、料金も正しく計算されます。コーディングエージェントの実際の費用の大部分を占めるのは、キャッシュのトラフィックです。
ループを任意の名前で記録したい場合は、いつものコマンドの前に単語を 1 つ追加します。
agenticledger run nightly-digest -- python agent.py
コマンドはこれまでどおり実行され、LLM 呼び出しは nightly-digest という名前の実行タイルに記録されます。起動のたびに次のイテレーションとしてカウントされるため、翌日の実行も同じタイルに追加されます。エージェントのコードを変更する必要はありません。開始時にダッシュボードのプロジェクトに実行を記録するには、--project acme を追加します。
夜通しループを実行していますか(Ralph 形式の while :; do cat PROMPT.md | claude -p; done)?ループ用のフラグを付けて同じコマンドを実行すると、イテレーションごとにコマンドが再実行され、すべての呼び出しが実行に関連付けられ(ベース URL 経由のため、ヘッダーは不要です)、完了の合図、予算の上限、またはイテレーション数の上限に達すると停止します。
AGENTICLEDGER_UPSTREAM_URL=https://api.anthropic.com \
AGENTICLEDGER_COMPLETION_PROMISE="ALL TASKS COMPLETE" \
uv run python -m agenticledger.proxy
agenticledger run overnight --max-iterations 50 --budget 25 -- \
claude -p "$(cat PROMPT.md)" --dangerously-skip-permissions
各イテレーションは /api/runs に「実行のイテレーション N」として表示されます。エージェントが応答で完了の合図を出力すると、実行ステータスが complete に変わり、費用とトークン数の要約を表示してループが終了します。run の後に続く単語が実行名です。名前を指定しない場合、実行名にはフォルダー名と時刻(myproject-0819-1936)が使われます。同じ名前で再実行すると、1 からやり直すのではなく、イテレーション数が引き継がれます。既存のループスクリプトもそのまま使えます。自分で GET /api/runs/{run_id} をポーリングするか、暴走したループを強制停止するためにプロキシの予算設定(AGENTICLEDGER_BUDGET_DAILY=25.00)を利用できます。
プロンプトを調整していますか?再実行して Loop Lens の ⇆ 比較を使うと、2 つの実行の費用、イテレーション数、呼び出し数、フラグを並べて比較できます。「新しいプロンプトで本当に改善したか」を感覚ではなく数値で確認できます。
同じ方法は、ベース URL を上書きできるすべてのクライアント(Codex CLI、opencode、OpenClaw、LiteLLM ベースのスタック)で使えます。OpenAI/Anthropic のベース URL をプロキシに設定するとトラフィックが記録されます。明示的に関連付けたい場合は、x-agenticledger-* ヘッダーを追加してください。
OTel ネイティブのツール(Gemini CLI、Codex [otel]、AutoGen/AG2、Pydantic AI、Vercel AI SDK)にはプロキシは不要です。OTLP エクスポーターを台帳に設定すると、GenAI スパンが直接取り込まれます。
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8000
どちらの OTLP/HTTP エンコーディングも利用できます。JSON は常に利用でき、protobuf は [otel] エクストラのインストール時に利用できます(Docker イメージには含まれています)。gRPC エクスポーターは HTTP に切り替えてください:OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf。
フレームワークガイド - 各連携のガイドを docs/integrations に用意しています:Claude Code、Codex CLI、opencode、OpenClaw、BMAD-METHOD、LangGraph/LangChain、CrewAI、OpenAI Agents SDK、Gemini CLI、AutoGen/AG2、Pydantic AI、Vercel AI SDK、LiteLLM、OpenRouter、LM Studio(完全オフライン:ローカルモデル、ローカル台帳)。
本番環境へのデプロイ - TLS 終端、認証キー、秘匿化、イメージ署名/SBOM の検証、エンタープライズミラー、スケーリングのガイダンスについては、docs/deployment.md をご覧ください。
数値
公称値ではなく、実測値です。python scripts/loadtest.py --calls 2000 --seed 1000000 で再現できます(Apple MシリーズのMacBook、SQLiteバックエンド。プロバイダーアダプターアーキテクチャを導入した0.10でも再測定済み。同じ数値で、どちらも毎秒2,580~2,800回の呼び出しです)。
| 項目 | 結果 |
|---|---|
| 継続的なキャプチャ処理量 | プロキシ経由で毎秒2,886回の呼び出し |
| 1回の呼び出しあたりの追加レイテンシー | 10ms p50 · 12ms p95 |
| ストアへの直接書き込み | 毎秒約38,000件の保存 |
| 100万回の呼び出しに必要なディスク容量 | 271 MB |
| 100万回の呼び出しがあるセッションを開く時間 | 2 ms |
| 100万回の呼び出しがある場合のセッション一覧表示 | 335 ms |
| 100万回の呼び出しがある場合の30日間レポート | 719 ms |
正直にお伝えする注意点:セッション一覧は読み込みのたびにすべてのセッションを集計するため、履歴全体の増加に伴って処理時間が伸びます。一方、レポート期間にはタイムスタンプインデックスを使うため、テーブル全体ではなく期間内のトラフィック量に応じて処理時間が伸びます。エージェントのプロバイダーレイテンシー(呼び出しあたり数百ms)は、プロキシのオーバーヘッドを桁違いに上回ります。Postgresの数値はサーバーによって異なりますが、同じスクリプトで--dsnを指定して測定できます。コスト計算には独自のガードレールと、プロバイダーのコンソールとの5分間のパリティチェックがあります。詳しくはdocs/accuracy.mdをご覧ください。
キャプチャされる内容
すべてのLLM呼び出しは、次の情報とともに保存されます。
| フィールド | 含まれる内容 |
|---|---|
action_id | インターセプト時に割り当てられるUUID |
session_id | 実行のグループ化情報(ヘッダーから取得) |
timestamp | 呼び出しが行われた時刻 |
model_id | 使用されたモデル |
provider | openaiまたはanthropic |
messages | モデルに送信されたメッセージ履歴全体 |
system_prompt | 抽出されたシステムプロンプト |
tools | モデルが利用できるツールの定義 |
tool_calls | モデルが呼び出すことを決定したツール |
tool_results | ツールが返した内容(次の呼び出しのメッセージから取得) |
content | モデルのテキスト出力 |
stop_reason | モデルが停止した理由 |
tokens_in / tokens_out | トークン使用量 |
cache_read_tokens / cache_write_tokens | プロンプトキャッシュの使用量。読み取りと書き込みはプロバイダーごとに正しく価格計算されます |
thinking | 拡張思考の出力(Anthropic)。contentとは別にキャプチャされます |
cost_usd | モデルの価格に基づく推定コスト |
latency_ms | エンドツーエンドの応答時間 |
status_code | アップストリームからのHTTPステータス。エラーもキャプチャされます |
error_detail | 200以外の応答に対するアップストリームのエラーメッセージ |
agent_name | x-agenticledger-agent-nameから取得。指定がない場合は自動検出(例:claude-code)、それもできない場合はOpenRouterのX-Titleから取得し、最後にエージェント自身の指示のフィンガープリントに基づくunnamed-<fingerprint>を使用します。ヘッダーのないエージェントも区別できます |
framework | x-agenticledger-frameworkヘッダーから取得するか、フィンガープリントから検出(例:claude-code、gemini-cli、litellm) |
user_id | x-agenticledger-user-idヘッダーから取得 |
app_id | x-agenticledger-app-idヘッダーから取得 |
environment | x-agenticledger-environmentヘッダーから取得 |
parent_action_id | ネストされたエージェントグラフにおける親呼び出し |
handoff_from / handoff_to | Flow DAGにおけるエージェントの引き継ぎ追跡 |
モデル呼び出しに加えて、セッションにはエージェント自身の実行記録を含めることができます。agenticledger connect claude-code --hooksを実行すると、エージェントが自身のマシンで行った操作(入力、出力、所要時間を含むツールの実行、許可の要求または拒否、サブエージェント、コンパクション、セッションの開始と終了)を/v1/hooks/claude-codeに送信するClaude Codeフックがインストールされます。この記録はセッションのアクティビティタブに表示され、管理ゲートウェイ経由でも動作し、エージェントの制御には一切使用されません。
APIリファレンス
| メソッド | エンドポイント | 説明 |
|---|---|---|
GET | /health | 生存確認 - {"status":"ok","version":"..."}。認証不要で、ストアにはアクセスしません。 |
GET | /readyz | 準備状態の確認 - ストアに ping を送信します。接続できない場合は 503 を返します。capture_dropped も報告します。 |
GET | /metrics | Prometheus メトリクス(永続化/破棄されたキャプチャ数、キューの深さ)。 |
GET | /api/audit | 機密性の高い操作の監査証跡。ハッシュチェーンで連結され、新しい順に表示されます。action、actor、target、since、until で絞り込み、before_seq でページ分割できます(管理者)。 |
GET | /api/audit/verify | 監査ハッシュチェーンをたどり、破損箇所があれば最初の箇所を示します(管理者)。 |
DELETE | /api/users/{user_id} | 消去権:ユーザーのキャプチャ済み呼び出しをすべて削除します(管理者)。 |
GET | / | ライブダッシュボード |
WS | /ws | WebSocket ストリーム - ライブダッシュボードの更新に使用します |
GET | /api/sessions | 集計統計付きのセッションを新しい順に表示します。limit(1~500、デフォルトは50)とoffsetでページ分割し、project(名前、__starred__、またはrun:<id>)、run_id、model、since、until(ISO形式、最終呼び出し時刻)、q(ID、ラベル、またはエージェント)で絞り込めます。X-Total-CountとX-Next-Offsetヘッダーで、残りの件数を確認できます。 |
GET | /api/runs | ループ実行(明示指定または自動推定)を、反復回数、コスト、ステータス、フラグ付き呼び出し数とともに新しい順に表示します。ページ分割とヘッダーは同じです。project、status(running、flagged、complete、ended、stopped)、model、since、until、q(IDまたはラベル)で絞り込めます。 |
GET | /api/runs/{run_id} | 1つの実行のステータス(running / flagged / complete / ended / stopped)を返します - ループスクリプトからポーリングしてください |
POST | /api/stop | すべての呼び出しを停止します。これは全体に適用される緊急停止です。LLM の呼び出しはリプレイも含めてすべてその場で拒否され、解除されるまで記録されます。再起動後も維持されます(エディター)。DELETEで解除し、GETで実行者と開始時刻を確認できます。 |
GET | /api/sessions/{session_id}/tools | 推定されたツール実行 - 各ツール呼び出しを結果、レイテンシ、エラーステータスと組み合わせて表示します |
GET | /api/sessions/{session_id}/loop-block | ループのサーキットブレーカーがセッションを停止しているかどうかと、その理由を返します。DELETEで再起動せずに解除し、現在の状態からガードを再設定します(エディター)。 |
DELETE | /api/sessions/{session_id} | セッションとそのすべての呼び出しを削除します |
GET | /api/reports?days=30 | 支出の分析情報:日別の推移、モデルの内訳と署名付きキャッシュ節約額、レイテンシのパーセンタイル、エージェント別およびチーム別の合計 |
GET | /api/whatif?model=...&run_id=... | キャプチャ済みトークンを別のモデルで再計算し、実行/セッション/呼び出しの料金を試算します - 単純な計算で、API 呼び出しは発生しません |
POST | /api/tokens | スコープ付き API トークンを発行します。budget_dailyと、独自のallow_models / deny_models / allow_providers / deny_providersリストを持つrole: ingestチームカードも発行できます |
GET | /api/calls/{action_id} | IDで1つの呼び出しを取得します - リプレイの親をたどって元の呼び出しを確認できます |
GET | /api/replay/targets | 設定済みのリプレイ先(ダッシュボードのドロップダウンに表示されます) |
GET | /api/replay/models | リプレイ先で実際に利用できるモデル(?provider=) |
GET | /auth/status | ここでサインインが設定されているか、プロバイダー名、サインインの開始場所を返します。認証不要です。 |
GET | /auth/login | ID プロバイダーのサインインを開始します(特定の場所に戻るには?next=/app#/runsを指定します) |
POST | /auth/logout | このサインインを終了し、Cookie をクリアします |
GET | /api/people | サインインしたすべてのユーザーを、グループによって付与されたロールと現在のサインイン数とともに表示します(管理者) |
POST | /api/people/{id}/signout | 1人のユーザーのすべてのサインインを直ちに終了します(管理者) |
POST | /api/ws/ticket | ヘッダーで送信したキーを使って発行する、ライブ/wsソケット用の1分間有効な使い捨てチケット(閲覧者) |
GET | /api/whoami | 現在保持しているキーの情報を返します。名前、ロール、チーム(チームカードの場合)を確認できます - ダッシュボードの⚿パネルで使用します |
POST | /api/replay/batch | 実行全体またはセッション全体を別のモデルでリプレイします - ジョブ ID を返します |
GET | /api/replay/jobs/{job_id} | バッチ処理の進捗とレポートカード |
PUT | /api/labels/{scope}/{ref_id} | セッション/実行に名前を付ける、ピン留めする、またはプロジェクトに分類します。ピッカーの固定リストからiconとcolorを設定してマークを付けられます(""でどちらもクリアします) |
GET | /api/projects | 使用中のプロジェクト名 |
GET | /api/settings | プロキシの実行設定を返します(管理者。シークレットはマスクされます)。各行には、設定する構成キーと選択肢が含まれます |
GET / PUT | /api/config | 有効な設定ファイルとその値を返します(シークレットはマスクされます)。PUT {key, value}で1つのキーを書き込みます(nullでクリア)。監査記録が残り、再起動後に適用されます(管理者) |
POST | /api/restart | 台帳をその場で再起動し、設定ファイルを再読み込みします(管理者) |
GET | /api/runs/{run_id}/cache-audit | この実行が対象となり、適用されたリピート割引を返します:判定、理由、修正方法、正確な割引額、ラベル付きの推定額 |
POST | /api/redetect | 属性が未設定の履歴に対してフレームワーク検出を再実行します。調査件数、更新件数、フレームワーク別件数を返します |
POST | /api/replay | キャプチャ済みの呼び出しを再実行します。同じプロバイダーを使うか、もう一方のプロバイダー向けに変換できます(modelと任意のproviderを指定)。結果は元の呼び出しにリンクして保存されます |
GET | /api/search?q=... | キャプチャ済みのすべての呼び出しを対象にした全文検索 |
GET | /session/{session_id} | セッション内のすべての呼び出しを時刻順に表示します |
GET | /explain/{action_id} | アクション ID で指定した1つの呼び出し |
GET | /export/{session_id} | SHA-256 整合性ハッシュ付きの JSON コンプライアンスエクスポート |
GET | /export/{session_id}/report | 印刷可能な HTML 監査レポート |
POST | /mcp | MCP ツールサーバー - list_sessions、explain、get_session、search、list_runs、get_run_status |
POST | /v1/traces | OTLP/HTTP JSON 取り込み - OTel ネイティブツールの GenAI スパンを台帳の呼び出しとして記録します(/v1/logsは Claude Code のツールイベントもツール実行時間に取り込みます。/v1/metricsは受信確認のみです) |
| 例: |
# All calls in a session
curl http://localhost:8000/session/run-1
# Search across all sessions
curl "http://localhost:8000/api/search?q=failed+to+connect"
# Download JSON audit trail (includes an integrity tag; keyed HMAC when configured)
curl http://localhost:8000/export/run-1 -o audit-run-1.json
# Printable HTML report - open in browser, print to PDF
open http://localhost:8000/export/run-1/report
MCP サーバー
Agentic Ledger は、キャプチャしたデータを POST /mcp にある MCP(Model Context Protocol)ツールサーバーとして公開します。Claude Desktop、Cursor、または MCP 互換クライアントを接続すると、AI アシスタントからトレースを直接クエリできます。
利用可能なツール:
| ツール | 説明 |
|---|---|
list_sessions | コスト、トークン数、呼び出し回数の概要を含む、最近のセッションを一覧表示します |
explain(action_id) | 1 回の LLM 呼び出しの完全なトレース(プロンプト、ツール呼び出し、出力、トークン数、コスト)を表示します |
get_session(session_id) | セッション内のすべての呼び出しを時系列順に表示します |
search(query) | キャプチャしたすべての呼び出しを対象に全文検索します |
list_runs | イテレーション数、コスト、ステータスとともにループの実行を一覧表示します |
get_run_status(run_id) | 1 回の実行のステータスを表示します。エージェントが自身のループを確認し、続行するかどうかを判断できます |
claude_desktop_config.json で設定します(HTTP、実行中のプロキシに接続):
{
"mcpServers": {
"agenticledger": {
"url": "http://localhost:8000/mcp"
}
}
}
または、stdio サブプロセスとして設定します(サーバーをコマンドとして起動するクライアント向け) (実行中のプロキシは不要です。同じデータベースを読み込みます):
{
"mcpServers": {
"agenticledger": {
"command": "agenticledger",
"args": ["mcp"],
"env": { "AGENTICLEDGER_DSN": "sqlite:////absolute/path/to/agenticledger.db" }
}
}
}
AGENTICLEDGER_API_KEY が設定されている場合は、ヘッダーとして渡します:
{
"mcpServers": {
"agenticledger": {
"url": "http://localhost:8000/mcp",
"headers": { "x-agenticledger-api-key": "your-key" }
}
}
}
接続すると、アシスタントに次のような質問ができます:
- 「前回のセッションで SearchAgent は何をしましたか?」
- 「レート制限エラーに言及したすべての呼び出しを表示してください」
- 「セッション run-abc123 の合計コストはいくらでしたか?」
設定リファレンス
以下のすべての変数は agenticledger.toml にも記述できます。ファイル、検索順序、環境変数が常に優先されるルールについては、
設定を参照してください。
環境変数
コア:
| 変数 | 必須 | デフォルト | 説明 |
|---|---|---|---|
AGENTICLEDGER_TELEMETRY_CALLS | いいえ | (オフ) | Claude Code 自身の api_request テレメトリ(/v1/logs に送信)を、モデル、トークン、キャッシュ、コスト、レイテンシーを含む呼び出しとして記録します。プロンプトは記録しません。管理設定によってプロキシがリクエスト経路から外れているマシン向けです。Claude Code ガイドを参照してください。プロキシが経路上にある場合はオフのままにしてください。 |
AGENTICLEDGER_BEDROCK_GATEWAY_URL | いいえ | (なし) | 会社の Bedrock ゲートウェイです。Bedrock 形式の呼び出しは、ヘッダーも含め、エージェントが送信したとおりに転送されます。Ledger は署名を行わず、AWS 認証情報も必要ありません。 |
AGENTICLEDGER_UPSTREAM_URL | いいえ | (未設定:呼び出し形式に応じてルーティング) | リクエストの転送先となる LLM エンドポイントです。OpenAI、Anthropic、LiteLLM、OpenRouter、または OpenAI 互換の URL を指定できます。省略すると、プロキシはワイヤ形式に応じて各呼び出しをルーティングします。Anthropic 形式の呼び出しは Anthropic に、Bedrock パスは Bedrock に、それ以外はすべて OpenAI に送信されます。 |
AGENTICLEDGER_TLS | いいえ | (オフ) | 1 にすると、ダッシュボード専用の https リスナーが自己生成証明書で追加されます(スマートフォンには警告が一度表示されます)。エージェントポートは通常の http のままです。 |
AGENTICLEDGER_TLS_PORT | いいえ | 8443 | https ダッシュボードリスナーのポートです。 |
AGENTICLEDGER_DSN | いいえ | sqlite:///agenticledger.db(Docker:sqlite:////data/agenticledger.db) | データベースです。ローカル開発では SQLite、本番環境では Postgres URL を使用します。 |
AGENTICLEDGER_HOST | いいえ | 0.0.0.0 | バインドするホストです。ローカルホストのみに制限するには 127.0.0.1 を使用します。 |
AGENTICLEDGER_PORT | いいえ | 8000 | 実行に使用するポートです。 |
AGENTICLEDGER_API_KEY | いいえ | (なし) | マスター管理者キーです。設定すると、ダッシュボード、読み取り、管理エンドポイントで認証が必須になり、このキーに admin ロールが付与され、API トークン(下記)の初期設定が行われます。ローカル開発では省略してください。プロキシをサーバー上で実行する場合に設定します。値は任意です。 |
AGENTICLEDGER_OIDC_ISSUER / _CLIENT_ID / _CLIENT_SECRET | いいえ | (なし) | ID プロバイダーを使ってサインインします(OpenID Connect、PKCE を用いたコードフロー)。ロールは _ROLE_MAP(group=role,...)で決まり、マッピングされていないユーザーは拒否されます。_GROUPS_CLAIM(groups)、_SCOPES、_PROVIDER_NAME は任意です。リダイレクトには AGENTICLEDGER_PUBLIC_URL が使用されます。 |
AGENTICLEDGER_OIDC_SCOPE_MAP | いいえ | (なし) | group=project,...(グループは繰り返し指定できます)。マッピングされたグループに属するユーザーには、Ledger が読み取るあらゆる場所で、該当プロジェクトのみが表示されます。プロジェクトに分類されていない作業は表示されません。マッピングされたグループに属さないユーザーには、スコープ制限は適用されません。 |
AGENTICLEDGER_SESSION_IDLE_HOURS / _MAX_HOURS | いいえ | 12 / 168 | サインインの有効期間です。アイドル時間の上限と絶対的な上限を指定します。 |
AGENTICLEDGER_INGEST_KEY | いいえ | (なし) | 設定すると、一致する x-agenticledger-ingest-key ヘッダーを含むリクエストのみをプロキシが転送し、オープンリレーを防ぎます。デフォルトではオフです。未設定の場合は、起動時に目立つ警告が表示されます。 |
AGENTICLEDGER_REPLAY_API_KEY | いいえ | (なし) | プロキシ自身のアップストリームを通じて同一プロバイダーに再生するためのキーです。プロキシはエージェントの認証情報を保存しないため、再実行には専用のキーが必要です。 |
AGENTICLEDGER_REPLAY_OPENAI_KEY / _URL | いいえ | (なし) / プロバイダー API | プロバイダーをまたいだ再生先です。OpenAI 形式のモデルであれば、あらゆるキャプチャを再生できます。_URL に LM Studio(http://localhost:1234、キーは任意)を指定すれば、キャプチャした Claude の呼び出しをローカルモデルで無料で再生できます。 |
AGENTICLEDGER_REPLAY_ANTHROPIC_KEY / _URL | いいえ | (なし) / プロバイダー API | Claude モデルへの、プロバイダーをまたいだ再生先です。 |
AGENTICLEDGER_*_KEY_FILE | いいえ | (なし) | 上記の各キーは、その _FILE 版で指定されたファイルからも読み取られます。これは Docker secrets パターンであり、キーがシェル履歴に残らないようにします。 |
AGENTICLEDGER_EXPORT_HMAC_KEY | いいえ | (なし) | 設定すると、コンプライアンスエクスポートには通常の sha256 チェックサムではなく、改ざん検知可能な鍵付き hmac-sha256 整合性タグが付与されます。 |
AGENTICLEDGER_EXTRA_PATHS | いいえ | (なし) | キャプチャ対象に追加するリクエストパスを、カンマ区切りで指定します。例:v1/responses,v1/custom。組み込みパス(v1/chat/completions、v1/messages、v1/responses、および無料呼び出しとして記録される v1/messages/count_tokens)は常にキャプチャされます。 |
AGENTICLEDGER_ASYNC_CAPTURE | いいえ | off | バックグラウンドワーカーでキャプチャを永続化し、ストレージによってエージェントの呼び出しにレイテンシーが追加されないようにします。トレードオフとして、読み取りは結果整合性になります(キャプチャ直後の呼び出しは、短時間クエリできない場合があります)。高スループット環境におすすめです。 |
AGENTICLEDGER_CAPTURE_QUEUE_MAX | いいえ | 10000 | 非同期モードで負荷を抑制する前にバッファーできるキャプチャの最大数です(破棄数は /metrics に記録されます)。 |
AGENTICLEDGER_CAPTURE_LEVEL | いいえ | full | full はすべてを保存します。metadata はメトリクスとメタデータ(モデル、トークン、コスト、レイテンシー、エージェント、ステータス)のみを保存し、プロンプト、応答、ツールを破棄します。 |
AGENTICLEDGER_REDACT | いいえ | (オフ) | 保存データ内の個人情報やシークレットを秘匿します。all、または email,ssn,credit_card,ip,api_key のようなカンマ区切りリストを指定します。一致箇所は [REDACTED:<label>] に置き換えられます。影響を受けるのは保存されたコピーのみで、エージェントの応答は変更されません。 |
AGENTICLEDGER_REDACT_PATTERNS | いいえ | (なし) | JSON 形式で追加の秘匿用正規表現を指定します。{"label": "regex", ...} または ["regex", ...] を使用します。 |
AGENTICLEDGER_RETENTION_DAYS | いいえ | (無期限に保持) | バックグラウンドの削除ワーカーを使用して、N 日より古いキャプチャ済み呼び出しを削除します。 |
AGENTICLEDGER_AUDIT_LOG | いいえ | on | 誰が何を閲覧、エクスポート、削除したかに加え、トークンや消去に関する操作、ログイン失敗、拒否された取り込み認証情報、MCP の読み取りを監査ログに記録します。無効にするには 0 を設定します。 |
AGENTICLEDGER_AUDIT_STRICT | いいえ | off | 監査ログに記録できない監査対象操作を拒否します(HTTP 503)。オフの場合、書き込みの失敗はカウントされ(agenticledger_audit_dropped_total)、ログに記録されたうえで、操作は続行されます。 |
AGENTICLEDGER_AUDIT_HMAC_KEY | いいえ | (なし) | HMAC-SHA256 で監査ハッシュチェーンに署名します。設定しない場合、チェーンは通常の SHA-256 となり、編集を検出できますが、データベースにアクセスできる書き込み者はチェーンを再構築できます。_FILE 版も使用できます。 |
AGENTICLEDGER_AUDIT_STDOUT | いいえ | off | ログ収集ツールや SIEM エージェント向けに、各監査行を 1 行の JSON として標準出力にも出力します。OTel エクスポートを設定している場合は、行は OTLP ログレコードとしても送信されます。 |
| コスト予算 - 支出上限を超える呼び出しをブロックします(HTTP 429 を返します)。 |
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_BUDGET_SESSION | (none) | session_id ごとの全期間における最大 USD 額です。 |
AGENTICLEDGER_BUDGET_AGENT | (none) | 暦日(UTC)ごとの agent_name あたりの最大 USD 額です。 |
AGENTICLEDGER_BUDGET_DAILY | (none) | 暦日(UTC)ごとの全呼び出し合計の最大 USD 額です。 |
AGENTICLEDGER_BUDGET_USER | (none) | 暦日(UTC)ごとの user_id あたりの最大 USD 額です。セッションをまたいでユーザーに適用されます。 |
AGENTICLEDGER_BUDGET_STATUS | 429 | 予算超過時に返す HTTP ステータスです。429 では、UTC の午前0時にウィンドウがリセットされるまでの秒数を示す適切な Retry-After が付与されます。クライアントが 429 を積極的に再試行する場合は 402 に設定してください。Payment Required は再試行されません。 |
AGENTICLEDGER_BUDGET_ACTION | block | 予算超過時の動作です。block は HTTP 429 を返します(呼び出しは LLM に到達しません)。warn は呼び出しを通し、Webhook アラートを送信します。both はブロックし、Webhook も送信します。 |
AGENTICLEDGER_BUDGET_UNPRICED | allow | 価格がパックに登録されていないモデルは集計できません。allow はコスト不明として記録し(決して $0 にはしません)、集計対象外のまま呼び出しを通し、ログにモデル名を記録します。refuse は、いずれかの予算が適用されている間、そのモデルを拒否します。 |
予算と実行上限は同時実行中も維持されます。受け付けた各呼び出しについて、実際のコストが記録されるまで推定額を予約します(テキストは 1 トークンあたり 4 文字として計算し、max_tokens と合わせて、あらゆる呼び出しと同じ方法で価格を算出します)。そのため、並列呼び出しが急増しても、それぞれが同じ残り枠を利用することはありません。上限を超える呼び出しは、常に 1 つの呼び出しは通るため、そのまま実行されます。したがって、超過額は 1 回の呼び出しのコスト以内に収まります。予約は、呼び出しが記録されたとき、失敗したとき、破棄されたとき、または拒否されたときに直ちに解放されます。
許可リストと拒否リスト - クォータを消費する前にモデルまたはプロバイダーを拒否します(ルール名を含む HTTP 403 を返すため、エージェントは再試行せずに停止します)。パターンにはシェルのグロブを使用し、大文字と小文字を区別せず照合します。拒否ルールは許可ルールより優先されます。許可リストが設定されている場合、そこに指定されたものだけが許可されます。チームカードにも同じ 4 つのリストを設定できます(チームカードを参照)。フリート全体のリストは常に適用され、チームカードでさらに範囲を絞ることができます。
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_ALLOW_MODELS | (none) | カンマ区切りのモデルパターンです(例:claude-*,gpt-4o)。設定すると、一致するモデルのみが許可されます。 |
AGENTICLEDGER_DENY_MODELS | (none) | 拒否するモデルパターンです(例:*-preview)。 |
AGENTICLEDGER_ALLOW_PROVIDERS | (none) | プロバイダー名またはパターン(openai、anthropic、bedrock、azure-openai)です。設定すると、これらのみが許可されます。 |
AGENTICLEDGER_DENY_PROVIDERS | (none) | 拒否するプロバイダーです。 |
レート制限 - リクエスト頻度の上限を超える呼び出しをブロックします(スライディング 60 秒ウィンドウで HTTP 429 を返します)。拒否された呼び出しはすべて、理由を示す琥珀色の blocked: 行として記録されます。レポートと /metrics(agenticledger_refusals_total{reason=...})ではセッション別およびチーム別に集計されるため、再試行の集中が見える形になり、記録から消えることはありません。
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_RATE_LIMIT_RPM | (none) | グローバルな 1 分あたりの最大リクエスト数です。 |
AGENTICLEDGER_RATE_LIMIT_SESSION_RPM | (none) | session_id ごとの 1 分あたりの最大リクエスト数です。 |
AGENTICLEDGER_RATE_LIMIT_AGENT_RPM | (none) | agent_name ごとの 1 分あたりの最大リクエスト数です。 |
AGENTICLEDGER_RATE_LIMIT_USER_RPM | (none) | user_id ごとの 1 分あたりの最大リクエスト数です。 |
ループエンジン - すべての呼び出しを ReAct スレッド(thread_id、step_index、prev_action_id)にまとめ、新しいコンテキストで行うループの反復を実行単位にグループ化し、停止したループを検出します。
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_LOOP_ACTION | warn | warn は loop_flags を記録し、loop_flag webhook アラートを発火します。block はさらに、ガードに引っかかったセッションに対して HTTP 429(loop_detected)を返し、拒否するたびに記録します。ダッシュボードのセッションから、再起動せずにブロックを解除できます(DELETE /api/sessions/{id}/loop-block。解除後、その時点からガードが再び有効になります)。off は推論を無効にします。 |
AGENTICLEDGER_LOOP_REPEAT_THRESHOLD | 3 | スレッドが停滞状態と判定されるまでの、連続する同一のツール呼び出し(同じツール、同じ引数)の回数です。 |
AGENTICLEDGER_LOOP_MAX_STEPS | (none) | ReAct のステップ数がこの値を超えたスレッドにフラグを付けます(ブロックモードでは停止します)。 |
AGENTICLEDGER_LOOP_RUN_GAP_SECONDS | 900 | 新しいコンテキストでの実行(同じシステムプロンプト)間に許容される最大間隔です。この範囲内の実行は、1 回の実行の反復としてカウントされます。 |
AGENTICLEDGER_COMPLETION_PROMISE | (none) | 応答テキストに照合する正規表現です。一致すると、呼び出しに completion_promise のフラグが付き、実行のステータスが complete になります。ループ実行ツールは GET /api/runs/{run_id} をポーリングして停止します。 |
アラート - しきい値を超えたときに webhook に POST します(呼び出しはブロックしません。詳細はアラートを参照してください)。
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_ALERT_WEBHOOK_URL | (none) | アラートのペイロードを POST する URL です。アラートを発火させるには必須です。Slack、Discord、PagerDuty の URL には、それぞれのネイティブ形式が使用されます。 |
AGENTICLEDGER_ALERT_FORMAT | auto | ペイロードの形式です。auto は webhook のホスト名から判定し、generic、slack、discord、pagerduty を指定すると、その形式を強制します。 |
AGENTICLEDGER_ALERT_PAGERDUTY_KEY | (none) | PagerDuty Events v2 の統合キーです。webhook が events.pagerduty.com の場合に必要です。_FILE 版も使用できます。 |
AGENTICLEDGER_PUBLIC_URL | (none) | ダッシュボードにアクセスできる URL(https://ledger.example.com)です。実行またはセッションに関する通知に、その URL へのリンクを含めます。 |
AGENTICLEDGER_DIGEST_HOUR | (off) | 日次の支出ダイジェスト(過去 24 時間の合計、キャッシュによる節約額、上位のモデル/エージェント)をアラート webhook に POST する UTC 時間(0~23)です。Slack の incoming webhook と互換性があります(text)。 |
AGENTICLEDGER_ALERT_COST_PER_CALL | (none) | 1 回の呼び出しのコストが $X を超えたときにアラートを送信します。 |
AGENTICLEDGER_ALERT_LATENCY_MS | (none) | 1 回の呼び出しに Xms を超える時間がかかったときにアラートを送信します。 |
AGENTICLEDGER_ALERT_ERROR_RATE | (none) | セッションのエラー率が X を超えたときにアラートを送信します(例:0.5 = 50%)。 |
AGENTICLEDGER_ALERT_DAILY_SPEND | (none) | 1 日の支出が $X を超えたときにアラートを送信します。予算とは異なり、呼び出しはブロックしません。 |
OpenTelemetry - OTLP 互換の任意のコレクターにスパンを送信します(pip install "agentic-ledger[otel]" が必要です。詳細はOpenTelemetry エクスポートを参照してください)。
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_OTEL_ENDPOINT | (none) | OTLP/HTTP のベース URL です。例:http://localhost:4318。設定されていない場合、OTel エクスポートは無効になります。 |
AGENTICLEDGER_OTEL_SERVICE_NAME | agenticledger | コレクターに報告される service.name の値です。 |
AGENTICLEDGER_OTEL_HEADERS | (none) | カンマ区切りの key=value 認証ヘッダーです。例:x-honeycomb-team=abc123。 |
価格の上書き - 組み込みのトークン単価テーブルを上書きまたは拡張します(起動時にマージされます)。
| 変数 | デフォルト | 説明 |
|---|---|---|
agenticledger pricing update | リポジトリから最新の価格パックを ~/.agenticledger/pricing/ に取得します(次回起動時に組み込みの価格を上書きします)。ネットワークにアクセスするのは、このコマンドを実行したときだけです(agenticledger upgrade も同様です)。自動的に外部へ通信することはありません。 | |
AGENTICLEDGER_PRICING | (none) | モデルから [input_per_million, output_per_million] の USD 価格へのインライン JSON マップです。例:'{"gpt-4o": [2.50, 10.00], "my-model": [1.00, 2.00]}'。 |
AGENTICLEDGER_PRICING_FILE | (none) | 同じ形式の JSON ファイルへのパスです。AGENTICLEDGER_PRICING の後に適用されます。 |
一般的な起動例
# Local dev - OpenAI (default)
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com uv run python -m agenticledger.proxy
# Local dev - Anthropic
AGENTICLEDGER_UPSTREAM_URL=https://api.anthropic.com uv run python -m agenticledger.proxy
# Local dev - LiteLLM gateway (any model)
AGENTICLEDGER_UPSTREAM_URL=http://localhost:4000 uv run python -m agenticledger.proxy
# Production - Postgres + auth + budgets + rate limits + alerts
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com \
AGENTICLEDGER_DSN=postgresql://user:password@localhost/agenticledger \
AGENTICLEDGER_API_KEY=my-secret \
AGENTICLEDGER_BUDGET_DAILY=20.00 \
AGENTICLEDGER_BUDGET_SESSION=2.00 \
AGENTICLEDGER_RATE_LIMIT_SESSION_RPM=20 \
AGENTICLEDGER_RATE_LIMIT_USER_RPM=60 \
AGENTICLEDGER_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz \
AGENTICLEDGER_ALERT_COST_PER_CALL=0.50 \
AGENTICLEDGER_ALERT_DAILY_SPEND=15.00 \
uv run python -m agenticledger.proxy
AGENTICLEDGER_API_KEY が設定されている場合は、保護されたエンドポイントにアクセスするため、ヘッダーに指定します。
curl -H "x-agenticledger-api-key: my-secret" http://localhost:8000/session/run-1
キーはヘッダーでのみ送信されます。クエリ文字列(?api_key=、?token=)にキーを指定すると、理由を示すメッセージとともに 401 で拒否されます。URL はアクセスログ、プロキシログ、ブラウザーの履歴、Referer ヘッダーに残るためです。ブラウザーでは、キーをダッシュボードの ⚿ パネルに貼り付けるか、agenticledger share で生成したペアリングリンクを開いてください。このリンクでは、キーは # の後(URL フラグメント)に含まれており、ブラウザーからサーバーに送信されることはありません。
ID プロバイダーでサインイン(OpenID Connect)
スクリプトではなく人向けの機能です。台帳を ID プロバイダーに接続すると、⚿ パネルに Okta でサインイン ボタン(または任意の名前を付けたボタン)が表示されます。PKCE を使うコードフロー、プロバイダーの鍵による ID トークンの検証(RS256)、およびグループによってロールが決まります。どのロールにも割り当てられないグループに属する人は、理由を通知されて拒否され、その記録が残ります。エージェントやスクリプト向けのキーも引き続き使用できます。
AGENTICLEDGER_OIDC_ISSUER=https://your-org.okta.com
AGENTICLEDGER_OIDC_CLIENT_ID=0oa...
AGENTICLEDGER_OIDC_CLIENT_SECRET_FILE=/run/secrets/oidc # omit for a public client
AGENTICLEDGER_OIDC_ROLE_MAP=ledger-admins=admin,ledger-editors=editor,ledger-viewers=viewer
AGENTICLEDGER_PUBLIC_URL=https://ledger.example.com # the redirect back lands here
プロバイダーにリダイレクト URI https://ledger.example.com/auth/callback を登録します。サインイン情報はサーバー側のレコードとして保持され、ブラウザーは Cookie で参照します(httponly、SameSite=Lax、https では Secure)。12 時間操作がない場合、または 7 日後(AGENTICLEDGER_SESSION_IDLE_HOURS、AGENTICLEDGER_SESSION_MAX_HOURS)、サインアウト時、あるいは管理者が終了した場合(POST /api/people/{id}/signout)にセッションが終了します。Cookie を使う変更リクエストは、ダッシュボード自身のオリジンから送信する必要があります。監査ログの各行には、ユーザーのメールアドレスが記録されます。GET /api/people では、サインインしたユーザーとそのロール、グループを確認できます。
スコープ付きアクセス。 AGENTICLEDGER_OIDC_SCOPE_MAP=team-alpha=alpha,team-alpha=alpha-infra を設定すると、team-alpha に属するユーザーには、該当するプロジェクトのみが表示されます。リスト、個別のセッションと実行、検索、レポート、エクスポート、what-if、リプレイ、MCP ツールの応答はすべてスコープ内に限定され、スコープ外の項目は見つからないものとして扱われます。プロジェクトが割り当てられていない作業は、誰かが割り当てるまでスコープ付きユーザーには表示されません。マッピングされたグループに属さないユーザーにはスコープが適用されず、従来どおりロールで許可されたすべての項目が表示されます。スコープ付きの編集者は、自分のプロジェクトにのみ作業を割り当てられます。
プロバイダーなしで試すには、agenticledger idp を実行します。ループバックでテスト用プロバイダーが起動し、架空のユーザー 4 人(alice は管理者、dave はマッピングされたグループなし)が用意されます。設定する 4 行が表示され、本番環境向けではないことが各ページに表示されます。
スコープ付き API トークン(RBAC)
マスターキーは便利ですが、アクセス範囲が大まかです。チームでアクセスする場合は、マスターシークレットを共有する代わりに、ロール付きのスコープ付きで失効可能なトークンを発行します。トークンは作成時に一度だけ表示されるランダムなシークレットで、保存されるのは SHA-256 ハッシュのみです。
ロールは階層構造ですが、例外が 1 つあります。ingest は階層の外にあり、プロキシパスのみを利用できます。
| ロール | 可能な操作 |
|---|---|
ingest | プロキシ経由でのみ呼び出しを送信します(チームカードに相当します)。各呼び出しをチームに帰属させ、チームの日次予算を適用します。ダッシュボード、API、エクスポート、MCP の読み取りはできません |
viewer | 取得したデータ(ダッシュボード、API、エクスポート、MCP)を読み取ります |
editor | viewer の権限に加えて、セッションを削除します |
admin | editor の権限に加えて、API トークンを管理します |
# Mint a viewer token (admin only - use the master key to bootstrap)
curl -X POST http://localhost:8000/api/tokens \
-H "x-agenticledger-api-key: my-secret" \
-H "content-type: application/json" \
-d '{"name": "grafana-readonly", "role": "viewer", "expires_in_days": 90}'
# → {"token_id": "...", "token": "agl_…", "role": "viewer", ...} (token shown once)
# Use it (Authorization: Bearer or the x-agenticledger-token header)
curl -H "Authorization: Bearer agl_…" http://localhost:8000/api/sessions
# List and revoke
curl -H "x-agenticledger-api-key: my-secret" http://localhost:8000/api/tokens
curl -X DELETE -H "x-agenticledger-api-key: my-secret" http://localhost:8000/api/tokens/<token_id>
認証が適用されるのは
AGENTICLEDGER_API_KEYが設定されている場合のみです。トークンを発行する際の管理者用初期設定にはマスターキーを使います。ライブ/wsフィードでは、ヘッダー(Authorization: Bearerまたはx-agenticledger-token)かチケットを使用できます。ブラウザーは WebSocket ハンドシェイクにヘッダーを付けられないため、ダッシュボードはまずヘッダーにキーを指定してPOST /api/ws/ticketを呼び出し、/ws?ticket=...に接続します。このチケットはランダムで、有効期間は 1 分、1 回限りで、使用後は無効です。認証されていない接続と、URL にキーを含む接続は、クローズコード 1008 で拒否されます。
リクエストヘッダー
LLM を呼び出すたびに、エージェントから以下のヘッダーを渡してください。すべて省略可能です。取得したデータに情報を追加し、Flow タブを有効にするとともに、ディメンションごとの予算とレート制限を設定できます。
| ヘッダー | デフォルト | 説明 |
|---|---|---|
x-agenticledger-session-id | (none) | 1 回の実行におけるすべての呼び出しをグループ化します。エージェントの実行ごとに一貫した ID(UUID や "run-1" など)を使用してください。指定しない場合、呼び出しは保存されますが、ダッシュボードではグループ化されません。 |
x-agenticledger-user-id | (none) | この実行を開始したエンドユーザーです。ユーザーごとのレート制限と監査が可能になります。 |
x-agenticledger-agent-name | (none) | この呼び出しを行うエージェントの名前("orchestrator"、"researcher" など)です。Flow タブの DAG とエージェントごとの予算およびレート制限に使用されます。 |
x-agenticledger-app-id | (none) | アプリケーション名または ID です。複数のアプリが 1 つのプロキシを共有する場合に便利です。 |
x-agenticledger-parent-action-id | (none) | この呼び出しを開始した呼び出しの action_id です。設定すると、Trace タブに親子間の接続が明示的に表示されます。指定しない場合、Trace タブはタイムスタンプから関係を自動的に推測します。 |
x-agenticledger-environment | development | production、staging、または development です。ダッシュボードに表示されます。 |
x-agenticledger-handoff-from | (none) | 制御を引き渡すエージェント("orchestrator" など)です。Flow DAG に有向エッジとして表示されます。 |
x-agenticledger-handoff-to | (none) | 制御を受け取るエージェント("researcher" など)です。Flow DAG に有向エッジとして表示されます。 |
x-agenticledger-framework | (auto-detected) | 呼び出しを行うフレームワーク/ツール("langgraph"、"bmad" など)です。指定されていない場合、既知のクライアント(Claude Code、Gemini CLI、LiteLLM)は自動的にフィンガープリントされます。 |
x-agenticledger-run-id | (auto-inferred) | セッションをループ実行(Ralph の夜間実行など)にまとめます。指定されていない場合、AGENTICLEDGER_LOOP_RUN_GAP_SECONDS の範囲内で、同じシステムプロンプトを共有する新しいコンテキストのセッションが自動的にグループ化されます。 |
x-agenticledger-iteration | (auto-inferred) | 実行内の反復回数です。 |
単一エージェント — すべての情報を付与:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="your-openai-key",
default_headers={
"x-agenticledger-session-id": "run-abc123",
"x-agenticledger-user-id": "user-42",
"x-agenticledger-agent-name": "researcher",
"x-agenticledger-app-id": "my-app",
"x-agenticledger-environment": "production",
},
)
マルチエージェントシステム — 制御の引き渡しを追跡:
from openai import OpenAI
# Orchestrator
orchestrator_client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="your-openai-key",
default_headers={
"x-agenticledger-session-id": "run-abc123",
"x-agenticledger-agent-name": "orchestrator",
},
)
# Researcher (receives handoff from orchestrator)
researcher_client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="your-openai-key",
default_headers={
"x-agenticledger-session-id": "run-abc123",
"x-agenticledger-agent-name": "researcher",
"x-agenticledger-handoff-from": "orchestrator",
"x-agenticledger-handoff-to": "researcher",
},
)
Flow タブでは、各ノードのコストとレイテンシを含む DAG として orchestrator → researcher が表示されます。
OpenAI Agents SDK(openai-agents)— エージェントごとのクライアント:
openai-agents SDK は独自の内部 OpenAI クライアントを使用します。Agentic Ledger のヘッダーを渡すには、OpenAIResponsesModel を使用してエージェントごとにクライアントを作成し、そのエージェントの model に設定する必要があります。
import uuid
import os
from openai import AsyncOpenAI
from agents import Agent
from agents.models.openai_responses import OpenAIResponsesModel
SESSION_ID = f"run-{uuid.uuid4().hex[:8]}" # one per execution
BASE_URL = os.getenv("OPENAI_BASE_URL") # e.g. http://localhost:8000/v1
def al_model(agent_name: str, model: str = "gpt-4o-mini",
handoff_from: str | None = None, handoff_to: str | None = None):
"""Create a model instance that sends Agentic Ledger metadata headers."""
if not BASE_URL:
return model # proxy not configured - use default client
headers = {
"x-agenticledger-session-id": SESSION_ID,
"x-agenticledger-agent-name": agent_name,
}
if handoff_from:
headers["x-agenticledger-handoff-from"] = handoff_from
if handoff_to:
headers["x-agenticledger-handoff-to"] = handoff_to
client = AsyncOpenAI(base_url=BASE_URL, api_key=os.getenv("OPENAI_API_KEY", ""),
default_headers=headers)
return OpenAIResponsesModel(model=model, openai_client=client)
planner = Agent(name="PlannerAgent", model=al_model("PlannerAgent", handoff_to="SearchAgent"), ...)
searcher = Agent(name="SearchAgent", model=al_model("SearchAgent", handoff_from="PlannerAgent", handoff_to="WriterAgent"), ...)
writer = Agent(name="WriterAgent", model=al_model("WriterAgent", handoff_from="SearchAgent", handoff_to="EmailAgent"), ...)
emailer = Agent(name="EmailAgent", model=al_model("EmailAgent", handoff_from="WriterAgent"), ...)
各エージェントの呼び出しには、エージェント名とパイプライン内の位置がタグ付けされます。Flow タブでは、PlannerAgent → SearchAgent → WriterAgent → EmailAgent の完全な DAG が自動的に表示されます。
エージェントごとにクライアントを作成する理由
set_default_openai_client()は単一のグローバルクライアントを設定します。単一エージェントのアプリでは問題ありませんが、マルチエージェントシステムではエージェントごとに異なるagent_nameやhandoff_*ヘッダーを設定できません。エージェントごとにOpenAIResponsesModelのインスタンスを作成する方法が適切です。
アラート
Agentic Ledger は、しきい値を超えたとき、ループが検出されたとき、実行が行き詰まったとき、または実行が終了したときに、Webhook URL へ通知を送信します。Slack の受信 Webhook、Discord Webhook、PagerDuty Events v2 は URL から認識され、それぞれのネイティブ形式で通知されます(AGENTICLEDGER_ALERT_FORMAT で上書きできます)。それ以外の場合は、以下のプレーン JSON が使用されます。
信頼性を考慮した設計です。 すべての通知はリクエスト処理の外で、バックオフ(1秒、3秒、9秒)を挟んで3回試行され、ウィンドウごとに1回送信され(超過した1日の予算は1日1回、検出されたループは10分に1回、行き詰まった実行は1時間に1回)、記録されます。設定ページでは、送信内容、通知が届いたかどうか、試行回数、届かなかった理由を確認できます。また、テスト通知を送信ボタンを使えば、ワンクリックで Slack を接続できます。GET /api/notifications は同じ履歴を返します。AGENTICLEDGER_PUBLIC_URL を設定すると、実行やセッションに関するすべての通知に、対象へ直接移動できるリンクが含まれます。
ペイロード形式(プレーン JSON。ネイティブ形式にも同じ情報が含まれます):
{
"type": "high_cost",
"message": "Single call cost $0.1842 exceeded threshold $0.10",
"value": 0.1842,
"threshold": 0.10,
"action_id": "a1b2c3d4-...",
"session_id": "run-1",
"agent_name": "researcher",
"timestamp": "2026-04-03T12:00:00+00:00"
}
アラートの種類:
| 種類 | 発生条件 |
|---|---|
high_cost | 1回の呼び出しのコストが AGENTICLEDGER_ALERT_COST_PER_CALL を超えたとき |
high_latency | 1回の呼び出しに AGENTICLEDGER_ALERT_LATENCY_MS を超える時間がかかったとき |
high_error_rate | セッションのエラー率が AGENTICLEDGER_ALERT_ERROR_RATE を超えたとき |
daily_spend | 1日の合計支出が AGENTICLEDGER_ALERT_DAILY_SPEND を超えたとき |
budget_exceeded | 予算上限に達し、AGENTICLEDGER_BUDGET_ACTION が warn または both のとき |
run_ceiling_approaching | 実行の支出がコスト上限の80%に達したとき(実行ごとに1回通知) |
loop_flag | ループエンジンが呼び出しにフラグを立てたとき(repeat_tool_call、step_budget_exceeded、completion_promise) |
run_complete | 実行の完了プロミスが検出されたとき。ペイロードには実行の完全な概要(反復回数、コスト、トークン数、フラグが立てられた呼び出し)が含まれます |
run_ended | 実行が停止状態になったとき(実行間隔中に呼び出しがない場合)。同じ概要が含まれるため、一晩続いたループの終了を朝までにチャンネルで確認できます |
run_failed | 実行が停止状態になり、最後の反復がエラーで終了したとき。同じ概要に、失敗を示すフラグが付きます |
run_blocked | 実行の呼び出しが上限で拒否されたとき(キルスイッチ、コスト上限、予算、すべての呼び出しの停止、モデルまたはプロバイダーのリスト)。理由ごとに1時間に1回、実行ごとに通知され、理由も含まれます |
test | 「テスト通知を送信」を押したとき |
チームカード - 1 つのプロキシで複数のチーム
利用枠付きカードをイメージしてください。実際のプロバイダーキーは 1 つだけ保持し、各チームにはそれぞれ専用のカードを渡します。各カードでプロキシを利用でき、すべての呼び出しにチーム名が記録されます。また、カードごとに 1 日あたりの予算を設定できます。マーケティングチームが $10 に達した場合、ブロックされるのはマーケティングチームだけです(正確な Retry-After が返されます)。
curl -X POST http://localhost:8000/api/tokens \
-H "x-agenticledger-api-key: $ADMIN_KEY" -H 'content-type: application/json' \
-d '{"name": "marketing", "role": "ingest", "budget_daily": 10.00}'
レスポンスにはカードが一度だけ表示され、台帳にはそのハッシュのみが保存されます。チームは共有キーの代わりに x-agenticledger-ingest-key にカードを設定します。レポートにはチーム別の表が追加され、各カードの利用枠に対するエラー、ブロック、今日の支出が表示されます。DELETE /api/tokens/{token_id} でカードを失効させると、影響を受けるのはそのチームだけです。失効した瞬間からカードには最終的な 403(「許可されません」)が返されるため、エージェントがリトライを繰り返すこともありません。誤ってダッシュボードの ⚿ パネルにカードを貼り付けると、カードで利用できるのはリレーであり、ダッシュボードではないことが分かりやすく表示されます。
カードごとに、フリート全体の AGENTICLEDGER_ALLOW_MODELS などに加えて、モデルとプロバイダーの許可リストおよび拒否リストを設定することもできます。フリートのリストは常に適用され、カードで範囲を狭めることはできますが、フリートが拒否したモデルを許可することはできません。拒否理由にはルール名とチーム名が示され、他のブロックと同様にチーム別の表に表示されます。
curl -X POST http://localhost:8000/api/tokens \
-H "x-agenticledger-api-key: $ADMIN_KEY" -H 'content-type: application/json' \
-d '{"name": "marketing", "role": "ingest", "budget_daily": 10.00,
"allow_models": ["gpt-4o", "claude-sonnet-*"], "deny_providers": ["bedrock"]}'
予算とアラートの違い:
- 予算(
AGENTICLEDGER_BUDGET_*)- LLM に到達する前に呼び出しをブロックします。エージェントには HTTP 429 が返されます。 - アラート(
AGENTICLEDGER_ALERT_*)- 呼び出しは実行され、その後に通知が届きます。
Webhook の受信内容。 各アラートは、独自のフィールド名を使った 1 件の JSON POST です。フィールドは type(下の表を参照)、message、value、threshold、action_id、session_id、agent_name、timestamp です。日次ダイジェスト(AGENTICLEDGER_DIGEST_HOUR=8)は別の POST で、type: daily_digest、そのまま読める text ブロック(直近 24 時間の支出、キャッシュによる節約額、上位のモデルとエージェント)、および totals が含まれます。
Slack - Incoming Webhook の URL(hooks.slack.com)を貼り付けます。各通知は、詳細と「Agentic Ledger を開く」リンクを含むタイトル付きメッセージとして届きます。
PagerDuty - Events API v2 の URL(https://events.pagerduty.com/v2/enqueue)を使用し、AGENTICLEDGER_ALERT_PAGERDUTY_KEY にインテグレーションキーを設定します。通知は、種類ごとの重大度(実行の失敗またはブロックは critical、しきい値は warning、概要とダイジェストは info)、重複排除キー、および実行へのリンクを含むインシデントをトリガーします。
Discord - チャンネルの Webhook URL(discord.com/api/webhooks/...)を指定します。詳細とリンクを含むタイトル付きの埋め込みメッセージが届きます。
カスタム - JSON の POST を受け付ける任意の HTTP エンドポイントです。
OpenTelemetry エクスポート
Agentic Ledger は、傍受したすべての LLM 呼び出しを OTel スパンとして、Grafana Tempo、Jaeger、Honeycomb、Datadog、Dynatrace、または OTLP/HTTP をサポートする任意のベンダーの OTLP 互換コレクターに送信できます。
追加機能をインストールします(Docker イメージには OTel が含まれているため、Docker を使用する場合は追加の手順は不要です):
pip install "agentic-ledger[otel]"
# or
uv add "agentic-ledger[otel]"
設定:
| 変数 | デフォルト | 説明 |
|---|---|---|
AGENTICLEDGER_OTEL_ENDPOINT | (none) | OTLP/HTTP のベース URL。例:http://localhost:4318。設定されていない場合、OTel エクスポートは無効になります。 |
AGENTICLEDGER_OTEL_SERVICE_NAME | agenticledger | 出力されるリソースの service.name の値です。 |
AGENTICLEDGER_OTEL_HEADERS | (none) | 認証ヘッダー用の、カンマ区切りの key=value ペアです。例:x-honeycomb-team=abc123,x-honeycomb-dataset=llm。 |
例 - Grafana Tempo:
AGENTICLEDGER_UPSTREAM_URL=https://api.openai.com \
AGENTICLEDGER_OTEL_ENDPOINT=http://localhost:4318 \
AGENTICLEDGER_OTEL_SERVICE_NAME=my-agent \
uv run python -m agenticledger.proxy
例 - Honeycomb:
AGENTICLEDGER_OTEL_ENDPOINT=https://api.honeycomb.io \
AGENTICLEDGER_OTEL_HEADERS=x-honeycomb-team=YOUR_API_KEY,x-honeycomb-dataset=llm-traces \
uv run python -m agenticledger.proxy
出力されるスパン属性(GenAI セマンティック規約):
| 属性 | ソース |
|---|---|
gen_ai.system | プロバイダー(openai / anthropic) |
gen_ai.operation.name | 常に chat |
gen_ai.request.model | モデル ID |
gen_ai.request.temperature | 設定されている場合 |
gen_ai.request.max_tokens | 設定されている場合 |
gen_ai.usage.input_tokens | 入力トークン数 |
gen_ai.usage.output_tokens | 出力トークン数 |
gen_ai.response.finish_reasons | 停止理由 |
agenticledger.action_id | 一意の呼び出し ID |
agenticledger.session_id | 実行のグループ化 |
agenticledger.agent_name | ヘッダーから取得 |
agenticledger.user_id | ヘッダーから取得 |
agenticledger.cost_usd | 推定コスト |
agenticledger.latency_ms | エンドツーエンドのレイテンシ |
agenticledger.environment | ヘッダーから取得 |
agenticledger.handoff_from / agenticledger.handoff_to | エージェントのハンドオフ |
http.status_code | アップストリームからの HTTP ステータス |
スパンは session_id によってトレースにグループ化されます。セッション内のすべての呼び出しが、バックエンドで 1 つのトレースとして表示されます。親子関係は x-agenticledger-parent-action-id に従います。エラースパン(status_code != 200)には StatusCode.ERROR が設定されます。
コンプライアンス関連ドキュメント
セキュリティまたはプライバシーのレビューには、docs/compliance に、データフロー図、DPA の付属書を含むデータ処理の説明、サブプロセッサーに関する声明(該当なし:ソフトウェアはインストール先で実行され、プロジェクトに情報を送信しません)、HIPAA への対応状況、各項目の証拠を含む SOC 2 および ISO 27001 の管理策対応表、サポート期間(最新のマイナーバージョンにはすべての修正が提供され、1 つ前のマイナーバージョンには 90 日間セキュリティ修正が提供されます)が記載されています。そのまま添付できるように作成されており、プロジェクトが保有しないものについても正直に記載しています。SOC 2 レポート、ISO 認証、BAA はありません。
コンプライアンスエクスポート
すべてのセッションを、整合性タグ付きの監査証跡としてエクスポートできます。規制対象の業界や内部監査、外部ツールへのトレースの受け渡しに便利です。
# Machine-readable JSON with an integrity tag over the calls array
curl http://localhost:8000/export/run-1 -o audit-run-1.json
# Printable HTML - open in browser and print to PDF
open http://localhost:8000/export/run-1/report
JSON エクスポートには、呼び出し配列に対する整合性タグが付与されます。デフォルトでは sha256 のチェックサムです。これは偶発的な破損を検出しますが、署名ではありません(呼び出しを編集した人は誰でも再計算できます)。AGENTICLEDGER_EXPORT_HMAC_KEY を設定すると、鍵を使用した hmac-sha256 タグに切り替わり、改ざんを検知できるようになります。鍵を持つ受信者は変更を検出でき、鍵なしではタグを偽造できません。
リリース
バージョンにタグを付けると、完全なリリースパイプラインが自動的に実行されます。
git tag v0.2.0
git push origin v0.2.0
次の 3 つのジョブが実行されます。
- Docker - linux/amd64 と linux/arm64 向けに
ghcr.io/shekharbhardwaj/agentic-ledger:{version}と:latestをビルドし、SBOM とプロベナンス証明を付けてプッシュし、Sigstore cosign でダイジェストに署名し(キーレス)、DOCKERHUB_USERNAME/DOCKERHUB_TOKENシークレットが設定されている場合は Docker Hub にもミラーリングします - PyPI - トラステッドパブリッシングを使用して
agentic-ledger=={version}をビルドし、PyPI に公開します(API トークンは不要)。PEP 740 証明も付与されます - GitHub Release - 自動生成された変更履歴を含むリリースを作成し、イメージの SBOM(SPDX)を添付します
PyPI の初回セットアップ(初回のみ):
- pypi.org/manage/account/publishing にアクセスします
- 新しい保留中のパブリッシャーを追加します:
PyPI project name: agentic-ledger Owner: ShekharBhardwaj Repository: AgenticLedger Workflow name: release.yml Environment name: pypi - GitHub に
pypi環境を作成します:リポジトリ → Settings → Environments → New environment → 名前をpypiにします - 以上です。シークレットは不要です
トラブルシューティング
まずはここから:agenticledger doctor。 このコマンドを実行すると、マシンの状態をすべて確認できます。PATH 上のすべてのインストールと、どれがどれを優先しているか、それぞれをどの Python が所有し、実際に実行できるか(実際のインポート検査で、アーキテクチャの異なるホイールや不足している依存関係を検出します)、バックグラウンドサービスが提供している内容、検出結果ごとの修正コマンドが表示されます。以下の問題の多くは、このコマンドで原因を特定できます。--fix を追加すると、表示された修正が適用されます。優先されているインストールは、それぞれを所有するインタープリターの pip を使って削除され、クリーンアップ用に提示された PATH の先頭への追加が行われた後、2 回目の診断が実行されます。
古いバージョン/agentledger(「ic」なし)という名前のコマンドや環境変数 -
0.4 より前のリリースを実行しています。すでにこのパッケージがインストールされていた venv が原因である可能性が高いです。通常の pip install agentic-ledger では「requirement already satisfied」と表示され、アップグレードされません。agenticledger upgrade を実行してください。インストールを所有する Python 環境を使うため、どの pip を使えばよいか迷うことはありません。その後、再起動してください。プロキシは起動時に最初の行でバージョンを表示し、curl localhost:8000/health でも確認できます。0.4.0 以降、すべての名前は agenticledger になりました。CHANGELOG の移行に関する注意事項をご覧ください。
再生時に 401「invalid x-api-key」が発生する - AGENTICLEDGER_REPLAY_API_KEY には、console.anthropic.com(または platform.openai.com)から取得した有効なプロバイダー API キーが必要です。Claude Code のサブスクリプションログインは API キーではないため、使用できません。キーがありませんか?LM Studio ガイドを参照して、ローカルモデルで無料で再生してください。
macOS で incompatible architecture (have 'arm64', need 'x86_64') が発生する - ターミナルが Rosetta 上で実行されているため、pip が arm64 ネイティブホイールをインストールした一方で、Python は x86_64 スライスを選択しています。arch で確認してください(Apple Silicon では arm64 と表示されるはずです)。簡単な解決方法:コマンドの前に arch -arm64 を付けます。恒久的な解決方法:ターミナルアプリの「Open using Rosetta」のチェックを外し、エディターの Apple Silicon 版を使用して、長時間実行中の tmux サーバーを再起動します。
module 'httpx' has no attribute 'AsyncClient' が発生する - 0.3.0-alpha.2 で修正済みです。pip install --upgrade agentic-ledger でアップグレードしてください。
ポート 8000 がすでに使用されている - 別のプロキシインスタンス(またはアプリ)が実行中です。停止するか、AGENTICLEDGER_PORT を設定してください。
Claude Code から 401 OAuth access token has expired が返される - プロキシは Anthropic の応答を変更せずにそのまま渡しています。claude → /login で再認証してください。エラーになった呼び出しも引き続き記録されるため、ダッシュボードに 401 が表示されます。
/ が 404「Web app not built」を返す - Web アプリをビルドせずにソースチェックアウトから実行しています。cd dashboard-app && npm ci && npm run build を実行して再起動してください。PyPI と Docker からのインストールには、常にアプリが含まれています。
ライセンス
MIT
mcp-name: io.github.ShekharBhardwaj/agentic-ledger
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。