ツールシステムアーキテクチャ
概要
ツールシステムはAI Dev Agentのコア実行レイヤーです。
言語モデルが推論と計画を担当する一方で、ツールシステムは外部環境との対話を担当します。
これには以下の操作が含まれます:
- ファイルの読み書き
- シェルコマンドの実行
- Gitとの連携
- コードの分析
- テストの実行
- 知識の取得
ツールシステムはLLMと開発環境の間の決定論的で制御されたインターフェースを提供します。
設計目標
ツールシステムは以下の目標で設計されています。
決定論的実行
ツールは決定論的に動作し、構造化された出力を生成しなければなりません。
これにより、LLMがツール結果について確実に推論できます。
セキュリティと分離
ツールはローカルシステムと対話します。
したがって、実行は以下をサポートしなければなりません:
- 権限制御
- サンドボックス
- 制限された機能
コンポーザビリティ
ツールはコンポーザブルでなければなりません。
複雑な操作は単一のモノリシックなツールではなく、複数のツール呼び出しから構築されるべきです。
明示的インターフェース
すべてのツールは以下を公開しなければなりません:
- 明確な入力スキーマ
- 明確な出力スキーマ
- 予測可能な副作用
これにより、人間とAIエージェントの両方にとっての信頼性が向上します。
アーキテクチャ概要
ツールシステムは5つの主要コンポーネントで構成されています。
LLM
│
▼
ツール呼び出し
│
▼
ツールレジストリ
│
▼
権限システム
│
▼
ツールエグゼキューター
│
▼
環境各コンポーネントには明確に定義された責務があります。
ツールインターフェース
すべてのツールは共通のインターフェースを実装します。
TypeScriptインターフェース例:
export interface Tool<Input, Output> {
name: string
description: string
schema: {
input: JSONSchema
output: JSONSchema
}
execute(input: Input, context: ToolContext): Promise<Output>
}主要プロパティ:
name
ツールの一意の識別子。
description
LLMが使用する人間が読める説明。
schema
構造化された入力と出力の型を定義。
execute
ツールが呼び出されたときに実行される関数。
ツールコンテキスト
ツールは現在の実行環境に関するコンテキスト情報を受け取ります。
例:
export interface ToolContext {
workspaceRoot: string
workingDirectory: string
permissions: PermissionSet
memory: MemoryClient
logger: Logger
}これにより、ツールは以下を実行できます:
- リポジトリへのアクセス
- メモリの取得
- 実行のログ記録
- 権限境界の尊重
ツールレジストリ
ツールレジストリは利用可能なツールの管理を担当します。
責務:
- ツールの登録
- ツールの検出
- スキーマの取得
- バージョン管理
実装例:
class ToolRegistry {
private tools = new Map<string, Tool<any, any>>()
register(tool: Tool<any, any>) {
this.tools.set(tool.name, tool)
}
get(name: string) {
return this.tools.get(name)
}
list() {
return Array.from(this.tools.values())
}
}レジストリはツールの可用性の中央インデックスとして機能します。
ツール呼び出しフロー
典型的なツール実行フロー:
1. LLMがツール呼び出しを生成
2. ツール呼び出しをスキーマに対して検証
3. レジストリからツールを取得
4. 権限チェックを実行
5. ツールを実行
6. 構造化出力をLLMに返すこのパイプラインは安全性と信頼性を確保します。
権限システム
すべてのツールが常にアクセス可能であるべきではありません。
権限システムはツールアクセスを制御します。
権限モデル例:
type PermissionSet = {
filesystemRead: boolean
filesystemWrite: boolean
shellExecution: boolean
gitWrite: boolean
}異なるエージェントモードは異なる権限レベルを使用することがあります。
例:
| モード | 権限 |
|---|---|
| ReadOnly | ファイル読み取りのみ |
| Dev | ファイルの読み書き |
| CI | テストの実行 |
| Full | すべての権限 |
これにより、偶発的な破壊的アクションが防止されます。
ツールエグゼキューター
ツールエグゼキューターはツールを安全に実行する責務を持ちます。
責務:
- 入力の検証
- ツール実行の呼び出し
- エラーの処理
- 出力のキャプチャ
- タイムアウトの強制
例:
async function executeTool(
tool: Tool<any, any>,
input: unknown,
context: ToolContext
) {
validate(tool.schema.input, input)
const result = await tool.execute(input, context)
validate(tool.schema.output, result)
return result
}これにより入力と出力のスキーマコンプライアンスが確保されます。
ツールカテゴリー
ツールはいくつかのカテゴリーにグループ化されています。
ファイルシステムツール
プロジェクトファイルと対話します。
例:
- read_file
- write_file
- list_directory
- search_files
これらのツールにより、エージェントはコードベースを検査・変更できます。
Gitツール
バージョン管理と対話します。
例:
- git_status
- git_diff
- git_commit
- git_branch
これらのツールにより、エージェントはリポジトリの変更を管理できます。
シェルツール
システムコマンドを実行します。
例:
- run_command
- run_test_suite
- install_dependencies
シェルツールは強力であり、明示的な権限が必要です。
コード分析ツール
コード構造と依存関係を分析します。
例:
- parse_typescript_ast
- find_symbol_definition
- find_references
- dependency_graph
これらのツールにより、エージェントは大規模なコードベースを推論できます。
知識ツール
内部メモリまたはドキュメントを取得します。
例:
- search_memory
- retrieve_spec
- retrieve_design_doc
これらのツールはツールシステムをメモリアーキテクチャと接続します。
エラー処理
ツール実行は構造化されたエラーを生成しなければなりません。
例:
type ToolError = {
type: "validation" | "runtime" | "permission"
message: string
}構造化されたエラーにより、LLMが失敗から回復できます。
回復戦略の例:
- 異なる入力で再試行
- 代替ツールを選択
- 明確化を要求
可観測性
すべてのツール実行はログに記録されるべきです。
メタデータ例:
- ツール名
- 入力パラメーター
- 実行時間
- 出力サイズ
- エラー
ログにより以下が可能になります:
- デバッグ
- 監査
- パフォーマンス最適化
サンドボックス
一部のツールは信頼できないコードやシェルコマンドを実行する可能性があります。
これらのツールはサンドボックス化された実行環境をサポートすべきです。
可能なアプローチ:
- コンテナ化された実行
- 制限シェル環境
- 一時作業ディレクトリ
サンドボックスはシステムへのダメージのリスクを削減します。
将来の拡張
ツールシステムは拡張可能に設計されています。
可能な将来の拡張:
- リモートツール実行
- 分散ビルドツール
- クラウドリソース管理
- デプロイメントツール
ツールは統一されたインターフェースを使用するため、コアエージェントロジックを変更せずに新しい機能を追加できます。
まとめ
ツールシステムはAI Dev Agentの実行バックボーンです。
LLMと開発環境の間の構造化されたインターフェースを提供します。
コアコンポーネント:
- ツールインターフェース
- ツールレジストリ
- 権限システム
- ツールエグゼキューター
- サンドボックス環境
このアーキテクチャにより、AIエージェントがソフトウェアエンジニアリングタスクを安全かつ決定論的に実行できます。