diff --git a/TODO.md b/TODO.md index 93cc88a0..8d85c9dc 100644 --- a/TODO.md +++ b/TODO.md @@ -17,7 +17,6 @@ - [ ] TUI 補完 + 型付き atom 化 → [tickets/submit-tui-completion.md](tickets/submit-tui-completion.md) - [ ] FileRef リゾルバ → [tickets/submit-file-ref-resolver.md](tickets/submit-file-ref-resolver.md) - [ ] メモリ機構 - - [ ] Phase 2 consolidation → [tickets/memory-phase2-consolidation.md](tickets/memory-phase2-consolidation.md) + - [ ] Phase 2 consolidation + 整理 → [tickets/memory-phase2-consolidation.md](tickets/memory-phase2-consolidation.md) - [ ] 使用頻度メトリクス + Knowledge 化候補レポート → [tickets/memory-usage-metrics.md](tickets/memory-usage-metrics.md) - - [ ] GC(定期再評価) → [tickets/memory-gc.md](tickets/memory-gc.md) - ワークスペースのメモリーをLintするヘッドレスCLI diff --git a/docs/plan/memory-prompts.md b/docs/plan/memory-prompts.md index 02274130..147067f0 100644 --- a/docs/plan/memory-prompts.md +++ b/docs/plan/memory-prompts.md @@ -29,18 +29,31 @@ Phase 1 は「派生物を作る」段階ではなく、「起きたことを抽 - 出力は schema 準拠の構造化データのみ。自由文の補足説明で schema 外情報を足さない - 対象が無ければ空配列を返す -### Phase 2: 統合 prompt +### Phase 2: 統合 + 整理 prompt -Phase 2 は既存 `memory/*`、`knowledge/*`、staging を見て、追加・更新・統合を agentic に判断する: +Phase 2 は既存 `memory/*`、`knowledge/*`、staging を見て、統合 phase と整理 phase を 1 セッション内で続けて回す。両 phase に共通する原則: -- 入力には staging の活動ログ、既存 `memory/*`(summary / decisions / requests)の全文、Knowledge 化候補レポートを含める +- 入力には staging の活動ログ、既存 `memory/*`(summary / decisions / requests)の全文、Knowledge 化候補レポート、整理材料(使用頻度メトリクス、Linter Warn、`replaced` chain、sources 過多情報)を含める - 既存 `knowledge/*` は prompt に埋めず、Knowledge 検索ツール経由で agent が必要分を引く。まず候補レポートの source や staging の話題に近い slug を検索し、ヒットした slug / description / kind / `model_invokation` を見て適合先を探す - 新規作成より update を優先し、既存 slug に自然に統合できる場合は新規 file を増やさない - Decisions / Requests は staging の `source` をそのまま使い、LLM が `sources` を組み立てない - summary は必要なときだけ rewrite し、常に 1-5k tokens 目安に圧縮する -- 削除は直接行わず、Decision の置き換えは `status: replaced` と `replaced_by` で表現する +- Decision の置き換えは `status: replaced` と `replaced_by` で表現する - 人間編集との不整合が見える rewrite は避け、衝突しそうなら保守的に統合する +統合 phase の追加指示: + +- staging の活動ログを decisions / requests / summary / Knowledge update に落とし込む +- Knowledge 新規作成は候補レポート掲載 source 由来に限る(詳細は §Phase 2: Knowledge 書き込み prompt) + +整理 phase の追加指示(統合 phase 完了後、余力で実行): + +- 既存 record 群を `outdated`、`superseded`、`unused`、`noisy` の観点で評価し、なぜ整理対象なのかを分類する +- 明示 invoke の保護閾値超過 record は drop / 大幅圧縮の対象外とする +- `similar-slug`、`sources-overflow`、`replaced` 滞留は主に `superseded` または `noisy` の材料として扱う +- merge / split / trim / drop の理由を git diff から読める形で残す +- 直接削除してよいが、git で可逆である前提に甘えすぎず、誤判定しやすいものは merge / trim を優先する + ### Phase 2: Knowledge 書き込み prompt Knowledge の新規作成 / 更新では、Phase 2 全体の原則に加えて以下を明示する: @@ -63,17 +76,6 @@ Knowledge の新規作成 / 更新では、Phase 2 全体の原則に加えて 初期範囲では専用の監査 LLM は持たない(`memory.md` §書き込み経路と Linter / §将来検討 参照)。意味破壊の抑制は Phase 2 prompt 側の情報損失最小化指示と git diff レビューに寄せる。後から 2 層目として挟む際の入力・check 項目・pass-fail 返却形式はそのときに詰める。 -### GC prompt - -GC は Phase 2 より攻撃的に整理してよいが、可逆性と説明可能性を保つ: - -- 入力には GC 対象 record 群に加えて、Linter Warn、使用頻度メトリクス、`replaced` chain、sources 過多情報を含める -- 明示 invoke 保護閾値を超える record は drop / 大幅圧縮の対象外とする -- 各 record を `outdated`、`superseded`、`unused`、`noisy` の観点で評価し、なぜ GC 対象なのかを分類する -- `similar-slug`、`sources-overflow`、`replaced` 滞留は主に `superseded` または `noisy` の材料として扱う -- merge / split / trim / drop の理由を diff から読める形で残す -- 直接削除してよいが、git で可逆である前提に甘えすぎず、誤判定しやすいものは merge / trim を優先する - ## 関連 - `docs/plan/memory.md`: memory 全体方針 diff --git a/docs/plan/memory.md b/docs/plan/memory.md index 9d97b07f..58a7e471 100644 --- a/docs/plan/memory.md +++ b/docs/plan/memory.md @@ -44,7 +44,7 @@ Knowledge は Phase 2 が自律的に新規作成 / 更新 / フラグ切替を - **採択 gate**: Knowledge 新規作成は使用頻度メトリクスの Knowledge 化候補レポート(後述)に載った source から派生する場合に限る。閾値未満のうちは decisions / requests に留める - **Linter**: 構造違反を watch(詳細は後述)。意味破壊の自動検出は初期は持たず、挙動を見てから監査 LLM 層を追加する(将来検討) -- **OS ファイル権限**: 人間が書き換えさせたくない record は `-r--` にしてロック。Phase 2 / GC の write は OS レベルで弾かれる +- **OS ファイル権限**: 人間が書き換えさせたくない record は `-r--` にしてロック。Phase 2 の write は OS レベルで弾かれる Workflow も同じフラグ仕様(`workflow.md` 参照)。per-record 保護フラグを提供する拡張は将来検討、初期は OS 権限で足りる。 @@ -135,15 +135,16 @@ Workflow 保護は専用 tool schema のトリックではなく Linter ルー - **Compact との順序**: 同一 turn 完了後の post-run チェックで Phase 1 を **compact より前** に走らせる。compact は history を組み替えるので、extract の入力範囲(session log 上の entry index)は compact 前のほうが安定する - **並走防止 (Phase 1 同士)**: Pod 上の `extract_in_flight` フラグで in-flight 中の新規 trigger を skip。完了時点で閾値超過していれば直ちに次回を発火し、新 pointer 以降の最大範囲を回収する(pending 状態は保持しない=完了時の閾値再評価で coalesce 相当の挙動を成立させる) -#### Phase 2: 永続化への統合 +#### Phase 2: 永続化への統合 + 整理 -- **Trigger**: staging の累積ファイル数 or bytes が閾値超過、または compact 発火時(必ず flush) +- **Trigger**: staging の累積ファイル数 or bytes が閾値超過 - **実行主体**: Phase 1 を終えた pod が consolidation Worker を spawn。並走防止は staging 配下の進行状況ファイル(後述)で担保 -- **入力**: 起動時スナップショットで確定した consumed ID list 分の staging エントリ(活動ログ + `source`)+ 既存 `memory/*`(summary / decisions / requests)の全文 + **Knowledge 化候補レポート**(後述の使用頻度メトリクスから機械集計、閾値超過の source 一覧)。既存 `knowledge/*` は全文を prompt に埋めず、Knowledge 検索ツール経由で agent が必要分を引く +- **入力**: 起動時スナップショットで確定した consumed ID list 分の staging エントリ(活動ログ + `source`)+ 既存 `memory/*`(summary / decisions / requests)の全文 + **Knowledge 化候補レポート**(後述の使用頻度メトリクスから機械集計、閾値超過の source 一覧)+ **整理材料**(明示 invoke の使用頻度メトリクス、Linter Warn、`replaced` chain、sources 過多情報)。既存 `knowledge/*` は全文を prompt に埋めず、Knowledge 検索ツール経由で agent が必要分を引く - **処理**: sub-Worker に **memory 専用 Tool(read / write / edit、Linter 内蔵)+ Knowledge 検索ツール + memory 検索ツール** を渡し、agentic に以下を自律判断: - - 新規 decisions / requests を 1 件 1 ファイルで追加。`sources` は staging の `source` をコピー(LLM 推論ではない) + - **統合**: 新規 decisions / requests を 1 件 1 ファイルで追加。`sources` は staging の `source` をコピー(LLM 推論ではない) - 活動ログから派生する Knowledge(用語定義 / 運用方針 / ルール / 事実 / ノウハウ)を新規作成 or 既存 patch。**新規作成は候補レポート掲載の source から派生する場合に限る**。`kind` を frontmatter に持ち、`last_sources` を更新 - summary を必要に応じて rewrite + - **整理(余力 phase)**: 既存 record 群を §評価カテゴリ で評価し、保護閾値外の対象を drop / merge / split / trim / rewrite。Linter Warn で検出した類似 slug 乱立 / sources 過多 / `replaced` 滞留はここで収斂させる - **書き込み先**: `memory/*` と `knowledge/*`。Workflow 禁止は Linter で担保(`workflow.md` 参照) - **完了処理**: consumed ID list の staging のみ cleanup(実行中に Phase 1 が追加した分は残す)。Phase 2 完了時に staging に新着があれば次を発火(Coalesce) - **モデル**: `memory.consolidation_model`。reasoning 系 @@ -164,7 +165,9 @@ Workflow 保護は専用 tool schema のトリックではなく Linter ルー - **rewrite は許可**。既存内容と新規情報を統合・再構成して情報密度を上げることを優先。単純 append(追記で増やすだけ)は避ける - rewrite 時は**情報損失を最小化**する: 既存の主張・根拠・sources を保持。表現を整理・短縮しても、含まれている要素は落とさない -- 削除は置き換え記録(`status: replaced` + `replaced_by: `)で表現、直接削除しない +- Decision の置き換えは `status: replaced` + `replaced_by: ` で表現、直接削除しない +- 整理 phase での drop は許可。ただし保護閾値(§判断ルール)超過 record は drop / 大幅圧縮の対象外。誤判定しやすいものは merge / trim を優先 +- 各 record の整理理由は `outdated | superseded | unused | noisy` の §評価カテゴリ で説明可能にし、git diff から読み取れる粒度の操作にする - Knowledge は既存 record 群の slug / description / kind / `model_invokation` を入口に適合先を探し、自然に統合できるなら新規 slug を増やさない - 人間編集は git diff で顕在化する前提。整合しない rewrite は避け、衝突時は git で解決 @@ -176,11 +179,11 @@ Memory record の書き込みは Phase 2 が自律判断し、Offer は設けな #### Compact との関係 -基本分離(memory は独立トリガー、compact は `input_tokens` 既存閾値のまま)。ただし **compact 発火時は Phase 2 を必ず同時 flush**(compact で失われる raw を漏らさないため)。 +基本分離(memory は独立トリガー、compact は `input_tokens` 既存閾値のまま)。compact で失われる session log の raw は **Phase 1 が compact より前に走ることで staging に保全**される(§Phase 1 §Compact との順序 参照)。Phase 2 を compact に同期させる義務はなく、staging 累積閾値で独立に発火する。 -### GC(定期再評価) +### 整理(GC 相当)の扱い -Phase 2 とは別経路で memory を再評価する定期ジョブ。Phase 2 は rewrite 許可で情報統合寄りの働きをするが、それでも残る以下の課題の出口として機能する: +Phase 2 は rewrite 許可で情報統合寄りの働きをするが、それでも残る以下の課題は **Phase 2 の余力 phase で同じ agent が処理**する(独立 trigger / 独立 Agent は持たない): - 重要度の低い record が累積する - 類似 slug が乱立する(Linter Warn で検出したものをまとめて処理) @@ -190,25 +193,23 @@ Phase 2 とは別経路で memory を再評価する定期ジョブ。Phase 2 他プロジェクトの GC 設計の横断比較は `docs/ref/memory-systems.md` §8。 -#### 権限と操作粒度 +#### 操作粒度 -GC Agent は **drop / merge / split を自律実行**(削除まで含む)。人間 offer はかけず、結果は git diff で検証する建て付け。operation 粒度は以下の両方: +整理 phase は Phase 2 統合 phase と同じ memory 専用 Tool(read / write / edit、内部で pre-write Linter)を使う。operation 粒度は自然にサポートされる(専用 API は用意しない): - **ファイル単位**: 丸ごと drop、複数ファイルの merge、1 ファイルの分割(split) - **ファイル内の部分削除**: 本文の一部節・箇条を削除 or 圧縮。frontmatter の `sources` 古いエントリの trim も含む -Phase 2 と同じ memory 専用 Tool(read / write / edit、内部で pre-write Linter)を使うので、operation 粒度は自然にサポートされる(専用 API は用意しない)。 +#### 評価カテゴリ -#### GC の評価カテゴリ - -GC は record を一律に「stale」とみなさず、少なくとも次の 4 カテゴリで評価する: +整理対象 record は一律に「stale」とみなさず、少なくとも次の 4 カテゴリで評価する: - `outdated`: 以前は妥当だったが、現在の実装・方針・運用と不整合になっている - `superseded`: 別 record が実質的な正本になっており、元の record は置き換え済みに近い - `unused`: 誤りではないが、明示 invoke や検索でほとんど参照されずノイズ化している - `noisy`: 内容自体は有効でも、粒度・重複・冗長さ・sources 過多などで discovery / retrieval を悪化させている -これらは **保護条件ではなく GC 理由の分類**。保護条件は別に持ち、その上で `drop / merge / split / trim / rewrite` のどれを選ぶかをこのカテゴリで説明可能にする。 +これらは **保護条件ではなく整理理由の分類**。保護条件は別に持ち、その上で `drop / merge / split / trim / rewrite` のどれを選ぶかをこのカテゴリで説明可能にする。 #### 使用頻度メトリクス @@ -226,12 +227,12 @@ GC は record を一律に「stale」とみなさず、少なくとも次の 4 **累積方式**(後集計アプローチ): 上記 invoke 記録に対して最大 10 回前の invoke から現在までの時系列窓でフィルタして集計する。 -**Knowledge 化候補レポート**: Phase 2 が入力に受け取る、Knowledge 新規作成 gate 用の機械集計。対象は `memory/*` 配下の record(Phase 1 成果物である decisions / requests / 既存 knowledge)で、明示 invoke 頻度が閾値超過のものを列挙する。spike 除外のため、同一 session 内の連続参照は 1 count に丸め、複数 session での再参照を要件とする。閾値の具体値は運用で調整、設定ファイルで tune。 +**Knowledge 化候補レポート**: Phase 2 統合 phase が入力に受け取る、Knowledge 新規作成 gate 用の機械集計。対象は `memory/*` 配下の record(Phase 1 成果物である decisions / requests / 既存 knowledge)で、明示 invoke 頻度が閾値超過のものを列挙する。spike 除外のため、同一 session 内の連続参照は 1 count に丸め、複数 session での再参照を要件とする。閾値の具体値は運用で調整、設定ファイルで tune。 #### 判断ルール - 保護閾値: **明示 invoke** の `frequency >= 1.0 invokes/Mtoken` の record は drop / 大幅圧縮の対象外(初期値 1.0、workspace 設定でカスタマイズ可)。`model_invokation` 注入による常駐は計数対象外(別指標として後段で参照) -- GC の評価カテゴリは `outdated | superseded | unused | noisy` を使う。単一 record が複数カテゴリに該当してもよい +- 整理 phase の評価カテゴリは `outdated | superseded | unused | noisy` を使う。単一 record が複数カテゴリに該当してもよい ### ファイル形式 diff --git a/docs/plan/tool_dispatch.md b/docs/plan/tool_dispatch.md new file mode 100644 index 00000000..20771fb8 --- /dev/null +++ b/docs/plan/tool_dispatch.md @@ -0,0 +1,135 @@ +# 複数ツール動的読み込み機構の設計 + +## Context + +INSOMNIA はエージェントが扱うツール数の増加 (built-in tools + MCP サーバ + ユーザ定義) を想定する必要がある。すべてを upfront に context へ展開すると以下が問題になる: + +- **入力トークン消費**: 30-50 ツールで 10-20K tokens を消費しうる (Anthropic 公式ガイド) +- **ツール選択精度の低下**: 数十個を超えるとモデルの tool selection accuracy が落ちる +- **KV cache 効率**: ローカル推論では prefill コストが重く、prefix が動くと再計算が走る + +Claude Code が採用する deferred tools 機構 (`docs/ref/claude-code-deferred-tools.md`) と OpenAI Harmony のアプローチ (`docs/ref/tool_approach_comparison.md`) を比較すると、**全モデルで同じ deferred 方式は通用しない**。モデルファミリごとに戦略を切り替えられる抽象が必要。 + +## 決定事項 + +### 二層分離: Registry / ContextRenderer + +ツール抽象を以下の二層に分ける。両者の責務を厳密に切り離す。 + +| 層 | 責務 | 単一の真実 | +|---|---|---| +| Registry | ツール実装・schema・名前解決・引数バリデーション | 全ツール常時登録 | +| ContextRenderer | モデルへ渡す prompt にどの tool 定義を、どの形式で、どこに置くか | モデル戦略ごとに差し替え | + +**重要**: バリデーションは **Registry 側で実引数 vs 登録 schema の照合**だけで行う。「context にスキーマテキストが現れているか」は検証条件にしない (Claude Code 実演で確認済み: `claude-code-deferred-tools.md` §10)。これにより、ContextRenderer がどんな戦略で schema を見せていようと、registry の真実性が一本化される。 + +### 戦略 (RenderStrategy) のモデル系統別マッピング + +| モデル系統 | 戦略 | 根拠 | +|---|---|---| +| Claude 系 (Anthropic API + ローカル Anthropic 互換) | **Deferred** + ToolSearch 相当 | XML+JSON のテキスト表現で tool_result からも schema 注入可。prefix 安定 | +| OpenAI 系 (gpt-oss / Harmony / Responses) | **Upfront** + MCP-style dispatcher | namespace ブロックが構造化されており、後追い注入が訓練分布外。汎用 dispatcher で外部解決 | +| Hermes / Qwen / Llama 等独自系 | **Upfront** または **Rolling Developer Message** | モデル個別 chat template に従い、必要なら境界で書き換え | + +### 戦略を決める軸 + +`RenderStrategy` は以下の組み合わせで表現: + +- **配置**: `SystemPrompt` (固定) / `DeveloperMessage` (cache 境界) / `ToolResultStream` (Claude 流注入) +- **発見手段**: `AlwaysVisible` / `MetaTool { search, describe }` / `Static` +- **変更時の cache 影響**: `PrefixStable` / `RewindToBoundary` + +Claude 系 = `(ToolResultStream, MetaTool, PrefixStable)`、OpenAI 系 = `(DeveloperMessage, Static, RewindToBoundary)` または `(SystemPrompt + dispatcher, AlwaysVisible, PrefixStable)`。 + +## 設計詳細 + +### Registry インターフェース + +```rust +pub trait ToolRegistry { + fn list(&self) -> Vec; // 名前+description のみ + fn schema(&self, name: &str) -> Option<&ToolSchema>; + fn dispatch(&self, name: &str, args: Value) -> Result; +} +``` + +- `list()` は常に全ツール返す (戦略は ContextRenderer 側の責務) +- `schema()` は ToolSearch 相当の動線で使用 +- `dispatch()` は schema 照合+実行。**context に schema text があるかは見ない** + +### ContextRenderer インターフェース + +```rust +pub trait ContextRenderer { + fn initial_render(&self, registry: &dyn ToolRegistry) -> InitialContext; + fn on_tool_load(&self, name: &str, registry: &dyn ToolRegistry) -> Option; + fn parse_call(&self, raw_output: &str) -> Result; + fn format_result(&self, name: &str, result: &ToolResult) -> String; +} +``` + +戦略ごとに実装を差し替える: + +- `ClaudeDeferredRenderer`: 初期 prompt に core tools のみ展開、`tool_search` メタツールを常設、ロード時は tool_result として `{schema}` を流す +- `HarmonyUpfrontRenderer`: developer メッセージに namespace で全 tool 展開、ロード概念なし +- `HarmonyDispatcherRenderer`: namespace は `call_mcp(server, tool, args)` だけ、サブツール解決は外部 MCP +- `RollingDeveloperRenderer`: 一定境界 (compaction 等) で developer メッセージを再描画。cache 損失は境界で吸収 + +### Validation / Retry レイヤ + +ツール呼び出しの失敗ハンドリングは ContextRenderer / Registry の上に置く独立層: + +```rust +pub struct ToolDispatcher { + registry: R, + renderer: C, + retry_policy: RetryPolicy, +} +``` + +責務: + +1. モデル出力をパース (`renderer.parse_call`) +2. registry で schema 照合 → invalid なら error tool_result を返す +3. dispatch → 結果を `renderer.format_result` で整形してモデルへ +4. malformed 出力時は error フィードバックして同一ターン内修正を促す + +これは `tool_approach_comparison.md` §4 で議論した「プロバイダ側がやっている (フォーマット規約 / バリデーション / リトライ / 訓練投資)」のうち、**ローカルモデル向けには (4) が効かないため (1)-(3) を自前で組む**ことに対応する。 + +### KV cache / prompt cache 整合 + +戦略の選択は cache 効率に直結する: + +- **PrefixStable 戦略 (Claude Deferred / Dispatcher パターン)**: 初期 prefix が固定。ToolSearch 結果や dispatcher 経由の動的解決は **会話末尾の tool_result** に積まれるため、前方プレフィックスが揺らがない +- **RewindToBoundary 戦略 (Rolling Developer)**: tool セット変更が cache 全消し。compaction 境界に同期させて損失を抑える + +Anthropic API の `prompt caching` は Explicit (cache_control) で、`llm_providers.md` §Prompt caching の `CacheStrategy::Explicit { max_breakpoints }` と整合する。ローカル推論の KV cache は基本 prefix-only のため `Auto` 相当。両方とも「安定 prefix 設計」に効く。 + +## 根拠 + +- **Registry vs Context 分離**: Claude Code の実演で「context に schema があるかは validation に無関係」と判明 (`claude-code-deferred-tools.md` §10)。同じ抽象で Claude / OpenAI / ローカル系を統一できる +- **戦略の差し替え可能性**: Harmony は構造化トークン+namespace 前提で、Claude の deferred 方式が直接通用しない (`tool_approach_comparison.md` §1, §2)。モデル系統ごとの戦略切り替えは避けられない +- **MCP-style dispatcher**: OpenAI が MCP 統合で採用している方向。namespace に汎用 entry point だけ置き、サブツール解決を外部化する。upfront にせず、訓練分布も逸脱しない +- **検証レイヤを別層に**: モデル側のフォーマットの強さ (Harmony の特殊トークン) と弱さ (Claude の正規表現パース) で fail mode が違うため、ContextRenderer に閉じ込めずに上位で統一的に扱う + +## 実装原則 + +- **registry は llm-worker の上位層に置く** (低レベル基盤に留める方針: `feedback_llm_worker_scope.md`) +- **MCP サーバ統合は registry のバックエンドの一つ**として扱い、Harmony 側 dispatcher と内部実装を共有 +- **ContextRenderer の選択は ProviderScheme と一対多**: `scheme/anthropic` → ClaudeDeferred、`scheme/openai_responses` → HarmonyUpfront 等。`llm_providers.md` のプロバイダカタログにレンダラ指定を載せる +- **ToolSearch 相当は MetaTool として実装**: registry 側に `__tool_search` / `__tool_describe` を登録し、ContextRenderer の戦略によって core tools に含めるか否かを決める +- **テスト**: registry のバリデーションが context schema 有無に依存しないことを property test で保証する + +## Scope 外 + +- 個別の MCP プロトコル実装 / サーバ連携の詳細 +- 各モデル固有の chat template レンダリング (Hermes / Qwen / Llama 等の差分は別 ticket) +- Tool 結果の構造化出力 (citation / file reference 等) のスキーマ +- Tool 並列実行・依存解決・cancellation +- ユーザ定義ツールの permission 管理 (sandbox.md と別) + +## 参考 + +- `docs/ref/claude-code-deferred-tools.md` — Claude Code の deferred tools 機構と実演による検証 +- `docs/ref/tool_approach_comparison.md` — Anthropic / OpenAI のツール呼び出しアプローチ比較 +- `docs/plan/llm_providers.md` — プロバイダ抽象とスキーム / capability 設計 diff --git a/docs/ref/claude-code-deferred-tools.md b/docs/ref/claude-code-deferred-tools.md index b3465c80..1c2ece74 100644 --- a/docs/ref/claude-code-deferred-tools.md +++ b/docs/ref/claude-code-deferred-tools.md @@ -266,6 +266,8 @@ system prompt 冒頭に置かれる: Pod / insomnia でローカル LLM を使う場合、(4) が効かない。最近のローカル向けエージェントモデルは tool use 用に訓練されているので XML パースのような原始的処理は不要だが、各モデルが訓練された自前のフォーマット (Hermes / Llama / Qwen / Mistral 等で異なる) があり、それに合わせてレンダリングする必要がある。 +なお、Anthropic と OpenAI のツール呼び出しアプローチの比較 (XML タグ vs 特殊制御トークン、JSON Schema vs TypeScript namespace、thinking block vs 3 チャネル分離) は [tool_approach_comparison.md](./tool_approach_comparison.md) を参照。ローカルモデル向けの設計では、Claude 系の知見 (本書: deferred / registry / context 圧縮) と OpenAI 系の知見 (Harmony: トークン保証 / チャネル分離 / 公開仕様) を役割で使い分けるのが自然。 + 具体的な責務分担は以下: - ツール定義のレンダリング: モデル固有のテンプレート (chat template の `tools` 拡張等) に合わせる diff --git a/docs/ref/tool_approach_comparison.md b/docs/ref/tool_approach_comparison.md new file mode 100644 index 00000000..57259e13 --- /dev/null +++ b/docs/ref/tool_approach_comparison.md @@ -0,0 +1,100 @@ +# Anthropic Claude と OpenAI ChatGPT におけるツール呼び出しアプローチの比較 + +## 概要 + +LLMをエージェントとして動かす上で、ツール呼び出し(function calling / tool use)の仕組みはモデルの実用性を大きく左右する。ChatGPTもClaudeも、最終的に開発者へ返るのは構造化されたJSONレスポンスである点は共通している。しかし、その裏側でモデルが実際に生成しているトークン列、ツールを定義する構文、思考過程の扱い方には明確な違いがある。本レポートでは、両者のアプローチを4つの観点から整理する。 + +--- + +## 1. 内部出力フォーマット — XML風タグ vs 特殊制御トークン + +最も根本的な違いは、モデルが生のテキストとして何を出力しているかにある。 + +**Claude (Anthropic)** は、``、``、`` といったXML風のタグでツール呼び出しを表現する。これらはトークナイザーから見れば普通のテキストトークンであり、APIサーバー側が正規表現でパースして構造化データに変換する。Anthropic公式のドキュメントでも、この出力は厳密なXMLとして扱われるわけではなく、正規表現パースを前提に設計されている、と明記されている。 + +**OpenAI (ChatGPT / gpt-oss)** は、Harmonyと呼ばれるレスポンスフォーマットを採用しており、`<|start|>`、`<|message|>`、`<|channel|>`、`<|call|>`、`<|end|>`、`<|return|>` といった**特殊制御トークン**でメッセージ構造を区切る。これらは見た目こそタグ風だが、トークナイザー内では1つの専用IDを持つ単一トークンとして扱われる。つまり、テキストを後からパースしているのではなく、トークンレベルで構造が埋め込まれている。 + +この違いは設計哲学の差を反映している。Claudeは可読性とトレーニングデータとの親和性を重視した「テキスト寄り」のアプローチであり、OpenAIはトークンレベルで構造を保証する「プロトコル寄り」のアプローチといえる。 + +--- + +## 2. ツール定義の構文 — JSON Schema vs TypeScript風 + +開発者がツールをモデルに教える際の書き方も大きく異なる。 + +**Claude** ではツールはJSON Schemaで定義する。`name`、`description`、`input_schema` を持つオブジェクトの配列をAPIに渡し、APIサーバーが内部でシステムプロンプトを構築してモデルに提示する。JSON Schemaという既存の標準仕様にそのまま乗っているため、他のJSON処理エコシステムとの相性が良い。 + +**OpenAI** はHarmonyフォーマットの中で、ツール定義をTypeScript風の型構文で記述する。関数は `namespace functions { ... }` というブロックでまとめられ、各関数は `type get_current_weather = (_: { location: string, format?: "celsius" | "fahrenheit" }) => any;` のように定義される。コメントが説明文として機能する。 + +開発者がOpenAI APIを叩く際にはJSON Schema形式で渡せるが、サーバー内部で `harmony` ライブラリがこれをTypeScript風構文に変換してからモデルに渡している。最終的にモデルが「読む」のはTypeScript風の表現である。これは、コード補完タスクで大量のTypeScriptを学習しているLLMにとって型シグネチャの方が認識しやすい、という経験的判断に基づくと考えられる。 + +--- + +## 3. 引数のフォーマット + +ツール呼び出し時の引数の渡し方は、両者で似てはいるが微妙に違う。 + +**Claude** では、文字列やスカラー値はそのままタグ内に書き、リストやオブジェクトなどの複合型はJSONとして埋め込む、というハイブリッド方式を取る。例えば `Tokyo` のようにシンプルな値は素のテキストで、配列やネストした構造はJSONで表現される。 + +**OpenAI (Harmony)** では、引数全体を一括してJSONで渡す。`<|channel|>commentary to=functions.get_current_weather <|constrain|>json<|message|>{"location":"San Francisco"}<|call|>` というように、`<|message|>` 以降に丸ごとJSONオブジェクトを置き、`<|call|>` トークンで実行要求を確定する。`<|constrain|>json` は出力をJSONに制約することを示すヒントとして機能する。 + +エンジニアリング的には、JSONで統一する方がパースが単純で予測可能だが、Claudeのハイブリッド方式は単純な値の場合のトークン消費を抑える効果がある。 + +--- + +## 4. 思考過程の分離 + +エージェントモデルでは、思考と最終応答とツール呼び出しを分離する仕組みが重要になる。両者ともこれに対応しているが、構造化の度合いが異なる。 + +**Claude** は `thinking` ブロックを持ち、Extended Thinkingモードでは推論内容を専用ブロックに格納する。基本的には「思考」と「応答」の2層構造である。 + +**OpenAI (Harmony)** は **チャネル** という、より明確に分離された3層構造を採用している。 + +- `analysis` チャネル — 生のchain-of-thought。安全性のトレーニングを受けておらず、ユーザーには通常見せない。 +- `commentary` チャネル — ツール呼び出しや、ユーザーに見せても良い計画的なコメント。 +- `final` チャネル — ユーザー向けの最終応答。 + +このチャネル分離により、開発者は推論プロセスをログとして残しつつ、ユーザーには `final` チャネルだけを表示する、といった運用が容易になる。 + +--- + +## 5. 開発者から見た最終的なレスポンス + +ここまで内部の差を見てきたが、API経由で開発者が受け取るレスポンスは両者ともJSONである。 + +- Claudeは `tool_use` タイプのコンテンツブロックとしてツール呼び出しを返す。 +- OpenAIは `tool_calls` 配列としてツール呼び出しを返す。 + +つまり、開発者の視点では「JSONを送ってJSONを受け取る」点は同じであり、内部表現の違いはアプリケーション層には漏れない。違いが顕在化するのは、ファインチューニング、推論サーバーの自前構築、デバッグでモデルの生出力を観察する場合などに限られる。 + +--- + +## 比較表 + +| 観点 | Claude (Anthropic) | ChatGPT (OpenAI / Harmony) | +|---|---|---| +| 構造の区切り | XML風タグ(通常のテキストトークン) | 特殊制御トークン(単一トークン) | +| パース方式 | 正規表現ベース | トークンレベルで構造化 | +| ツール定義の表現 | JSON Schema | TypeScript風型構文 + namespace | +| 引数のフォーマット | スカラはそのまま、複合型はJSON | 全てJSON | +| 思考の分離 | thinkingブロック(2層) | analysis / commentary / final(3層チャネル) | +| API応答 | tool_useブロック(JSON) | tool_calls配列(JSON) | +| 設計の傾向 | テキスト寄り・既存標準活用 | プロトコル寄り・トークン専用化 | + +--- + +## 考察 + +両社のアプローチの違いは、それぞれの強みとトレードオフを反映している。 + +Claudeのアプローチは、JSON SchemaとXML風タグという既存の表記法を活用しており、ツールチェーンの相互運用性が高い。一方で、生成された出力が「壊れた」場合(タグの閉じ忘れなど)のパース失敗リスクは構造的に存在する。 + +OpenAIのHarmonyは、特殊トークンによってトークンレベルで構造が保証されるため、フォーマットの破綻が起きにくい。チャネル分離のような細かい構造化も自然に実現できる。一方で、独自プロトコルであるため、モデルを使う側のスタックがHarmonyを正しく扱う必要があり、外部ツールとの統合に追加実装が必要になる場面もある(実際、TensorRT-LLMやvLLMなどでHarmonyトークンの取り扱いに関する問題が報告されている)。 + +エージェント開発者にとって重要なのは、これらの差は通常APIの抽象化に隠されている、という点である。ただし、ローカルで重み付きモデルを動かす、ファインチューニングを行う、エージェントの動作をデバッグする、といった一段深い作業に踏み込む場合には、内部表現の理解が直接実装に効いてくる。 + +--- + +## 注記 + +本レポートで示したOpenAI側の詳細は、主にオープンウェイトモデル `gpt-oss` 向けに公開されているHarmonyフォーマットの仕様に基づく。商用のGPT-4o / GPT-5などの内部表現は完全には公開されていないが、HarmonyはOpenAIのResponses APIを模倣するように設計されており、商用モデルもおおむね類似した構造を採用していると推測される。 diff --git a/docs/research/zed-deltadb.md b/docs/research/zed-deltadb.md new file mode 100644 index 00000000..453a5f19 --- /dev/null +++ b/docs/research/zed-deltadb.md @@ -0,0 +1,104 @@ +# DeltaDB 調査メモ(Zed Industries) + +調査日: 2026-05-01 +出典: Zed 公式ブログ「Sequoia Backs Zed's Vision for Collaborative Coding」を中心に、二次情報・関連記事を補強。 + +## 1. 何か + +DeltaDB は Zed Industries が開発中の **operation-based version control system / synchronization engine** である。Zed エディタの Series B(Sequoia Capital 主導、$32M)と同時に発表された、同社の次フェーズの中核プロダクト。 + +ひとことで言うと「Git の commit ベースを置き換えるのではなく、**コミット間の "あらゆる編集操作"** を粒度として保持する VCS」。CRDT を用いてリアルタイムに変更を記録・同期し、Git と相互運用可能な設計を採る。 + +> "DeltaDB ... uses CRDTs to incrementally record and synchronize changes as they happen ... designed to interoperate with Git" — Zed Blog + +## 2. 動機(解こうとしている問題) + +LLM/AI エージェント時代のコーディングで、Git の粒度が粗すぎることが課題と捉えられている。 + +- **会話/意図がコードから剥がれる**: PR コメントやチャットでのやり取り、AI への指示・修正・pivot は、コードが変わると参照先を失い、文脈ごと失われる。 +- **スナップショットでは追えない**: Git は commit という離散点しか持たない。エージェントとの "continuous dialogue" や、commit 未満の編集ステップを履歴として扱えない。 +- **同時編集の衝突**: 複数の AI エージェント+人間がリアルタイムに編集する時、従来の merge conflict モデルは機能しにくい。 +- **コード位置の永続参照**: コードがリファクタや改名で移動するたび、URL 形式のパーマリンクや議論の固定ピンが切れる。 + +これらは OpenAI の Sean Grove が指摘した「進化する仕様・プロンプトをどう track するか」という課題感とも重なるとされている。 + +## 3. 技術的な構成要素 + +### 3.1 Operation-based design(vs. snapshot-based) + +- Git の **commit = snapshot** に対し、DeltaDB は **operation = 編集 1 個** を一次データとして保持する。 +- 「every operation, not just commits」を track する。 +- スナップショットは operation log から導出可能な派生物として位置付けられる(VCS 系では "operational" / "patch theory" 系の系譜:Pijul, Fossil, darcs と同じ家系の発想)。 + +### 3.2 CRDT による同期 + +- 並行編集の整合性を CRDT(Conflict-free Replicated Data Types)で取る。 +- これは Zed エディタの multiplayer editing で既に実戦投入されている技術の延長: + - **Logical location**: 編集をオフセットではなく `(insertion id, offset)` のアンカーで表現し、操作を可換にする。 + - **Replica ID + sequence number**: 中央が replica id を一度割り当てれば、以降は各 replica が独立に一意 ID を生成可能。 + - **Tombstone**: 削除はテキストを物理削除せず墓標として残し、論理位置解決を保つ。 + - **Lamport timestamp / vector timestamp**: 因果順序を尊重し、並行挿入の可視性を制御。 + - **Per-user undo map**: 単一スタックではなく操作 ID → カウントの map で、ユーザーごとに独立 undo を実現。 +- DeltaDB はこの editor 内 CRDT を、**ファイル横断・リポジトリ規模・永続化**にスケールさせるレイヤと読み解ける。 + +### 3.3 Character-level permalink + +- 「あらゆるコード変換を生き延びる文字単位のパーマリンク」を提供する。 +- スナップショット時刻のファイル+行番号ではなく、CRDT のアンカー(insertion id ベース)に対して URL 的な参照を発行できるため、リネーム・リフォーマット・移動でも切れない。 +- ユースケース: 議論/レビュー/AI への指示/設計メモを、特定の文字位置に永続的に固定する。 + +### 3.4 Git との相互運用 + +- リプレースではなく interop 前提。 +- 既存 Git リポジトリを保ったまま段階導入できる戦略で、エンタープライズ採用のハードルを下げる狙い。 +- 推測: operation log → Git commit へのフラット化/ Git commit → operation log への lift が可能な層を持つはず(公式の実装仕様は未公開)。 + +## 4. Zed エディタとの関係 + +- DeltaDB は Zed の中で「人間 × 人間」「人間 × AI エージェント」「AI × AI」の協働基盤になる。 +- Zed が既に持つ multiplayer editing(CRDT)を、**editor session の寿命を超えて永続化・分散同期**する位置づけ。 +- 「terminal interface、local IDE、web-based agent tool」の 3 系統の良さを束ねた統合 GUI を作る、という Zed の方針の中核。 +- 「コードベースを生きた、辿れる履歴(a living, navigable history)として扱う」というビジョンの実装手段。 + +## 5. ビジネス/ライセンス + +- Zed 本体と同様に **オープンソース+ optional paid managed service** モデル。 +- Series B($32M、Sequoia 主導)の調達は DeltaDB 開発を主目的の一つとしている。報道では累計 $42M 規模との表記もある。 +- 競合として GitHub と比較する論調も出てきている(例: Hypeburner が "GitHub Competitor" と表現)。ただし公式は「Git と interop」を強調しており、置換戦略ではなく上位レイヤ戦略。 + +## 6. 既知の不明点(現時点で公開されていない情報) + +- 具体的なデータモデル/ストレージフォーマット(log の物理表現、圧縮、GC、tombstone 回収など)。 +- Git ↔ DeltaDB ブリッジの双方向変換の詳細(特に rebase、cherry-pick、shallow clone との整合)。 +- ブランチ・マージのモデル(patch theory ライクな順序非依存マージか、Git ライクなブランチ概念を載せるか)。 +- スケーラビリティ特性(モノレポ、巨大履歴、多数 replica)。 +- アクセス制御・権限モデル(CRDT の特性上、後付けが難しい領域)。 +- リリース時期、API 仕様、SDK の有無。 + +これらは公開ロードマップが出るまで判断保留。 + +## 7. 関連技術/系譜 + +- **Operation-based / patch-based VCS**: darcs, Pijul, Fossil。理論的には patch theory/category-theoretic merge。 +- **CRDT 系コラボエディタ**: Google Docs, Figma, Zed multiplayer。Yjs / Automerge は CRDT ライブラリの代表。 +- **永続的位置参照**: Tree-sitter ベースの semantic anchor、Sourcegraph の SCIP、`git-blame` の line tracking。DeltaDB は CRDT identity を使うため理論的にこれらより堅牢な anchor を提供できる。 +- **AI エージェント協働基盤**: OpenAI の "evolving spec" 議論、Anthropic の Computer Use 系、各社の MCP。DeltaDB は「エージェント↔コード↔人間の対話」を VCS 層で受ける狙い。 + +## 8. 自プロジェクト(insomnia)への含意メモ + +参考材料として残す(採用の可否ではない)。 + +- LLM エージェントのインタラクション履歴をコードに永続的に紐付けたい場面(例: 「この修正はどの会話・どのプロンプトから来たか」)で、character-level permalink の発想は流用余地がある。 +- ScopedFs を将来スクリプティング言語に公開する計画(memory: project_scopedfs_scripting)と組み合わせる際、エージェントの編集系列を operation log として残すかどうかは設計判断ポイント。 +- 短期的には DeltaDB そのものを依存に取り込む選択肢はないが、「commit 未満の粒度をどう持つか」という設計議論の参照点として有用。 + +## 9. 参考リンク + +- [Sequoia Backs Zed's Vision for Collaborative Coding — Zed Blog](https://zed.dev/blog/sequoia-backs-zed) — 一次情報源 +- [How CRDTs make multiplayer text editing part of Zed's DNA — Zed Blog](https://zed.dev/blog/crdts) — DeltaDB の基盤となる Zed の CRDT 実装解説 +- [Partnering with Zed — Sequoia Capital](https://sequoiacap.com/article/partnering-with-zed-the-ai-powered-code-editor-built-from-scratch/) — 投資側の論点 +- [Zed Raises $32M in Series B, Pivots to DeltaDB — Hypeburner](https://hypeburner.com/blog/news/zed-deltadb) +- [Zed Raises $32M ... Unveils DeltaDB — Menlo Times](https://www.menlotimes.com/post/zed-raises-32-million-in-series-b-to-build-next-gen-operation-based-version-control-unveils-deltad) +- [Zed Industries Raises $32M ... DeltaDB — CXO Digital Pulse](https://www.cxodigitalpulse.com/zed-industries-raises-32-million-to-redefine-ai-powered-code-collaboration-with-deltadb/) +- [DeltaDB From Zed — shapeof.com (August Mueller)](https://shapeof.com/archives/2025/8/deltadb_from_zed.html) — 第三者の所感 +- [Conflict-free replicated data type — Wikipedia](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) diff --git a/tickets/memory-gc.md b/tickets/memory-gc.md deleted file mode 100644 index c25320a4..00000000 --- a/tickets/memory-gc.md +++ /dev/null @@ -1,61 +0,0 @@ -# メモリ機構: GC(定期再評価) - -## 背景 - -`docs/plan/memory.md` §GC の実装。Phase 2 は情報統合寄りだが、それでも残る重要度低下・類似 slug 乱立・`replaced` 滞留・sources 累積・現状不整合を整理する定期再評価経路。人間 offer はかけず、結果は git diff で検証する建て付け。 - -保護閾値は使用頻度メトリクスの明示 invoke frequency に依存する。 - -## 要件 - -### Trigger - -- 定期実行(累積 input token ベース推奨、具体値は設定で tune、実装判断) - -### 実行主体と渡すツール - -- GC Agent が spawn -- Phase 2 と同じ汎用 CRUD + 検索ツール + post-write Linter Hook -- 入力: GC 対象 record 群 + Linter Warn + 使用頻度メトリクス + `replaced` chain + sources 過多情報 - -### 操作粒度 - -- ファイル単位: 丸ごと drop / 複数ファイル merge / 1 ファイルの split -- ファイル内部分: 節・箇条の削除 or 圧縮、`sources` 古いエントリの trim - -### 評価カテゴリ - -`outdated`, `superseded`, `unused`, `noisy` を GC 理由の分類として使う。record に一律の「stale」フラグは付けない。drop / merge / split / trim / rewrite のどれを選ぶかをこのカテゴリで説明可能にする。 - -### 判断ルール - -- 保護閾値: **明示 invoke** の `frequency >= 1.0 invokes/Mtoken` の record は drop / 大幅圧縮の対象外 - - 初期値 1.0、workspace 設定でカスタマイズ可 - - `model_invokation` 注入による常駐は計数対象外(別指標として参照のみ) -- 単一 record が複数カテゴリに該当してもよい -- 直接削除してよいが、誤判定しやすいものは merge / trim を優先(prompt 側で誘導) - -### prompt - -- `docs/plan/memory-prompts.md` §GC prompt に従う - -## 範囲外 - -- 監査 LLM 層(将来検討) -- Vector index / FTS5 導入(将来検討、GC 判断には影響しない) -- Workflow の GC 対象化(初期は触らない) - -## 完了条件 - -- Trigger で GC Agent が走り、不要 record が整理される -- Linter Warn で検出した類似 slug 乱立などが GC でまとめて収斂する -- 保護閾値超過 record が drop / 大幅圧縮から外れる -- 置き換えは `status: replaced` + `replaced_by` で残り、直接削除と区別可能 -- git diff で drop / merge / split / trim / rewrite の理由が読める - -## 参照 - -- `docs/plan/memory.md` §GC / §使用頻度メトリクス / §判断ルール -- `docs/plan/memory-prompts.md` §GC prompt -- `tickets/memory-phase2-consolidation.md`(ツール構成の共通化) -- `tickets/memory-usage-metrics.md`(保護閾値の依存) diff --git a/tickets/memory-phase2-consolidation.md b/tickets/memory-phase2-consolidation.md index 47e50b83..1e138551 100644 --- a/tickets/memory-phase2-consolidation.md +++ b/tickets/memory-phase2-consolidation.md @@ -1,17 +1,19 @@ -# メモリ機構: Phase 2 consolidation +# メモリ機構: Phase 2 consolidation + 整理 ## 背景 -`docs/plan/memory.md` §Phase 2 の実装。staging の活動ログ + 既存 `memory/*` + Knowledge 化候補レポートを入力に、consolidation Worker が汎用 CRUD + 検索ツール + Linter Hook で agentic に統合する。Phase 1 を終えた pod が spawn し、並走防止は staging 配下の進行状況ファイルで担保する。 +`docs/plan/memory.md` §自動化メカニズム / §整理(GC 相当)の扱い の実装。staging の活動ログ + 既存 `memory/*` + Knowledge 化候補レポート + 整理材料を入力に、consolidation Worker が **統合 phase(活動ログを memory/knowledge へ落とす)** と **整理 phase(既存 record の drop / merge / split / trim / rewrite)** を 1 セッション内で順に実行する。Phase 1 を終えた pod が spawn し、並走防止は staging 配下の進行状況ファイルで担保する。 -Knowledge 新規作成は「候補レポート掲載の source から派生する場合」に限る。使用頻度メトリクス(候補レポートの集計元)が未完のうちは、レポートは空入力として動作し、Phase 2 は decisions / requests / summary / 既存 Knowledge update のみ行う。 +整理 phase は Phase 2 とは別 trigger を持たない。同じ Worker 同じツール surface で済むため、別 Agent / 別 spawn 経路は設けない。 + +Knowledge 新規作成は「候補レポート掲載の source から派生する場合」に限る。使用頻度メトリクス(候補レポートと保護閾値の集計元)が未完のうちは、レポートと整理材料は空入力として動作し、統合 phase は decisions / requests / summary / 既存 Knowledge update のみ、整理 phase は Linter Warn と `replaced` chain と sources 累積を見るに留まる(保護閾値による drop 抑制は metrics 完成後に有効化)。 ## 要件 ### Trigger - staging の累積ファイル数 or bytes 閾値(設定で tune) -- compact 発火時に必ず flush(compact で失われる raw を漏らさない) +- compact 同期発火は持たない(raw 保全は Phase 1 が compact 前に走ることで担保される) ### 実行主体と入力 @@ -21,6 +23,7 @@ Knowledge 新規作成は「候補レポート掲載の source から派生す - consumed ID 分の staging エントリ(活動ログ + `source`) - 既存 `memory/*`(summary / decisions / requests)全文 - Knowledge 化候補レポート(メトリクスチケットの成果物。未完のうちは空) + - 整理材料(使用頻度メトリクス、Linter Warn、`replaced` chain、sources 過多情報。メトリクス未完のうちは Linter Warn / `replaced` / sources のみ) - 既存 `knowledge/*` は prompt に埋めず、Knowledge 検索ツール経由で agent が引く ### 渡すツール @@ -38,12 +41,23 @@ Knowledge 新規作成は「候補レポート掲載の source から派生す ### 処理内容 +#### 統合 phase + - 新規 decisions / requests を 1 件 1 ファイルで追加、`sources` は staging の `source` をコピー(LLM 推論ではない) - 活動ログから派生する Knowledge を新規作成 or 既存 patch。**新規作成は候補レポート掲載の source 由来に限る** - summary を必要に応じて rewrite(1-5k tokens 目安) -- 削除は `status: replaced` + `replaced_by: ` で置き換え記録、直接削除しない +- Decision の置き換えは `status: replaced` + `replaced_by: `、直接削除しない - 書き込み先: `memory/*`, `knowledge/*`。`memory/workflow/` は Linter で弾かれる +#### 整理 phase(統合 phase 完了後、余力で実行) + +- 既存 record 群を `outdated | superseded | unused | noisy` の評価カテゴリで分類 +- 操作粒度はファイル単位(drop / merge / split)とファイル内部分(節・箇条削除、`sources` 古いエントリ trim) +- **保護閾値**: 明示 invoke `frequency >= 1.0 invokes/Mtoken` の record は drop / 大幅圧縮の対象外(初期値 1.0、workspace 設定でカスタマイズ可、metrics 未完のうちは閾値判定スキップで保守的に振る舞う) +- 単一 record が複数カテゴリに該当してもよい +- 直接削除してよいが、誤判定しやすいものは merge / trim を優先(prompt 側で誘導) +- Linter Warn で検出した類似 slug 乱立 / sources 過多 / `replaced` 滞留はここで収斂 + ### 並走防止 - staging 配下に 1 ファイル(Pod 識別子 + consumed ID list) @@ -59,28 +73,30 @@ Knowledge 新規作成は「候補レポート掲載の source から派生す ### prompt -- `docs/plan/memory-prompts.md` §共通原則 / §Phase 2: 統合 prompt / §Phase 2: Knowledge 書き込み prompt に従う +- `docs/plan/memory-prompts.md` §共通原則 / §Phase 2: 統合 + 整理 prompt / §Phase 2: Knowledge 書き込み prompt に従う ## 範囲外 -- 使用頻度メトリクスと Knowledge 化候補レポートの集計(別チケット。未完の間は空レポートで動作) -- GC(別チケット) +- 使用頻度メトリクスと Knowledge 化候補レポート / 保護閾値の集計(別チケット。未完の間は空入力で動作) - Workflow 関連の offer(別チケット、Notification 経路が先) - 意味破壊検出の監査 LLM 層(将来検討) ## 完了条件 -- Phase 1 が staging に残した活動ログを Phase 2 が `memory/*` / `knowledge/*` に統合する +- Phase 1 が staging に残した活動ログを統合 phase が `memory/*` / `knowledge/*` に統合する +- 統合 phase 完了後、整理 phase が同じ agent セッション内で続けて走り、既存 record を整理する - Linter 違反時は turn が戻り、sub-Worker が自己修正する - 並走防止ファイルが想定通り機能し、複数 Phase 2 の重複起動が防げる - Coalesce で実行中追加分が次回に引き継がれる -- compact 発火時に Phase 2 が flush される -- 空レポートでも新規 Knowledge を作らずに動く(decisions / requests / summary / 既存 Knowledge update のみ) +- 空レポートでも新規 Knowledge を作らずに動く(統合は decisions / requests / summary / 既存 Knowledge update のみ) +- 整理 phase は git diff で drop / merge / split / trim / rewrite の理由(評価カテゴリ)が読める形で記録される +- 置き換えは `status: replaced` + `replaced_by` で残り、直接削除と区別可能 ## 参照 -- `docs/plan/memory.md` §Phase 2 / §Phase 2 agent への原則 / §Compact との関係 +- `docs/plan/memory.md` §自動化メカニズム / §整理(GC 相当)の扱い / §Compact との関係 - `docs/plan/memory-prompts.md` §Phase 2 関連 - `tickets/memory-file-format.md`(Linter) - `tickets/memory-search-tools.md`(検索ツール) - `tickets/memory-phase1-extract.md`(staging 生産) +- `tickets/memory-usage-metrics.md`(候補レポート / 保護閾値の供給) diff --git a/tickets/memory-usage-metrics.md b/tickets/memory-usage-metrics.md index 4b5452dc..f60f0867 100644 --- a/tickets/memory-usage-metrics.md +++ b/tickets/memory-usage-metrics.md @@ -2,7 +2,7 @@ ## 背景 -`docs/plan/memory.md` §使用頻度メトリクス の実装。memory 検索ツール / Knowledge 検索ツール内に invoke 計測フックを入れ、時間単位ではなく累積 input token で正規化した頻度を算出する。Phase 2 の Knowledge 新規作成 gate と GC の保護閾値の両方で使われる。 +`docs/plan/memory.md` §使用頻度メトリクス の実装。memory 検索ツール / Knowledge 検索ツール内に invoke 計測フックを入れ、時間単位ではなく累積 input token で正規化した頻度を算出する。Phase 2 統合 phase の Knowledge 新規作成 gate と Phase 2 整理 phase の保護閾値の両方で使われる。 ## 要件 @@ -36,12 +36,12 @@ ### 消費者 -- Phase 2 Worker の入力として候補レポートを渡す -- GC Agent の保護閾値判定(明示 invoke frequency >= 1.0 invokes/Mtoken) +- Phase 2 Worker の統合 phase 入力として候補レポートを渡す +- Phase 2 Worker の整理 phase で保護閾値判定(明示 invoke frequency >= 1.0 invokes/Mtoken)に使う ## 範囲外 -- GC の実装本体(別チケット。本チケットは保護閾値判定に必要なメトリクスの提供まで) +- Phase 2 整理 phase の実装本体(`memory-phase2-consolidation` 側。本チケットは保護閾値判定に必要なメトリクスの提供まで) - `model_invokation` ON/OFF の自動判定ロジック(将来検討) - Shallow request の自動除外(将来検討) @@ -57,4 +57,4 @@ - `docs/plan/memory.md` §使用頻度メトリクス / §判断ルール / §retrieval 経路 - `tickets/memory-search-tools.md`(hook 挿入点) -- `tickets/memory-phase2-consolidation.md`(消費者) +- `tickets/memory-phase2-consolidation.md`(統合 / 整理 両 phase の消費者) diff --git a/tickets/workflow.md b/tickets/workflow.md index 014c98dc..14b0bb46 100644 --- a/tickets/workflow.md +++ b/tickets/workflow.md @@ -4,7 +4,7 @@ `docs/plan/workflow.md` で決まった「制約付きの強制的な作業フロー」を `/` で呼び出せるようにする。Knowledge (`#`) を依存として inject できる経路を持つことで、procedural な能力を再利用可能な単位に固定する。 -memory 機構(`docs/plan/memory.md`)からは独立してスタートできる: Workflow は人間が書く / consolidation の offer 経由でしか作られず、自動書き込み禁止のため Phase 2 / GC の前提に依存しない。Knowledge resolver は `requires` の inject 経路として相互依存する。 +memory 機構(`docs/plan/memory.md`)からは独立してスタートできる: Workflow は人間が書く / consolidation の offer 経由でしか作られず、自動書き込み禁止のため Phase 2 の前提に依存しない。Knowledge resolver は `requires` の inject 経路として相互依存する。 agent-skills (agentskills.io 形式) は本チケットの ingest 経路を再利用して Workflow として読み込む側になる(`tickets/agent-skills.md` 参照)。