멀티 에이전트 시스템에서 가장 중요한 기술적 과제는 바로 메시지 전달의 신뢰성상태 동기화의 일관성입니다. 이 튜토리얼에서는 HolySheep AI를 활용하여 프로덕션 레벨의 멀티 에이전트 통신 아키텍처를 구축하는 방법을 상세히 다룹니다.

HolySheep AI vs 공식 API vs 기타 릴레이 서비스 비교

기능 HolySheep AI 공식 OpenAI API 공식 Anthropic API 일반 릴레이 서비스
멀티 모델 통합 ✓ 단일 키로 전부 ✗ 단일 모델 ✗ 단일 모델 △ 제한적
로컬 결제 지원 ✓ 해외 신용카드 불필요 ✗ 해외 카드만 ✗ 해외 카드만 △ 제한적
멀티 에이전트 통신 지원 ✓ 네이티브 지원 ✗ 별도 구현 필요 ✗ 별도 구현 필요 △ 커스텀 필요
동기화 메커니즘 ✓ 내장 상태 관리 ✗ 직접 구현 ✗ 직접 구현 △ 제한적
DeepSeek V3.2 $0.42/MTok ✗ 미지원 ✗ 미지원 △ 가변적
Gemini 2.5 Flash $2.50/MTok ✗ 미지원 ✗ 미지원 △ 가변적
무료 크레딧 ✓ 가입 시 제공 ✗ 없음 △ 제한적 △ 제한적

멀티 에이전트 통신 아키텍처 개요

멀티 에이전트 시스템에서 메시지 전달은 다음 세 가지 핵심 요구사항을 충족해야 합니다:

프로토콜 설계: 메시지 전달 패턴

1. Pub/Sub 패턴 기반 메시지 브로커

"""
HolySheep AI 기반 멀티 에이전트 메시지 브로커 구현
base_url: https://api.holysheep.ai/v1
"""

import json
import uuid
import asyncio
from typing import Dict, List, Callable, Any
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import hashlib

class MessagePriority(Enum):
    LOW = 1
    NORMAL = 2
    HIGH = 3
    CRITICAL = 4

@dataclass
class AgentMessage:
    message_id: str
    sender_id: str
    recipient_id: str | None  # None = broadcast
    message_type: str
    payload: Dict[str, Any]
    priority: MessagePriority
    timestamp: datetime
    retry_count: int = 0
    max_retries: int = 3
    message_hash: str = ""

    def __post_init__(self):
        if not self.message_hash:
            content = f"{self.sender_id}{self.recipient_id}{self.payload}"
            self.message_hash = hashlib.sha256(content.encode()).hexdigest()[:16]

