返回 Skill 列表
extension
分类: 开发与工程无需 API Key

File Protocol

此技能应在实现“基于文件的通信”、“通过文件进行代理通信”、“JSON状态管理”、“文件锁定”、“竞态条件处理”、“原子写入”,或构建通过共享文件协调的多代理系统时使用。为基于文件的代理间通信协议提供了全面的指导。

person作者: jakexiaohubgithub

File Protocol Skill

Overview

This skill provides guidance for implementing file-based communication protocols that enable multiple agents to coordinate through structured file reads and writes. This approach is particularly valuable for multi-agent systems where agents need to share state, signal events, and coordinate actions without direct API communication.

Core Concepts

File-Based Communication

File-based communication uses the filesystem as a message-passing and state-sharing medium:

Advantages:

  • Simple and transparent (can inspect files manually)
  • Language/process agnostic
  • Built-in persistence (files survive process crashes)
  • Easy debugging and logging
  • No network configuration required

Challenges:

  • Race conditions (simultaneous reads/writes)
  • File locking coordination
  • Atomicity concerns
  • Performance (disk I/O overhead)

Best for: Multi-agent coordination, game state management, asynchronous workflows

Communication Patterns

Signal Files: Trigger-based coordination

  • File presence or modification signals an event
  • Example: turn-signal.json triggers player agent spawn

State Files: Shared state management

  • Central authority writes, multiple readers consume
  • Example: game-state.json maintains authoritative state

Action Files: Request/response communication

  • Agents write action requests, coordinator processes and responds
  • Example: Player writes player-actions/player-1.json, gamemaster reads and validates

Log Files: Append-only history

  • Immutable record of events for debugging and analysis
  • Example: game-log.json records all moves

File Structure Design

Directory Organization

Organize files by purpose and access pattern:

games/<game-name>/
├── RULES.md                    # Static configuration (read-only)
├── state/                      # Active game state (read-write)
│   ├── game-state.json        # Authoritative state (GM writes, all read)
│   ├── turn-signal.json       # Turn notifications (GM writes, hooks read)
│   ├── player-actions/        # Player decisions (players write, GM reads)
│   │   ├── player-1.json
│   │   └── player-2.json
│   └── .locks/                # Lock files for coordination
│       └── game-state.lock
├── logs/                       # Completed games (append-only)
│   └── game-2024-01-27.json
└── traces/                     # Detailed debugging (append-only)
    └── game-2024-01-27.md

File Naming Conventions

Use consistent, descriptive names:

State files: Describe the content

  • game-state.json (not state.json)
  • turn-signal.json (not signal.json)
  • player-1-hand.json (not p1.json)

Action files: Include actor identifier

  • player-actions/player-1.json
  • player-actions/player-2.json

Lock files: Match the protected resource

  • .locks/game-state.lock
  • .locks/turn-signal.lock

Log files: Include timestamp

  • logs/game-2024-01-27-14-30-00.json
  • traces/game-2024-01-27-14-30-00.md

JSON Schema Design

Principles

Include metadata: Every file should have context

{
  "fileType": "game-state",
  "version": "1.0",
  "timestamp": "2024-01-27T14:30:00Z",
  "gameId": "uno-game-42",
  "data": { ... }
}

Use explicit types: Avoid ambiguous values

// Good
{"action": "play", "card": {"color": "Red", "value": "7"}}

// Bad
{"action": "p", "c": "R7"}

Include validation: Add fields for integrity checking

{
  "turnNumber": 42,
  "previousTurnHash": "abc123...",
  "playerId": "player-1",
  "action": { ... }
}

State File Schema

Authoritative game state maintained by gamemaster:

{
  "fileType": "game-state",
  "version": "1.0",
  "timestamp": "2024-01-27T14:30:00Z",
  "game": "UNO",
  "gameId": "uno-game-42",
  "turnNumber": 12,
  "gameActive": true,
  "players": [
    {
      "id": "player-1",
      "cardCount": 5,
      "score": 0,
      "isActive": true
    }
  ],
  "currentPlayer": "player-1",
  "direction": 1,
  "deck": {
    "remaining": 42,
    "shuffled": true
  },
  "discardPile": [
    {"color": "Red", "value": "7"}
  ]
}

Turn Signal Schema

Signals which player should act:

{
  "fileType": "turn-signal",
  "version": "1.0",
  "timestamp": "2024-01-27T14:30:05Z",
  "gameId": "uno-game-42",
  "turnNumber": 12,
  "currentPlayer": "player-1",
  "availableActions": ["play", "draw"],
  "visibleState": {
    "discardTop": {"color": "Red", "value": "7"},
    "opponentCardCounts": {
      "player-2": 3,
      "player-3": 6,
      "player-4": 4
    }
  }
}

Action File Schema

Player decision output:

{
  "fileType": "player-action",
  "version": "1.0",
  "timestamp": "2024-01-27T14:30:10Z",
  "gameId": "uno-game-42",
  "playerId": "player-1",
  "turnNumber": 12,
  "action": "play",
  "card": {
    "color": "Blue",
    "value": "7"
  },
  "reasoning": "Changing to Blue to keep Red 7 as option",
  "confidence": 0.85
}

See references/schema-reference.md for complete schema specifications and validation rules.

Atomic Operations

Read-Modify-Write Pattern

When updating state based on previous value:

  1. Acquire lock
while ! mkdir .locks/game-state.lock 2>/dev/null; do
  sleep 0.1
