invoking-cli-agents
PythonからCLIコーディングエージェント(Claude CodeやOpenCodeなど)をプログラム的に呼び出したい場合、またはサブエージェントに処理を委譲したい場合、複数のエージェントを統合したい場合に使用します。AgentShellのインスタンス化、プロンプト実行、レスポンスストリーミング、セッション再開、ツールスコープ設定、コスト追跡に対応しています。
description の原文を見る
Use when needing to programmatically invoke a CLI coding agent (Claude Code, OpenCode) from Python, delegate work to a sub-agent, or orchestrate multiple agents. Covers AgentShell instantiation, prompt execution, response streaming, session resumption, tool scoping, and cost tracking.
SKILL.md 本文
AgentShellを使用したCLIエージェントの呼び出し
AgentShellはCLIコーディングエージェントをヘッドレスで実行し、構造化された出力を返すPythonライブラリです。エージェント固有のCLI違いを統一されたインターフェースの背後に隠すため、どのエージェントが実行されても同じコードで動作します。
使用する場合
- PythonからClaude Code、OpenCode、または別のCLIエージェントを呼び出す必要がある
- コーディングタスクをサブエージェントに委譲し、結果を収集したい
- エージェント間の複数ステップのワークフローを統合する必要がある
- エージェント出力をリアルタイムでストリーミングしたい
使用しない場合
- Anthropic APIを直接呼び出したい(代わりにSDKを使用してください)
- CLIエージェントが既にインタラクティブに実行されており、その出力だけが必要である
インストール
uv add agent-shell-py
コアコンセプト
AgentShellには2つのメソッドがあります: 完全なレスポンスを収集するexecute()と、リアルタイムイベント処理を行うstream()です。どちらも非同期です。
Execute: 実行と収集
最終的な答えが必要で、中間出力は不要な場合に使用します。
from agent_shell.shell import AgentShell
from agent_shell.models.agent import AgentType
shell = AgentShell(agent_type=AgentType.CLAUDE_CODE)
response = await shell.execute(
cwd="/path/to/project",
prompt="Analyse the authentication module and list all public functions",
allowed_tools=["Read", "Glob", "Grep"],
model="sonnet",
)
print(response.response) # Full text output
print(f"Cost: ${response.cost:.4f}")
print(f"Session: {response.session_id}")
Stream: リアルタイムイベント
進捗フィードバックが必要な場合、出力を段階的に表示したい場合、または特定のイベントタイプ(ツール使用、思考、エラー)に反応する必要がある場合に使用します。
async for event in shell.stream(
cwd="/path/to/project",
prompt="Refactor the auth module to use dependency injection",
allowed_tools=["Read", "Edit", "Bash"],
model="sonnet",
effort="high",
include_thinking=True,
):
if event.type == "system":
print(f"Session: {event.session_id}")
elif event.type == "thinking":
print(f"[thinking] {event.content}")
elif event.type == "tool_use":
print(f"[tool] {event.content}")
elif event.type == "text":
print(event.content)
elif event.type == "result":
print(f"Done. Cost: ${event.cost:.4f}, Duration: {event.duration:.1f}s")
セッション再開
前のレスポンスのsession_idを渡して、会話を続行します。これにより、各ステップが前のステップに基づいて構築される複数ターンのワークフローが可能になります。
# ステップ1: 分析
analysis = await shell.execute(
cwd="/path/to/project",
prompt="Analyse this codebase and identify areas that need refactoring",
allowed_tools=["Read", "Glob", "Grep"],
model="sonnet",
)
# ステップ2: 分析に基づいて実行(同じセッション)
refactor = await shell.execute(
cwd="/path/to/project",
prompt="Now refactor the top priority item you identified",
allowed_tools=["Read", "Edit", "Bash"],
model="sonnet",
session_id=analysis.session_id,
)
パラメータ
| パラメータ | 型 | デフォルト | 目的 |
|---|---|---|---|
cwd | str | 必須 | 作業ディレクトリ(存在する必要があります) |
prompt | str | 必須 | エージェントへのタスクまたは質問 |
allowed_tools | list[str] | None | None | エージェントが使用できるツールを制限します。None = すべてのツール。Claude Codeのみ。 |
model | str | None | None | モデルエイリアスまたはフル名(例: "sonnet"、"claude-sonnet-4-6") |
effort | str | None | None | 推論努力: "low"、"medium"、"high"、"max"。Claude Codeのみ。 |
include_thinking | bool | False | フィルタのみ: CLIの出力に既に存在する場合、stream()で思考イベントを生成します。CLIフラグを追加しません。Claude Code stream()のみ。execute()では破棄されます。 |
auto_approve | bool | True | ツール許可プロンプトをスキップします。Claude Codeのみ。 |
session_id | str | None | None | 前のセッションを再開します |
エージェント互換性の警告: OpenCodeは現在、
modelとsession_idのみをCLIフラグにマッピングしています。allowed_tools、effort、include_thinking、auto_approveなどのパラメータは受け付けられていますが、暗黙的に無視されます。OpenCodeを使用する場合、allowed_toolsのセキュリティに依存しないでください。
サポートされるエージェント
from agent_shell.models.agent import AgentType
AgentType.CLAUDE_CODE # Claude Code CLI
AgentType.OPENCODE # OpenCode CLI
Gemini CLI、Copilot CLI、Codexには列挙値がありますが、まだアダプタがありません。
ツールスコーピング(Claude Codeのみ)
allowed_toolsを渡して、エージェントが実行できることを制限します。これは作業を委譲する場合のセキュリティに重要です。
重要: ツールスコーピングはClaude Codeのみで機能します。OpenCodeは
allowed_toolsを無視し、渡されたもの関係なくエージェントはすべてのツールにアクセスできます。ツール制限が必要なセキュリティに敏感な委譲にはOpenCodeを使用しないでください。
注意:
allowed_tools=[](空リスト)はPythonで偽であるため、--allowed-toolsフラグは送信されず、エージェントはすべてのツールにアクセスできます。ツールを制限するには、常に空でないリストを渡してください。このパラメータを通じてすべてのツールを無効にする方法はありません。
# 読み取り専用分析(Claude Code)
shell = AgentShell(agent_type=AgentType.CLAUDE_CODE)
response = await shell.execute(
cwd=project_path,
prompt="Review this code for security issues",
allowed_tools=["Read", "Glob", "Grep"], # 書き込みアクセスなし
)
# 実装のための完全な書き込みアクセス
response = await shell.execute(
cwd=project_path,
prompt="Implement the fix you recommended",
allowed_tools=["Read", "Edit", "Write", "Bash", "Glob", "Grep"],
)
エラーハンドリング
AgentShellは一部のエラーについて例外を発生させますが、CLIエージェントの失敗は例外ではなくイベントとして報告されます。
from pathlib import Path
# cwd検証 - ディレクトリが存在しない場合はValueErrorを発生させます
try:
response = await shell.execute(cwd="/nonexistent", prompt="hello")
except ValueError as e:
print(f"Bad directory: {e}")
# サポートされていないエージェントタイプ - 構築時にValueErrorを発生させます
try:
shell = AgentShell(agent_type=AgentType.GEMINI_CLI)
except ValueError as e:
print(f"No adapter: {e}")
# KeyboardInterrupt - AgentShellはサブプロセスをクリーンに取り消します
try:
response = await shell.execute(cwd=project_path, prompt="long task...")
except KeyboardInterrupt:
print("Agent cancelled")
CLIエージェントの失敗は例外を発生させません。 execute()は蓄積されたテキストを持つAgentResponseを返し(空の場合もあります)、失敗の兆候はありません。ストリーミング時には、失敗は2つの方法で表面化します:
StreamEvent(type="error")— CLIプロセスエラーまたはOpenCodeエージェントエラーStreamEvent(type="result", content="error")— Claude Codeエージェントレベルの失敗
ストリーミング時には両方をチェックします:
async for event in shell.stream(cwd=project_path, prompt="do something"):
if event.type == "error":
print(f"Agent error: {event.content}")
break
elif event.type == "result" and event.content == "error":
print("Agent reported failure")
break
elif event.type == "text":
print(event.content)
ログ
import logging
logging.getLogger("agent_shell").setLevel(logging.DEBUG)
logging.getLogger("agent_shell").addHandler(logging.StreamHandler())
INFOはツール呼び出し、セッションID、コスト、エラーをキャプチャします。DEBUGは生のJSONイベントを追加します。
クイックリファレンス
| やりたいこと | このようにします |
|---|---|
| 完全な答えを取得する | await shell.execute(cwd, prompt) |
| イベントをライブストリーミングする | async for event in shell.stream(cwd, prompt) |
| 会話を続行する | session_id=response.session_idを渡す |
| エージェント機能を制限する | allowed_tools=["Read", "Glob"]を渡す |
| コストを追跡する | response.costまたはevent.costを読み取る |
| 特定のモデルを使用する | model="sonnet"を渡す |
| 推論の深さを増やす | effort="high"を渡す |
| エージェントの思考を確認する | include_thinking=Trueを渡す |
| 実行中のエージェントをキャンセルする | KeyboardInterrupt(自動的に処理されます) |
よくある間違い
| 間違い | 修正方法 |
|---|---|
存在しないcwdを渡す | 呼び出し前にパスが存在することを確認します |
execute()のawaitを忘れる | execute()とstream()の非同期イテレータの両方が非同期コンテキストが必要です |
allowed_toolsをスコープしない(Claude Code) | 常にツールをタスクに必要な最小限に制限します |
OpenCodeでallowed_toolsが機能すると仮定する | OpenCodeはこのパラメータを無視します — ツール制限タスクにはClaude Codeを使用します |
execute()に思考が含まれると予想する | include_thinkingはstream()イベントのみに影響します; execute()は思考を破棄します |
stream()でエラーイベントを確認しない | エージェント失敗はStreamEvent(type="error")を生成し、例外を発生させません |
複数ステップ作業でsession_idを無視する | これなしでは、各呼び出しは前のコンテキストなしで新しい会話を開始します |
サポートされていないAgentTypeを使用する | 現在、CLAUDE_CODEとOPENCODEのみがアダプタを持っています |
API リファレンス
詳細なモデル定義、イベントタイプ、アダプタプロトコルについては: api-reference.mdを参照してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- ScottRBK
- リポジトリ
- ScottRBK/agent-shell
- ライセンス
- MIT
- 最終更新
- 2026/5/10
Source: https://github.com/ScottRBK/agent-shell / ライセンス: MIT