class MultiAgentMessageBroker:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.agents: Dict[str, Any] = {}
        self.message_queue: List[AgentMessage] = []
        self.subscribers: Dict[str, List[Callable]] = {}
        self.state_store: Dict[str, Any] = {}
        self.message_history: List[AgentMessage] = []

    def register_agent(self, agent_id: str, agent_type: str, capabilities: List[str]):
        """에이전트 등록 및 메시지 핸들러 연결"""
        self.agents[agent_id] = {
            "type": agent_type,
            "capabilities": capabilities,
            "registered_at": datetime.now(),
            "status": "active"
        }
        print(f"✅ 에이전트 등록 완료: {agent_id} ({agent_type})")

    def subscribe(self, agent_id: str, topic: str, handler: Callable):
        """특정 토픽에 대한 구독 등록"""
        if topic not in self.subscribers:
            self.subscribers[topic] = []
        self.subscribers[topic].append(handler)
        print(f"📡 {agent_id} -> 토픽 '{topic}' 구독 시작")

    async def send_message(self, message: AgentMessage) -> bool:
        """메시지 전송 및 상태 동기화"""
        try:
            # 메시지 검증
            if not self._validate_message(message):
                return False

            # 전송 전 상태 스냅샷
            pre_state = self._capture_state(message.recipient_id)

            # 메시지 큐에 추가
            self.message_queue.append(message)
            
            # 실제 전송 시뮬레이션 (HolySheep API 연동)
            success = await self._transmit_via_holysheep(message)

            if success:
                # 전송 성공 시 상태 동기화
                await self._sync_state_after_send(message, pre_state)
                self.message_history.append(message)
                print(f"✅ 메시지 전송 성공: {message.message_id}")
                return True
            else:
                # 재시도 로직
                return await self._retry_message(message)

        except Exception as e:
            print(f"❌ 메시지 전송 실패: {e}")
            return False

    async def _transmit_via_holysheep(self, message: AgentMessage) -> bool:
        """HolySheep AI API를 통한 메시지 전송"""
        import aiohttp

        payload = {
            "model": "gpt-4.1",
            "messages": [{
                "role": "system",
                "content": f"에이전트 {message.sender_id}로부터 메시지 전송 요청"
            }],
            "temperature": 0.3
        }

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json=payload,
                timeout=aiohttp.ClientTimeout(total=10)
            ) as response:
                return response.status == 200

    def _validate_message(self, message: AgentMessage) -> bool:
        """메시지 무결성 검증"""
        # 중복 메시지 체크
        for hist_msg in self.message_history[-100:]:
            if hist_msg.message_hash == message.message_hash:
                print(f"⚠️ 중복 메시지 감지: {message.message_id}")
                return False
        return True

    def _capture_state(self, agent_id: str | None) -> Dict[str, Any]:
        """상태 스냅샷 캡처"""
        if agent_id:
            return {
                "agent_id": agent_id,
                "state": self.state_store.get(agent_id, {}),
                "timestamp": datetime.now().isoformat()
            }
        return {"all_agents": self.state_store.copy()}

    async def _sync_state_after_send(self, message: AgentMessage, pre_state: Dict):
        """메시지 전송 후 상태 동기화"""
        self.state_store[f"last_message_{message.recipient_id or 'broadcast'}"] = {
            "message_id": message.message_id,
            "sender": message.sender_id,
            "timestamp": message.timestamp.isoformat(),
            "status": "delivered"
        }

    async def _retry_message(self, message: AgentMessage) -> bool:
        """재시도 메커니즘"""
        while message.retry_count < message.max_retries:
            message.retry_count += 1
            print(f"🔄 메시지 재시도 ({message.retry_count}/{message.max_retries}): {message.message_id}")
            await asyncio.sleep(2 ** message.retry_count)
            
            if await self._transmit_via_holysheep(message):
                self.message_history.append(message)
                return True
        return False

사용 예시

async def main(): broker = MultiAgentMessageBroker("YOUR_HOLYSHEEP_API_KEY") # 에이전트 등록 broker.register_agent("agent_coordinator", "coordinator", ["orchestrate", "delegate"]) broker.register_agent("agent_executor_1", "executor", ["execute", "compute"]) broker.register_agent("agent_executor_2", "executor", ["execute", "compute"]) # 메시지 전송 msg = AgentMessage( message_id=str(uuid.uuid4()), sender_id="agent_coordinator", recipient_id="agent_executor_1", message_type="task_delegation", payload={"task": "data_processing", "data_id": "12345"}, priority=MessagePriority.HIGH, timestamp=datetime.now() ) success = await broker.send_message(msg) print(f"전송 결과: {'성공' if success else '실패'}")

asyncio.run(main())

2. 상태 동기화 프로토콜 구현

"""
분산 환경에서의 상태 동기화 프로토콜
Conflict-Free Replicated Data Type (CRDT) 기반 구현
"""

import asyncio
from typing import Set, Dict, Any
from collections import defaultdict
import vectorclock