done
  1. Read current state
const state = JSON.parse(await Read("games/uno/state/game-state.json"));
  1. Modify state
state.turnNumber += 1;
state.currentPlayer = "player-2";
  1. Write atomically
// Write to temp file first
await Write("games/uno/state/game-state.json.tmp", JSON.stringify(state, null, 2));

// Atomic rename
await Bash("mv games/uno/state/game-state.json.tmp games/uno/state/game-state.json");
  1. Release lock
rmdir .locks/game-state.lock

Write-Only Pattern

When writing new file (no read needed):

  1. Generate unique filename
const filename = `player-actions/player-${playerId}-${Date.now()}.json`;
  1. Write directly (no lock needed for new files)
await Write(`games/uno/state/${filename}`, JSON.stringify(action, null, 2));

Race Condition Handling

Common Scenarios

Scenario 1: Simultaneous state updates

  • Problem: Two agents try to update game-state.json
  • Solution: Use lock files, only one agent writes at a time

Scenario 2: Reading stale data

  • Problem: Agent reads state before latest update completes
  • Solution: Include version numbers or timestamps, retry on conflict

Scenario 3: Lost updates

  • Problem: Second write overwrites first write
  • Solution: Atomic write pattern with lock acquisition

See references/race-conditions.md for detailed scenarios and solutions.

File Locking Strategies

Directory-Based Locks

Most reliable cross-platform approach:

# Acquire lock (mkdir is atomic)
while ! mkdir .locks/resource.lock 2>/dev/null; do
  sleep 0.1

  # Timeout after 10 seconds
  if [ $SECONDS -gt 10 ]; then
    echo "Lock timeout"
    exit 1
  fi
done

# Critical section
# ... perform locked operations ...

# Release lock
rmdir .locks/resource.lock

PID-Based Locks

Track lock owner for debugging:

# Acquire with PID
mkdir .locks/resource.lock
echo $$ > .locks/resource.lock/owner

# Critical section
# ...

# Release
rm .locks/resource.lock/owner
rmdir .locks/resource.lock

Stale Lock Detection

Handle crashes that leave locks:

# Check lock age
if [ -d .locks/resource.lock ]; then
  lock_age=$(($(date +%s) - $(stat -f%m .locks/resource.lock)))
  if [ $lock_age -gt 30 ]; then
    echo "Removing stale lock"
    rmdir .locks/resource.lock
  fi
fi

See references/locking-patterns.md for complete implementations.

Hook Integration

File-based communication integrates with hooks for event-driven coordination:

PostToolUse(Write) hook detects file changes:

{
  "PostToolUse": [{
    "matcher": "Write",
    "hooks": [{
      "type": "prompt",
      "prompt": "A file was written: {{tool_use.parameters.file_path}}. If this is a turn-signal or player-action file in games/*/state/, trigger appropriate agent response."
    }]
  }]
}

See hook-sync skill for detailed hook implementation.

Best Practices

File Design

DO:

  • Use descriptive, consistent naming
  • Include metadata in every file
  • Use JSON for structured data
  • Version your schemas
  • Add timestamps for debugging

DON'T:

  • Use cryptic abbreviations
  • Mix different data types in one file
  • Rely on file modification times only
  • Change schemas without versioning
  • Omit error context

Concurrency

DO:

  • Use locks for read-modify-write
  • Implement timeout for lock acquisition
  • Clean up stale locks
  • Write to temp files then rename
  • Handle lock contention gracefully

DON'T:

  • Skip locks for "fast" operations
  • Hold locks longer than necessary
  • Ignore lock acquisition failures
  • Write directly to final file
  • Assume operations are instant

Error Handling

DO:

  • Validate JSON schema on read
  • Check file existence before reading
  • Handle parse errors gracefully
  • Log all file operations
  • Provide clear error messages

DON'T:

  • Assume files always exist
  • Skip validation
  • Silently fail
  • Leave incomplete files
  • Ignore I/O errors

Debugging

File Inspection

Monitor file changes in real-time:

# Watch directory for changes
watch -n 0.5 'ls -lt games/uno/state/'

# Tail logs as they're written
tail -f games/uno/logs/game-latest.json

# View file with timestamps
stat -f "%Sm %N" -t "%Y-%m-%d %H:%M:%S" games/uno/state/*.json

Validation Tools

Validate JSON files:

# Check JSON syntax
jq empty games/uno/state/game-state.json

# Validate against schema
ajv validate -s schema.json -d games/uno/state/game-state.json

# Pretty-print for inspection
jq . games/uno/state/game-state.json

Common Issues

File not found: Check paths, ensure directory exists Parse error: Validate JSON syntax, check for partial writes Stale data: Verify atomic write pattern, check timestamps Lock contention: Review lock acquisition logic, add logging Race condition: Add locks, use atomic operations

Additional Resources

Reference Files

For detailed implementation guidance:

  • references/schema-reference.md - Complete JSON schemas and validation
  • references/race-conditions.md - Detailed race condition scenarios and solutions
  • references/locking-patterns.md - Advanced locking implementations

Example Files

Working examples in examples/:

  • file-operations.sh - Shell scripts for atomic operations
  • state-schemas.json - JSON schema definitions
  • validation-example.js - File validation implementation

Integration

This skill works together with:

  • game-coordination: Agents that read/write these files
  • hook-sync: Hooks that detect file changes and trigger agents

For complete multi-agent file-based coordination, use all three skills together.