xbe.at

LLMs and generative AI / Agents and LangChain

Building an Agentic Mesh for Autonomous Agents

13 min read, 15 sections

Contents
  1. Agent Directory Implementation with ChromaDB
  2. Agent Discovery Protocol
  3. Collaborative Planning Engine
  4. Secure Transaction Framework
  5. Multi-Agent Communication Protocol
  6. Agent Knowledge Base Implementation
  7. Task Orchestration System
  8. Consensus Mechanism Implementation
  9. Agent Learning Module
  10. Mesh Synchronization Protocol
  11. Capability Discovery and Matching
  12. Task Decomposition Engine
  13. Resource Allocation System
  14. Performance Monitoring System
  15. Additional Resources

Agent Directory Implementation with ChromaDB

The Agent Directory serves as a foundational component for the Agentic Mesh, enabling efficient storage and retrieval of agent metadata. ChromaDB provides persistent vector storage with efficient similarity search capabilities for agent discovery.

import chromadb
from chromadb.config import Settings
import uuid

class AgentDirectory:
    def __init__(self):
        # Initialize ChromaDB client with persistence
        self.client = chromadb.Client(Settings(
            chroma_db_impl="duckdb+parquet",
            persist_directory="agent_directory"
        ))
        # Create collection for agents
        self.collection = self.client.create_collection("agents")
        
    def register_agent(self, capabilities, metadata):
        agent_id = str(uuid.uuid4())
        # Store agent data with vector embedding
        self.collection.add(
            documents=[str(capabilities)],
            metadatas=[metadata],
            ids=[agent_id]
        )
        return agent_id
    
    def find_agents(self, query, n_results=5):
        # Query similar agents based on capabilities
        results = self.collection.query(
            query_texts=[query],
            n_results=n_results
        )
        return results

# Example usage
directory = AgentDirectory()
agent_id = directory.register_agent(
    capabilities=["natural language processing", "data analysis"],
    metadata={"name": "AnalyticsAgent", "version": "1.0"}
)

Agent Discovery Protocol

This implementation defines the core protocol for agent discovery within the mesh, using semantic similarity matching to identify relevant collaborators based on capability requirements and constraints.

from dataclasses import dataclass
from typing import List, Dict
import numpy as np

@dataclass
class AgentProfile:
    id: str
    capabilities: List[str]
    metadata: Dict
    
class DiscoveryProtocol:
    def __init__(self, directory):
        self.directory = directory
        self.capability_weights = {
            "primary": 1.0,
            "secondary": 0.5
        }
    
    def find_collaborators(self, requirements, constraints=None):
        # Weighted query based on requirement priority
        weighted_query = self._build_weighted_query(requirements)
        candidates = self.directory.find_agents(weighted_query)
        
        if constraints:
            candidates = self._apply_constraints(candidates, constraints)
            
        return self._rank_candidates(candidates)
    
    def _build_weighted_query(self, requirements):
        query = ""
        for cap, priority in requirements.items():
            weight = self.capability_weights.get(priority, 0.3)
            query += f"{cap} * {weight} + "
        return query.rstrip(" + ")

# Example usage
protocol = DiscoveryProtocol(directory)
collaborators = protocol.find_collaborators({
    "data analysis": "primary",
    "visualization": "secondary"
})

Collaborative Planning Engine

The planning engine coordinates multi-agent collaboration through a structured workflow that includes task decomposition, capability matching, and consensus-building mechanisms for distributed decision-making.

from typing import Optional
import asyncio