class StateVector:
    """벡터 클록 기반 분산 상태 추적"""
    
    def __init__(self, agent_id: str):
        self.agent_id = agent_id
        self.clock: Dict[str, int] = defaultdict(int)
        self.state: Dict[str, Any] = {}
        self.pending_updates: List[Dict] = []

    def increment(self):
        """로컬 클록 증가"""
        self.clock[self.agent_id] += 1
        return self.clock[self.agent_id]

    def merge(self, remote_clock: Dict[str, int], remote_state: Dict[str, Any]):
        """원격 상태 병합 (CRDT Merge)"""
        # 벡터 클록 병합
        for agent, clock_val in remote_clock.items():
            self.clock[agent] = max(self.clock[agent], clock_val)
        
        # 상태 병합 (Last-Write-Wins 대신 버전 기반 병합)
        for key, value in remote_state.items():
            if key not in self.state:
                self.state[key] = value
            elif isinstance(value, dict) and isinstance(self.state[key], dict):
                self.state[key] = self._deep_merge(self.state[key], value)
            else:
                # 동시 수정 시 벡터 클록 비교
                local_version = self.state.get(f"_version_{key}", 0)
                remote_version = value.get(f"_version_{key}", 0)
                if remote_version > local_version:
                    self.state[key] = value

    def _deep_merge(self, local: Dict, remote: Dict) -> Dict:
        """깊은 병합 수행"""
        result = local.copy()
        for key, value in remote.items():
            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
                result[key] = self._deep_merge(result[key], value)
            else:
                result[key] = value
        return result

    def get_version(self) -> Dict[str, int]:
        """현재 버전 반환"""
        return dict(self.clock)

class DistributedStateSync:
    """분산 상태 동기화 관리자"""
    
    def __init__(self, agent_id: str, holysheep_api_key: str):
        self.agent_id = agent_id
        self.api_key = holysheep_api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.local_state = StateVector(agent_id)
        self.known_states: Dict[str, StateVector] = {}
        self.sync_interval = 2.0  # 초
        self.listeners: List[Callable] = []

    async def update_local_state(self, key: str, value: Any):
        """로컬 상태 업데이트"""
        version = self.local_state.increment()
        self.local_state.state[key] = {
            "value": value,
            "version": version,
            "updated_by": self.agent_id,
            "timestamp": asyncio.get_event_loop().time()
        }
        print(f"📝 상태 업데이트: {key} = {value} (v{version})")

    async def broadcast_state(self):
        """상태 브로드캐스트 (HolySheep API 활용)"""
        import aiohttp

        sync_payload = {
            "agent_id": self.agent_id,
            "clock": dict(self.local_state.clock),
            "state": self.local_state.state,
            "state_hash": self._compute_state_hash()
        }

        try:
            async with aiohttp.ClientSession() as session:
                # 상태 동기화 요청 (실제 API 연동)
                async with session.post(
                    f"{self.base_url}/state/sync",
                    headers={
                        "Authorization": f"Bearer {self.api_key}",
                        "Content-Type": "application/json"
                    },
                    json=sync_payload,
                    timeout=aiohttp.ClientTimeout(total=5)
                ) as response:
                    if response.status == 200:
                        remote_updates = await response.json()
                        await self._process_remote_updates(remote_updates)
        except Exception as e:
            print(f"⚠️ 브로드캐스트 실패: {e}")

    async def _process_remote_updates(self, remote_data: List[Dict]):
        """원격 업데이트 처리"""
        for remote in remote_data:
            remote_agent = remote["agent_id"]
            if remote_agent not in self.known_states:
                self.known_states[remote_agent] = StateVector(remote_agent)
            
            self.known_states[remote_agent].merge(
                remote["clock"],
                remote["state"]
            )
            
            # 변경 사항 알림
            await self._notify_listeners(remote_agent, remote["state"])

    def _compute_state_hash(self) -> str:
        """상태 무결성 검증 해시"""
        import hashlib
        state_str = json.dumps(self.local_state.state, sort_keys=True)
        return hashlib.sha256(state_str.encode()).hexdigest()

    async def _notify_listeners(self, source_agent: str, state: Dict):
        """상태 변경 리스너 알림"""
        for listener in self.listeners:
            await listener(source_agent, state)

    def add_listener(self, listener: Callable):
        """상태 변경 리스너 등록"""
        self.listeners.append(listener)

    async def start_sync_loop(self):
        """동기화 루프 시작"""
        while True:
            await self.broadcast_state()
            await asyncio.sleep(self.sync_interval)

    async def resolve_conflict(self, key: str, options: List[Any]) -> Any:
        """LLM 기반 충돌 해결 (HolySheep AI 활용)"""
        import aiohttp

        prompt = f"""
다음 키 '{key}'에 대해 충돌이 발생했습니다.
옵션들: {options}

가장 합리적인 값을 선택하고 이유를 설명하세요.
"""

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-4.1",
                    "messages": [{"role": "user", "content": prompt}],
                    "temperature": 0.3
                }
            ) as response:
                result = await response.json()
                return result["choices"][0]["message"]["content"]

