Overview

The BORT learning system provides two main approaches:

  1. Simple Agents (JSON Light Experience): Traditional static agents with predefined behavior

  2. Learning Agents (Merkle Tree Learning): Advanced agents that can learn and evolve through interactions

Learning Architecture

Dual-Path System

The learning system is designed with a dual-path architecture to accommodate different use cases:

Path 1: Simple Agents

  • Use Case: Basic automation, static NFTs, simple interactions

  • Benefits: Low gas costs, familiar development patterns, immediate deployment

  • Architecture: Traditional JSON metadata with persona, experience, and voice

  • Target Audience: Developers seeking quick deployment and minimal complexity

Path 2: Learning Agents

  • Use Case: Adaptive AI assistants, evolving game characters, intelligent automation

  • Benefits: Verifiable learning progression, higher market value, sophisticated behavior

  • Architecture: Enhanced metadata with Merkle tree roots and learning modules

  • Target Audience: Developers building advanced AI applications

Learning Module System

The learning system uses a modular approach with pluggable learning modules:

interface ILearningModule {
    struct LearningMetrics {
        uint256 totalInteractions;    // Total user interactions
        uint256 learningEvents;       // Significant learning updates
        uint256 lastUpdateTimestamp;  // Last learning update time
        uint256 learningVelocity;     // Learning rate (scaled by 1e18)
        uint256 confidenceScore;      // Overall confidence (scaled by 1e18)
    }

    struct LearningUpdate {
        bytes32 previousRoot;         // Previous Merkle root
        bytes32 newRoot;              // New Merkle root
        bytes32[] proof;              // Merkle proof for update
        bytes metadata;               // Encoded learning data
    }

    function updateLearning(uint256 tokenId, LearningUpdate calldata update) external;
    function verifyLearning(uint256 tokenId, bytes32 claim, bytes32[] calldata proof) external view returns (bool);
    function getLearningMetrics(uint256 tokenId) external view returns (LearningMetrics memory);
    function recordInteraction(uint256 tokenId, bytes calldata interactionData) external;
    function isLearningEnabled(uint256 tokenId) external view returns (bool);
}

Merkle Tree Learning Implementation

Core Concept

The Merkle Tree Learning system stores learning data off-chain while maintaining cryptographic verification on-chain through Merkle roots. This approach provides:

  • Efficiency: Only 32-byte Merkle roots stored on-chain

  • Verifiability: All learning claims are cryptographically verifiable

  • Tamper-Proof: Learning history cannot be falsified

  • Scalability: Off-chain storage scales with learning data

Learning Tree Structure

Example learning tree JSON structure:

{
  "root": "0x...", // Merkle root (32 bytes, stored on-chain)
  "version": 15,
  "agent_id": 123,
  "last_updated": "2025-01-20T10:00:00Z",
  "branches": {
    "user_preferences": {
      "communication_style": "professional",
      "preferred_frameworks": ["React", "Vue"],
      "working_hours": "9am-5pm EST",
      "confidence": 0.92
    },
    "domain_knowledge": {
      "blockchain": {
        "ethereum": 0.95,
        "binance_smart_chain": 0.88,
        "polygon": 0.75
      },
      "programming": {
        "javascript": 0.98,
        "solidity": 0.85,
        "python": 0.70
      }
    },
    "interaction_patterns": {
      "total_sessions": 247,
      "avg_session_length": "18min",
      "successful_tasks": 89,
      "learning_velocity": 0.15,
      "adaptation_rate": 0.12
    },
    "behavioral_evolution": {
      "personality_drift": {
        "formality_level": 0.8,
        "helpfulness_score": 0.95,
        "proactivity": 0.7
      },
      "skill_development": {
        "problem_solving": 0.88,
        "communication": 0.92,
        "technical_accuracy": 0.85
      }
    }
  },
  "metadata": {
    "total_nodes": 156,
    "tree_depth": 4,
    "compression_ratio": 0.65,
    "verification_complexity": "O(log n)"
  }
}

Learning Metrics

The system tracks comprehensive learning metrics:

  • Total Interactions: Number of user interactions

  • Learning Events: Significant learning updates

  • Learning Velocity: Rate of learning (events per day)

  • Confidence Score: Overall agent confidence (0-1)

  • Milestones: Achievement markers (100 interactions, 80% confidence, etc.)