class CollaborativePlanner:
    def __init__(self, discovery_protocol):
        self.discovery = discovery_protocol
        self.task_queue = asyncio.Queue()
        
    async def create_execution_plan(self, task_description):
        # Decompose task into subtasks
        subtasks = self._decompose_task(task_description)
        
        execution_plan = []
        for subtask in subtasks:
            # Find capable agents
            agents = self.discovery.find_collaborators(subtask.requirements)
            
            # Allocate subtask to best-fit agent
            allocation = await self._allocate_subtask(subtask, agents)
            execution_plan.append(allocation)
            
        return self._optimize_plan(execution_plan)
    
    def _decompose_task(self, task):
        # Task decomposition logic
        subtasks = []
        # Implementation details
        return subtasks
    
    async def _allocate_subtask(self, subtask, agents):
        # Allocation logic with consensus
        return {"subtask": subtask, "agent": agents[0]}

Secure Transaction Framework

A robust transaction system ensures secure and verifiable exchanges between agents, implementing atomic operations and rollback mechanisms to maintain system consistency during multi-agent interactions.

import hashlib
from datetime import datetime
from typing import Any

class SecureTransaction:
    def __init__(self):
        self.ledger = {}
        self.pending = {}
        
    def initiate_transaction(self, 
                           sender_id: str, 
                           receiver_id: str, 
                           payload: Any) -> str:
        # Create transaction record
        transaction_id = self._generate_transaction_id(sender_id, receiver_id)
        
        # Hash payload for verification
        payload_hash = hashlib.sha256(str(payload).encode()).hexdigest()
        
        self.pending[transaction_id] = {
            'sender': sender_id,
            'receiver': receiver_id,
            'payload_hash': payload_hash,
            'status': 'pending',
            'timestamp': datetime.utcnow()
        }
        
        return transaction_id
    
    def commit_transaction(self, transaction_id: str, verification_hash: str):
        if transaction_id not in self.pending:
            raise ValueError("Invalid transaction ID")
            
        transaction = self.pending[transaction_id]
        if verification_hash == transaction['payload_hash']:
            self.ledger[transaction_id] = {
                **transaction,
                'status': 'completed'
            }
            del self.pending[transaction_id]
            return True
        return False

Multi-Agent Communication Protocol

This implementation establishes a robust communication framework allowing agents to exchange messages, share context, and coordinate activities through an asynchronous event-driven architecture.

import asyncio
from enum import Enum
from dataclasses import dataclass
from typing import Dict, Any, Callable

class MessageType(Enum):
    QUERY = "query"
    RESPONSE = "response"
    TASK = "task"
    STATUS = "status"

@dataclass
class Message:
    sender: str
    recipient: str
    msg_type: MessageType
    content: Dict[str, Any]
    correlation_id: str

class CommunicationBus:
    def __init__(self):
        self.subscribers: Dict[str, Callable] = {}
        self.message_queue = asyncio.Queue()
        
    async def publish(self, message: Message):
        await self.message_queue.put(message)
        if message.recipient in self.subscribers:
            await self.subscribers[message.recipient](message)
    
    def subscribe(self, agent_id: str, callback: Callable):
        self.subscribers[agent_id] = callback
        
    async def start(self):
        while True:
            message = await self.message_queue.get()
            # Message processing logic
            self.message_queue.task_done()

# Example usage
async def agent_callback(message):
    print(f"Agent received: {message.content}")

comm_bus = CommunicationBus()
comm_bus.subscribe("agent1", agent_callback)

Agent Knowledge Base Implementation

The knowledge base component provides a persistent storage mechanism for agent experiences, learned patterns, and shared knowledge, utilizing vector embeddings for efficient information retrieval and knowledge sharing.

import numpy as np
from typing import List, Dict, Optional
import pickle

