Dynamic Persona MoE RAG - Building a Sovereign Synthetic Intelligence System

A comprehensive guide to building a local-first, privacy-focused AI system that transforms large corpuses into grounded, attributable, and conversationally explorable intelligence while maintaining complete data sovereignty.

AIMachine LearningLocal-FirstPrivacySovereigntySynthetic Intelligence

image

Dynamic Persona MoE RAG - Building a Sovereign Synthetic Intelligence System

Date: January 25, 2026
Author: Daniel Kliewer

Code

Introduction

In an era where artificial intelligence is increasingly centralized in the hands of a few tech giants, the need for sovereign, local-first AI systems has never been more critical. This blog post explores the implementation of a Dynamic Persona Mixture-of-Experts Retrieval-Augmented Generation (MoE RAG) system - a sophisticated architecture that transforms large, heterogeneous corpuses into grounded, attributable, and conversationally explorable intelligence while maintaining complete data sovereignty.

This system represents a paradigm shift from traditional "Artificial Intelligence" - which implies a hollow imitation of human cognition - toward Synthetic Intelligence: an engineered, deterministic, and human-constrained system designed for high-integrity knowledge synthesis.

The Problem with Current AI Systems

Before diving into the solution, let's examine the fundamental issues with current AI approaches:

1. Centralization and Surveillance

Most AI systems rely on cloud-based infrastructure, exposing sensitive data to third-party surveillance and creating single points of failure. For sectors like healthcare, legal, and defense, this is unacceptable.

2. Hallucination and Unaccountability

Current RAG systems are fundamentally limited by their reliance on opaque cloud infrastructure, static model weights, and probabilistic generation that prone to hallucination. When an AI "hallucinates," it's not a bug - it's an architectural failure.

3. Lack of Determinism

Traditional systems produce different outputs for identical inputs, making them unsuitable for high-integrity environments where reproducibility is paramount.

4. Static Personas

Most systems treat "personas" as static text prompts, failing to capture the dynamic, evolving nature of human expertise and perspective.

The Solution: Dynamic Persona MoE RAG

Our system addresses these challenges through a sophisticated architecture that separates Intelligence (the LLM) from Identity (the Persona Lens). This separation enables air-gapped security, deterministic reasoning, and the creation of evolving, autonomous personas that adapt to new information through explicit heuristic feedback loops.

System Architecture Overview

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Input Query   │───▶│ Entity Constructor│───▶│ Dynamic Graph   │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                │                        │
                                ▼                        ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Persona Store  │◀───│ MoE Orchestrator │◀───│ Graph Traversal │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                │                        │
                                ▼                        ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Ollama LLM     │◀───│ Evaluation &     │◀───│ Graph Snapshots │
│  (Local)        │    │ Scoring          │    │ & Persistence   │
└─────────────────┘    └──────────────────┘    └─────────────────┘

Core Components

1. Entity Constructor Agent

The Entity Constructor Agent serves as the system's eyes and ears, extracting meaningful entities and relationships from input text. This component implements both sophisticated NLP techniques (using spaCy when available) and robust fallback mechanisms using regex patterns.

class EntityConstructorAgent:
    def extract_entities(self, text: str) -> Dict[str, List[str]]:
        """Extract entities from input text."""
        entities = defaultdict(list)
        
        # Use spaCy if available
        if self.nlp:
            doc = self.nlp(text)
            for ent in doc.ents:
                entity_type = ent.label_.lower()
                entity_text = ent.text.strip()
                if entity_text and len(entity_text) > 1:
                    entities[entity_type].append(entity_text)
        
        # Fallback to regex-based extraction
        entities.update(self._extract_with_regex(text))
        return dict(entities)

The agent extracts various entity types including:

  • Named Entities: People, organizations, locations
  • Technical Entities: Dates, numbers, percentages
  • Communication Entities: Emails, URLs, phone numbers
  • Conceptual Entities: Key phrases and proper nouns

2. Dynamic Knowledge Graph

Unlike traditional vector stores that flatten semantic relationships, our Dynamic Knowledge Graph represents knowledge as explicit, traversable relationships between entities. Built using NetworkX, this graph is constructed on-demand for each query, ensuring relevance and preventing state pollution.

