115 lines
5.1 KiB
Markdown
115 lines
5.1 KiB
Markdown
# Worker Macro Documentation
|
||
|
||
## `#[tool]` マクロ
|
||
|
||
関数をLLMツールとして登録するためのプロシージャルマクロです。関数のドキュメントコメントを自動抽出してツール説明として利用し、JSONスキーマ生成、動的ツール登録に必要な`Tool` trait実装を自動生成します。
|
||
|
||
**重要**: このマクロはCore Crate Patternに基づき`worker-macros`クレートで実装され、`worker-types`クレートの型を完全修飾パスで直接参照しています。これにより循環依存を防ぎ、保守性の高いアーキテクチャを実現しています。
|
||
|
||
### 基本的な使用方法
|
||
|
||
```rust
|
||
use worker_macros::tool;
|
||
use worker::types::ToolResult; // worker-typesからの再エクスポート
|
||
use serde::{Deserialize, Serialize};
|
||
use schemars::JsonSchema;
|
||
|
||
#[derive(Deserialize, Serialize, JsonSchema)]
|
||
struct CalculateArgs {
|
||
/// 第一の数値
|
||
a: i32,
|
||
/// 第二の数値
|
||
b: i32,
|
||
}
|
||
|
||
/// 二つの数値を加算し、結果を返します。
|
||
/// このコメントはLLMに送られるツール説明になります。
|
||
#[tool]
|
||
async fn calculate(args: CalculateArgs) -> ToolResult<i32> {
|
||
Ok(args.a + args.b)
|
||
}
|
||
```
|
||
|
||
### 動的ツール登録での使用方法
|
||
|
||
```rust
|
||
// Worker初期化
|
||
let mut worker = Worker::new(
|
||
LlmProvider::Gemini,
|
||
"gemini-1.5-flash",
|
||
&api_keys,
|
||
None
|
||
)?;
|
||
|
||
// マクロで生成されたツールを登録
|
||
worker.register_tool(Box::new(CalculateTool::new()))?;
|
||
|
||
// ツール実行
|
||
let args = serde_json::json!({"a": 10, "b": 20});
|
||
let result = worker.execute_tool("calculate", args).await?;
|
||
println!("Result: {}", result); // Result: 30
|
||
```
|
||
|
||
### 機能
|
||
|
||
1. **自動ドキュメント抽出**: 関数のドキュメントコメント(`///`)を自動抽出してツール説明として使用
|
||
2. **JSONスキーマ生成**: `schemars`を使用して引数型からJSONスキーマを自動生成
|
||
3. **フォールバック説明**: ドキュメントコメントがない場合、関数名からデフォルト説明を生成
|
||
4. **Tool trait実装**: 動的ツール登録に必要な全メソッドを自動実装
|
||
5. **エラーハンドリング**: `ToolResult<T>`型を使用した一貫したエラー処理
|
||
|
||
### 要件
|
||
|
||
- **関数シグニチャ**: `async fn`である必要があります
|
||
- **引数型**: 単一の構造体で`Deserialize + Serialize + JsonSchema`トレイトを実装必要
|
||
- **返り値型**: `ToolResult<T>`で`T`は`Serialize + JsonSchema`トレイトを実装必要
|
||
- **エラー型**: `ToolResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>`(`worker-types`で定義)
|
||
|
||
**注意**: プリミティブ型(`i32`, `String`等)を直接引数に使用することはできません。必ず構造体でラップしてください。
|
||
|
||
### 生成されるコード
|
||
|
||
マクロは以下の要素を自動生成します:
|
||
|
||
1. **元の関数**: 元のasync関数をそのまま保持
|
||
2. **Tool構造体**: 関数名からPascalCaseで構造体名を生成(`read_file` → `ReadFileTool`)
|
||
3. **Tool trait実装**: 以下のメソッドを自動実装:
|
||
- `name()`: 関数名を返す
|
||
- `description()`: ドキュメントコメントから抽出
|
||
- `parameters_schema()`: 引数型からJSONスキーマを生成
|
||
- `execute()`: 元の関数を呼び出して結果をシリアライズ
|
||
|
||
**実装詳細**: マクロは`::worker_types::`名前空間で型を参照し、`async_trait`を使用してtrait実装を行います。
|
||
|
||
### 自動生成される構造体名
|
||
|
||
関数名からsnake_caseをPascalCaseに変換し、`Tool`サフィックスを付加:
|
||
- `read_file` → `ReadFileTool`
|
||
- `calculate_sum` → `CalculateSumTool`
|
||
- `fetch_data` → `FetchDataTool`
|
||
- `send_email` → `SendEmailTool`
|
||
- `process_image` → `ProcessImageTool`
|
||
|
||
**コンストラクタ**: 生成された構造体には`new()`メソッドが自動的に提供されます。
|
||
|
||
## Core Crate Patternとの統合
|
||
|
||
`#[tool]`マクロはCore Crate Patternの利点を最大限に活用:
|
||
|
||
- **循環依存の完全回避**: `worker-macros` → `worker-types`の一方向依存のみ
|
||
- **コンパイル時型安全性**: 型チェックで実行時エラーを事前検出
|
||
- **自動更新保守性**: `worker-types`の型変更がマクロ生成コードに自動反映
|
||
- **拡張容易性**: 新しいtraitや機能を簡単に追加可能
|
||
- **パフォーマンス**: コンパイル時コード生成で実行時オーバーヘッドなし
|
||
|
||
## メリットと使用事例
|
||
|
||
このアーキテクチャにより、以下のような利点が得られます:
|
||
|
||
- **簡单なツール作成**: 関数にマクロを付けるだけでLLMツール完成
|
||
- **ドキュメント連動**: コメントがそのままLLMのツール説明に
|
||
- **型安全なインターフェース**: JSONシリアライゼーションを自動処理
|
||
- **動的登録サポート**: 実行時ツールの追加・削除が可能
|
||
- **MCP統合**: Model Context Protocolとのシームレスな連携
|
||
|
||
これにより、柔軟性と使いやすさを兼ね備えたツールシステムが実現されています。 |