class KnowledgeBase:
    def __init__(self, embedding_dim: int = 768):
        self.embedding_dim = embedding_dim
        self.knowledge_vectors = {}
        self.knowledge_metadata = {}
        
    def store_knowledge(self, 
                       key: str, 
                       content: Dict,
                       embedding: np.ndarray,
                       metadata: Optional[Dict] = None):
        if embedding.shape[0] != self.embedding_dim:
            raise ValueError(f"Expected embedding dim {self.embedding_dim}")
            
        self.knowledge_vectors[key] = embedding
        self.knowledge_metadata[key] = {
            'content': content,
            'metadata': metadata or {},
            'access_count': 0
        }
        
    def query_knowledge(self, 
                       query_embedding: np.ndarray, 
                       top_k: int = 5) -> List[Dict]:
        similarities = {}
        for key, vector in self.knowledge_vectors.items():
            sim = self._cosine_similarity(query_embedding, vector)
            similarities[key] = sim
            
        # Get top-k similar entries
        sorted_keys = sorted(similarities.items(), 
                           key=lambda x: x[1], 
                           reverse=True)[:top_k]
        
        results = []
        for key, sim in sorted_keys:
            self.knowledge_metadata[key]['access_count'] += 1
            results.append({
                'key': key,
                'content': self.knowledge_metadata[key]['content'],
                'similarity': sim
            })
        
        return results
    
    def _cosine_similarity(self, a: np.ndarray, b: np.ndarray) -> float:
        return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

Task Orchestration System

A sophisticated orchestration system that manages complex workflows across multiple agents, handling task dependencies, parallel execution, and failure recovery mechanisms.

from enum import Enum
from typing import List, Dict, Optional
import asyncio
from datetime import datetime

class TaskStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"

class TaskOrchestrator:
    def __init__(self):
        self.task_graph = {}
        self.task_status = {}
        self.execution_history = []
        
    async def schedule_task(self, 
                           task_id: str, 
                           dependencies: List[str],
                           executor_agent: str,
                           payload: Dict):
        self.task_graph[task_id] = {
            'dependencies': dependencies,
            'executor': executor_agent,
            'payload': payload,
            'created_at': datetime.utcnow()
        }
        self.task_status[task_id] = TaskStatus.PENDING
        
        # Check if task can be executed
        if self._can_execute(task_id):
            await self._execute_task(task_id)
            
    async def _execute_task(self, task_id: str):
        try:
            self.task_status[task_id] = TaskStatus.RUNNING
            task = self.task_graph[task_id]
            
            # Execute task logic
            result = await self._delegate_to_agent(
                task['executor'], 
                task['payload']
            )
            
            self.task_status[task_id] = TaskStatus.COMPLETED
            self.execution_history.append({
                'task_id': task_id,
                'status': TaskStatus.COMPLETED,
                'result': result,
                'completed_at': datetime.utcnow()
            })
            
            # Check dependent tasks
            await self._process_dependent_tasks(task_id)
            
        except Exception as e:
            self.task_status[task_id] = TaskStatus.FAILED
            self._handle_failure(task_id, str(e))
    
    def _can_execute(self, task_id: str) -> bool:
        dependencies = self.task_graph[task_id]['dependencies']
        return all(
            self.task_status.get(dep) == TaskStatus.COMPLETED 
            for dep in dependencies
        )

Consensus Mechanism Implementation

The consensus mechanism ensures agreement between agents on shared decisions and state changes, implementing a Byzantine fault-tolerant protocol suitable for decentralized agent networks.

from dataclasses import dataclass
from typing import List, Dict, Set
import time
import hashlib

@dataclass
class ConsensusProposal:
    proposal_id: str
    proposer: str
    value: Dict
    timestamp: float