Security Features

  • Rate Limiting: Maximum 50 learning updates per day per agent

  • Access Control: Only agent owners can update learning

  • Cryptographic Verification: All learning claims require Merkle proofs

  • Tamper-Proof History: Learning history cannot be falsified

Implementation Guide

Creating a Learning Agent

Use the stepper below to follow the multi-step process for creating a learning agent.

1

Deploy Learning Module

const MerkleTreeLearning = await ethers.getContractFactory("MerkleTreeLearning");
const merkleLearning = await MerkleTreeLearning.deploy();
await merkleLearning.deployed();

console.log("Learning module deployed at:", merkleLearning.address);
2

Create Initial Learning Tree

function createLearningTree(initialData) {
  const tree = {
    branches: {
      user_preferences: {
        communication_style: "professional",
        preferred_frameworks: ["React", "Vue"],
        confidence: 0.1
      },
      domain_knowledge: {
        blockchain: { ethereum: 0.5, bsc: 0.3 },
        programming: { javascript: 0.7, solidity: 0.4 }
      },
      interaction_patterns: {
        total_sessions: 0,
        successful_tasks: 0,
        learning_velocity: 0
      }
    },
    metadata: {
      version: 1,
      created: new Date().toISOString(),
      agent_id: null // Will be set when agent is created
    }
  };
  
  return tree;
}

// Create initial learning tree
const initialLearningData = {
  preferences: { communication: "friendly", detail: "comprehensive" },
  patterns: ["helpful", "accurate"],
  confidence: 0.1
};

const learningTree = createLearningTree(initialLearningData);
const initialRoot = ethers.utils.keccak256(
  ethers.utils.toUtf8Bytes(JSON.stringify(learningTree.branches))
);
3

Create Enhanced Metadata

const enhancedMetadata = {
  persona: JSON.stringify({
    traits: ["adaptive", "intelligent", "learning"],
    style: "evolving",
    tone: "personalized"
  }),
  experience: "AI assistant with learning capabilities",
  voiceHash: "bafkreigh2akiscaildc...",
  animationURI: "ipfs://Qm.../learning_agent.mp4",
  vaultURI: "ipfs://Qm.../learning_vault.json",
  vaultHash: ethers.utils.keccak256(ethers.utils.toUtf8Bytes("vault_content")),
  learningEnabled: true,
  learningModule: merkleLearning.address,
  learningTreeRoot: initialRoot,
  learningVersion: 1,
  lastLearningUpdate: 0
};
4

Create the Learning Agent

const tx = await agentFactory.createAgent(
  "My Learning Agent",
  "MLA",
  logicAddress,
  "ipfs://metadata-uri",
  enhancedMetadata,
  { value: ethers.utils.parseEther("0.01") }
);

const receipt = await tx.wait();
const agentCreatedEvent = receipt.events.find(e => e.event === "AgentCreated");
const agentAddress = agentCreatedEvent.args.agent;

console.log(`🧠 Learning agent created at: ${agentAddress}`);

Recording Learning Interactions

Basic Interaction Recording

async function recordInteraction(tokenId, interactionType, success) {
  const merkleLearning = await ethers.getContractAt(
    "MerkleTreeLearning", 
    "0x81116065841ebBb65b15D0eb8EAB87f0eccc7e78"
  );

  await merkleLearning.recordInteraction(tokenId, interactionType, success);
  
  console.log(`📊 Interaction recorded: ${interactionType} - ${success ? 'Success' : 'Failure'}`);
}

// Record successful interaction
await recordInteraction(tokenId, "code_generation", true);

// Record failed interaction
await recordInteraction(tokenId, "bug_fixing", false);

Advanced Learning Updates

async function updateLearningTree(tokenId, newLearningData) {
  const merkleLearning = await ethers.getContractAt(
    "MerkleTreeLearning", 
    "0x81116065841ebBb65b15D0eb8EAB87f0eccc7e78"
  );

  // Get current learning state
  const currentMetrics = await merkleLearning.getLearningMetrics(tokenId);
  const currentRoot = await merkleLearning.getLearningTreeRoot(tokenId);

  // Create new learning tree with updated data
  const newTree = createUpdatedLearningTree(newLearningData);
  const newRoot = ethers.utils.keccak256(
    ethers.utils.toUtf8Bytes(JSON.stringify(newTree.branches))
  );

  // Generate Merkle proof (simplified - in practice, use a proper Merkle tree library)
  const proof = generateMerkleProof(currentRoot, newRoot);

  // Create learning update
  const learningUpdate = {
    previousRoot: currentRoot,
    newRoot: newRoot,
    proof: proof,
    metadata: ethers.utils.toUtf8Bytes(JSON.stringify(newTree))
  };

  // Update learning
  await merkleLearning.updateLearning(tokenId, learningUpdate);
  
  console.log(`🧠 Learning tree updated for agent ${tokenId}`);
}