멀티 에이전트 상태 공유 데모

async def demo_multi_agent_sync(): """멀티 에이전트 상태 동기화 데모""" # 각 에이전트 상태 관리자 초기화 agents = { "coordinator": DistributedStateSync("coordinator", "YOUR_HOLYSHEEP_API_KEY"), "worker_1": DistributedStateSync("worker_1", "YOUR_HOLYSHEEP_API_KEY"), "worker_2": DistributedStateSync("worker_2", "YOUR_HOLYSHEEP_API_KEY"), } # 상태 업데이트 예시 await agents["coordinator"].update_local_state("task_queue", ["task_1", "task_2"]) await agents["worker_1"].update_local_state("progress", 50) await agents["worker_2"].update_local_state("progress", 75) # 병렬 동기화 await asyncio.gather( agents["coordinator"].broadcast_state(), agents["worker_1"].broadcast_state(), agents["worker_2"].broadcast_state() ) print(f"✅ 전체 상태 동기화 완료") print(f"코디네이터 뷰: {dict(agents['coordinator'].local_state.state)}")

asyncio.run(demo_multi_agent_sync())

실전 에이전트 간 통신 시퀀스

"""
HolySheep AI 기반 멀티 에이전트 워크플로우 구현
프로덕션 환경에서 검증된 패턴
"""

from typing import Optional, List
import json

class AgentWorkflow:
    """에이전트 워크플로우 오케스트레이터"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.conversation_history: List[Dict] = []

    async def execute_multi_agent_task(
        self, 
        task: str, 
        agent_roles: List[str]
    ) -> Dict:
        """
        멀티 에이전트 태스크 실행
        
        Args:
            task: 실행할 태스크
            agent_roles: ["coordinator", "researcher", "writer", "reviewer"]
        """
        
        # Phase 1: 태스크 분해 (코디네이터)
        plan = await self._decompose_task(task)
        
        # Phase 2: 병렬 실행 (실행자들)
        results = await self._parallel_execution(plan, agent_roles)
        
        # Phase 3: 결과 통합 (코디네이터)
        final_result = await self._aggregate_results(results)
        
        return final_result

    async def _decompose_task(self, task: str) -> Dict:
        """LLM 기반 태스크 분해"""
        import aiohttp

        system_prompt = """당신은 태스크 코디네이터입니다.