class ConsensusProtocol:
    def __init__(self, agent_id: str, total_agents: int):
        self.agent_id = agent_id
        self.total_agents = total_agents
        self.threshold = (2 * total_agents) // 3 + 1
        self.proposals: Dict[str, ConsensusProposal] = {}
        self.votes: Dict[str, Set[str]] = {}
        self.committed: Dict[str, Dict] = {}
        
    def propose(self, value: Dict) -> str:
        proposal_id = self._generate_proposal_id(value)
        proposal = ConsensusProposal(
            proposal_id=proposal_id,
            proposer=self.agent_id,
            value=value,
            timestamp=time.time()
        )
        
        self.proposals[proposal_id] = proposal
        self.votes[proposal_id] = {self.agent_id}
        
        return proposal_id
    
    def vote(self, proposal_id: str, agent_id: str) -> bool:
        if proposal_id not in self.proposals:
            return False
            
        self.votes[proposal_id].add(agent_id)
        
        if len(self.votes[proposal_id]) >= self.threshold:
            self._commit_proposal(proposal_id)
            return True
            
        return False
    
    def _commit_proposal(self, proposal_id: str):
        proposal = self.proposals[proposal_id]
        self.committed[proposal_id] = proposal.value
        
    def _generate_proposal_id(self, value: Dict) -> str:
        content = f"{self.agent_id}:{str(value)}:{time.time()}"
        return hashlib.sha256(content.encode()).hexdigest()

Agent Learning Module

The learning module enables agents to improve their decision-making capabilities through experience, implementing a reinforcement learning approach with experience replay and policy updates.

import numpy as np
from collections import deque
from typing import Tuple, List

class AgentLearningModule:
    def __init__(self, 
                 state_dim: int, 
                 action_dim: int,
                 memory_size: int = 10000):
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.memory = deque(maxlen=memory_size)
        self.gamma = 0.95  # Discount factor
        self.epsilon = 1.0  # Exploration rate
        self.epsilon_decay = 0.995
        self.epsilon_min = 0.01
        self.learning_rate = 0.001
        
        # Initialize neural network weights
        self.weights = {
            'W1': np.random.randn(state_dim, 64) / np.sqrt(state_dim),
            'W2': np.random.randn(64, 32) / np.sqrt(64),
            'W3': np.random.randn(32, action_dim) / np.sqrt(32)
        }
        
    def remember(self, 
                 state: np.ndarray, 
                 action: int, 
                 reward: float,
                 next_state: np.ndarray, 
                 done: bool):
        self.memory.append((state, action, reward, next_state, done))
        
    def act(self, state: np.ndarray) -> int:
        if np.random.rand() <= self.epsilon:
            return np.random.randint(self.action_dim)
        
        q_values = self._forward(state)
        return np.argmax(q_values)
    
    def train(self, batch_size: int = 32):
        if len(self.memory) < batch_size:
            return
            
        batch = np.random.choice(len(self.memory), batch_size, replace=False)
        losses = []
        
        for idx in batch:
            state, action, reward, next_state, done = self.memory[idx]
            target = reward
            
            if not done:
                target += self.gamma * np.max(self._forward(next_state))
                
            current_q = self._forward(state)
            current_q[action] = target
            
            loss = self._backward(state, current_q)
            losses.append(loss)
            
        self.epsilon = max(self.epsilon_min, 
                          self.epsilon * self.epsilon_decay)
        
        return np.mean(losses)
    
    def _forward(self, state: np.ndarray) -> np.ndarray:
        h1 = np.tanh(state.dot(self.weights['W1']))
        h2 = np.tanh(h1.dot(self.weights['W2']))
        return h2.dot(self.weights['W3'])

Mesh Synchronization Protocol

A distributed synchronization mechanism ensuring consistency across the agent mesh, implementing vector clocks and conflict resolution strategies for eventual consistency.

from typing import Dict, Set, Optional
import time
from dataclasses import dataclass, field

@dataclass
class VectorClock:
    timestamps: Dict[str, int] = field(default_factory=dict)
    
    def increment(self, agent_id: str):
        self.timestamps[agent_id] = self.timestamps.get(agent_id, 0) + 1
        
    def merge(self, other: 'VectorClock'):
        all_agents = set(self.timestamps.keys()) | set(other.timestamps.keys())
        for agent_id in all_agents:
            self.timestamps[agent_id] = max(
                self.timestamps.get(agent_id, 0),
                other.timestamps.get(agent_id, 0)
            )