class DynamicKnowledgeGraph:
    def __init__(self):
        self.graph = nx.DiGraph()  # Use NetworkX for robust graph operations
        self.nodes = {}  # Cache for Node objects
        self.edges = []  # Cache for Edge objects
        self.query_context = None
        self._is_active = False

    def add_node(self, node_id: str, node_data: Dict[str, Any]) -> Node:
        """Lazily construct a node when needed."""
        if node_id in self.nodes:
            return self.nodes[node_id]
        
        # Create NetworkX node with metadata
        node_attributes = {
            'id': node_id,
            'data': node_data,
            'timestamp': self._get_timestamp(),
            'query_id': self.query_context['query_id']
        }
        self.graph.add_node(node_id, **node_attributes)
        
        # Create and cache Node object
        node = Node(node_id, node_data)
        self.nodes[node_id] = node
        return node

The graph supports sophisticated operations including:

  • Pathfinding: Shortest path algorithms for logical reasoning
  • Centrality Analysis: Identifying key entities in the knowledge network
  • Subgraph Extraction: Focusing on specific domains of knowledge
  • Relationship Traversal: Following semantic connections between concepts

3. Persona Store

The Persona Store manages the lifecycle of digital personas - the system's "experts" that provide diverse perspectives on queries. Personas are stored as validated JSON files with strict schemas ensuring consistency and reliability.

{
  "persona_id": "analytical_thinker",
  "name": "Analytical Thinker",
  "description": "A methodical and detail-oriented analyst who focuses on logical reasoning and evidence-based conclusions.",
  "traits": {
    "analytical_rigor": 0.9,
    "evidence_based": 0.8,
    "skepticism": 0.7,
    "objectivity": 0.8,
    "thoroughness": 0.9
  },
  "expertise": ["data_analysis", "research", "problem_solving", "critical_thinking"],
  "activation_cost": 0.3,
  "historical_performance": {
    "total_queries": 0,
    "average_score": 0.0,
    "last_used": null,
    "success_rate": 0.0
  },
  "metadata": {
    "created_at": "2026-01-25T10:00:00Z",
    "updated_at": "2026-01-25T10:00:00Z",
    "version": "1.0",
    "status": "active"
  }
}

Personas progress through a sophisticated lifecycle:

  1. Experimental: Newly created or modified personas being tested
  2. Active: Proven performers participating in inference
  3. Stable: Reliable performers, quick to activate
  4. Pruned: Underperforming personas, archived for potential recovery

4. MoE Orchestrator

The MoE Orchestrator serves as the system's conductor, coordinating the complex interplay between personas, graphs, and evaluation. It implements the core Mixture-of-Experts algorithm with three distinct phases:

Phase 1: Expansion

The orchestrator activates relevant personas and has them traverse the knowledge graph to generate diverse perspectives on the query.

def expansion_phase(self, query: str, entities: Dict[str, Any]) -> List[Dict[str, Any]]:
    """Expansion phase: Generate diverse outputs from active personas."""
    if not self.active_personas:
        return []

    # Create dynamic knowledge graph for this query
    self.graph = DynamicKnowledgeGraph()
    self.current_query_id = f"query_{int(time.time())}"
    self.graph.start_query(self.current_query_id, query)

    # Build graph from entities
    self._build_graph_from_entities(entities)

    # Generate outputs from each persona
    persona_outputs = []
    for persona in self.active_personas:
        try:
            output = self._generate_persona_output(persona, query, entities)
            persona_outputs.append({
                'persona_id': persona['persona_id'],
                'output': output,
                'timestamp': time.time()
            })
        except Exception as e:
            self.logger.error(f"Failed to generate output for persona {persona['persona_id']}: {e}")

    self.outputs = persona_outputs
    return persona_outputs
Phase 2: Evaluation

Each persona's output is rigorously evaluated using multiple criteria:

  • Relevance: How well the output addresses the query
  • Consistency: Alignment with reference outputs and established knowledge
  • Novelty: Contribution of new insights or perspectives
  • Grounding: Connection to provided entities and factual accuracy
Phase 3: Pruning

Based on performance metrics, the system automatically manages the persona population:

  • Promotion: High-performing experimental personas become active
  • Demotion: Underperforming active personas move to stable status
  • Pruning: Consistently poor performers are archived
  • Activation: Stable personas are reactivated when needed

5. Persona Traversal System

The Persona Traversal System implements different cognitive strategies that personas use to navigate the knowledge graph:

