412 lines
13 KiB
Markdown
412 lines
13 KiB
Markdown
# AI-Nyash Compact Notation Protocol (ANCP)
|
||
Status: Idea → Design Complete
|
||
Created: 2025-08-29
|
||
Updated: 2025-08-29 (Gemini & Codex分析統合、スモークテスト統合追加)
|
||
Priority: High
|
||
Category: AI Integration / Code Compression / Testing Infrastructure
|
||
|
||
## 概要
|
||
AIとNyashの効率的な通信のための圧縮記法プロトコル。予約語を1-2文字の記号に変換し、トークン数を大幅削減しながら、副次的にコード整形機能も提供する。さらに、既存のスモークテスト基盤との統合により、品質保証も自動化する。
|
||
|
||
## 動機
|
||
- AIのコンテキストウィンドウ制限への対応(50-90%削減目標)
|
||
- 人間が書いたコードをAIに効率的に渡す必要性
|
||
- Nyashパーサーとの100%同期による確実性
|
||
- 圧縮→展開プロセスでの自動コード整形
|
||
- 既存テスト基盤との統合による品質保証
|
||
|
||
## 設計詳細
|
||
|
||
### 基本的な変換例
|
||
```nyash
|
||
// 元のコード
|
||
box Cat from Animal {
|
||
init { name, age }
|
||
birth() {
|
||
me.name = "Tama"
|
||
}
|
||
}
|
||
|
||
// ANCP圧縮後
|
||
$Cat@Animal{#{name,age}b(){m.name="Tama"}}
|
||
|
||
// プロトコルヘッダー付き
|
||
;ancp:1.0 nyash:0.5;
|
||
$Cat@Animal{#{name,age}b(){m.name="Tama"}}
|
||
```
|
||
|
||
### 記号マッピング体系
|
||
```
|
||
【型・オブジェクト操作系】
|
||
box → $ # Box定義
|
||
new → n # インスタンス生成
|
||
me → m # 自己参照
|
||
|
||
【構造・スコープ系】
|
||
from → @ # 継承/デリゲーション
|
||
init → # # フィールド初期化
|
||
static → S # 静的定義
|
||
local → l # ローカル変数
|
||
|
||
【制御フロー系】
|
||
if → ? # 条件分岐
|
||
else → : # else節
|
||
loop → L # ループ
|
||
return → r # 戻り値
|
||
|
||
【メソッド系】
|
||
birth → b # コンストラクタ
|
||
override → O # オーバーライド
|
||
```
|
||
|
||
## 技術的実装設計(Rust)
|
||
|
||
### 1. Lexer拡張設計
|
||
```rust
|
||
// 双方向トランスコーダー
|
||
pub struct AncpTranscoder {
|
||
// 静的マップ(phf使用でO(1)ルックアップ)
|
||
nyash_to_ancp: phf::Map<&'static str, &'static str>,
|
||
ancp_to_nyash: phf::Map<&'static str, &'static str>,
|
||
|
||
// 位置情報マッピング(Source Map相当)
|
||
span_map: SpanMap,
|
||
|
||
// バージョン情報
|
||
version: AncpVersion,
|
||
}
|
||
|
||
// LosslessToken層(空白・コメント保持)
|
||
struct Token {
|
||
kind: TokenKind,
|
||
span: Span,
|
||
raw: RawLexemeId,
|
||
leading_trivia: Trivia,
|
||
trailing_trivia: Trivia,
|
||
}
|
||
|
||
// Dialect検出
|
||
enum Dialect {
|
||
Nyash,
|
||
ANCP(Version),
|
||
}
|
||
```
|
||
|
||
### 2. トークン効率最適化
|
||
```python
|
||
# tiktoken実測スクリプト
|
||
import tiktoken
|
||
enc = tiktoken.get_encoding("cl100k_base") # GPT-4等
|
||
|
||
def measure_tokens(code):
|
||
return len(enc.encode(code))
|
||
|
||
# 実測して最適な記号を選定
|
||
original = 'box Cat from Animal { init { name } }'
|
||
ancp = '$Cat@Animal{#{name}}'
|
||
|
||
reduction = 1 - (measure_tokens(ancp) / measure_tokens(original))
|
||
print(f"Token reduction: {reduction:.1%}")
|
||
```
|
||
|
||
### 3. 双方向変換保証テスト戦略
|
||
```rust
|
||
// プロパティベーステスト
|
||
#[test]
|
||
fn roundtrip_property(code in any_valid_nyash()) {
|
||
let transcoder = AncpTranscoder::new();
|
||
let (ancp, _) = transcoder.encode(&code)?;
|
||
let (restored, _) = transcoder.decode(&ancp)?;
|
||
assert_eq!(code, restored); // 完全一致
|
||
}
|
||
|
||
// AST同値性テスト
|
||
#[test]
|
||
fn ast_equivalence(code: &str) {
|
||
let ast_original = parse_nyash(code);
|
||
let ancp = transcode_to_ancp(code);
|
||
let ast_ancp = parse_ancp(ancp);
|
||
assert_ast_eq!(ast_original, ast_ancp);
|
||
}
|
||
|
||
// ファジングテスト
|
||
#[cfg(fuzzing)]
|
||
fuzz_target!(|data: &[u8]| {
|
||
if let Ok(s) = std::str::from_utf8(data) {
|
||
let _ = transcode_roundtrip(s);
|
||
}
|
||
});
|
||
```
|
||
|
||
### 4. デバッグ体験の維持
|
||
```rust
|
||
// ハイブリッドエラー表示
|
||
fn format_error(span: Span, ancp_src: &str, nyash_src: &str) {
|
||
let ancp_token = get_token_at(ancp_src, span);
|
||
let nyash_token = map_to_original(ancp_token);
|
||
eprintln!("Error at {} ({})", ancp_token, nyash_token);
|
||
// 例: "Error at @f (from)"
|
||
}
|
||
|
||
// IDE統合(LSP)
|
||
impl LanguageServer for NyashLsp {
|
||
fn hover(&self, position: Position) -> Hover {
|
||
// ANCP記号にホバーすると元の予約語を表示
|
||
let original = self.map_to_original(position);
|
||
Hover { contents: format!("ANCP: {} → Nyash: {}", ...) }
|
||
}
|
||
}
|
||
```
|
||
|
||
## スモークテストとの統合
|
||
|
||
### 統一検証フレームワーク
|
||
```nyash
|
||
// 検証用Box - スモークテストとANCP検証を統合
|
||
box TestValidatorBox {
|
||
init { patterns, mode, transcoder }
|
||
|
||
birth() {
|
||
me.patterns = new ArrayBox()
|
||
me.mode = "smoke" // smoke/full/ancp/roundtrip
|
||
me.transcoder = new AncpTranscoder()
|
||
}
|
||
|
||
// 共通のパターンチェック(既存スモークテストの仕組み)
|
||
checkPatterns(output) {
|
||
loop(me.patterns.hasNext()) {
|
||
local pattern
|
||
pattern = me.patterns.next()
|
||
|
||
if (not output.contains(pattern)) {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// Nyashコード実行して検証(既存)
|
||
validateScript(scriptPath) {
|
||
local output
|
||
output = me.runNyash(scriptPath)
|
||
return me.checkPatterns(output)
|
||
}
|
||
|
||
// ANCP変換して実行・検証(新規)
|
||
validateAncp(ancpPath) {
|
||
// 1. ANCP → Nyash変換
|
||
local nyashCode
|
||
nyashCode = me.transcoder.decode(ancpPath)
|
||
|
||
// 2. 実行(既存の実行パスを再利用)
|
||
local output
|
||
output = me.runNyashCode(nyashCode)
|
||
|
||
// 3. パターン検証(既存のcheckPatternsを再利用!)
|
||
return me.checkPatterns(output)
|
||
}
|
||
|
||
// 双方向テスト(ANCP特有)
|
||
validateRoundtrip(scriptPath) {
|
||
// 元の実行結果
|
||
local originalOutput
|
||
originalOutput = me.runNyash(scriptPath)
|
||
|
||
// Nyash → ANCP → Nyash → 実行
|
||
local ancp
|
||
ancp = me.transcoder.encode(scriptPath)
|
||
local restored
|
||
restored = me.transcoder.decode(ancp)
|
||
local roundtripOutput
|
||
roundtripOutput = me.runNyashCode(restored)
|
||
|
||
// 実行結果が同一か検証
|
||
return originalOutput == roundtripOutput
|
||
}
|
||
}
|
||
```
|
||
|
||
### 統合スモークテストスクリプト
|
||
```bash
|
||
#!/bin/bash
|
||
# 統一スモークテスト(Nyash & ANCP対応)
|
||
|
||
# 共通の検証関数
|
||
run_test() {
|
||
local mode=$1 # nyash/ancp/roundtrip
|
||
local file=$2 # ファイルパス
|
||
local pattern=$3 # 期待パターン
|
||
|
||
case "$mode" in
|
||
"ancp")
|
||
# ANCP → Nyash変換 → 実行
|
||
output=$(./target/release/nyash --from-ancp "$file" 2>&1)
|
||
;;
|
||
"roundtrip")
|
||
# Nyash → ANCP → Nyash → 実行
|
||
ancp=$(./target/release/nyash --to-ancp "$file")
|
||
output=$(echo "$ancp" | ./target/release/nyash --from-ancp - 2>&1)
|
||
;;
|
||
*)
|
||
# 通常のNyash実行
|
||
output=$(./target/release/nyash "$file" 2>&1)
|
||
;;
|
||
esac
|
||
|
||
# 共通のパターン検証(既存のスモークテストと同じ!)
|
||
echo "$output" | grep -q "$pattern"
|
||
}
|
||
|
||
# 自動テスト生成
|
||
generate_ancp_tests() {
|
||
for test in examples/*.nyash; do
|
||
# Nyashテストから自動的にANCPテストを生成
|
||
./tools/nyash2ancp "$test" > "${test%.nyash}.ancp"
|
||
|
||
# 同じ期待値パターンで両方をテスト
|
||
pattern=$(extract_expected_pattern "$test")
|
||
|
||
echo "Testing $test (Nyash)..."
|
||
run_test nyash "$test" "$pattern"
|
||
|
||
echo "Testing ${test%.nyash}.ancp (ANCP)..."
|
||
run_test ancp "${test%.nyash}.ancp" "$pattern"
|
||
|
||
echo "Testing roundtrip for $test..."
|
||
run_test roundtrip "$test" "$pattern"
|
||
done
|
||
}
|
||
```
|
||
|
||
### CI/CD統合
|
||
```yaml
|
||
# .github/workflows/smoke.yml への追加
|
||
jobs:
|
||
smoke-ancp:
|
||
runs-on: ubuntu-latest
|
||
needs: smoke # 通常のスモークテスト後に実行
|
||
env:
|
||
CARGO_TERM_COLOR: always
|
||
NYASH_DISABLE_PLUGINS: '1'
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Build with ANCP support
|
||
run: cargo build --release -j32 --features ancp
|
||
|
||
- name: Run ANCP roundtrip tests
|
||
run: |
|
||
# すべてのサンプルでANCP往復テスト
|
||
for f in examples/*.nyash; do
|
||
echo "Testing ANCP roundtrip: $f"
|
||
./tools/test_ancp_roundtrip.sh "$f"
|
||
done
|
||
|
||
- name: Run ANCP smoke tests
|
||
run: |
|
||
# 既存のスモークテストをANCPモードでも実行
|
||
ANCP_MODE=1 bash tools/smoke_phase_10_10.sh
|
||
|
||
- name: Measure token reduction
|
||
run: |
|
||
# 実際のトークン削減率を測定・報告
|
||
./tools/measure_ancp_efficiency.sh examples/*.nyash
|
||
```
|
||
|
||
### 共通化のメリット
|
||
|
||
1. **コード再利用**:
|
||
- 既存のパターン検証ロジックをそのまま活用
|
||
- `grep`ベースの柔軟な検証方法を継承
|
||
|
||
2. **テスト網羅性**:
|
||
- すべてのNyashテストが自動的にANCPテストにもなる
|
||
- 双方向変換の正確性を継続的に検証
|
||
|
||
3. **開発効率**:
|
||
- 新機能追加時、Nyashテストを書けばANCPテストも自動生成
|
||
- スモークテストの期待値パターンを共有
|
||
|
||
4. **品質保証**:
|
||
- ANCP変換によるセマンティクスの保持を自動検証
|
||
- AIが生成したANCPコードも同じ基準で検証可能
|
||
|
||
5. **将来の拡張性**:
|
||
- WebAssembly出力との統合も同じフレームワークで可能
|
||
- 他の中間表現(MIR等)も同様に統合可能
|
||
|
||
## 実装ロードマップ(更新版)
|
||
|
||
### Phase 1: 基礎実装(2週間)
|
||
- [ ] tiktoken実測による最適記号選定
|
||
- [ ] 固定辞書(20語)でTranscoder実装
|
||
- [ ] 基本的な往復テスト
|
||
- [ ] **既存スモークテストとの基本統合**
|
||
|
||
### Phase 2: パーサー統合(3週間)
|
||
- [ ] Lexer拡張(Dialect検出)
|
||
- [ ] TokenKind統一化
|
||
- [ ] SpanMapによるエラー位置マッピング
|
||
- [ ] **TestValidatorBox実装**
|
||
|
||
### Phase 3: 品質保証(2週間)
|
||
- [ ] プロパティベーステスト
|
||
- [ ] ファジングテスト
|
||
- [ ] ベンチマーク(性能測定)
|
||
- [ ] **自動ANCP テスト生成スクリプト**
|
||
|
||
### Phase 4: ツール統合(3週間)
|
||
- [ ] CLI: --view=ancp|nyash|hybrid
|
||
- [ ] VSCode拡張(ホバー変換)
|
||
- [ ] プロトコルヘッダー処理
|
||
- [ ] **CI/CDパイプライン統合**
|
||
|
||
### Phase 5: AI統合(4週間)
|
||
- [ ] 並列コーパス生成
|
||
- [ ] ファインチューニング実験
|
||
- [ ] 実運用評価
|
||
- [ ] **AIコード検証の自動化**
|
||
|
||
## リスクと対策
|
||
|
||
### 技術的リスク
|
||
1. **記号衝突**: 既存演算子との衝突 → 慎重な記号選定
|
||
2. **デバッグ困難**: 圧縮コードの可読性 → ハイブリッド表示
|
||
3. **バージョン互換**: 将来の拡張 → ヘッダーによるバージョニング
|
||
4. **テスト複雑性**: ANCP特有のバグ → スモークテスト統合で早期発見
|
||
|
||
### 運用リスク
|
||
1. **AIの誤解釈**: 記号の誤認識 → 明示的なヘッダー
|
||
2. **人間の混乱**: 2つの記法混在 → 明確な使い分け
|
||
3. **ツール対応**: エコシステム分断 → 段階的移行
|
||
4. **テスト負荷**: 2倍のテスト実行 → 並列実行とキャッシュ活用
|
||
|
||
## 成功指標(更新版)
|
||
- トークン削減率: 50%以上(目標70%)
|
||
- 往復変換成功率: 100%
|
||
- パース時間増加: 10%以内
|
||
- AIエラー率改善: 30%以上
|
||
- **スモークテスト合格率: 100%(Nyash/ANCP両方)**
|
||
- **CI実行時間増加: 20%以内**
|
||
|
||
## 関連技術・参考
|
||
- JavaScript Minification (Terser, UglifyJS)
|
||
- WebAssembly (.wat ⇔ .wasm)
|
||
- Protocol Buffers (スキーマベース圧縮)
|
||
- Source Maps (位置情報マッピング)
|
||
- **Nyashスモークテスト基盤**(パターン検証方式)
|
||
|
||
## 専門家レビュー
|
||
- Gemini: トークナイザ最適化、記号体系化の重要性を指摘
|
||
- Codex: Rust実装設計、テスト戦略の詳細を提供
|
||
- Claude: スモークテストとの統合可能性を発見
|
||
|
||
## 次のアクション
|
||
1. tiktoken実測実験の実施
|
||
2. 最小プロトタイプの作成
|
||
3. ChatGPTさんとの実装協議
|
||
4. **既存スモークテストへのANCPモード追加**
|
||
|
||
---
|
||
*このアイデアは2025-08-29にGeminiさん、Codexさんとの深い技術討論を経て、実装可能な設計として成熟し、さらにスモークテストとの統合により品質保証も含めた完全なソリューションとなりました。* |