class MeshSynchronizer:
    def __init__(self, agent_id: str):
        self.agent_id = agent_id
        self.vector_clock = VectorClock()
        self.state_log = []
        self.peers: Set[str] = set()
        
    def update_state(self, state_update: Dict) -> Dict:
        # Update vector clock
        self.vector_clock.increment(self.agent_id)
        
        # Log state update with timestamp
        log_entry = {
            'timestamp': self.vector_clock.timestamps.copy(),
            'agent_id': self.agent_id,
            'update': state_update,
            'physical_time': time.time()
        }
        self.state_log.append(log_entry)
        
        return {
            'vector_clock': self.vector_clock.timestamps,
            'update': state_update
        }
        
    def receive_update(self, 
                      peer_id: str, 
                      update: Dict,
                      peer_clock: Dict[str, int]):
        # Merge vector clocks
        peer_vc = VectorClock(peer_clock)
        self.vector_clock.merge(peer_vc)
        
        # Check for causality violations
        if self._check_causality(peer_id, peer_clock):
            self._apply_update(peer_id, update)
            self.peers.add(peer_id)
            
    def _check_causality(self, 
                        peer_id: str, 
                        peer_clock: Dict[str, int]) -> bool:
        local_time = self.vector_clock.timestamps.get(peer_id, 0)
        peer_time = peer_clock.get(peer_id, 0)
        
        return peer_time == local_time + 1

Capability Discovery and Matching

The capability discovery system implements semantic matching algorithms to identify and pair agents based on their abilities and requirements, using embeddings for capability comparison.

from typing import List, Dict, Tuple
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

class CapabilityMatcher:
    def __init__(self, embedding_dim: int = 768):
        self.embedding_dim = embedding_dim
        self.capability_embeddings = {}
        self.agent_capabilities = {}
        
    def register_agent_capabilities(self, 
                                  agent_id: str, 
                                  capabilities: List[Dict]):
        # Generate embeddings for each capability
        agent_embeddings = []
        for cap in capabilities:
            embedding = self._generate_capability_embedding(cap)
            self.capability_embeddings[cap['id']] = embedding
            agent_embeddings.append(embedding)
            
        self.agent_capabilities[agent_id] = {
            'embeddings': agent_embeddings,
            'metadata': capabilities
        }
        
    def find_matching_agents(self, 
                           required_capabilities: List[Dict],
                           threshold: float = 0.8) -> List[Tuple[str, float]]:
        required_embeddings = [
            self._generate_capability_embedding(cap) 
            for cap in required_capabilities
        ]
        
        matches = []
        for agent_id, agent_data in self.agent_capabilities.items():
            match_score = self._calculate_match_score(
                required_embeddings,
                agent_data['embeddings']
            )
            if match_score >= threshold:
                matches.append((agent_id, match_score))
                
        return sorted(matches, key=lambda x: x[1], reverse=True)
    
    def _calculate_match_score(self, 
                             required: List[np.ndarray],
                             available: List[np.ndarray]) -> float:
        similarity_matrix = cosine_similarity(
            np.vstack(required),
            np.vstack(available)
        )
        return np.mean(np.max(similarity_matrix, axis=1))
    
    def _generate_capability_embedding(self, capability: Dict) -> np.ndarray:
        # Implement your embedding generation logic here
        # This could use transformers or other embedding methods
        return np.random.randn(self.embedding_dim)

Task Decomposition Engine

An intelligent system for breaking down complex tasks into manageable subtasks, considering dependencies, resource constraints, and optimal agent allocation strategies.

from dataclasses import dataclass
from typing import List, Dict, Optional
import networkx as nx

@dataclass
class SubTask:
    id: str
    description: str
    requirements: Dict
    estimated_duration: float
    dependencies: List[str]