Analytical Traversal

Focuses on logical connections and evidence-based reasoning:

class AnalyticalTraversal(PersonaTraversalInterface):
    def evaluate_node_relevance(self, persona: Dict[str, Any], node: Node) -> float:
        analytical_rigor = persona.get('traits', {}).get('analytical_rigor', 0.5)
        evidence_weight = persona.get('traits', {}).get('evidence_based', 0.5)
        
        node_relevance = node.data.get('relevance_score', 0.5)
        weighted_relevance = (
            node_relevance * analytical_rigor * 0.6 +
            evidence_weight * 0.4
        )
        return min(max(weighted_relevance, 0.0), 1.0)
Creative Traversal

Emphasizes novel connections and lateral thinking:

class CreativeTraversal(PersonaTraversalInterface):
    def decide_traversal(self, current_node: Node, available_nodes: List[Node], 
                        persona: Dict[str, Any]) -> List[Node]:
        # Add randomness for creative exploration
        import random
        creative_boost = random.uniform(0, 0.3) * persona.get('traits', {}).get('creativity', 0.5)
        # Return more candidates for creative exploration
        return [node for node, score in node_scores[:5]]
Pragmatic Traversal

Prioritizes efficiency and practical outcomes:

class PragmaticTraversal(PersonaTraversalInterface):
    def evaluate_node_relevance(self, persona: Dict[str, Any], node: Node) -> float:
        practicality = persona.get('traits', {}).get('practicality', 0.5)
        efficiency = persona.get('traits', {}).get('efficiency', 0.5)
        
        utility_score = node.data.get('utility_score', 0.5)
        weighted_relevance = (
            utility_score * practicality * 0.7 +
            efficiency * 0.3
        )
        return min(max(weighted_relevance, 0.0), 1.0)

6. Evaluation and Scoring Framework

The Evaluation Framework implements sophisticated multi-criteria scoring that goes beyond simple similarity metrics:

Relevance Scoring

Uses TF-IDF cosine similarity with non-linear transformations to emphasize high similarity:

def score_relevance(self, output: str, query_id: str) -> float:
    documents = [query_text, output]
    tfidf_matrix = self.vectorizer.fit_transform(documents)
    similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
    
    # Apply non-linear transformation to emphasize high similarity
    relevance_score = math.tanh(similarity * 3.0)
    return max(0.0, min(1.0, relevance_score))
Consistency Scoring

Measures alignment with reference outputs while penalizing high variance:

def score_consistency(self, output: str, query_id: str, persona_id: str) -> float:
    # Calculate similarity with each reference
    similarities = []
    for ref_output in reference_outputs:
        documents = [output, ref_output]
        tfidf_matrix = self.vectorizer.fit_transform(documents)
        similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
        similarities.append(similarity)
    
    # Use median similarity to reduce outlier impact
    median_similarity = np.median(similarities)
    
    # Apply consistency penalty for high variance
    if len(similarities) > 1:
        variance_penalty = np.var(similarities) * 0.5
        consistency_score = max(0.0, median_similarity - variance_penalty)
    else:
        consistency_score = median_similarity
    
    return max(0.0, min(1.0, consistency_score))
Novelty Scoring

Rewards genuinely novel content while detecting creative elements:

def score_novelty(self, output: str, query_id: str, persona_id: str) -> float:
    # Calculate dissimilarity with existing outputs
    dissimilarities = []
    for existing_output in existing_outputs:
        documents = [output, existing_output]
        tfidf_matrix = self.vectorizer.fit_transform(documents)
        similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]
        dissimilarity = 1.0 - similarity
        dissimilarities.append(dissimilarity)
    
    # Use maximum dissimilarity to reward truly novel content
    novelty_score = max(dissimilarities)
    
    # Apply novelty bonus for creative elements
    novelty_bonus = self._calculate_creative_bonus(output)
    novelty_score = min(1.0, novelty_score + novelty_bonus * 0.2)
    
    return max(0.0, min(1.0, novelty_score))
Grounding Scoring

Ensures outputs are connected to provided entities and minimizes hallucinations:

