BraveとTavilyのAPI使用量を安全に見える化する


BraveとTavilyのAPI使用量を安全に見える化する

Web検索や公式情報の収集をHermes Agentに任せると、外部APIの残量が見えにくくなる。検索が急に失敗したとき、原因が通信障害なのか、認証切れなのか、月間上限なのかを切り分けるには、利用量を普段から短く確認できる仕組みが必要だった。そこで今回は、Brave Search APIとTavily APIの使用量を取得し、APIキーを出さずに人が読める監視メッセージへ整形する小さなCLIを作った。

実際に行ったことと確認結果

手元の実装では、`BRAVE_SEARCH_API_KEY`と`TAVILY_API_KEY`を環境変数または`.env`から読み、既存の環境変数を上書きしないようにした。Brave Searchは最小件数の検索リクエストを送り、レスポンスヘッダーに含まれる`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`、`X-RateLimit-Policy`を読む。Tavilyは公式の`/usage`エンドポイントから、契約プラン、利用量、上限、search/extract/crawl/map/research別の内訳を読む。

検証として、単体テストを実行し5件すべて成功した。確認内容は、`.env`読み込み時に既存の秘密値を保持すること、Braveのレート制限ヘッダーを秒単位と月間枠へ分けて解釈できること、Tavilyのプランと内訳を読めること、Discord向けメッセージが長くなりすぎずキー文字列を含まないこと、キー未設定時にも配信可能なエラー文になることだった。

さらに確認日現在の実行では、JSON出力でBrave Search APIがHTTP 200、Tavily APIがHTTP 200を返し、Tavily側は`Researcher`プラン、`plan_usage`が5、`plan_limit`が1000として取得できた。Brave側は月間枠が0と表示されたため、この記事では「手元の契約状態でそう返った」とだけ扱い、一般的な無料枠や課金条件としては断定しない。

仕組みの流れ

処理は次の順番で進む。

1. プロジェクト、カレントディレクトリ、ユーザー設定の`.env`を読み、既存の環境変数は上書きしない。
2. Brave Search APIへ小さな検索リクエストを送り、本文ではなくレート制限ヘッダーを取り出す。
3. Tavily APIの`/usage`へBearer tokenでGETし、key単位とaccount単位の利用量を読む。
4. 取得できた数値を、JSONまたはDiscord向けの短い日本語メッセージへ変換する。
5. 未設定、HTTPエラー、接続失敗は例外で落とさず、監視で読める失敗結果として返す。

ポイントは、監視のために秘密値そのものを出力しないことだ。メッセージには時刻、HTTP状態、残量、利用量、エラー概要だけを入れ、キーや内部パスは含めない。

再現手順

まず、必要なキーを安全な設定ファイルか実行環境に置く。公開例では値をプレースホルダーにする。

“`bash
BRAVE_SEARCH_API_KEY=YOUR_BRAVE_SEARCH_API_KEY
TAVILY_API_KEY=YOUR_TAVILY_API_KEY
“`

次に、監視用スクリプトをCLIとして実行する。

“`bash
python /path/to/project/web_api_usage_report.py –json –timeout 10
“`

人向け通知に使う場合は、JSONではなく通常出力をDiscordやチャット通知へ渡す。Hermes cronで定期化する場合は、実行ディレクトリをプロジェクトに向け、失敗時にも短いレポートが返るようにしておく。

“`bash
hermes cron create "every day at 08:00" \
"Run the web API usage monitor and report only the sanitized summary." \
–workdir /path/to/project
“`

単体テストでは、実APIを叩かずにレスポンスをモックして整形ルールを固定する。

“`bash
python -m unittest discover -s tests -p "test_web_api_usage_report.py" -v
“`

失敗しやすい点と安全策

Brave Searchは専用の使用量APIではなく、レスポンスヘッダーからレート制限を読む構成にした。そのため、ヘッダーの並びや契約状態の解釈を固定しすぎないほうがよい。確認日現在の公式ドキュメントでは、ヘッダーは複数の時間窓をカンマ区切りで返し、例として1秒枠と月間枠が示されている。

Tavilyは`/usage`でkey単位とaccount単位の数値を返すが、プランや上限は契約によって変わる。記事や通知で「この上限が全員に適用される」と書かず、取得時点の値として扱う。

また、監視ログは便利だが、キー未設定エラーやHTTPエラーの詳細を長く残すと運用情報が広がる。ログには秘密値、絶対パス、内部URLを含めず、必要ならhashや短い結果コードに寄せる。月末近くの残量不足は自動課金や契約変更に直結し得るため、最終判断は人が確認する。

再現チェックリスト

  • [ ] APIキーを環境変数または安全な`.env`に置き、Gitや記事本文へ書いていない。
  • [ ] `.env`読み込みが既存の環境変数を上書きしない。
  • [ ] Braveの`X-RateLimit-*`ヘッダーを取得できる。
  • [ ] Tavilyの`/usage`からプラン、利用量、上限、内訳を取得できる。
  • [ ] JSON出力と人向けメッセージの両方を確認した。
  • [ ] 出力にAPIキー、個人絶対パス、内部URLが含まれない。
  • [ ] キー未設定やHTTPエラーでも、監視で読める短い結果になる。

公式一次情報

  • [Brave Search API Rate Limiting](https://api-dashboard.search.brave.com/documentation/guides/rate-limiting)
  • [Brave Search API](https://brave.com/search/api/)
  • [Tavily Usage API](https://docs.tavily.com/documentation/api-reference/endpoint/usage)
  • [Hermes Agent Scheduled Tasks](https://hermes-agent.nousresearch.com/docs/user-guide/features/cron)

Back to top