class TaskDecomposer:
    def __init__(self):
        self.task_graph = nx.DiGraph()
        self.completion_times = {}
        
    def decompose_task(self, task_spec: Dict) -> List[SubTask]:
        # Clear previous task graph
        self.task_graph.clear()
        
        # Generate subtasks based on task specification
        subtasks = self._generate_subtasks(task_spec)
        
        # Build dependency graph
        for subtask in subtasks:
            self.task_graph.add_node(subtask.id, task=subtask)
            for dep in subtask.dependencies:
                self.task_graph.add_edge(dep, subtask.id)
                
        # Validate acyclic graph
        if not nx.is_directed_acyclic_graph(self.task_graph):
            raise ValueError("Circular dependencies detected")
            
        # Calculate critical path
        self._calculate_completion_times()
        
        return self._get_execution_order()
    
    def _generate_subtasks(self, task_spec: Dict) -> List[SubTask]:
        subtasks = []
        # Implement your task decomposition logic here
        # This could use NLP or rule-based approaches
        return subtasks
    
    def _calculate_completion_times(self):
        for node in nx.topological_sort(self.task_graph):
            task = self.task_graph.nodes[node]['task']
            pred_time = max(
                [self.completion_times.get(p, 0) 
                 for p in self.task_graph.predecessors(node)],
                default=0
            )
            self.completion_times[node] = (
                pred_time + task.estimated_duration
            )
    
    def _get_execution_order(self) -> List[SubTask]:
        return [
            self.task_graph.nodes[node]['task']
            for node in nx.topological_sort(self.task_graph)
        ]

Resource Allocation System

The resource allocation system manages computational and data resources across the agent mesh, implementing fair scheduling and priority-based allocation strategies for optimal resource utilization.

from dataclasses import dataclass
from typing import Dict, List, Optional
from enum import Enum
import heapq

class ResourceType(Enum):
    CPU = "cpu"
    MEMORY = "memory"
    STORAGE = "storage"
    API_CALLS = "api_calls"

@dataclass
class ResourceRequest:
    agent_id: str
    resource_type: ResourceType
    amount: float
    priority: int
    timestamp: float

class ResourceAllocator:
    def __init__(self, resource_limits: Dict[ResourceType, float]):
        self.resource_limits = resource_limits
        self.allocated_resources: Dict[str, Dict[ResourceType, float]] = {}
        self.request_queue = []
        self.allocation_history = []
        
    def request_resources(self, request: ResourceRequest) -> bool:
        if self._can_allocate(request):
            self._allocate_resources(request)
            return True
            
        heapq.heappush(
            self.request_queue, 
            (-request.priority, request.timestamp, request)
        )
        return False
    
    def release_resources(self, agent_id: str, resource_type: ResourceType):
        if agent_id in self.allocated_resources:
            amount = self.allocated_resources[agent_id].get(resource_type, 0)
            if amount > 0:
                del self.allocated_resources[agent_id][resource_type]
                self._process_queue()
                
    def _can_allocate(self, request: ResourceRequest) -> bool:
        current_usage = sum(
            alloc.get(request.resource_type, 0)
            for alloc in self.allocated_resources.values()
        )
        return (current_usage + request.amount <= 
                self.resource_limits[request.resource_type])
    
    def _allocate_resources(self, request: ResourceRequest):
        if request.agent_id not in self.allocated_resources:
            self.allocated_resources[request.agent_id] = {}
            
        self.allocated_resources[request.agent_id][request.resource_type] = (
            request.amount
        )
        
        self.allocation_history.append({
            'agent_id': request.agent_id,
            'resource_type': request.resource_type,
            'amount': request.amount,
            'timestamp': request.timestamp
        })
    
    def _process_queue(self):
        if not self.request_queue:
            return
            
        # Try to process pending requests
        new_queue = []
        while self.request_queue:
            _, _, request = heapq.heappop(self.request_queue)
            if self._can_allocate(request):
                self._allocate_resources(request)
            else:
                new_queue.append((-request.priority, 
                                request.timestamp, request))
                
        self.request_queue = new_queue
        heapq.heapify(self.request_queue)