def score_entity_grounding(self, output: str, query_id: str) -> float:
    entities = self._extract_entities_from_query(query_id)
    
    # Count entity mentions in output
    entity_mentions = 0
    for entity_type, entity_list in entities.items():
        for entity in entity_list:
            mentions = len(re.findall(r'\b' + re.escape(entity.lower()) + r'\b', output.lower()))
            if mentions > 0:
                entity_mentions += 1
    
    # Calculate grounding score
    entity_coverage = entity_mentions / len(entities)
    
    # Apply grounding penalty for hallucinations
    hallucination_penalty = self._detect_hallucinations(output, entities)
    grounding_score = max(0.0, entity_coverage - hallucination_penalty)
    
    return max(0.0, min(1.0, grounding_score))

7. Ollama Integration

The Ollama Interface provides local LLM inference with deterministic configuration, ensuring complete data sovereignty:

class OllamaInterface:
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.api_endpoint = config.get('api_endpoint', 'http://localhost:11434')
        self.model_name = config.get('model_name', 'llama3.2')
        self.temperature = config.get('temperature', 0.1)  # Low temperature for determinism
        self.seed = config.get('seed', 42)  # Fixed seed for reproducibility
        self.max_tokens = config.get('max_tokens', 2000)

    def generate_response(self, prompt: str, system_prompt: Optional[str] = None) -> str:
        # Build the request payload with deterministic parameters
        payload = {
            "model": self.model_name,
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": prompt}
            ],
            "options": {
                "temperature": self.temperature,
                "seed": self.seed,
                "num_predict": self.max_tokens
            },
            "stream": False
        }
        
        # Make the API call
        response = requests.post(f"{self.api_endpoint}/api/chat", json=payload)
        return response.json()['message']['content']

8. Graph Snapshots and Persistence

The Graph Snapshot Manager provides persistent storage and analysis of graph states, enabling system debugging, performance analysis, and knowledge preservation:

class GraphSnapshotManager:
    def save_snapshot(self, graph, query_id: str, scores: List[Dict[str, Any]], 
                     metadata: Optional[Dict[str, Any]] = None) -> bool:
        snapshot_data = {
            'query_id': query_id,
            'timestamp': datetime.utcnow().isoformat(),
            'graph_data': self._serialize_graph(graph),
            'scores': scores,
            'metadata': metadata or {},
            'graph_stats': self._get_graph_stats(graph)
        }
        
        # Save compressed snapshot
        with gzip.open(filepath, 'wt', encoding='utf-8') as f:
            json.dump(snapshot_data, f, indent=2, ensure_ascii=False)
        
        return True

Key Innovations and Advantages

1. Persona as Constraints, Not Prompts

Traditional systems treat personas as text prompts that are concatenated to the input. Our system implements personas as weighted constraint vectors that deterministically shape model behavior:

def _build_persona_prompt(self, persona: Dict[str, Any], query: str, context: str) -> str:
    traits = persona.get('traits', {})
    system_prompt = f"You are a {persona.get('name', 'specialist')} with the following traits: "
    trait_descriptions = []
    
    for trait_name, trait_value in traits.items():
        trait_descriptions.append(f"{trait_name} ({trait_value:.2f})")
    
    system_prompt += ", ".join(trait_descriptions) + ". "
    system_prompt += persona.get('description', 'You are an expert in your field.')
    
    user_prompt = f"Context: {context}\n\nQuery: {query}\n\nPlease provide a response based on the context and your expertise."
    
    return f"{system_prompt}\n\n{user_prompt}"

2. Query-Scoped Graphs

Unlike persistent knowledge graphs that accumulate noise and become unwieldy, our system builds query-scoped graphs that are constructed fresh for each query. This ensures:

  • Relevance: Only entities and relationships relevant to the current query are included
  • Performance: Graphs remain manageable in size
  • Accuracy: No state pollution from unrelated queries
  • Security: No persistent storage of sensitive relationships

3. Auditable Persona Evolution

Persona evolution follows bounded update functions with explicit audit trails:

def update_persona_performance(self, persona_id: str, score: float) -> bool:
    # Load current persona data
    persona_data = self.load_persona_from_file(persona_file)
    
    # Update performance metrics
    performance = persona_data['historical_performance']
    performance['total_queries'] += 1
    performance['last_used'] = datetime.utcnow().isoformat() + 'Z'
    
    # Calculate new average score
    old_avg = performance['average_score']
    total_queries = performance['total_queries']
    new_avg = ((old_avg * (total_queries - 1)) + score) / total_queries
    performance['average_score'] = new_avg
    
    # Update metadata timestamp
    persona_data['metadata']['updated_at'] = datetime.utcnow().isoformat() + 'Z'
    
    # Save updated persona
    return self.save_persona_to_file(persona_data, persona_file)