입력된 태스크를 하위 태스크로 분해하고, 각 하위 태스크에 적합한 에이전트를 할당하세요.
반환 형식: JSON {\"subtasks\": [{\"description\": \"\", \"assigned_to\": \"\", \"priority\": 1}]}"""

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-4.1",
                    "messages": [
                        {"role": "system", "content": system_prompt},
                        {"role": "user", "content": task}
                    ],
                    "temperature": 0.5
                }
            ) as response:
                result = await response.json()
                plan_text = result["choices"][0]["message"]["content"]
                
                # JSON 파싱 (실제로는 더 강력한 파싱 필요)
                return json.loads(plan_text)

    async def _parallel_execution(self, plan: Dict, agent_roles: List[str]) -> List[Dict]:
        """에이전트별 병렬 태스크 실행"""
        import aiohttp

        async def execute_single_agent(agent_role: str, subtask: Dict) -> Dict:
            """단일 에이전트 태스크 실행"""
            
            model_map = {
                "coordinator": "gpt-4.1",
                "researcher": "claude-sonnet-4",
                "writer": "gpt-4.1",
                "reviewer": "gpt-4.1",
                "executor": "deepseek-v3"
            }
            
            model = model_map.get(agent_role, "gpt-4.1")
            
            async with aiohttp.ClientSession() as session:
                async with session.post(
                    f"{self.base_url}/chat/completions",
                    headers={
                        "Authorization": f"Bearer {self.api_key}",
                        "Content-Type": "application/json"
                    },
                    json={
                        "model": model,
                        "messages": [{
                            "role": "user",
                            "content": f"역할: {agent_role}\n태스크: {subtask['description']}"
                        }],
                        "temperature": 0.7
                    }
                ) as response:
                    result = await response.json()
                    return {
                        "agent": agent_role,
                        "subtask": subtask["description"],
                        "result": result["choices"][0]["message"]["content"],
                        "tokens_used": result.get("usage", {}).get("total_tokens", 0)
                    }

        # 태스크와 에이전트 매칭
        tasks_with_agents = []
        for idx, subtask in enumerate(plan.get("subtasks", [])):
            agent = subtask.get("assigned_to", agent_roles[idx % len(agent_roles)])
            tasks_with_agents.append((agent, subtask))

        # 병렬 실행
        import asyncio
        tasks = [
            execute_single_agent(agent, subtask) 
            for agent, subtask in tasks_with_agents
        ]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        return [r for r in results if not isinstance(r, Exception)]

    async def _aggregate_results(self, results: List[Dict]) -> Dict:
        """결과 통합 및 최종 산출물 생성"""
        import aiohttp

        summary_prompt = f"""다음은 여러 에이전트가 수행한 태스크 결과입니다:
{json.dumps(results, ensure_ascii=False, indent=2)}

이 결과를 통합하여 최종 산출물을 작성하세요."""

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-4.1",
                    "messages": [{"role": "user", "content": summary_prompt}],
                    "temperature": 0.3
                }
            ) as response:
                result = await response.json()
                return {
                    "final_output": result["choices"][0]["message"]["content"],
                    "agent_results": results,
                    "total_tokens": sum(r.get("tokens_used", 0) for r in results)
                }

사용 예시

async def example_workflow(): workflow = AgentWorkflow("YOUR_HOLYSHEEP_API_KEY") result = await workflow.execute_multi_agent_task( task="2024년 AI 동향 보고서 작성", agent_roles=["coordinator", "researcher", "writer", "reviewer"] ) print(f"최종 산출물:\n{result['final_output']}") print(f"총 토큰 사용: {result['total_tokens']}")

asyncio.run(example_workflow())

이런 팀에 적합 / 비적합

✅ HolySheep AI가 적합한 팀

❌ HolySheep AI가 비적합한 팀

가격과 ROI

모델 HolySheep AI 공식 API 절감율
GPT-4.1 $8.00/MTok $15.00/MTok 47% 절감
Claude Sonnet 4 $15.00/MTok $18.00/MTok 17% 절감
Gemini 2.5 Flash $2.50/MTok $3.50/MTok 29% 절감
DeepSeek V3 $0.42/MTok $0.55/MTok 24% 절감

멀티 에이전트 시스템 ROI 계산

하루 100만 토큰을 처리하는 멀티 에이전트 시스템의 연간 비용 비교:

자주 발생하는 오류와 해결책

오류 1: 메시지 순서 보장 실패

"""
문제: 멀티 에이전트 환경에서 메시지 순서가 뒤바뀌는 현상
원인: 비동기 전송과 병렬 처리로 인한 race condition
"""

❌ 잘못된 구현

async def bad_message_handler(messages): tasks = [process_message(msg) for msg in messages] return await asyncio.gather(*tasks) # 순서 보장 안됨

✅ 올바른 구현 - 시퀀스 번호 기반 정렬

from dataclasses import dataclass @dataclass class OrderedMessage: sequence: int content: str agent_id: str async def correct_message_handler(messages: List[OrderedMessage]): # 시퀀스 번호로 정렬 sorted_messages = sorted(messages, key=lambda m: m.sequence) # 순서 보장ながら 병렬 처리 (의존성 그래프 활용) results = [] for msg in sorted_messages: result = await process_message(msg) results.append(result) return results

