GeminiにCLIでタスクを投げるツール「shitauke-cli」をClaude Desktopで作ってみた
https://zenn.dev/t3ta/articles/90257a2a659d70 に関する真面目な記事です。
背景
普段、VS Code で Roo Code を使いながら AI を活用している。その中で、以下のような運用が自然と定着していた。
- 簡単なタスクは Gemini に依頼
- 難しいタスクは Claude に依頼
Gemini はレスポンスが速く、簡単な質問や補助タスクに適している。一方、Claude は長文の文脈を理解するのが得意で、深い推論が必要な場合に向いている。これによって、適材適所で AI モデルを使い分ける ことで、より快適に作業できていた。
しかし、Claude Desktop と Roo Code + Gemini を同時運用すると、文脈が一貫しない という問題に直面。
なぜ CLI を作ろうと思ったのか?
1. Claude Desktop と Roo Code + Gemini では文脈の一貫性が保てない
同じ作業フローの中で、簡単なタスクを Roo Code + Gemini で処理し、複雑なタスクを Claude Desktop に投げると、AIごとの履歴管理が異なるため、前後の文脈が分断されてしまう ことが頻発。いちいちコピペしたり、手動で文脈を再構築するのが面倒だった。
2. プロンプト、入力、出力の最適化を柔軟にしたかった
Claude Desktop の UI からだと、プロンプトや入力フォーマットの最適化を細かく制御するのが難しい。CLI を作れば、スクリプトで管理しながら試行錯誤できるのでは?と考えた。
3. MCP(Model Context Protocol)での実装も考えたが…
MCP を使えば Claude Desktop から直接使うことができる。しかし、変更の反映のタイミングがうまくコントロールできないので、開発の試行錯誤がスムーズにできなかった。そこで、まずは CLI として作ってみるほうが実用的と判断した。
4. 適切なモデルを選択し、コストを抑えたかった
モデルごとに得意・不得意があるため、適切なプロンプトと適切なモデルの組み合わせを自動化することで、不要なコストを削減できるのではと考えた。
5. ノウハウを蓄積したかった
CLI にすることで、試したプロンプトや効果的な設定を examples
ディレクトリに保存し、ナレッジを蓄積していけるようにしたかった。
開発中に得た知見
1. プロンプト最適化の自動化
プロンプトの最適化ルールを「プロンプトとして」持たせることで、Claude が 同じ工程を踏んでくれるようになった。これにより、プロンプトの試行錯誤を省略でき、より一貫性のある結果を得ることができた。
2. Examples ディレクトリの活用
examples
ディレクトリに、効果的なプロンプトや入力/出力の例を蓄積し、以下のガイドラインで管理。
- アトミックな設計: 1つの入力に対して1つの出力という原則を徹底。
- 自己完結性: 例ごとに必要な情報を含み、依存関係をなくす。
- 標準化: ファイル命名規則やディレクトリ構造を統一。
- 実行可能性: 実際に CLI で動作する例のみを掲載。
- 簡潔さ: 余分な情報を削ぎ落とし、本質的な部分にフォーカス。
3. Gemini で処理可能なタスクの把握
実際に作成したプロンプト例(GitHub リンク)を試したことで、どのようなタスクなら Gemini で適切に処理できるのか が明確になった。
Markdown を JSON に変換するプロンプト例
マークダウン文書を構造化されたJSONに変換してください。
## 変換ルール
1. 階層構造:
- 各見出し (# 大項目, ## 中項目, ### 小項目) はJSONのキーとなります
- 見出しレベルに基づいて適切な入れ子構造を維持してください
- 見出し直後の段落は "description" プロパティとして扱います
- 構造はできるだけフラットに保ちます
2. リスト処理:
- 箇条書きリスト(-) は文字列の配列に変換。
- 書式付きリスト項目は適切なオブジェクト表現を使用。
- 番号付きリスト(1. 2.)は順序を保持した配列として処理。
- 定義スタイルの項目(用語: 値)は適切な場合キーと値のペアに変換。
3. テーブル処理:
- テーブルはオブジェクトの配列に変換。
- 最初の行を各オブジェクトのキーとして使用。
- 後続の各行は配列内の1つのオブジェクトになる。
- 適切なデータ型を維持(数値は数値として等)。
4. 書式情報の保持:
- 太字テキスト(**テキスト**)は {"value": "テキスト", "format": "bold"} として処理。
- リンク[テキスト](url)は {"text": "テキスト", "url": "url"} として処理。
- コードブロックは言語情報がある場合はそれも保持。
感想
プロンプトエンジニアリングの学習のためにわざわざ長いプロンプトを書くのが嫌だったので、ちょうどよい方法を見出せてよかった。
Discussion