Performance Monitoring System

A comprehensive monitoring system that tracks agent performance metrics, resource utilization, and interaction patterns to optimize mesh operations and identify bottlenecks.

from typing import Dict, List, Optional
import time
import numpy as np
from collections import deque

class PerformanceMonitor:
    def __init__(self, window_size: int = 1000):
        self.metrics = {
            'response_times': deque(maxlen=window_size),
            'success_rates': deque(maxlen=window_size),
            'resource_usage': deque(maxlen=window_size),
            'interaction_counts': {}
        }
        self.alerts = []
        self.thresholds = {
            'response_time': 1.0,  # seconds
            'success_rate': 0.95,
            'resource_usage': 0.8
        }
        
    def record_interaction(self, 
                         source_id: str, 
                         target_id: str, 
                         duration: float,
                         success: bool,
                         resource_usage: Dict[str, float]):
        # Record response time
        self.metrics['response_times'].append(duration)
        
        # Record success/failure
        self.metrics['success_rates'].append(float(success))
        
        # Record resource usage
        self.metrics['resource_usage'].append(
            max(resource_usage.values())
        )
        
        # Record interaction count
        key = f"{source_id}:{target_id}"
        self.metrics['interaction_counts'][key] = (
            self.metrics['interaction_counts'].get(key, 0) + 1
        )
        
        # Check for anomalies
        self._check_anomalies()
        
    def get_performance_summary(self) -> Dict:
        return {
            'avg_response_time': np.mean(self.metrics['response_times']),
            'success_rate': np.mean(self.metrics['success_rates']),
            'avg_resource_usage': np.mean(self.metrics['resource_usage']),
            'total_interactions': sum(
                self.metrics['interaction_counts'].values()
            ),
            'active_agents': len(set(
                agent_id.split(':')[0]
                for agent_id in self.metrics['interaction_counts'].keys()
            ))
        }
        
    def _check_anomalies(self):
        window = 100
        if len(self.metrics['response_times']) >= window:
            recent_resp_times = list(self.metrics['response_times'])[-window:]
            recent_success_rates = list(self.metrics['success_rates'])[-window:]
            
            if np.mean(recent_resp_times) > self.thresholds['response_time']:
                self._create_alert('High average response time detected')
                
            if np.mean(recent_success_rates) < self.thresholds['success_rate']:
                self._create_alert('Low success rate detected')
    
    def _create_alert(self, message: str):
        self.alerts.append({
            'message': message,
            'timestamp': time.time(),
            'metrics': self.get_performance_summary()
        })

Additional Resources

Note: These URLs are examples of the type of papers you might find. For the most current research, please search academic databases and preprint servers.

More in Agents and LangChain

  1. Building an LLM-Powered Shopping Assistant with Python10 min

    Building an LLM Shopping Copilot combines natural language processing with e-commerce to enhance the shopping experience. This AI-powered assistant helps...

  2. Building a LangGraph Agent with Graph Memory8 min

    A LangGraph Agent combines natural language processing with graph neural networks to create an intelligent system capable of maintaining contextual memory...

  3. Building and Deploying an LLM Agent in Python A Step-by-Step Guide15 min

    Building an LLM (Large Language Model) agent in Python involves creating a system that can understand and generate human-like text, and perform tasks based...

  4. Building a Custom LangChain QnA Agent with Wikipedia Using Python4 min

    LangChain is a framework for building applications with large language models (LLMs). It provides abstractions for working with LLMs, data retrieval, and...

  5. Building LLMs from Scratch Python Practical Code Examples16 min

    Neural networks form the backbone of modern deep learning, starting with the fundamental building blocks. The key components include weights, biases...

  6. Building a Content Summarizer with OpenAI LangChain and Gradio10 min

    The foundation of our YouTube and website summarizer requires specific Python packages. We'll use OpenAI for the language model, LangChain for chain...