Memoryシステムの整理・Promptカタログチケット
This commit is contained in:
parent
270d7923ab
commit
0c1276b730
1
TODO.md
1
TODO.md
|
|
@ -6,6 +6,7 @@
|
|||
- [ ] LLM プロバイダ/モデルカタログ → [tickets/llm-provider-catalog.md](tickets/llm-provider-catalog.md)
|
||||
- [ ] Pod オーケストレーション
|
||||
- [ ] 動的 Scope 変更 → [tickets/dynamic-scope.md](tickets/dynamic-scope.md)
|
||||
- [ ] Pod 内部プロンプトのカタログ化 → [tickets/pod-prompt-catalog.md](tickets/pod-prompt-catalog.md)
|
||||
- [ ] ネイティブ GUI クライアント MVP → [tickets/native-gui-mvp.md](tickets/native-gui-mvp.md)
|
||||
- [ ] TUI 拡充
|
||||
- [ ] フルスクリーン化によるオーバーホール → [tickets/tui-fullscreen-overhaul.md](tickets/tui-fullscreen-overhaul.md)
|
||||
|
|
|
|||
84
docs/plan/memory-prompts.md
Normal file
84
docs/plan/memory-prompts.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# メモリ機構の prompt 要件
|
||||
|
||||
## Context
|
||||
|
||||
`docs/plan/memory.md` で決めた memory の挙動を、実装時に prompt 要件へ落とすための補助ページ。ここでは「個別タスクをこなすベーシックな system / developer 指示」の上に追加で必要になる、memory 固有の指示だけをまとめる。
|
||||
|
||||
前提は **tool-based + agentic**。専用 schema で挙動を閉じ込めるのではなく、基本は sub-Worker に CRUD tool を渡し、prompt と post-write 検証で振る舞いを制約する。例外は Workflow で、`docs/plan/workflow.md` の通り自動書き込みはしない。
|
||||
|
||||
## 決定事項
|
||||
|
||||
### 共通原則
|
||||
|
||||
memory 関連 prompt は種別を問わず、最低限以下を共有する:
|
||||
|
||||
- **source を推論しない**。`session_id` や entry range は wrapper / 呼び出し側が機械付与し、LLM が捏造しない
|
||||
- **rewrite は許可**するが、情報損失は最小化する。既存の主張・根拠・参照を保ったまま整理・圧縮する
|
||||
- **単純 append を優先しない**。既存 record に統合できるなら update を優先する
|
||||
- **session 固有の進行状態を書かない**。長期参照価値のある内容だけを memory に残す
|
||||
- **既存 docs と重複保存しない**。`AGENTS.md`、`docs/plan/*`、固定運用文書に既にある内容を再保存しない
|
||||
- **空出力を許容**する。保存価値が無ければ「何も追加しない」を正当な結果として扱う
|
||||
|
||||
### Phase 1: 活動抽出 prompt
|
||||
|
||||
Phase 1 は「派生物を作る」段階ではなく、「起きたことを抽出する」段階として縛る:
|
||||
|
||||
- 対象は `decisions`、`discussions`、`attempts`、`requests` の候補に限る
|
||||
- Knowledge 化、summary rewrite、slug 命名、`auto_invoke` 判断は行わない
|
||||
- 一回限りの雑談、浅い質問、長期参照価値の薄い進行ログは返さなくてよい
|
||||
- 出力は schema 準拠の構造化データのみ。自由文の補足説明で schema 外情報を足さない
|
||||
- 対象が無ければ空配列を返す
|
||||
|
||||
### Phase 2: 統合 prompt
|
||||
|
||||
Phase 2 は既存 `memory/*` と staging を見て、追加・更新・統合を agentic に判断する:
|
||||
|
||||
- 入力には staging の活動ログ、既存 `memory/*`、Knowledge 化候補レポートを含める
|
||||
- 新規作成より update を優先し、既存 slug に自然に統合できる場合は新規 file を増やさない
|
||||
- Decisions / Requests は staging の `source` をそのまま使い、LLM が `sources` を組み立てない
|
||||
- summary は必要なときだけ rewrite し、常に 1-5k tokens 目安に圧縮する
|
||||
- 削除は直接行わず、Decision の置き換えは `status: replaced` と `replaced_by` で表現する
|
||||
- 人間編集との不整合が見える rewrite は避け、衝突しそうなら保守的に統合する
|
||||
|
||||
### Phase 2: Knowledge 書き込み prompt
|
||||
|
||||
Knowledge の新規作成 / 更新では、Phase 2 全体の原則に加えて以下を明示する:
|
||||
|
||||
- 採択ラインは「このプロジェクト / ユーザーに対して再度参照価値のある事実・ルール・ノウハウ」に限る
|
||||
- 一回限りの判断や議論は Decisions に留め、繰り返し参照される抽象化だけを Knowledge に上げる
|
||||
- 新規作成は Knowledge 化候補レポートに載った source から派生する場合に限る
|
||||
- 既存 Knowledge の slug / description 一覧を見て、適合先があるなら必ず update を優先する
|
||||
- 新規 slug は「既存に適合先が無い」と説明できるときだけ作る
|
||||
- `last_sources` は入力で与えられた source を使い、推論で補完しない
|
||||
- `description` は「何の知識か / いつ使うか」が短く分かる文にする
|
||||
- `auto_invoke` ON/OFF は頻度・常駐コストの判断材料を踏まえて慎重に扱い、初期値は OFF とする
|
||||
- `#<slug>` 参照を書く場合は、実在 record への参照だけを使う
|
||||
- `AGENTS.md` や `docs/` に既に固定化されたルールの写しは作らない
|
||||
- 保存価値が無ければ Knowledge を何も追加しない
|
||||
|
||||
### 監査 LLM prompt
|
||||
|
||||
監査 LLM は「よく書けているか」ではなく、「壊していないか」を見る:
|
||||
|
||||
- 入力には write 前後 diff、対象 record の直前内容、今回の source / staging 抜粋、採択基準を渡す
|
||||
- rewrite / 圧縮で主張、根拠、参照が失われていないかを確認する
|
||||
- 新規追加が source や活動ログに裏打ちされているかを確認する
|
||||
- session 固有の進行状態や一時的事情が混入していないかを確認する
|
||||
- `description` が本文のスコープと一致しているかを確認する
|
||||
- `auto_invoke` の設定が本文の重要度や再利用性と不整合でないかを確認する
|
||||
- 問題がある場合は `pass | fail` に加えて違反カテゴリと具体箇所を返し、Hook が差し戻せる形にする
|
||||
|
||||
### GC prompt
|
||||
|
||||
GC は Phase 2 より攻撃的に整理してよいが、可逆性と説明可能性を保つ:
|
||||
|
||||
- 入力には GC 対象 record 群に加えて、Linter Warn、使用頻度メトリクス、`replaced` chain、sources 過多情報を含める
|
||||
- 明示 invoke 保護閾値を超える record は drop / 大幅圧縮の対象外とする
|
||||
- `similar-slug`、`sources-overflow`、`replaced` 滞留、stale record を優先的に処理する
|
||||
- merge / split / trim / drop の理由を diff から読める形で残す
|
||||
- 直接削除してよいが、git で可逆である前提に甘えすぎず、誤判定しやすいものは merge / trim を優先する
|
||||
|
||||
## 関連
|
||||
|
||||
- `docs/plan/memory.md`: memory 全体方針
|
||||
- `docs/plan/workflow.md`: workflow を自動書き込みの例外にしている理由
|
||||
|
|
@ -6,19 +6,20 @@ INSOMNIA がユーザーのプロジェクトに対して提供するメモリ
|
|||
|
||||
リサーチは `docs/ref/memory-systems.md`。前提として、**レポジトリがファイルシステム上にある**ケースで設計する(越境・バックエンド抽象は Scope 外)。
|
||||
|
||||
prompt 要件の整理は `docs/plan/memory-prompts.md` に切り出した。
|
||||
|
||||
Workflow(`/<slug>` で呼び出される制約付き作業フロー)は別 plan に切り出した。`docs/plan/workflow.md` 参照。
|
||||
|
||||
## 決定事項
|
||||
|
||||
### 記録対象の 5 種
|
||||
### 記録対象の 4 種
|
||||
|
||||
| 種別 | パス | 備考 |
|
||||
| ---------------- | ------------------------------ | ----------------------------------------------------------------------------------------------- |
|
||||
| Always-on サマリ | `memory/summary.md` | 1-5k tokens 目安 |
|
||||
| Lessons | `memory/lessons/<slug>.md` | |
|
||||
| Decisions | `memory/decisions/<slug>.md` | `status: open \| resolved \| replaced` で未決議論も保持、置き換え時は `replaced_by: <slug>` |
|
||||
| Requests | `memory/requests/<slug>.md` | ユーザー submit の構造化要約 |
|
||||
| Knowledge | `memory/knowledge/<slug>.md` | `#slug` で注入。ノウハウ / 用語 / 運用方針 / ルール / 事実など型を設けず Markdown 自由記述 |
|
||||
| 種別 | パス | 備考 |
|
||||
| ---------------- | ---------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| Always-on サマリ | `memory/summary.md` | 1-5k tokens 目安 |
|
||||
| Decisions | `memory/decisions/<slug>.md` | `status: open \| resolved \| replaced` で未決議論も保持、置き換え時は `replaced_by: <slug>` |
|
||||
| Requests | `memory/requests/<slug>.md` | ユーザー submit の構造化要約 |
|
||||
| Knowledge | `memory/knowledge/<slug>.md` | `#slug` で注入。ノウハウ / 用語 / 運用方針 / ルール / 事実など型を設けず Markdown 自由記述 |
|
||||
|
||||
- `<slug>` は kebab-case(内容を要約した短い識別子)。**ファイル名そのものが ID**、frontmatter に別途 `id` field は持たない
|
||||
- **1 件 1 ファイル**。append-only な複数エントリログファイルは作らない
|
||||
|
|
@ -37,18 +38,27 @@ agentskills.io の `SKILL.md` 形式は採用しない。Knowledge は `#<slug>`
|
|||
| `auto_invoke` | description が LLM context に載り、LLM が自発的に呼べる | **OFF** |
|
||||
| `user_invocable` | ユーザーが `#<slug>` で明示的に呼べる | **ON** |
|
||||
|
||||
`auto_invoke` の ON 化は人間の判断、または consolidation が頻繁に `user_invoke` されているものを検出して offer する。自律的に新規エンティティを生成はしない。Workflow も同じフラグ仕様(`workflow.md` 参照)。
|
||||
Knowledge は Phase 2 が自律的に新規作成 / 更新 / フラグ切替を行う前提。毎回の人間承認 gate は設けない(実効性が低い)。保護は 3 段で担保:
|
||||
|
||||
- **採択 gate**: Knowledge 新規作成は使用頻度メトリクスの Knowledge 化候補レポート(後述)に載った source から派生する場合に限る。閾値未満のうちは decisions / requests に留める
|
||||
- **Linter + 監査 LLM**: 構造違反と意味破壊を watch(詳細は後述)
|
||||
- **OS ファイル権限**: 人間が書き換えさせたくない record は `-r--` にしてロック。Phase 2 / GC の write は OS レベルで弾かれる
|
||||
|
||||
Workflow も同じフラグ仕様(`workflow.md` 参照)。per-record 保護フラグを提供する拡張は将来検討、初期は OS 権限で足りる。
|
||||
|
||||
### 書き込み経路と Linter
|
||||
|
||||
人間も consolidation sub-Worker も**同じ CRUD tool(file read / write / edit)**で `memory/*` を触る。書き込み時の制約は Linter で検証し、違反時は post-write Hook が turn を戻して sub-Worker に自己修正させる(N 回失敗で abort)。
|
||||
人間も consolidation sub-Worker も**同じ CRUD tool(file read / write / edit)**で `memory/*` を触る。書き込み時の制約は 2 層で検証し、違反時は post-write Hook が turn を戻して sub-Worker に自己修正させる(N 回失敗で abort):
|
||||
|
||||
1. **Linter(静的)**: frontmatter / slug / 参照整合などの機械的ルール
|
||||
2. **監査 LLM(意味的)**: rewrite が元の情報を壊していないかを別 prompt で check。特に Knowledge の意味損壊を watch する主経路
|
||||
|
||||
Linter ルールは 2 系統:
|
||||
|
||||
**静的 error**(post-write Hook で turn 戻し、sub-Worker が自己修正):
|
||||
|
||||
- frontmatter 必須 field
|
||||
- Lessons / Decisions / Requests: `created_at`, `updated_at`, `sources`
|
||||
- Decisions / Requests: `created_at`, `updated_at`, `sources`
|
||||
- Knowledge: `description`, `auto_invoke`, `user_invocable`, `last_sources`, `created_at`, `updated_at`
|
||||
- Summary: `updated_at`(optional: `last_rewritten_from_range`)
|
||||
- `memory/workflow/` への書き込み禁止(sub-Worker context のみ、人間編集は除外)
|
||||
|
|
@ -75,7 +85,7 @@ Workflow 保護は専用 tool schema のトリックではなく Linter ルー
|
|||
|
||||
- **Trigger**: activity tokens の累積閾値。tool call カウントは不採用(ツールカスタマイズ非依存・大小重みづけのため)
|
||||
- **実行主体**: 既存 compact と同じ Worker spawn 機構を再利用。Pod は立てない
|
||||
- **入力**: 前回 Phase 1 以降の session log 範囲
|
||||
- **入力**: 前回 Phase 1 以降の session log 範囲。処理済み境界の pointer は session 側に保持(寿命を session と揃える)
|
||||
- **出力**: JSON schema で**活動ログ**の候補配列を返す。Knowledge 等の派生物は Phase 2 が活動ログから導出するので、Phase 1 では純粋な「起きたこと」に絞る
|
||||
- `decisions`: 判断したこと(選択肢 + 選んだ + 根拠)
|
||||
- `discussions`: 議論したこと(トピック + 論点)
|
||||
|
|
@ -89,17 +99,26 @@ Workflow 保護は専用 tool schema のトリックではなく Linter ルー
|
|||
#### Phase 2: 永続化への統合
|
||||
|
||||
- **Trigger**: staging の累積ファイル数 or bytes が閾値超過、または compact 発火時(必ず flush)
|
||||
- **実行主体**: Phase 1 を終えた pod が `memory/_staging/.lock` の advisory file lock を `LOCK_EX | LOCK_NB` で取得試行。取れたら consolidation Worker を spawn。取れなければ skip(他 pod が処理中)
|
||||
- **Lock**: POSIX `flock(2)` / `fcntl` ベース。プロセスが生きている限り保持、落ちれば OS が自動解放。stale 検出・heartbeat 不要。reasoning 処理が数分〜十数分かかる前提
|
||||
- **入力**: staging 全件(活動ログ + `source`)+ 既存 `memory/*`(summary / lessons / decisions / requests / knowledge)
|
||||
- **実行主体**: Phase 1 を終えた pod が consolidation Worker を spawn。並走防止は staging 配下の進行状況ファイル(後述)で担保
|
||||
- **入力**: 起動時スナップショットで確定した consumed ID list 分の staging エントリ(活動ログ + `source`)+ 既存 `memory/*`(summary / decisions / requests / knowledge)+ **Knowledge 化候補レポート**(後述の使用頻度メトリクスから機械集計、閾値超過の source 一覧)
|
||||
- **処理**: sub-Worker に**汎用 CRUD tool(file read / write / edit)+ post-write Linter Hook** を渡し、agentic に以下を自律判断:
|
||||
- 新規 lessons / decisions / requests を 1 件 1 ファイルで追加。`sources` は staging の `source` をコピー(LLM 推論ではない)
|
||||
- 活動ログから派生する Knowledge(用語定義 / 運用方針 / ルール / 事実 / ノウハウ)を新規作成 or 既存 patch。`last_sources` を更新
|
||||
- 新規 decisions / requests を 1 件 1 ファイルで追加。`sources` は staging の `source` をコピー(LLM 推論ではない)
|
||||
- 活動ログから派生する Knowledge(用語定義 / 運用方針 / ルール / 事実 / ノウハウ)を新規作成 or 既存 patch。**新規作成は候補レポート掲載の source から派生する場合に限る**。`last_sources` を更新
|
||||
- summary を必要に応じて rewrite
|
||||
- **書き込み先**: `memory/*` 配下。Workflow 禁止は Linter で担保(`workflow.md` 参照)
|
||||
- **完了処理**: staging cleanup + lock release。Phase 2 完了時に staging に新着があれば次を発火(Coalesce)
|
||||
- **完了処理**: consumed ID list の staging のみ cleanup(実行中に Phase 1 が追加した分は残す)。Phase 2 完了時に staging に新着があれば次を発火(Coalesce)
|
||||
- **モデル**: `memory.consolidation_model`。reasoning 系
|
||||
|
||||
##### 並走防止
|
||||
|
||||
- 場所: staging 配下に 1 ファイル(名前・形式は未定)
|
||||
- 中身: 動作中の Pod 識別子 + **consumed ID list**(この Phase 2 run が起動時スナップショットで確定した staging エントリ ID の列)
|
||||
- 占有ルール: そのファイルが存在し、示された Pod が動作している間、そのプロセスが排他占有
|
||||
- 実行中に Phase 1 が staging に追加したエントリは触らず、次回 Phase 2(Coalesce)に委ねる
|
||||
- cleanup は consumed ID list のエントリのみ削除、追加分は残す
|
||||
- クラッシュ時は consumed ID list から処理途中を特定できる。重複作成は同一 slug update に自然収束
|
||||
- 占有の実現方法(pid 存在確認 / flock / 他)は未定
|
||||
|
||||
#### Phase 2 agent への原則
|
||||
|
||||
`memory/` 配下は人間も git 経由で編集する。Phase 2 prompt で以下を明示:
|
||||
|
|
@ -111,9 +130,8 @@ Workflow 保護は専用 tool schema のトリックではなく Linter ルー
|
|||
|
||||
#### Offer 経路
|
||||
|
||||
consolidation は自律生成しない。以下は Client に `Event::Notification` で提案し、人間承認で反映:
|
||||
Memory record の書き込みは Phase 2 が自律判断し、Offer は設けない(Knowledge 含む)。人間承認経路が必要なのは以下:
|
||||
|
||||
- Knowledge の `auto_invoke` ON 化
|
||||
- Workflow 関連の offer(新規作成 / 改善 / `auto_invoke` ON 化)は `workflow.md` 参照
|
||||
|
||||
#### Compact との関係
|
||||
|
|
@ -122,7 +140,7 @@ consolidation は自律生成しない。以下は Client に `Event::Notificati
|
|||
|
||||
### GC(定期再評価)
|
||||
|
||||
Phase 2 とは別経路で memory を再評価し、drop / merge / split / `replaced` chain の整理を行う。Shann³ llm-wiki の lint 相当。Phase 2 は rewrite 許可で情報統合寄りの働きをするが、それでも残る以下の課題の出口として機能する:
|
||||
Phase 2 とは別経路で memory を再評価する定期ジョブ。Phase 2 は rewrite 許可で情報統合寄りの働きをするが、それでも残る以下の課題の出口として機能する:
|
||||
|
||||
- 重要度の低い record が累積する
|
||||
- 類似 slug が乱立する(Linter Warn で検出したものをまとめて処理)
|
||||
|
|
@ -130,14 +148,45 @@ Phase 2 とは別経路で memory を再評価し、drop / merge / split / `repl
|
|||
- sources 累積
|
||||
- 長期的に陳腐化した記録の drop
|
||||
|
||||
**詳細仕様は後で詰める**(scope 内、未決定)。方針として LLM 駆動の定期ジョブで、Linter Warn 群 + 人間 offer 承認を併用する前提。
|
||||
他プロジェクトの GC 設計の横断比較は `docs/ref/memory-systems.md` §8。
|
||||
|
||||
#### 権限と操作粒度
|
||||
|
||||
GC Agent は **drop / merge / split を自律実行**(削除まで含む)。人間 offer はかけず、結果は git diff で検証する建て付け。operation 粒度は以下の両方:
|
||||
|
||||
- **ファイル単位**: 丸ごと drop、複数ファイルの merge、1 ファイルの分割(split)
|
||||
- **ファイル内の部分削除**: 本文の一部節・箇条を削除 or 圧縮。frontmatter の `sources` 古いエントリの trim も含む
|
||||
|
||||
Phase 2 と同じ CRUD tool + Linter Hook を使うので、operation 粒度は自然にサポートされる(専用 API は用意しない)。
|
||||
|
||||
#### 使用頻度メトリクス
|
||||
|
||||
時間単位は実時間を使わない(LLM スループット向上で陳腐化の意味が変わるため)、累積 input token で正規化する。
|
||||
|
||||
**観測経路**: `memory/*` への読み取りは専用の memory 検索ツール(既存 built-in の grep / read とは別に用意)経由に揃える。invoke 計測はツール内でフックし、`#<slug>` / `/<slug>` / 明示検索呼び出しを同一経路に集約する。
|
||||
|
||||
**カウント対象**:
|
||||
|
||||
- **明示 invoke**: 検索ツール経由の読み取り / `#<slug>` / `/<slug>` を n回/Mtoken でスコア化
|
||||
- **auto_invoke 注入**: 注入は context 常駐コストで、「載っているだけ」か「使われた」かを統計上区別不能。明示 invoke の分子には含めず、**コスト側(注入した record に対する消費 input tokens)として別途記録**する。使われ率 ratio や ON/OFF 判断の材料として後段で使う
|
||||
- ファイル token 数
|
||||
|
||||
**記録先**: staging とは独立。invoke event を UUID + Stats 形式で workspace 側に記録し、session データが失われても統計が残るようにする。具体 schema・フォーマットは未定。
|
||||
|
||||
**累積方式**(後集計アプローチ): 上記 invoke 記録に対して最大 10 回前の invoke から現在までの時系列窓でフィルタして集計する。
|
||||
|
||||
**Knowledge 化候補レポート**: Phase 2 が入力に受け取る、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 設定でカスタマイズ可)。auto_invoke 注入による常駐は計数対象外(別指標として後段で参照)
|
||||
|
||||
### ファイル形式
|
||||
|
||||
- frontmatter + Markdown 本文。全 record 共通: `created_at`, `updated_at`
|
||||
- ファイル名(slug)がそのまま識別子、frontmatter に `id` / `name` field は持たない
|
||||
- source トレーサビリティ(session log への逆引き、粒度は `session_id` + entry range):
|
||||
- Lessons / Decisions / Requests: `sources: [{session_id, range: [start, end]}, ...]` 永続化(update 時は追記累積)
|
||||
- Decisions / Requests: `sources: [{session_id, range: [start, end]}, ...]` 永続化(update 時は追記累積)
|
||||
- Knowledge: `last_sources: [{session_id, range}, ...]`(最新更新時のみ、過去履歴は git log で追う)
|
||||
- Summary: optional `last_rewritten_from_range`(なしでも可)
|
||||
- Knowledge 固有: `description`, `auto_invoke`, `user_invocable`
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ Codex CLI に 2026-03 頃から追加された "Memories" 機能と、2026-04-15
|
|||
- `memory_summary.md` を中心に「summaries / durable entries / recent inputs / supporting evidence」の Markdown を束ねる構成。
|
||||
- Chronicle 派生メモリは `$CODEX_HOME/memories_extensions/chronicle/` に分離。
|
||||
- スクリーンキャプチャ中間物は `$TMPDIR/chronicle/screen_recording/` に置かれ、running 中 6h で自動削除。サーバー側には保存しない(法的義務時を除く)。
|
||||
- **Extension resource retention は決定論的 7 日 hard-coded**(`EXTENSION_RESOURCE_RETENTION_DAYS = 7`, `memories/extensions.rs:11`)。filename embedded timestamp (`%Y-%m-%dT%H-%M-%S`) が cutoff より古い `.md` リソースを Phase 2 直前に物理削除し、削除リストを `removed_extension_resources` として consolidation prompt に渡す(agent はそれを見て派生メモリを抹消)。
|
||||
|
||||
### 設定
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ Shann³ の構成は Karpathy が 2026-04 に公開した `llm-wiki` gist をそ
|
|||
- **query**: wiki を検索し citation 付きで答える。意義ある合成は `syntheses/` として保存。
|
||||
- **lint**: 矛盾・stale claim・孤立ページ・参照抜け・データ欠落の定期点検。
|
||||
|
||||
`SamurAIGPT/llm-wiki-agent` がこのパターンを具体化しており、ディレクトリ構造が示唆的:
|
||||
`SamurAIGPT/llm-wiki-agent` がこのパターンを具体化しており、ディレクトリ構造が示唆的(なお `/wiki-lint` のプロダクション実装としては OpenClaw `memory-wiki` extension があり、§4 / §9 で触れる):
|
||||
|
||||
```
|
||||
wiki/
|
||||
|
|
@ -168,6 +169,7 @@ Self-improving agent を名乗るフレーム。メモリ周りは **3 層 + ク
|
|||
|
||||
- `skill_manage` tool: OpenAI function-calling schema。frontmatter YAML 検証、security scan、atomic write (temp + `os.replace()`)
|
||||
- `memory` tool: target = `memory | user`、action = `add | replace | remove`。fcntl/msvcrt で file lock、entry-based rewrite
|
||||
- **char limit 超過時は `add` を hard reject**(`memory_tool.py:248-259`)。エラーメッセージに `Memory at {current}/{limit} chars. Adding this entry would exceed the limit. Replace or remove existing entries first.` と明記し、LLM 側に「自分で削減してから再追加」を強制する。GC は完全に LLM agentic(決定論的 eviction は無い)、人間 offer や scoring も無い、非常にシンプルな設計
|
||||
- FTS5: `messages_fts` virtual table + INSERT/DELETE/UPDATE trigger で auto-sync、CJK は LIKE フォールバック
|
||||
|
||||
### 実装観点
|
||||
|
|
@ -197,13 +199,14 @@ Self-improving agent を名乗るフレーム。メモリ周りは **3 層 + ク
|
|||
- 4 区画: **Message Buffer**(直近)、**Core Memory**(in-context の編集可能 block: user prefs / persona)、**Recall Memory**(全履歴の検索)、**Archival Memory**(ベクトル or グラフ DB に外部化された宣言的知識)。
|
||||
- OS メタファ: context window = RAM、外部ストア = Disk。エージェントが function call で階層間を移動させる。
|
||||
- memory block = `{label, description, value, char_limit}`。
|
||||
- **sleep-time agent** が idle 中に非同期で block を書き換える。
|
||||
- context 限界近くで要約による eviction → 再帰要約で古いメッセージを累進圧縮。
|
||||
- **sleep-time agent** が idle 中に非同期で block を書き換える。主要 agent と **別 process で並列**に走り、`core_memory_replace` / `core_memory_append` / archival tool 群を呼んで **直接 memory block を書き換える**。主 agent のターン処理をブロックしないため、「mid-session で memory 品質を上げる」のが特徴。
|
||||
- context 限界近くで要約による eviction → 再帰要約で古いメッセージを累進圧縮。**eviction 判断は context window fill の決定論的しきい値**で発火するが、要約の内容生成は LLM。evicted message は recursive summary として memory block に残り、古いほど重みが相対的に下がる。
|
||||
|
||||
### Cloudflare Agent Memory (2026-04 Agents Week)
|
||||
|
||||
- 分類: **Fact / Event / Instruction / Task**(Task のみベクトル索引除外)。
|
||||
- 基盤: Durable Objects(プロファイル毎の SQLite、FTS・supersession chain・tx write を担う)、Vectorize(セマンティック)、Workers AI(Llama 4 Scout: 構造化、Nemotron 3: 自然文合成)。
|
||||
- **Supersession chain は決定論的**(公式 blog 再確認): Fact / Instruction は classification pipeline で **normalized topic key** が振られ、同 key の新 memory が来ると旧 memory を **supersede(物理削除せず forward pointer で版チェーン化)**。LLM 判断は入らない。superseded 側の vector は並行して削除され、新 vector が upsert される。SHA-256 content-addressed ID で `INSERT OR IGNORE` による冪等 dedupe も併用。
|
||||
- API:
|
||||
```javascript
|
||||
const profile = await env.MEMORY.getProfile("my-project");
|
||||
|
|
@ -262,6 +265,17 @@ Agent Workspace(`~/.openclaw/workspace/`)構成:
|
|||
|
||||
**insomnia にとって重要**: consolidation を LLM 依存から切り離せる見本。narrative は subagent が生成するが、promotion の判断は純機械(scoring)。insomnia の plan では Scope 外(Phase 2 は当面 agent 委任)だが、成熟したカテゴリから決定論的 promotion に差し替える upgrade path の参考になる。
|
||||
|
||||
**GC 観点の追加詳細**(`extensions/memory-core/src/short-term-promotion.ts:1518-1652` 実装より):
|
||||
|
||||
- `applyShortTermPromotions()` は **append 専用**。gate 通過候補の snippet を `MEMORY.md` 末尾に `<!-- openclaw-memory-promotion:<hash> --> ` marker 付きで追記するだけで、既存 `MEMORY.md` ブロックの書き換えや削除は一切行わない
|
||||
- **重複回避**: marker set を先読みし、既に書かれた key はスキップ
|
||||
- **汚染検出**: `isContaminatedDreamingSnippet()` で dreaming narrative prompt が snippet に混入している候補を promotion 前に弾く(再帰汚染防止)
|
||||
- **日次ノートの decay は物理削除ではなく search score 減衰のみ**(`memory/temporal-decay.ts`)。`halfLifeDays = 30` で `exp(-ln2/HL * age)` を score に乗じる。対象は `memory/YYYY-MM-DD.md` 形式のファイル限定で、`MEMORY.md` や topic ファイルは evergreen 扱い(減衰しない)
|
||||
- **自己参照汚染の退避**: `dreaming-repair.ts` は dreaming narrative が session corpus や `DREAMS.md` に逆流した場合を検出し、該当ファイルを `.openclaw-repair/dreaming/<timestamp>/` に **rename で退避**(削除ではない)。lint と同じく audit-first の GC スタイル
|
||||
- `MEMORY.md` 側の GC(重複 block の統合、stale record の drop 等)は **この extension には存在しない**。書き込みは promotion の append のみで、ユーザーが手で消すか `memory-wiki` lint のレポート経由で扱う
|
||||
|
||||
OpenClaw は「**削除は人間、script は append と退避まで**」という強い原則が貫かれている。
|
||||
|
||||
設計上の示唆:
|
||||
|
||||
- Workspace = git リポジトリ 1 本で完結、配置もフラット。insomnia の pod workspace 概念にそのまま借用できる。
|
||||
|
|
@ -448,9 +462,108 @@ insomnia で意思決定すべきポイントはこの対応表:
|
|||
|
||||
---
|
||||
|
||||
## 8. 未調査 / 次に掘るべき項目
|
||||
## 8. GC 機構の横断比較
|
||||
|
||||
`docs/plan/memory.md` §GC は「Phase 2 とは別経路で memory を再評価し、drop / merge / split / `replaced` chain 整理を行う」ことを決めた段階で、判断主体と処理種別の仕様をこれから詰める。本節は他プロジェクトの GC 設計を共通の 6 軸で並べて、insomnia で採るべき型の材料とする。
|
||||
|
||||
### 8.1 比較表
|
||||
|
||||
対象の行は「その system が実装している GC 機構」単位で、同じプロジェクトが複数機構を持つ場合は複数行にした。
|
||||
|
||||
| # | プロジェクト / 機構 | 対象 | トリガー | 判断主体 | 処理種別 | 人間介入点 | 履歴保持 |
|
||||
|---|---------------------|------|----------|----------|----------|-----------|---------|
|
||||
| 1 | Codex Phase 2 consolidation | `MEMORY.md` block / `memory_summary.md` / `skills/*` | session idle + age | **LLM agentic**(sub-agent) | drop / merge / split / rewrite、removed thread id に紐づく block を **部分削除**(block 丸ごとは消さない、thread-local 記述のみ除去) | 無し(`/memories` で thread 単位 opt-out のみ) | git 任意、memory_root は単なる Markdown |
|
||||
| 2 | Codex extension resource retention | `memories_extensions/<name>/resources/*.md` | Phase 2 実行直前に cron 相当 | **決定論** | **物理削除** (filename timestamp cutoff) | 無し | 完全消去、Phase 2 prompt に removed list を通知 |
|
||||
| 3 | Codex stage1 pruning | `stage1_outputs` SQLite row | Phase 2 後 / 容量超過 | **決定論** | `selected_for_phase2 = 0` の古い row を cutoff + `LIMIT` で DELETE | 無し | SQL 完全削除 |
|
||||
| 4 | Hermes `memory` tool | `MEMORY.md` / `USER.md` のエントリ | **char limit (2,200 / 1,375) 超過時の add 拒否** | **LLM agentic**(エラー受けて自分で `replace` / `remove` を呼ぶ) | drop / rewrite | 無し(all-agent) | ディスク消去(file lock で tx 化) |
|
||||
| 5 | Hermes background review | entry / skill | turn / iter カウンタ(10 デフォルト) | **LLM agentic**(fork agent、max_iterations = 8) | add / update / delete をレビュー判断、`Nothing to save.` で no-op | 無し | same as 4 |
|
||||
| 6 | OpenClaw `applyShortTermPromotions` | promotion candidate → `MEMORY.md` | Deep dreaming phase | **決定論**(6 重み合算 + 3 ゲート、LLM ゼロ) | **append のみ**(`<!-- openclaw-memory-promotion:<hash> -->` marker、既存 block は触らない) | 無し | 追記のみ、削除系統は別 |
|
||||
| 7 | OpenClaw temporal decay | `memory/YYYY-MM-DD.md` | search 呼び出し毎 | **決定論** | **物理削除せず search score 減衰**(half-life 30d) | 無し | ファイル残置、検索順位だけ沈む |
|
||||
| 8 | OpenClaw dreaming-repair | `DREAMS.md` / session-corpus / session-ingestion | 手動 + audit CLI | **決定論** | **archive 退避**(`.openclaw-repair/dreaming/<timestamp>/` に rename)、完全削除しない | 退避後は手動判断 | archive ディレクトリに rename で保持 |
|
||||
| 9 | memory-wiki `/wiki-lint`(OpenClaw extension、SamurAIGPT/llm-wiki-agent と Karpathy llm-wiki の production 実装) | wiki page / claim | `/wiki-lint` 手動 or cron 想定 | **決定論**(issue 検出ロジック) + その後の **human/LLM 任意判断** | **削除ゼロ**、`reports/lint.md` に issue を書き出すのみ。修正は別コマンド / 人間が行う | 全出力点が人間承認 | 原ファイル無変更、report は上書き |
|
||||
| 10 | Cloudflare Agent Memory supersession | Fact / Instruction row(Durable Object SQLite) | 新 memory ingest 時 | **決定論**(normalized topic key が一致した瞬間) | **supersede**(旧 row を forward pointer で版チェーン化、物理削除せず)、vector は非同期 delete + new upsert | 無し(全自動) | SQLite に旧版残置、version chain で参照可能 |
|
||||
| 11 | Letta sleep-time agent | in-context memory block | 非同期 idle process | **LLM agentic** | `core_memory_replace` / `core_memory_append` / archival 移動で block 書き換え | 無し | 書き換え後の block が保存、旧 block は失われる |
|
||||
| 12 | Letta recursive summarization | message buffer | **context window fill の決定論閾値** | 発火は決定論 / 要約内容は LLM | evict + 再帰要約(古いほど重み減) | 無し | 要約に畳み込まれる(原メッセージは消失) |
|
||||
| 13 | LinkedIn CMA(公開情報レベル) | Episodic / Semantic / Procedural 各層 | 未公開 | 未公開 | **summarization による compaction**(階層別の drop 仕様は非公開、"cache invalidation is one of the hardest problems" と明示) | **高 stake 用途は human validation** を挟む | 非公開 |
|
||||
|
||||
### 8.2 軸別の知見
|
||||
|
||||
**対象(何が GC されるか)の粒度差**:
|
||||
|
||||
- 最小粒度の Hermes(entry)と Cloudflare(row)は、LLM がエントリ単位で `remove` / `replace` する設計に寄る。
|
||||
- 中粒度の Codex(`MEMORY.md` block)は、block 内を thread id で部分削除しながら必要なら split / rewrite する agentic 寄り。
|
||||
- 最大粒度の OpenClaw / memory-wiki は **ファイル単位でのみ削除 / 退避** し、file 中身は LLM / 人間に委ねる。`docs/plan/memory.md` の「1 件 1 ファイル」方針とは **OpenClaw の粒度が最も近い**。
|
||||
|
||||
**トリガー(いつ GC するか)の 4 パターン**:
|
||||
|
||||
1. **容量超過 hard reject**(Hermes): 追加要求を失敗で返して LLM に自律対処を強制。**決定論的 trigger + agentic 処理**で、設計最小コスト。
|
||||
2. **session idle + age**(Codex Phase 2): 人間の活動終了を待って非同期、最もユーザー体感を壊しにくい。
|
||||
3. **cron / scheduled sweep**(OpenClaw dreaming default `0 3 * * *`, Codex extension retention): 定期的・予測可能。人間 review との組み合わせがしやすい。
|
||||
4. **ingest 時の即時**(Cloudflare supersession): 書き込みの tx 内で完結、後続 GC 走査が要らない。topic key 設計が前提。
|
||||
|
||||
insomnia の plan は (2) Phase 2 で rewrite 許可を置きつつ、GC は (3) 方向で別経路という構造。これは Codex / OpenClaw の両方と整合する。
|
||||
|
||||
**判断主体の 3 系統**:
|
||||
|
||||
- **決定論のみ**: Codex retention / stage1 pruning / OpenClaw temporal decay / Cloudflare supersession / lint 検出。条件がはっきりしているもの(age / key 一致 / 構造的 issue)は決定論が強い。
|
||||
- **決定論 scoring → 閾値 gate → 機械適用**: OpenClaw Deep promotion。LLM の揺れを除き、コストも LLM コールゼロ。ただし対象が append 側のみで、削除には使われていない。
|
||||
- **LLM agentic**: Codex Phase 2 / Hermes review / Letta sleep-time。判断の柔軟性(block 内部分削除、context 依存の merge)を LLM に委ねる。
|
||||
|
||||
`docs/plan/memory.md` は Phase 2 が LLM agentic、GC も暫定的に **LLM agentic + Linter Warn 併用**としている。完全に一致する事例は **Codex Phase 2 の consolidation prompt**(836 行)で、「removed thread id を `MEMORY.md` から部分削除し、blockに他の thread が残っている場合は split / rewrite して保持」という手続きを自然言語で指示している。**insomnia は Linter 側に警告カテゴリ(類似 slug / `replaced` 滞留 / sources 過多 / stale)を先に定義し、GC 実行の agent プロンプトはそれを入力にする**構造が素直。
|
||||
|
||||
**処理種別の選択肢**:
|
||||
|
||||
- `drop / merge / split / rewrite` の組み合わせは Codex Phase 2 が最も自由度高く、Hermes もそれに近い(entry 粒度)。
|
||||
- `replaced` chain の整理は **Cloudflare だけが自動で版チェーン維持**、他は LLM 任せ。insomnia は decision record に `replaced_by` を入れているので、Cloudflare 方式の forward pointer 概念を **人間可読な `replaced_by:` frontmatter** で既に踏襲している。GC 時に chain をどこまで短く畳むか(長大な `a → b → c → d` を `a → d` に圧縮するか)は未決定論点で、Cloudflare は圧縮せず chain を保持する設計。
|
||||
- **`split` は Codex だけが明示**。block 内に複数 thread id が混ざった場合に thread id 単位で分ける。insomnia の「1 件 1 ファイル」方針では split = ファイル分割となり、主題の粒度判断は GC agent に委ねる必要がある。
|
||||
|
||||
**人間介入点の 3 段**:
|
||||
|
||||
- 完全無介入: Codex / Cloudflare / Letta / Hermes
|
||||
- audit-first(issue を surface し、人間が決断): memory-wiki lint / OpenClaw dreaming-repair
|
||||
- high-stake 限定 gate: LinkedIn CMA
|
||||
|
||||
insomnia の plan は「人間 offer 承認を併用」なので **audit-first に寄る**のが自然。lint 相当の Warn を Linter で出し、LLM Phase 2 / GC がそれを消費する前に人間が承認 / 拒否できる UI を提供する構造。memory-wiki lint は `reports/lint.md` というシンプルな Markdown 出力なので、そのまま `memory/reports/gc-lint.md` 相当を tick off する実装が参考になる。
|
||||
|
||||
**履歴保持の 3 モデル**:
|
||||
|
||||
1. **物理削除**: Codex retention / stage1 / Hermes / Letta(要約で畳む分は実質消失)
|
||||
2. **archive 退避(rename)**: OpenClaw dreaming-repair
|
||||
3. **forward pointer / tombstone**: Cloudflare supersession
|
||||
|
||||
insomnia は **git 管理下に memory を置く**前提なので、物理削除を選んでも git log で復元できるのが強み。`replaced_by:` frontmatter が forward pointer の役割を果たしているので、Cloudflare 型と git を足した「**現物は物理削除、frontmatter pointer で chain を参照、git で history**」が最も設計コストに合う。archive 退避は git を前提にすると冗長。
|
||||
|
||||
### 8.3 insomnia の GC 仕様を詰めるときの示唆
|
||||
|
||||
1. **GC trigger は 2 系統に割る**。(a) 決定論: Linter Warn 群 + age / count / size 閾値の sweep、(b) LLM 判定: Phase 2 とは別 prompt で Linter の issue リストを入力に渡す。両方が `memory/reports/gc-*.md` 相当を書き、それを次回の GC run が読む、というフィードバックループが OpenClaw lint / Codex Phase 2 input selection の両方と整合する。
|
||||
2. **Linter に「GC 候補検出」カテゴリを足す**。memory-wiki の lint issue code が参考になる: `stale-page`(90d 超)/ `stale-claim` / `low-confidence` / `orphan` / `duplicate-id` / `broken-wikilink` / `contradiction-present` / `open-question`。insomnia 固有の追加候補: `similar-slug`(類似 slug 乱立、既に plan に記載)/ `replaced-chain-long`(`replaced_by` が 3 段以上)/ `sources-overflow`(1 record の sources が閾値超)/ `knowledge-invoke-frequency-low`(`user_invoke` が一定期間ゼロ)。
|
||||
3. **処理は rewrite 優先、削除は `status: replaced` 経由**(既に plan 方針と一致)。forward pointer は Cloudflare 流、ただし chain 圧縮ルール(例: 「chain が n 段超えたら中間を drop、端のみ残す」)を決めるかは別論点。Cloudflare は圧縮しない、insomnia は git があるので圧縮してよい。
|
||||
4. **char limit は採用しない方が筋が良い**。Hermes の hard limit + LLM self-rewrite は設計最小だが、insomnia は 1 record 1 file なのでファイル内 size 制約は薄く、file 数による grep コストの方が支配的になる。file 数閾値 → GC trigger の方が insomnia の形に合う。
|
||||
5. **決定論 scoring を後から差し込む余地を残す**。OpenClaw Deep phase のような「頻度 / 関連度 / 多様性 / 時間減衰 / 整合性 / 概念」の 6 重み + 閾値は、agent LLM の出力が運用で評価可能になった段階で部分的に差し替える upgrade path として最適。初期は Phase 2 LLM + Linter Warn で十分。
|
||||
6. **削除は git commit 単位で可逆**という前提を明示する。プロジェクトメモリは git 管理下なので、GC が誤って drop してもユーザーは revert できる。これは Codex が持っていない利点で、GC agent の判断を多少攻めても安全マージンがある。
|
||||
|
||||
一次ソース:
|
||||
- Codex Phase 2 consolidation: `github.com/openai/codex/codex-rs/core/src/memories/phase2.rs`, `core/templates/memories/consolidation.md`
|
||||
- Codex retention / stage1 pruning: `github.com/openai/codex/codex-rs/core/src/memories/extensions.rs:11-139`, `codex-rs/state/src/runtime/memories.rs:290-331, 333-464`
|
||||
- Hermes char limit reject: `github.com/NousResearch/hermes-agent/tools/memory_tool.py:211-266`
|
||||
- Hermes review spawn: `github.com/NousResearch/hermes-agent/run_agent.py:2727-2830`
|
||||
- OpenClaw promotion apply: `github.com/openclaw/openclaw/extensions/memory-core/src/short-term-promotion.ts:1518-1652`
|
||||
- OpenClaw temporal decay: `github.com/openclaw/openclaw/extensions/memory-core/src/memory/temporal-decay.ts`
|
||||
- OpenClaw dreaming-repair: `github.com/openclaw/openclaw/extensions/memory-core/src/dreaming-repair.ts:70-165`
|
||||
- memory-wiki lint: `github.com/openclaw/openclaw/extensions/memory-wiki/src/lint.ts`, `claim-health.ts:6-7`(`WIKI_AGING_DAYS = 30`, `WIKI_STALE_DAYS = 90`)
|
||||
- Cloudflare supersession: https://blog.cloudflare.com/introducing-agent-memory/
|
||||
- Letta sleep-time: https://docs.letta.com/guides/agents/memory/, https://www.letta.com/blog/sleep-time-compute, arxiv 2504.13171
|
||||
- Letta recursive summary: https://www.letta.com/blog/agent-memory
|
||||
- Karpathy llm-wiki lint: https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
|
||||
- SamurAIGPT/llm-wiki-agent `/wiki-lint`: https://github.com/SamurAIGPT/llm-wiki-agent
|
||||
- LinkedIn CMA: https://www.infoq.com/news/2026/04/linkedin-cognitive-memory-agent/
|
||||
|
||||
---
|
||||
|
||||
## 9. 未調査 / 次に掘るべき項目
|
||||
|
||||
- Letta `memory block` の Rust 実装例・永続化形式。
|
||||
- Cloudflare Agent Memory の supersession chain の具体アルゴリズム(記事は概略のみ)。
|
||||
- `agentskills.io` の CRDT 的バージョニング方針(標準は version metadata を任意 key にしている。実運用でどう衝突解決するかは未整備)。
|
||||
- Hermes の Honcho 連携の実体(外部サービス API 越しの dialectic user modeling、repo には prompt と API 呼び出しのみ)。
|
||||
- LinkedIn CMA の層別 GC 仕様(公開情報では compaction-by-summarization までしか開示されていない)。
|
||||
- Cloudflare supersession chain の圧縮ポリシー(chain 長の上限、vector GC と row GC の tx 境界)。
|
||||
|
|
|
|||
140
tickets/pod-prompt-catalog.md
Normal file
140
tickets/pod-prompt-catalog.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Pod 内部プロンプトのカタログ化
|
||||
|
||||
## 背景
|
||||
|
||||
Pod は Worker を拡張する機構を持つ: コンテキスト圧縮 (Compact)、非同期通知 (Notify)、中断と再開 (Interrupt)、system prompt の trailing section、AGENTS.md 取込時の注記。これらの機構がランタイムで Worker に注入する/Worker 向けに構成するプロンプトは、現状各モジュール内の `const &str` / `format!` に分散している。
|
||||
|
||||
| 場所 | 役割 |
|
||||
|---|---|
|
||||
| `crates/pod/src/pod.rs:50` `SUMMARY_SYSTEM_PROMPT` | Compact worker の system prompt |
|
||||
| `crates/pod/src/notification_buffer.rs:73` `format_notification` | `Method::Notify` を Worker history に system_message として注入するラッパー |
|
||||
| `crates/pod/src/interrupt_and_run.rs:18-20` | 中断時の synthetic tool_result と system_message |
|
||||
| `crates/pod/src/system_prompt.rs:179-203` `append_trailing_section` | `## Working boundaries` / `## Project instructions (AGENTS.md)` ヘッダとレイアウト |
|
||||
| `crates/pod/src/agents_md.rs:19` `TRUNCATION_NOTICE` | AGENTS.md が 64KB 超過したときの末尾注記 |
|
||||
|
||||
`resources/prompts/default.md` でユーザー向け instruction テンプレートは一元化された一方、Pod が Worker を拡張する側のプロンプトは並行した一元管理を持たない。結果として:
|
||||
|
||||
- 全体を俯瞰しづらく、新しい injection 点を足すときに既存との一貫性が取れない
|
||||
- 多言語化や文体カスタマイズの導線がない
|
||||
- builtin から差分だけ書き換える軽量な手段がない
|
||||
|
||||
tool description は tool 宣言と併置が自然(tool 追加 = 1 箇所追加)なので本チケット対象外。Pod の Worker 拡張機構は異質なものが「Pod のトーン」として束になって振る舞う性質上、中央で扱う価値がある。
|
||||
|
||||
## 要件
|
||||
|
||||
### 1. 中央モジュール: `PodPrompt` enum
|
||||
|
||||
Pod が Worker に注入する全プロンプトを列挙する enum を 1 つ置く。variant の集合が「存在する injection 点」の master。新しい注入点を増やすときは variant 追加が必要 = コード上で勝手に散らかせない。
|
||||
|
||||
Pod 内部の各モジュールは `PodPrompt::CompactSystem.render(&ctx)` のように 1 本の API で引く。直接 `include_str!` / `const &str` / `format!` で prompt 文字列を書かない。
|
||||
|
||||
### 2. 翻訳パック形式: `prompts.toml`
|
||||
|
||||
全 variant を key-value で持つ TOML。値は minijinja テンプレート文字列(builtin/ランタイム問わず一律 minijinja render)。
|
||||
|
||||
```toml
|
||||
[prompt]
|
||||
interrupt_system_note = "[The previous turn was interrupted by the user. The user's next request follows.]"
|
||||
|
||||
notify_wrapper = """[Notification]
|
||||
{{ message }}
|
||||
|
||||
This is a notification, not a blocking request. ..."""
|
||||
|
||||
# 長文は外部ファイルに link
|
||||
compact_system = "{% include '$insomnia/internal/compact_system.md' %}"
|
||||
```
|
||||
|
||||
変数展開は各 variant ごとに定義された context を render 時に渡す(例: `notify_wrapper` は `message`、`compact_system` は tool 名リストなど)。context の具体形は実装段階で variant ごとに確定する。
|
||||
|
||||
### 3. Builtin pack の網羅性をビルドエラーで強制
|
||||
|
||||
`resources/prompts/internal.toml` が `PodPrompt` 全 variant を網羅していないとビルド失敗。enum に variant を足したが builtin pack に key が無い、あるいは逆、はコンパイルが通らない。`build.rs` もしくは proc-macro で検査する(どちらを取るかは実装時判断)。
|
||||
|
||||
### 4. 4 段の置換マージ
|
||||
|
||||
key 単位で overlay。下層から順に apply、後勝ち:
|
||||
|
||||
```
|
||||
builtin resources/prompts/internal.toml (必須・網羅)
|
||||
↓
|
||||
user $XDG_CONFIG_HOME/insomnia/prompts.toml (任意・auto)
|
||||
↓
|
||||
workspace <project>/.insomnia/prompts.toml (任意・auto)
|
||||
↓
|
||||
manifest pack manifest.pod.prompt_pack で指名 (任意)
|
||||
```
|
||||
|
||||
- 欠落 key: 下層から継承
|
||||
- ランタイム層 (user/workspace/manifest pack) の unknown key: `tracing::warn!` して無視
|
||||
- builtin 層の不整合はビルドエラー(前項)
|
||||
|
||||
### 5. 値 render は minijinja 統一、include は既存 prefix resolver 流用
|
||||
|
||||
全値を minijinja で parse / render。`{% include "$prefix/..." %}` によって外部ファイルを link 可能。resolver は既存 `crates/pod/src/prompt_loader.rs` を流用し、`$insomnia` / `$user` / `$workspace` すべてをどの層の pack からも参照できる。
|
||||
|
||||
### 6. manifest 露出
|
||||
|
||||
```toml
|
||||
[pod]
|
||||
prompt_pack = "$user/packs/japanese.toml"
|
||||
```
|
||||
|
||||
任意フィールド。指定されていれば 4 段目 overlay として適用。auto-discovery (user/workspace) とは独立で共存する。子 Pod を spawn する際、親が子の役割に応じた pack を明示する用途を想定。
|
||||
|
||||
## 設計判断
|
||||
|
||||
### prompt_pack は prefix 名前空間に載せない
|
||||
|
||||
既存 `$insomnia/` / `$user/` / `$workspace/` は**名前空間**で、同じ key で複数の source を指し合うことはない。一方 pack は**レイヤー**で、同じ key を置き換える。この 2 つを同じ軸に混ぜるとユーザーが「どの書き方で上書きされるか」を予測できなくなる。
|
||||
|
||||
pack ファイルは**固定パスの auto-discovery** と **manifest による明示指名**の 2 経路のみ。各値内部で `{% include "$prefix/..." %}` を使うのは別軸なので prefix 体系の利点はそのまま享受できる。
|
||||
|
||||
### 長文ファイル分離用の独立フィールドを作らない
|
||||
|
||||
値が minijinja である以上、長文を別ファイルにしたければ `"{% include '$insomnia/internal/foo.md' %}"` と書けば済む。「TOML 値の文字列」と「ファイル参照」の 2 値型を用意する必要はない。1 種類で統一する。
|
||||
|
||||
### ランタイム層の unknown key は warn
|
||||
|
||||
pack ファイルを書いた時点と Pod バージョンがずれたとき、hard error にすると古い pack で Pod が起動しなくなる。前方互換のため warn で無視する。builtin 層は build-time に同梱するので不整合はビルドで捕まえられる = error で問題ない。
|
||||
|
||||
### tool description は本チケット対象外
|
||||
|
||||
tool 追加は tool ごとの 1 箇所の自然な単位で、description は tool の属性として宣言と併置が読みやすい。Pod 内部 injection は「異質なものが一体としてトーンを決める」共通軸なので中央化の価値が別にある。この差を混ぜない。
|
||||
|
||||
### auto-discovery と manifest 指定を両立させる
|
||||
|
||||
auto-discovery は「ユーザー or プロジェクトの永続設定 (翻訳、文体)」、manifest 指定は「**その Pod の役割**による差し替え」と目的が別。どちらか一方では片方のユースケースが潰れるので両立する。key 単位の merge は共通なので実装コスト差は小さい。
|
||||
|
||||
## Scope 外
|
||||
|
||||
- tool description の resources 化(併置方針を維持)
|
||||
- 具体的な翻訳 pack の作成(本チケットは導線のみ)
|
||||
- pack 編集 GUI / TUI
|
||||
- user/workspace 以外の auto-discovery パス追加(別 XDG 層、bundle pack 等)
|
||||
|
||||
## 依存
|
||||
|
||||
- `crates/pod/src/prompt_loader.rs` (`$prefix` resolver を minijinja include から流用)
|
||||
- `crates/pod/src/system_prompt.rs` (minijinja 使用パターン)
|
||||
- `crates/manifest`: `pod.prompt_pack: Option<String>` 追加のみで破壊的変更なし
|
||||
|
||||
## 影響範囲
|
||||
|
||||
- `crates/pod/src/prompts.rs` (新設): `PodPrompt` enum、render API、pack loader、4 段 merge
|
||||
- `resources/prompts/internal.toml` (新設): builtin pack
|
||||
- `resources/prompts/internal/*.md` (新設): 長文外出し
|
||||
- `crates/pod/` 各モジュール: 既存ハードコードを `PodPrompt::...render(&ctx)` 呼び出しに置換
|
||||
- `crates/pod/build.rs` もしくは proc-macro (新設): enum ⇔ builtin pack 網羅検査
|
||||
- `crates/manifest/src/config.rs`: `prompt_pack` フィールド追加
|
||||
|
||||
## 実装順序
|
||||
|
||||
1. `PodPrompt` enum と render API を定義。builtin map (in-memory、`include_str!`) から引くだけの最小実装。variant の render 網羅を単体テストで確認
|
||||
2. `resources/prompts/internal.toml` に全 key を書き、既存ハードコードをそのまま文字列として移植。各モジュールの呼び出しを `PodPrompt::...render` に置換 (挙動は既存と完全同一)
|
||||
3. builtin 網羅を build-time 検査に格上げ (enum ⇔ pack の双方向で欠落/余剰を検出)
|
||||
4. user / workspace の auto-load と 3 段マージ。ランタイム unknown key の warn
|
||||
5. `manifest.pod.prompt_pack` を追加、4 段目 overlay として load
|
||||
6. 長文 variant (compact_system など) を `{% include "$insomnia/internal/..." %}` 形式に分離。`$user` / `$workspace` から include で override できることをテスト
|
||||
|
||||
各ステップ終了時点でビルド通過・既存テスト合格を維持する。
|
||||
|
|
@ -7,8 +7,5 @@
|
|||
|
||||
## 検討事項
|
||||
|
||||
- `llm-worker`: LlmClient の mock 実装によるターンループ・ツール実行のテスト
|
||||
- `llm-worker-persistence`: FsStore / FsBlobStore のファイルシステムテスト(tempdir)
|
||||
- `pod`: PodController / SocketServer の結合テスト
|
||||
- `protocol`: シリアライズ/デシリアライズの往復テスト
|
||||
- `manifest`: パースのバリエーション(既存テストの拡充)
|
||||
低層部分のテストを信頼し、上層までモックデータを引っ張ってきてテストする必要は無いのか?
|
||||
実際の認証を使ったE2Eはどの様に結果を出すか?/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user