4. Multi-Strategy Cognitive Processing

The system implements different cognitive strategies that personas use to process information:

  • Analytical: Logical, evidence-based reasoning
  • Creative: Novel connections and lateral thinking
  • Pragmatic: Efficiency and practical outcomes

This multi-strategy approach ensures comprehensive analysis from multiple perspectives, similar to how human experts with different backgrounds would approach the same problem.

5. Hallucination Control

The system implements multiple layers of hallucination control:

  1. Structural Constraints: Explicit entity grounding requirements
  2. Provenance Tracking: Every output is traceable to specific graph nodes
  3. Multi-Criteria Evaluation: Grounding is explicitly scored
  4. Contextual Validation: Outputs are validated against provided context

Use Cases and Applications

1. Secure Intelligence Analysis

For sectors where data cannot leave the premise (legal, medical, defense), this system offers a "SCIF-in-a-box" solution:

# Secure analysis of sensitive documents
python3 scripts/run_pipeline.py --input classified_documents.txt --air-gapped-mode

2. Research and Development

Researchers can ingest terabytes of academic papers and use specialized personas to identify connections and generate hypotheses:

# Create domain-specific personas
python3 scripts/run_pipeline.py --input research_corpus.json --create-personas --domain "quantum_computing"

3. Business Intelligence

Companies can analyze market data, competitor information, and internal reports without exposing sensitive information to external services:

# Business analysis with multiple expert personas
python3 scripts/run_pipeline.py --input market_analysis.json --multi-expert-mode

4. Personal Knowledge Management

Individuals can create digital twins that evolve with their thinking and provide personalized insights:

# Create a personalized digital assistant
python3 scripts/run_pipeline.py --input personal_notes.json --create-digital-twin

Performance and Scalability

The system is designed for local-first performance while maintaining scalability:

Memory Management

  • Query-scoped graphs prevent memory accumulation
  • Compressed snapshots minimize storage requirements
  • Efficient persona storage using JSON with validation

Processing Efficiency

  • Parallel persona processing during expansion phase
  • Optimized graph algorithms using NetworkX
  • Caching strategies for frequently accessed data

Scalability Considerations

  • Modular architecture allows component scaling
  • Configuration-driven thresholds enable performance tuning
  • Monitoring and logging for performance analysis

Security and Privacy

Air-Gapped Operation

The system operates entirely offline, with no external network dependencies:

# System configuration
air_gapped_mode: true
enable_caching: true
deterministic_mode: true

Data Sovereignty

All data processing occurs on local hardware, ensuring complete control over sensitive information.

Auditability

Every system operation is logged and traceable, enabling compliance with regulatory requirements.

Future Enhancements

1. Multi-Modal Personas

Support for different input/output modalities (text, audio, image, video) to handle diverse data types.

2. Federated Learning

Distributed persona training across multiple systems while maintaining privacy.

3. Hierarchical Graphs

Multi-level graph representations for complex domain knowledge.

4. Real-Time Adaptation

Continuous learning during inference cycles for dynamic environments.

5. Advanced Evaluation Metrics

Integration with external knowledge bases for enhanced validation.

Conclusion

The Dynamic Persona MoE RAG system represents a significant advancement in local-first, sovereign AI systems. By separating intelligence from identity and implementing sophisticated persona-based reasoning, the system provides a robust alternative to centralized AI services.

Key achievements include:

  • Complete data sovereignty through air-gapped operation
  • Deterministic outputs ensuring reproducibility and trust
  • Sophisticated persona management enabling diverse perspectives
  • Robust hallucination control maintaining factual accuracy
  • Comprehensive evaluation frameworks ensuring quality and reliability

This system demonstrates that it's possible to build powerful, intelligent systems without sacrificing privacy, security, or control. As the demand for sovereign AI solutions grows, architectures like this will become increasingly important for organizations and individuals who cannot afford to compromise on data sovereignty.

The codebase is available and ready for use, testing, and contribution. Whether you're working in healthcare, legal, defense, research, or simply value your digital sovereignty, this system provides a foundation for building intelligent applications that respect your privacy and maintain your control over sensitive information.