Create ai-tools-interaction.md, filesystem-discovery.md

This commit is contained in:
2026-10-07 03:29:56 +09:00
parent c4fdff5b6b
commit e37155ee00
2 changed files with 270 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
# AI Tools: tree / inspect / invoke(草案)
## 位置付け
この文書は、Yoiでの利用・実装検討を通して決めた、WIP ClientのAI向け操作仕様を記録するdraftである。Protocol interactionをそのままToolとして公開するのではなく、AIが対象の配置を見て、できることを理解し、操作するための上位インターフェースを定める。
基本操作は **tree / inspect / invoke** とする。Tool名にProtocol名の接頭辞を付ける必要はない。ここでの小文字表記は操作の呼称であり、providerごとのTool登録名の大文字・小文字やTool response envelopeまでは規定しない。
[AI用Toolsの例](../4.1-ai-tools-example.md)にある `discover(scope, query)` に対し、本draftでは `tree(path, depth)` を基本とする。既存章を書き換え済み、またはすべてのWIP Clientへ採用済みという意味ではない。Protocolの `observe` / `fetch_interface` / `call_operation` は変更しない。
関連する責務は[Client](../4-client.md)、表示書式の候補は[WIP Text View](text-view.md)、FSの探索境界は[Filesystem Discovery](filesystem-discovery.md)を参照する。Yoi側の実装追跡はT-713で行う。
## 基本的な利用モデル
| AI向け操作 | AIが行うこと | Clientが引き受けること |
| --- | --- | --- |
| `tree(path, depth)` | indexableな対象の配置を見る | 必要なdepthの観測とtree表示 |
| `inspect(path)` | 対象の説明とできることを知る | Object観測、Interface集合の解決、Signature View生成 |
| `invoke(target, interface, operation, arguments)` | 選択した操作を名前付き引数で呼ぶ | 引数検証、観測との対応、validator、Protocol requestと結果の処理 |
これらはProtocol interactionとの一対一対応ではない。特に `inspect` の対象はInterface参照ではなく、Objectを指すpathである。必要な `observe` と複数の `fetch_interface` はClient内部で行う。
Operationを調べた後も、AI向け入口はこの3操作のままでよい。InspectしたOperationごとに新しいToolを登録することは、この利用モデルの前提ではない。
## tree: indexableな配置を見る
`tree(path, depth)` は、起点をdepth 0として、指定depth内のindexableなツリーを全量取得・表示する。
- 必要なcoverageを持つ観測を再利用できる。不足する場合はClientが取得する。
- 全量とは、指定した起点・depth・主体に公開されたindexableな範囲の全量であり、Worldspace全体やすべてのドメインデータではない。
- 名前、path、親子構造を中心に提示する。すべてのObjectのDescriptorやドメインデータを展開しない。
- Protocolのdepth境界にある未観測のchildrenと、観測済みの空のindexable childrenを混同しない。
- 指定depth内の一部を黙って省略して完全なtreeとして返さない。既存のresource limit内で成立しない場合は、その失敗を伝える。
- Cacheに保持されたpathを単にprefixで集めてtreeにしない。Hostから観測したindexable edgeに従い、指定depth外やOperation経由で知っただけのentryを混ぜない。
浅い位置に大量の要素があれば、小さいdepthでもAIが把握できない出力になる。これはdepth調整やClient側の切り捨てだけで解決する問題ではなく、Hostが何をindexableにするかの問題である。
大量の要素やドメインデータの発見には、Collection Objectの `list` / `search` / `query` 等のOperationを使う。Client独自の全文検索、semantic search、ランキングを基本の3操作に追加する前提にはしない。
## inspect: 対象の説明とできることを知る
`inspect(path)` は、そのpathで公開されているObjectの説明と操作を返す。
AIがそのpathをtree、会話、Operation結果のいずれから知ったかは、事前条件にしない。ClientがまだObjectを観測していなくても、有効なpathを直接指定できる。
Clientは必要に応じて次を行う。
1. 対象pathのObjectを観測する。対象だけが必要なら `depth = 0` を使用する。
2. Objectが公開するInterface参照のordered setを取得する。
3. 必要なDescriptorをcacheから解決し、不足するものを取得・検証する。
4. Objectの説明と、InterfaceごとのSignature Viewをまとめて提示する。
AIに「先にObjectをobserveして、Interface参照を抜き出し、一つずつfetchする」という手順を要求しない。一方で、Objectの本文やドメインmetadataまで暗黙に読み込むわけではない。それらの取得は対象のOperationとして扱う。
### 表示に必要な情報
- 対象のpathと、公開されているObjectの説明。
- InterfaceとOperationの対応。
- Operation名、短い用途説明、名前付き引数、必須性、引数・結果の型。
- 操作を理解するために必要な名前付き型・複合型の定義。
生のDescriptor JSONを返すだけではなく、検証済みの情報から読みやすいSignature Viewを生成する。同名Operationが複数Interfaceに存在しても、一つへ平坦化したり、出所を失ったりしない。Invokeへ渡すInterface参照とOperation名は区別して保持し、表示textを再parseして呼出先を決めない。
具体的なObject block、Interface block、型、documentation、省略の表記は、既存の[WIP Text View草案](text-view.md)を参照する。本draftはその表示候補を重複定義せず、最終採用も決定しない。未展開や取得失敗を「操作が存在しない」と誤表示しないことは、取得側と表示側の共通条件である。
## invoke: 選んだ操作を実行する
`invoke(target, interface, operation, arguments)` は、対象のInterfaceとOperationを明示して呼び出す。Argumentsはparameter declarationに従う名前付きfieldのrecordであり、位置引数ではない。
Interfaceを明示するのは、同じObjectの複数Interfaceに同名Operationがあり得るためである。Interfaceの選択をAIへ示すことと、Descriptorの取得手順をAIに管理させることは別である。
ClientはObjectとDescriptorの観測を保持し、引数を検証し、path、Object validator、Interface参照とvalidatorをProtocol requestへ設定する。AIにvalidatorの取得・コピー・更新をさせない。通常のSignature Viewへ同一性管理やvalidatorを混ぜる必要もない。
Pathを知っていることやInterfaceが表示されたことは、実行権限を意味しない。Hostは呼出時の公開状態、権限、capability、実行条件を引き続き検証する。
再観測とOperationの再実行を同一視しない。Stale、取消、拒否、結果不明などの扱いは既存Protocolに従う。結果不明のOperationを自動再実行せず、Operation名からread/writeやretry可否を推測しない。
## AIのpath認知とClientの観測状態
次の状態は別のものとして扱う。
1. AIがpathを参照できるが、ClientはそのObjectをまだ観測していない。
2. ClientがObjectを観測し、Known Spaceへ保持している。
3. Clientがindexable edgeも観測し、Discoverable Spaceとして保持している。
1は正常な利用状態である。未観測のpathを偽のObjectとしてKnown Spaceへ登録する必要はないし、Known Spaceにないという理由でそのpathのinspectを拒否する必要もない。
Clientが内部で保持する情報とAIに表示済みの情報も一致する必要はない。Treeの取得でObject情報を保持していても、AIには名前と構造だけを見せ、詳しい説明と操作はinspectで提示できる。
Known Spaceは過去の全pathの台帳でも、Host状態のreplicaでもない。非indexableなObjectを観測してKnown Spaceへ保持しても、その事実だけでtreeの子にはならない。Cacheは接続先・主体・security contextごとに分離する。
## Operation結果からの移動
Operation結果の `entry` 型pathは、そのまま次の対象への参照として提示できる。すべての結果を即時に観測したり、再帰展開したりすることを必須にしない。AIが必要なpathを選んでinspectするときに、Clientが観測できる。
Entryの抽出はDescriptorの型に従う。普通のstringを内容だけからpathと推測しない。結果のentryを観測・保持しても、それだけでindexable edgeを追加しない。
Clientが付随的なentry取得を行う場合、その取得失敗と元のOperationの成否を混同しない。成功済みOperationを、結果の参照先が取得できなかったために失敗扱いして再実行させてはならない。
## 検証する利用シナリオ
- 観測が空のClientで既知pathを直接inspectし、説明と操作を取得できる。
- Treeが指定depthのindexable範囲を完全に提示し、cache内の他のpathを混ぜない。
- 複数Interfaceに同名Operationがあっても、表示から正しいInterfaceとOperationを選んでinvokeできる。
- Search/list結果から必要なentryだけをinspectでき、全件先行取得を要求しない。
- 非indexableなentryを観測した後も、rootからのtreeにそのentryが混入しない。
- 表示やcache利用によって、権限・観測整合性・結果不明の扱いを弱めない。
## 未決事項と既存文書への反映
- Treeの具体的なtext layout、Tool引数のdefault、Tool response envelope。
- WIP Text View草案の最終採用と、inspectでの詳細表示・表示範囲の選択方法。
- 既存の `discover(scope, query)` 例を、汎用Clientの別の投影例として残すか、tree中心の説明へ改訂するか。
取得・表示・cache保持を分離することは決定事項だが、特定の内部class構成、eviction algorithm、prefetch schedulerを採用することは、このdraftの決定に含めない。
+155
View File
@@ -0,0 +1,155 @@
# Filesystem Discovery: 入口と内容の分離(草案)
## 位置付け
この文書は、YoiのFS投影に対して決めた探索仕様を、WIP Hostの投影方針として記録するdraftである。**Treeで発見するのはfilesystemの入口までとし、その内容はdirectoryのlist / glob / grep Operationで発見する。**
Indexableな範囲の全量取得をClientで縮めるのではなく、Hostが何をindexableとして公開するかを修正する。個々のファイル・フォルダは非indexableなObjectとして要求時に直接解決できる。
[Object tree / SchemaのIndexable children](../2.1-object-tree-schema.md#indexable-children)、[Client](../4-client.md)、[AI Toolsの操作仕様](ai-tools-interaction.md)を前提とする。Yoi側の実装追跡はT-714、既存投影はT-699である。本稿は仕様決定の記録であり、実装済みであることを示さない。
## なぜFS全体をindexableにしないか
Indexable childrenには、件数がboundedまたは現実的な範囲で列挙でき、比較的安価で、自然な所有・内包関係であることが求められる。全件列挙が高コストまたは不自然な集合は、Collection Operationで検索・filter・paginationし、`entry` を返すのが既存の方針である。
任意のfilesystem directoryは、浅い位置に大量のfileやdirectoryを持ち得る。Depthが小さくてもAIが把握できない件数になるため、depth制限だけでは適切な探索空間を作れない。
次の対策だけでFS内容をindexableにしてよいとはしない。
- Clientが小さいdepthを選ぶこと。
- Hostが件数上限で `ResourceLimitExceeded` を返すこと。
- Directoryをlazyに列挙し、常駐Objectや事前indexを作らないこと。
- Clientが応答を切り捨てて表示すること。
前二者は必要な安全弁、lazy解決は実装上の性質であり、indexabilityの判断とは別である。部分的な応答を完全なtreeとして見せることもできない。本投影では、内容の件数が少ない場合だけchildrenへ展開する方式にはせず、入口と内容の境界を一貫させる。
## Indexableな公開境界
Yoiでは、rootからtreeで発見できる範囲を次とする。
```text
/
└── checkouts
├── main
└── docs
```
`/checkouts/<checkout-name>` は、現在利用できるfilesystemの入口であり、directoryとして操作できるObjectでもある。その直下から先のfile / directoryは、入口や内容directoryのindexable childrenには含めない。
例えば次のpathは有効な操作対象として存在し得るが、上のtreeには展開しない。
```text
/checkouts/main/README.md
/checkouts/main/src
/checkouts/main/src/lib.rs
```
`/checkouts` はYoi側の配置例であり、WIP Protocol全体へ固定namespaceを追加するものではない。単一FSをWorldspace `/` に直接投影する場合は `/` 自体が入口に相当し、その内容をindexable childrenへ展開しない。
入口の一覧自体についてもindexableの一般条件は維持する。この境界は、入口の数まで無制限に増やしてよいという意味ではない。
## 非indexableと非公開は別
File / directoryをindexableにしないことは、Objectとして非公開にすることでも、pathで解決不能にすることでもない。
- `observe("/checkouts/main/src/lib.rs", depth = 0)` は、現在の主体に公開できるfileなら、そのObjectを返せる。
- AI向け `inspect(path)` は、ClientがまだObjectを観測していないpathにも使える。
- Directoryの探索やfileの読み書きは、そのObjectが公開するInterfaceのOperationとして実行する。
- 直接解決にも現在の可視性・権限を適用する。Pathを知っていることは権限ではない。
非公開・存在しないpathの扱いは従来のProtocolに従う。非indexableという理由だけで `NotFound` を返してはならない。
## observeのchildren契約
FS入口およびその内容のdirectory/fileは、この投影では内容のindexable childrenを持たない。
| 観測 | 応答の意味 |
| --- | --- |
| `observe("/checkouts", 1)` | 接続済み入口をchildrenとして列挙。入口はdepth境界なのでchildren fieldを省略 |
| `observe("/checkouts", 2)` | 同じ入口までを列挙。各入口のchildrenは `[]`。内容は列挙しない |
| `observe("/checkouts/main", 0)` | 入口Objectのみ。children fieldを省略 |
| `observe("/checkouts/main", 1)` | 入口Objectと `children: []` |
| `observe("/checkouts/main/src", 1)` | 直接解決したdirectory Objectと `children: []` |
`children: []` は「indexable childがない」という意味であり、filesystem directoryが空であるとは限らない。内容が空かどうかを知るにはdirectoryの `list` を使う。
File数が増えても、入口の正のdepth観測でbackendの全内容を列挙する必要はない。Client側だけで非表示にするのではなく、Hostのchildren列挙境界で内容への走査を行わないようにする。Depth境界でのfield省略と、観測済みの空のchildrenは従来どおり区別する。
## 内容を発見するOperation
FS入口と配下directoryには、次の探索Operationを提供する。これらはInterface上のOperationであり、新しいProtocol interactionや `list` という子Objectではない。
| Operation | 役割 |
| --- | --- |
| `list` | 対象directory直下のfile / directoryを列挙する |
| `glob` | 指定した範囲とpath patternに一致する対象を探す |
| `grep` | 指定した範囲のfile内容を検索する |
### list
- 一つのdirectoryの直接の内容を対象とする。暗黙に全subtreeを再帰展開しない。
- Fileとdirectoryを区別でき、空directoryも対象として発見できる。
- 各項目から、その主体のWorldspace内の正しい `entry` pathへ辿れる。
- 大量件数はOperation結果として上限と継続を明示して扱う。部分的な一覧を全件であるかのように返さない。
- Cursor等の継続方式、並び順、parameter名、result recordの具体形は、このdraftでは未決とする。
Yoiの `/checkouts` 自体にある `list` は入口一覧であり、`/checkouts/<checkout-name>` や配下directoryの `list` は内容一覧である。Operation名が同じでも対象とInterfaceが異なる。
### glob / grep
対象directoryを基準にpatternや検索範囲を解釈する。Resultsからfile / directoryへ移動する参照は `entry` 型として宣言し、表示済みのfilenameや行番号付きtextを再parseして作らない。
Globは条件に一致する対象を探す操作であり、directory直下の全内容を表すとは限らない。特にYoiの通常ToolsのGlobはfileのみを返し、directoryは返さず、配下を再帰的に走査し得る。`glob("*")` を `list` と同じ契約として扱わない。
Grepは内容検索であり、treeの名前・構造の探索ではない。Ignore、検索範囲、結果上限、context、継続等は各Operationの明示された契約に従う。
## Clientとの接続
典型的な利用は次の流れになる。これは操作の順序の例であり、Tool responseやInterface参照の具体構文を定義するものではない。
1. `tree("/", depth)` で `/checkouts/main` の入口を知る。
2. `inspect("/checkouts/main")` でdirectoryの `list` / `glob` / `grep` を知る。
3. 選んだOperationを `invoke` し、結果から `/checkouts/main/src` やfileのpathを得る。
4. 必要なpathだけを `inspect` し、さらに探索するかfileのOperationを実行する。
結果のすべてのentryを即時にObjectへ展開する必要はない。AIはまずpathだけを受け取り、説明や操作が必要になったときにClientへinspectを依頼できる。
Clientがそれらを観測してKnown Spaceへ保持しても、rootからのtreeには混ぜない。Pathの階層関係だけからindexable edgeを生成しない。既知の内容directoryをtreeの起点として直接指定した場合も、そのObjectは表示できるが、内容をindexableな子として復活させない。
## 解決・権限・整合性
探索方式の変更で、既存の権限やファイル操作の意味を変えない。
- 現在の主体、root/attachment、scope、provider capabilityに基づき、一覧・検索・直接path解決・操作を実行する。
- Hostの一覧結果には、主体へ公開できる対象だけを含める。直接path指定でも同じ境界を守る。
- Detach、権限取消、入口名の再利用後に、古い観測から別の対象を操作しない。
- Object identityとvalidatorは既存Protocolとproviderの実行境界で管理する。
- Fileのread/edit/write等の具体的契約は、各投影のInterfaceに従う。本稿はbyte操作やtext操作の統一を要求しない。
Yoiの実装では、既存Workdir providerのList/Glob/Grep処理と権限・transport境界を共有する。Worker側でremote filesystemのホストパスを直接開く方法や、Bashの `ls` を必須にする方法へ置き換えない。
## 現行文書・実装との差
[Dynamic Worldspace Projection](dynamic-worldspace-projection.md)のFilesystem評価例と、現行 `wip-fs-server` は、directoryの内容をchildrenとして列挙する経路を持つ。Yoiの既存 `/checkouts` 投影も、内部List処理をchildren列挙に使い、directoryの独立した `list` Operationは提供していなかった。
本draftは、それらの現状を承認する文書ではなく、FS内容の探索をOperationへ分離する修正方針である。Lazyなrequest-time解決と、既知pathからの直接解決は維持するが、directory listingをindexable childrenの列挙として使う部分は見直す。
既存ProtocolがあらゆるFS Objectのindexabilityを一律に禁止する明文を持つという意味ではない。既存のindexable条件を、任意件数の内容を持つFSへ適用する具体的方針として、このdraftでは入口で境界を固定する。
## 検証するシナリオ
- 入口直下に大量のfileを置いても、rootから深いdepthで取得するtreeの件数がfile数に比例せず、内容の全件走査も発生しない。
- 少数のfileしかないdirectoryでも、同じ非indexable境界が維持される。
- 深いdirectoryの正のdepth観測は `children: []` だが、そのdirectoryのlistは内容を返す。
- Directory listがfileと空directoryを返し、結果上限と継続を扱える。
- List/glob/grepで得たpathを直接inspect・操作できる。Bash/COMMAND権限を必要としない。
- 非indexableな結果をClientが保持しても、treeへ混入しない。
- Scope外、権限取消、detach、入口名再利用、stale validatorの拒否に回帰がない。
## 未決事項
- Directory listの具体的なschema、並び順、継続方式、変更中の一覧の保証。
- Symlinkや特殊entryのlist上の種別表現、各providerのignore方針との整合。
- 本稿を既存の動的投影例、FS実装、AI用Toolsの正本文書へどう反映するか。
通常Tools modeへ独立したList Toolを追加するかどうかは、directory Operationの公開とは別の適用事項であり、本稿で追加済みとは扱わない。