Checking Learning Progress

async function checkLearningProgress(tokenId) {
  const merkleLearning = await ethers.getContractAt(
    "MerkleTreeLearning", 
    "0x81116065841ebBb65b15D0eb8EAB87fcc0eccc7e78"
  );

  const metrics = await merkleLearning.getLearningMetrics(tokenId);
  
  console.log("📊 Learning Metrics:");
  console.log(`Total Interactions: ${metrics.totalInteractions}`);
  console.log(`Learning Events: ${metrics.learningEvents}`);
  console.log(`Learning Velocity: ${ethers.utils.formatUnits(metrics.learningVelocity, 18)}`);
  console.log(`Confidence Score: ${ethers.utils.formatUnits(metrics.confidenceScore, 18)}`);
  console.log(`Last Update: ${new Date(metrics.lastUpdateTimestamp * 1000).toISOString()}`);
}

Learning Module Types

1. Merkle Tree Learning (Default)

Standard learning module using Merkle trees:

contract MerkleTreeLearning is ILearningModule {
    struct AgentLearning {
        bytes32 treeRoot;
        uint256 version;
        uint256 totalInteractions;
        uint256 learningEvents;
        uint256 lastUpdateTimestamp;
        uint256 learningVelocity;
        uint256 confidenceScore;
        mapping(bytes32 => bool) verifiedClaims;
    }
    
    mapping(uint256 => AgentLearning) public agentLearning;
    
    function updateLearning(uint256 tokenId, LearningUpdate calldata update) external override {
        require(_canUpdateLearning(tokenId), "Rate limit exceeded");
        require(_verifyLearningProof(tokenId, update), "Invalid learning proof");
        
        AgentLearning storage learning = agentLearning[tokenId];
        learning.treeRoot = update.newRoot;
        learning.version++;
        learning.learningEvents++;
        learning.lastUpdateTimestamp = block.timestamp;
        
        _updateLearningMetrics(tokenId);
        _checkMilestones(tokenId);
        
        emit LearningTreeUpdated(tokenId, update.newRoot, learning.version);
    }
}

2. Federated Learning Module

Advanced learning module supporting cross-agent knowledge sharing:

contract FederatedLearning is ILearningModule {
    struct FederatedAgent {
        bytes32 localModelRoot;
        bytes32 sharedKnowledgeRoot;
        uint256 contributionScore;
        uint256 collaborationCount;
        mapping(uint256 => bytes32) peerConnections;
        mapping(bytes32 => uint256) knowledgeContributions;
    }
    
    mapping(uint256 => FederatedAgent) public federatedAgents;
    
    function shareKnowledge(
        uint256 sourceTokenId,
        uint256 targetTokenId,
        bytes32 knowledgeHash,
        bytes calldata encryptedKnowledge
    ) external {
        require(_canShareKnowledge(sourceTokenId, targetTokenId), "Sharing not authorized");
        
        FederatedAgent storage source = federatedAgents[sourceTokenId];
        FederatedAgent storage target = federatedAgents[targetTokenId];
        
        source.knowledgeContributions[knowledgeHash]++;
        source.contributionScore++;
        target.collaborationCount++;
        
        emit KnowledgeShared(sourceTokenId, targetTokenId, knowledgeHash);
    }
}

3. Specialized Learning Modules

Domain-specific learning modules for different use cases:

DeFi Learning Module

contract DeFiLearningModule is ILearningModule {
    struct TradingExperience {
        mapping(address => uint256) tokenPerformance;
        mapping(bytes32 => uint256) strategySuccess;
        uint256 totalTrades;
        uint256 successfulTrades;
        uint256 learningConfidence;
        bytes32 adaptiveStrategyRoot;
    }
    
    mapping(uint256 => TradingExperience) public tradingExperience;
    
    function updateTradingStrategy(
        uint256 tokenId,
        bytes32 strategyHash,
        bytes calldata strategyData
    ) external {
        TradingExperience storage experience = tradingExperience[tokenId];
        experience.strategySuccess[strategyHash]++;
        experience.totalTrades++;
        
        // Update learning metrics based on trading performance
        _updateTradingMetrics(tokenId);
    }
}