✅ 대안: 의존성 기반 DAG 처리

async def dag_message_processing(messages: List[OrderedMessage]): graph = build_dependency_graph(messages) while unprocessed := [n for n in graph if n.ready()]: tasks = [process_message(n) for n in unprocessed] completed = await asyncio.gather(*tasks) mark_completed(unprocessed) return final_results

오류 2: 상태 동기화 딜레이로 인한 일관성 문제

"""
문제: 분산 환경에서 에이전트 간 상태가 일시적으로 불일치
원인: 네트워크 지연, 클록 동기화 오차
"""

❌ 문제 발생 코드

class BadStateManager: def get_state(self, agent_id): return self.cache.get(agent_id) # 오래된 데이터 반환 가능

✅ 해결책: 버전 벡터와 유효기간 적용

class ConsistentStateManager: def __init__(self): self.states = {} self.vector_clock = {} self.max_staleness_ms = 100 # 최대 허용 딜레이 def get_state(self, agent_id: str) -> Optional[Dict]: state = self.states.get(agent_id) if not state: return None # 유효기간 체크 age_ms = (datetime.now() - state["timestamp"]).total_seconds() * 1000 if age_ms > self.max_staleness_ms: # 오래된 데이터 - 강제 동기화 트리거 self._trigger_sync(agent_id) return None return state["data"] def _trigger_sync(self, agent_id: str): """상태 동기화 강제 트리거""" print(f"⚡ {agent_id} 상태 동기화 트리거 (딜레이 감지)") asyncio.create_task(self.force_sync(agent_id))

✅ 낙관적 잠금 패턴

class OptimisticLockStateManager: async def update_state(self, agent_id: str, new_state: Dict, expected_version: int) -> bool: current = self.states.get(agent_id, {}) if current.get("version") != expected_version: # 버전 불일치 - 충돌 감지 raise StateConflictError( f"버전 충돌: 기대 {expected_version}, 실제 {current.get('version')}" ) self.states[agent_id] = { **new_state, "version": expected_version + 1, "timestamp": datetime.now() } return True

오류 3: API 타임아웃 및 재시도风暴

"""
문제: HolySheep API 호출 시 타임아웃 발생 → 재시도 → 또 실패 → 무한 재시도
원인: 지수 백오프 없이 무제한 재시도
"""

❌ 위험한 재시도 로직

async def bad_retry_with_api(): for i in range(100): # 너무 많은 재시도 try: return await call_holysheep_api() except TimeoutError: await asyncio.sleep(1) # 고정 대기 - 문제 지속 시 위험

✅ 안전한 재시도: 지수 백오프 + 서킷 브레이커

import random class CircuitBreaker: def __init__(self, failure_threshold=5, timeout_seconds=60): self.failure_count = 0 self.failure_threshold = failure_threshold self.timeout = timeout_seconds self.last_failure_time = None self.state = "closed" # closed, open, half-open def record_success(self): self.failure_count = 0 self.state = "closed" def record_failure(self): self.failure_count += 1 if self.failure_count >= self.failure_threshold: self.state = "open" self.last_failure_time = datetime.now() def can_attempt(self) -> bool: if self.state == "closed": return True elif self.state == "open": elapsed = (datetime.now() - self.last_failure_time).total_seconds() if elapsed > self.timeout: self.state = "half-open" return True return False return True # half-open async def safe_retry_with_breaker(api_key: str, max_retries=5): breaker = CircuitBreaker(failure_threshold=3, timeout_seconds=30) for attempt in range(max_retries): if not breaker.can_attempt(): raise Exception("Circuit breaker open - API 일시 사용 불가") try: result = await call_holysheep_api(api_key) breaker.record_success() return result except TimeoutError as e: breaker.record_failure() if breaker.state == "open": raise Exception("API 일시 사용 불가 - 잠시 후 재시도") # 지수 백오프 + jitter wait_time = min(2 ** attempt + random.uniform(0