# rig 参照設計の導入実装方針 ## 目的 `llm_worker_rs` の既存方針(Timeline中心、Worker主導)を維持しながら、`rig` 由来で有効だった設計を段階導入する。 対象は以下の5項目。 1. Tool 実行を `ToolServer` 的に分離する 2. Hook をストリーミング粒度まで拡張する 3. Typed output(構造化出力)の第一級 API 化 4. Provider 固有最適化を provider 層で吸収する 5. GenAI telemetry を標準実装にする --- ## 1. Tool 実行を `ToolServer` 的に分離する ✅ ### 目的 Worker から「ツール登録・呼び出し・定義解決・動的選択」の責務を分離し、Worker は turn orchestration と hook 制御に集中させる。 ### 実装状況: ✅ 完了 - `tool_server.rs` に `ToolServer` / `ToolServerHandle` を実装済み。 - `Worker` は `ToolServerHandle` を保持し、直接 `Tool` マップを持たない設計に移行済み。 - `Worker::register_tool()` は内部で `ToolServerHandle::register_tool()` を呼ぶ形に統一済み。 - ツール実行は `ToolServerHandle::call_tool(name, args)` 経由に統一済み。 - `tool_definitions_sorted()` で決定的順序のツール定義送信を実装済み。 - 単体テスト(重複登録・未登録呼び出し・ソート順)を `tool_server.rs` 内に実装済み。 ### 計画との差分 - `ToolExecutor` trait 抽象は未導入。現状 `ToolServerHandle` が具象型として直接使われている。remote tool / MCP 対応時に trait 化する余地あり。 --- ## 2. Hook をストリーミング粒度まで拡張する ✅ ### 目的 Text/Tool delta を受けた時点でフック介入できるようにし、監査・UI 連携・早期停止を改善する。 ### 実装状況: ✅ 完了 - `hook.rs` に以下の streaming 系イベント種別を追加済み: - `OnTextDelta` (入力: `TextDeltaContext`) - `OnToolCallDelta` (入力: `ToolCallDeltaContext`) - `OnStreamChunk` (入力: `StreamChunkContext`) - `OnStreamComplete` (入力: `StreamCompleteContext`) - 戻り値は `StreamHookResult { Continue | Abort(String) | Pause }` で統一済み。 - `Worker` に個別登録 API を実装済み: - `add_on_text_delta_hook()` - `add_on_tool_call_delta_hook()` - `add_on_stream_chunk_hook()` - `add_on_stream_complete_hook()` - `HookRegistry` に全 streaming hook のストレージを追加済み。 - `worker.rs` の stream dispatch ループ内で `BlockDelta` 受信時に各 hook を順序保証付きで呼び出し済み。 - `Abort` / `Pause` の制御線が Worker の run ループに接続済み。 ### 計画との差分 - 高レベル統合 API(subscriber/DSL)は `worker_api_plan` 側で別途進行中。 - 実行順序仕様の文書化は未完了(コード上は登録順実行を実装済み)。 --- ## 3. Typed output(構造化出力)の第一級 API 化 ⬚ ### 目的 「テキストを返して呼び出し側で JSON parse」から脱却し、型付きレスポンスを API レベルで保証する。 ### 実装状況: ⬚ 未着手 - `run_typed()` API は未実装。 - `output_schema` の request builder 統合は未実装。 - エラー種別(`StructuredOutputUnsupported` / `Deserialize` / `Empty`)は未追加。 ### 次のステップ 1. `output_schema` を Worker request builder に追加 2. typed 実行 API と decode ロジックを実装 3. provider capability 判定を `llm_client` 層に追加 4. エラー型とユーザー向けメッセージを整理 --- ## 4. Provider 固有最適化を provider 層で吸収する 🔄 ### 目的 キャッシュ、beta header、細粒度 stream 差分などの provider 特有処理を Worker から排除する。 ### 実装状況: 🔄 部分的に進行 - `llm_client/providers/*` に Anthropic / OpenAI / Gemini / Ollama の provider 実装が存在する。 - `llm_client/scheme/*` に各 provider の request/events 変換が分離済み。 - Worker は provider 非依存の `Event` を Timeline 経由で処理する設計に移行済み。 - ただし `ProviderOptions` 型や capability trait は未導入。 ### 次のステップ 1. provider capability trait を追加 2. 既存 provider 実装を capability 駆動へ移行 3. Worker 側に残る provider 分岐があれば削除 --- ## 5. GenAI telemetry を標準実装にする ⬚ ### 目的 運用時に必要な追跡情報(turn、tool call、usage、latency、abort reason)を一貫して記録可能にする。 ### 実装状況: ⬚ 未着手 - `tracing` クレートは依存に含まれており、`worker.rs` 内で `debug!` / `info!` / `trace!` / `warn!` マクロが使用されている。 - ただし GenAI semantic conventions に沿った構造化 span は未実装。 - `TelemetryConfig` / telemetry モジュールは未追加。 ### 次のステップ 1. telemetry モジュール追加(field key 定義) 2. Worker/timeline/tool/hook に span 計装 3. usage と stop reason を終了イベントで集約 4. ログとメトリクス出力の最小 adapter を実装 --- ## 導入順序(更新版) 1. ~~ToolServer 分離~~ ✅ 2. ~~Streaming Hook 拡張~~ ✅ 3. Telemetry 標準化 ⬚ 4. Typed output API ⬚ 5. Provider capability 移行の仕上げ 🔄 --- ## チケット分解(実装順・進捗付き) ### Epic A: ToolServer 分離 ✅ | ID | タイトル | 状態 | 備考 | | --- | --- | --- | --- | | A1 | ToolServer 最小骨格の追加 | ✅ | `tool_server.rs` に `ToolServer` / `ToolServerHandle` 実装済み | | A2 | Worker の tool map を ToolServerHandle に置換 | ✅ | `Worker` は `ToolServerHandle` を保持。`register_tool` / `call_tool` / `tool_definitions_sorted` 全て経由 | | A3 | Hook context を ToolServer 参照へ接続 | ✅ | `pre_tool_call` / `post_tool_call` で `ToolCallContext` に `meta` / `tool` を `ToolServerHandle::get_tool()` から取得 | | A4 | KV キャッシュ保護ルールの実装 | ✅ | `CacheLocked` 型状態パターンで実装。`lock()` 後は prefix の変更が型レベルで防止される | | A5 | ToolServer 単体/統合テスト追加 | ✅ | `tool_server.rs` 内に重複登録・未登録呼び出し・ソート順のテスト実装済み | ### Epic B: Streaming Hook 拡張 ✅ | ID | タイトル | 状態 | 備考 | | --- | --- | --- | --- | | B1 | Hook event 種別追加(delta/stream) | ✅ | `OnTextDelta` / `OnToolCallDelta` / `OnStreamChunk` / `OnStreamComplete` 定義済み | | B2 | Timeline dispatch に hook 呼び出し点追加 | ✅ | `BlockDelta` 受信時に hook 実行。stream dispatch ループ内に組み込み済み | | B3 | Abort/Pause 制御線の接続 | ✅ | `StreamHookResult` の `Abort` / `Pause` が Worker の run ループに接続済み | | B4 | 実行順序仕様と回帰テスト | 🔄 | コード上は登録順実行を実装。仕様文書化・専用回帰テストは未完了 | ### Epic C: Telemetry 標準化 ⬚ | ID | タイトル | 状態 | 備考 | | --- | --- | --- | --- | | C1 | telemetry モジュールと semantic key 定義 | ⬚ | 未着手 | | C2 | worker/turn/llm/tool/hook span 計装 | ⬚ | 未着手。`tracing` の基本利用はあるが構造化 span は未実装 | | C3 | マスキング設定と no-op 運用 | ⬚ | 未着手 | | C4 | telemetry テスト/サンプル整備 | ⬚ | 未着手 | ### Epic D: Typed Output API ⬚ | ID | タイトル | 状態 | 備考 | | --- | --- | --- | --- | | D1 | Request builder に output_schema 追加 | ⬚ | 未着手 | | D2 | `run_typed` / `run_typed_with_history` 実装 | ⬚ | 未着手 | | D3 | 非対応 provider のフォールバックとエラー分離 | ⬚ | 未着手 | | D4 | typed 出力の回帰テスト | ⬚ | 未着手 | ### Epic E: Provider Capability 移行 🔄 | ID | タイトル | 状態 | 備考 | | --- | --- | --- | --- | | E1 | provider capability trait 導入 | ⬚ | 未着手 | | E2 | Anthropic/OpenAI/Gemini の capability 移行 | 🔄 | scheme 層での request/events 分離は完了。capability trait は未導入 | | E3 | Worker 側 provider 分岐の削除 | 🔄 | Worker は Event ベースで provider 非依存に近いが、完全な分離は未検証 | | E4 | snapshot テストと責務ドキュメント更新 | ⬚ | 未着手 | --- ## チケット運用ルール - 各 ticket は `feature/-...` ブランチで実装する。 - 依存 ticket が `main` に入るまで、後続 ticket は着手しない。 - 各 ticket で最低 1 つ回帰テストを追加する(ドキュメント専用 ticket を除く)。 - `CacheLocked` の prefix 不変性を崩す変更は、A4 と同時に防止テストを追加する。 - tool 定義のリクエスト化は決定的順序にする(内部保持が `HashMap` でも送信順は固定)。 ## 非目標 - 既存 Worker API の全面破壊的変更 - 1回の PR で5項目を同時に実装 - Open Responses 完全準拠の即時達成 ## 備考 `llm_worker_rs` は Timeline 駆動設計が中核であり、この方針は維持する。`rig` の設計は部品として参照し、全体アーキテクチャは置換しない。