Gaming Learning Module

contract GamingLearningModule is ILearningModule {
    struct GameExperience {
        mapping(bytes32 => uint256) skillLevels;
        mapping(address => uint256) playerInteractions;
        uint256 experiencePoints;
        uint256 adaptationLevel;
        bytes32 personalityEvolution;
        bytes32 behaviorLearningRoot;
    }
    
    mapping(uint256 => GameExperience) public gameExperience;
    
    function levelUpSkill(uint256 tokenId, bytes32 skillId) external {
        GameExperience storage experience = gameExperience[tokenId];
        experience.skillLevels[skillId]++;
        experience.experiencePoints += 100;
        
        // Trigger learning update
        _updateGameLearningMetrics(tokenId);
    }
}

Migration and Upgrades

Simple to Learning Agent Migration

async function migrateToLearning(tokenId, learningModule) {
  const bap578 = await ethers.getContractAt("BAP578", agentAddress);
  
  // Create initial learning tree
  const initialLearningData = { tokenId };
  const learningTree = createLearningTree(initialLearningData);
  const initialRoot = ethers.utils.keccak256(
    ethers.utils.toUtf8Bytes(JSON.stringify(learningTree.branches))
  );

  // Enable learning on existing agent
  await bap578.enableLearning(tokenId, learningModule, initialRoot);
  
  console.log(`🔄 Learning enabled for agent ${tokenId}`);
}

Learning Module Upgrades

async function upgradeLearningModule(tokenId, newLearningModule) {
  const bap578 = await ethers.getContractAt("BAP578", agentAddress);
  
  // Get current learning state
  const currentRoot = await merkleLearning.getLearningTreeRoot(tokenId);
  
  // Prepare migration data
  const migrationData = await prepareMigrationData(tokenId, currentRoot);
  
  // Upgrade to new learning module
  await bap578.upgradeLearningModule(tokenId, newLearningModule, migrationData);
  
  console.log(`🔄 Learning module upgraded for agent ${tokenId}`);
}

Best Practices

Learning Data Management

  • Structured Data: Use consistent data structures for learning trees

  • Version Control: Track learning tree versions for rollback capability

  • Compression: Compress learning data to reduce storage costs

  • Backup: Regularly backup learning trees off-chain

Security Considerations

  • Access Control: Implement proper access controls for learning updates

  • Rate Limiting: Use rate limiting to prevent spam

  • Verification: Always verify Merkle proofs before accepting updates

  • Emergency Controls: Implement emergency pause mechanisms

Performance Optimization

  • Batch Updates: Batch multiple learning updates together

  • Lazy Verification: Only verify learning claims when needed

  • Efficient Storage: Use appropriate data types and structures

  • Gas Optimization: Optimize gas usage for frequent operations

User Experience

  • Progress Tracking: Provide clear learning progress indicators

  • Milestone Rewards: Implement milestone-based rewards

  • Transparency: Make learning metrics visible to users

  • Control: Give users control over their agent's learning

Troubleshooting

Common Issues

"Rate limit exceeded" error
  • Check daily update limits (max 50 per day)

  • Implement proper rate limiting in your application

"Invalid learning proof" error
  • Verify Merkle proof generation

  • Ensure proof matches the current learning tree root

"Learning not enabled" error
  • Check if learning is enabled for the agent

  • Verify learning module address is correct

Debugging Tools

// Check learning status
async function debugLearningStatus(tokenId) {
  const merkleLearning = await ethers.getContractAt(
    "MerkleTreeLearning", 
    "0x8d1116065841ebBb65b15D0eb8EAB87f0eccc7e78"
  );

  const isEnabled = await merkleLearning.isLearningEnabled(tokenId);
  const metrics = await merkleLearning.getLearningMetrics(tokenId);
  const root = await merkleLearning.getLearningTreeRoot(tokenId);

  console.log("Learning Status:", {
    enabled: isEnabled,
    metrics: {
      totalInteractions: metrics.totalInteractions.toString(),
      learningEvents: metrics.learningEvents.toString(),
      confidenceScore: ethers.utils.formatUnits(metrics.confidenceScore, 18)
    },
    currentRoot: root
  });
}

Last updated