この記事はIBM Bobとともに作成しました。
ログが溜まってきた。ざっと確認したい。でもターミナルを離れたくない。
ファイル変換や定型レポートも、毎回同じ作業を手でやるのは面倒だ。
そんなとき、こんなコマンド一発でAIに解析させられたら便利だと思いませんか?
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob --hide-intermediary-output
Bob Shell には Headless mode(非インタラクティブモード) があり、stdin にテキストを流し込むだけでAIへの問い合わせをパイプに組み込めます。ログ解析・ファイル変換・定型レポート生成など、繰り返し発生する作業を半自動化できます。
この記事では、実際にハマったポイントと、試行錯誤で見つけた実践的なTIPSをまとめます。
環境
- OS: macOS (zsh)
- Bob Shell: v1.0.6
Headless mode とは
Bob Shell には大きく2つの使い方があります。
| モード | 起動方法 | 用途 |
|---|---|---|
| インタラクティブ | bob |
対話形式でコード生成・質問 |
| Headless(非インタラクティブ) |
bob "プロンプト" または stdin | bob
|
自動化・スクリプト・バッチ処理 |
Headless mode の最大のメリットは、シェルスクリプトや他のコマンドと組み合わせられることです。ログ解析・ファイル変換・定型レポート生成など、繰り返し発生する作業を半自動化できます。
TIPS 1: 複数ファイルをまとめてBobに渡す
✅ グループ化して結合する
# prompt.txt の内容 → ログの末尾100行 の順で bob に渡す
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob
✅ 複数ファイルを cat で結合(最もシンプル)
cat prompt.txt /tmp/app.log | bob
cat は複数ファイルを引数に取れるため、シンプルなケースではこれが最短です。
TIPS 2: stdin とプロンプトの渡し方
-p / --prompt は現在 非推奨(deprecated) です。
-p, --prompt Prompt. Appended to input on stdin (if any). [string]
[deprecated: Use the positional prompt instead.]
✅ stdin をそのまま渡す(-p 不要)
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob
✅ 固定のプロンプトを添えるならポジショナル引数で
-p は非推奨(deprecated)です。コマンドの末尾に文字列をそのまま渡すポジショナル引数が現在の推奨です。
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob "ログを解析してください"
stdin の内容にポジショナル引数のプロンプトが追記される形で Bob に渡されます。
✅ xargs -I を使う場合の正しい書き方
複数ファイルを find で列挙して1件ずつ Bob に渡すケースでは xargs -I が有効です。
# ログファイルを1件ずつ Bob に渡して解析
find /tmp/logs -name "*.log" | xargs -I {} bob "このログを要約して: {}"
xargs -I {} の {} がプレースホルダーで、各ファイルパスに置換されます。
TIPS 3: ログ解析を端的に出力する
問題:「説明してください」は長くなる
観点を列挙するプロンプトは、Bobが丁寧で長い回答を生成します。
# ❌ これだと見出し付きの長文が返ってくる
以下の観点から説明してください。
- 各行のログの内容
- 全体の流れ
- エラーの原因
- 正常・異常の判断
解決策:出力例をそのまま書く
LLMは具体的なフォーマット例に最も強く引きずられます。 観点を説明するのではなく、欲しい出力をテンプレートとして埋めさせる形にします。
# ✅ 出力例を直接書く
以下のログを解析し、下記の出力例と全く同じ形式・分量で日本語で回答してください。
説明文・見出し・補足は一切不要です。
【出力例】
- 処理: (1行で概要)
- 進捗: (数値のみ)
- 結果: PASS=xx FAIL=xx ERR=xx
- 異常: (ある場合のみ。なければ「なし」)
- 判定: 正常 / 要確認 / 異常 — (理由を1行)
【ログ】
実際の出力
- 処理: navidromeコンテナイメージのpullとテスト実行
- 進捗: 27/37
- 結果: PASS=3 FAIL=1 ERR=0
- 異常: インスタンス27(6b3b4d83)でテスト失敗
- 判定: 要確認 — 1件のテスト失敗が発生
プロンプトをファイルに保存しておけば、毎回使い回せます。
# prompt.txt に出力テンプレートを書いておく
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob --hide-intermediary-output
TIPS 4: <thinking> を消す — --hide-intermediary-output
非インタラクティブモードでは、Bobの内部思考プロセス(<thinking>)が出力に混入することがあります。
{ cat prompt.txt; tail -n 100 /tmp/app.log; } | bob --hide-intermediary-output
パイプで次のコマンドに渡す場合は特に重要
# ❌ 中間出力が jq に流れてパースエラーになる
bob -o json "..." | jq '.stats'
# ✅ クリーンな出力のみが流れる
bob -o json "..." --hide-intermediary-output | jq '.stats'
単体で使う場合はトークン数に影響しません(表示制御のみ)。ただし出力をパイプで別コマンドやBobに渡す場合は、中間出力の除去分だけトークン削減になります。
TIPS 5: 翻訳結果をファイルに保存する
Bob にファイル保存を指示する方法と、シェルのリダイレクトを使う方法で、トークン消費量が大きく変わります。
方法1: リダイレクト(推奨)
bob "@ document.txt を日本語に翻訳して" --hide-intermediary-output \
> /path/to/document_ja.txt
方法2: ファイル保存をBobに指示する
bob --approval-mode auto_edit \
"@ document.txt を日本語に翻訳し、document_ja.txt としてファイルに保存して"
--approval-mode auto_edit でファイル編集ツールのみ自動承認されます。
実測トークン比較
| フィールド | 方法1 (リダイレクト) | 方法2 (ファイル保存指示) | 差分 |
|---|---|---|---|
prompt |
28,320 | 50,179 | +21,859 |
candidates |
1,211 | 1,401 | +190 |
total |
29,531 | 51,580 | +22,049 |
cached |
27,034 | 31,848 | +4,814 |
方法2は約43%多くのトークンを消費します。
なぜ prompt が膨らむのか
方法2では write_file ツール呼び出しが発生し、LLMへのリクエストが2回になります。LLMはステートレスなため、2回目のリクエストでは1回目の内容(システムプロンプト・入力ファイル・翻訳テキスト)をすべて再送します。これが prompt トークンが膨らむ根本的な原因です。
[方法1: リクエスト1回で完結]
システムプロンプト + ファイル内容 + "翻訳して"
↓ 出力
翻訳テキスト → リダイレクトでファイルへ
[方法2: write_file ツール呼び出しで2回]
1回目: システムプロンプト + ファイル内容 + "翻訳してファイル保存して"
↓ write_file ツール呼び出し
2回目: システムプロンプト + ファイル内容 + "翻訳してファイル保存して"
+ Bobの翻訳テキスト + ツール実行結果 ← 全部再送される
翻訳のような単純な出力タスクではリダイレクト方式が圧倒的にコスト効率が良いです。
TIPS 6: トークン数を確認する
-o json オプションで実行統計をJSON形式で取得できます。プロンプト改善の効果を数値で検証するのに役立ちます。
{ cat prompt.txt; tail -n 100 /tmp/app.log; } \
| bob -o json --hide-intermediary-output \
| tee /tmp/bob_out.txt \
| sed -n '/{/,$p' | jq '.stats.models.premium.tokens'
出力例
{
"prompt": 33331,
"candidates": 672,
"total": 34003,
"cached": 32734,
"thoughts": 0,
"tool": 0
}
各フィールドの意味
| フィールド | 意味 |
|---|---|
prompt |
入力トークン数(送ったテキスト全体) |
candidates |
出力トークン数(Bobが生成した回答) |
total |
prompt + candidates の合計 |
cached |
prompt のうちキャッシュから再利用された分 |
thoughts |
内部推論(CoT)に使ったトークン数 |
tool |
ツール呼び出しに使ったトークン数 |
この例では cached=32734 / prompt=33331 で約96%がキャッシュヒットしています。同じプロンプトファイルを使い回すとキャッシュが効きやすくなります。
jq は brew install jq でインストールできます。tee を使うと通常出力を /tmp/bob_out.txt に保持しつつ、トークン数をターミナルに表示できます。
トークン削減まとめ
| 手段 | 効果 |
|---|---|
ログの行数を減らす(tail -n N) |
prompt を直接削減 ✅ |
| プロンプトに出力例を書く |
candidates を削減 ✅ |
| ツール呼び出しを減らす(リダイレクト方式) |
prompt の2回目送信を回避 ✅ |
出力をパイプで渡す際に --hide-intermediary-output
|
中間出力の混入を防止 ✅ |
| 同じプロンプトファイルを使い回す |
cached が増え実質コスト削減 ✅ |
--hide-intermediary-output(単体使用時) |
❌ トークンに影響なし(表示制御のみ) |
まとめ:ログ解析の最終形コマンド
# 出力 + トークン確認を一発で行う
{ cat prompt.txt; tail -n 100 /tmp/app.log; } \
| bob -o json --hide-intermediary-output \
| tee /tmp/bob_out.txt \
| sed -n '/{/,$p' | jq '.stats.models.premium.tokens'
Headless mode を活用するポイントは3つです。
{ }グループ化でファイルを結合してパイプで渡す- プロンプトに出力例を書いてテンプレートとして埋めさせる
- ファイル保存はリダイレクト
>で行いトークンを節約する
インタラクティブセッションで試行錯誤してパターンが決まったら、Headless mode でスクリプト化する — この2段階の使い方が Bob Shell をフル活用する近道です。