Skip to main content
Glama

AREL — 에이전트 신뢰성 및 평가 연구소

MCP 에이전트 런타임을 기반으로 구축된 프로덕션 지향 신뢰성, 벤치마킹 및 평가 시스템입니다.


왜 이 프로젝트가 필요한가

업스트림 MCP 에이전트 런타임은 Model Context Protocol로 에이전트를 구성하기에 훌륭한 프레임워크이지만, 이를 프로덕션에 배포하려면 구성 프리미티브 이상의 것이 필요합니다. 실제 프로덕션 시스템에는 다중 버전 프로토콜 협상, 피어 투 피어 에이전트 검색, 백프레셔 인지 스트리밍, 서킷 브레이커가 포함된 연결 풀링, 핫 리로드 가능한 플러그인 아키텍처, 복원력 있는 재시도 및 상태 복구, 그리고 자동 스케일링이 포함된 지속적인 상태 모니터링이 필요합니다.

AREL은 업스트림 런타임을 기반으로 유지하면서 그 위에 완전한 신뢰성, 벤치마킹 및 평가 플랫폼을 계층화합니다:

  • 5가지 프로토콜 버전 지원 (MCP 1.0 → 2.1 + A2A v0.3) — 공식 협상 및 폐기 경고 포함

  • 9개의 신규 서브시스템 — 추가형, 비침습적 모듈로 구현 (소스 3,155 LOC, 테스트 2,096 LOC)

  • 신규 테스트 109개 추가 — 회귀 0건, 스위트 통과율 85.9% → 99.4% 로 회복

  • 신규 enhancements 패키지에 대한 82% 라인 커버리지

  • 470k msg/s 적응형 스트리밍 처리량 (순진한 베이스라인 대비 +34%)


한눈에 보기

기능

이전

이후

테스트 통과율

1292 / 1503 (85.9%)

1602 / 1612 (99.4%)

추가된 신규 테스트

109 (회귀 0건)

enhancements/ 커버리지

n/a

82%

MCP 프로토콜 버전

1.0 – 1.20

1.0 – 2.1 + A2A v0.3

적응형 스트리밍 처리량

352k msg/s (순진)

470k msg/s (+34%)

연결 풀 재사용

팩토리 호출 약 4배 감소

신규 서브시스템

9개 (기능 표면 참조)

추가된 소스 LOC

3,155 (12개 파일)

추가된 테스트 LOC

2,096 (11개 파일)


아키텍처

Architecture
├── Benchmark methodology
├── Evaluation methodology
├── Fault injection
├── Observability
├── Measured results
└── Reproducibility

위의 각 분기는 src/mcp_agent/enhancements/ 아래의 구체적인 모듈로 구현되며, tests/enhancements/ 아래의 테스트 스위트로 검증됩니다. 분기는 마케팅 문구가 아닙니다 — 파일, 클래스 및 측정 가능한 수치와 1:1로 매핑됩니다 (아래 측정 결과 참조).


시스템 아키텍처

아래 다이어그램은 AREL이 업스트림 MCP 에이전트 런타임 위에 어떻게 위치하는지 보여줍니다. 업스트림 mcp_agent.* 패키지(왼쪽, 회색)는 구성 프리미티브를 제공하고, 신규 mcp_agent.enhancements.* 패키지(오른쪽, 컬러)는 신뢰성, 벤치마킹 및 평가 플랫폼을 제공합니다. 두 패키지는 HybridMCPA2AGatewayResilientExecutor로 연결되며, 그 외의 모든 것은 추가형이므로 점진적으로 채택할 수 있습니다.

flowchart LR
    subgraph UP["Upstream mcp_agent runtime (Apache-2.0, unchanged)"]
        direction TB
        APP["MCPApp<br/>context & lifecycle"]
        AGENT["Agent + AgentSpec"]
        LLM["AugmentedLLM<br/>(OpenAI/Anthropic/Bedrock/…)"]
        WF["Workflows<br/>orchestrator · router · parallel · swarm"]
        MCP["MCP client<br/>stdio + HTTP transports"]
        TRACE["OpenTelemetry tracing"]
        LOG["Rich structured logging"]
    end

    subgraph ENH["AREL enhancements package (this project)"]
        direction TB
        P1A["P1.1 Protocol<br/>MCPProtocolAdapter"]
        P1B["P1.2 A2A<br/>AgentCard · A2AClient<br/>HybridMCPA2AGateway"]
        P2A["P2.1 Streaming<br/>AdaptiveStreamProcessor<br/>StreamingMultiplexer"]
        P2B["P2.2 Connection<br/>MCPConnectionPool<br/>CircuitBreaker · QuotaManager"]
        P3A["P3.1 Plugin<br/>PluginManager<br/>(hot-reload)"]
        P3B["P3.2 Patterns<br/>WorkflowPatternRegistry<br/>PatternComposer"]
        P4A["P4.1 Resilience<br/>ResilientExecutor<br/>RetryPolicy · FallbackChain<br/>StateRecovery"]
        P4B["P4.2 Health<br/>HealthMonitor<br/>HealthCheck · AutoScaler"]
    end

    subgraph EXT["External surfaces"]
        direction TB
        PEER["A2A peer agents"]
        LLM_API["LLM provider APIs"]
        MCP_SRV["MCP servers"]
        USER["Operator / SRE"]
    end

    APP --> AGENT --> LLM
    AGENT --> WF
    WF --> MCP
    MCP --> MCP_SRV
    LLM --> LLM_API

    P1A -. negotiates .-> MCP
    P1B -. bridges .-> MCP
    P1B <--> PEER
    P2A -. wraps streams .-> WF
    P2B -. pools .-> MCP
    P2B -. guards .-> LLM
    P3A -. injects into .-> APP
    P3B -. extends .-> WF
    P4A -. wraps .-> WF
    P4A -. wraps .-> P1B
    P4B -. observes .-> P2B
    P4B -. observes .-> P2A
    P4B -. emits signals .-> USER

    TRACE -. consumes .-> ENH
    LOG -. consumes .-> ENH

    classDef upstream fill:#F5F5F5,stroke:#999999,color:#333333
    classDef enh fill:#EEF2FF,stroke:#425CC7,color:#1E1B4B
    classDef ext fill:#FEF3C7,stroke:#D97706,color:#78350F

    class APP,AGENT,LLM,WF,MCP,TRACE,LOG upstream
    class P1A,P1B,P2A,P2B,P3A,P3B,P4A,P4B enh
    class PEER,LLM_API,MCP_SRV,USER ext

계층적 관점

네 개의 P-티어 그룹은 레이어 케이크를 형성합니다. P1은 프로토콜 기반이고, P2는 전송 및 리소스 계층이며, P3는 확장성 계층이고, P4는 아래의 모든 것을 관찰하고 보호하는 복원력 및 운영 계층입니다.

flowchart TB
    subgraph L4["P4 — Resilience & Operations"]
        HM["HealthMonitor + AutoScaler<br/>(EWMA · predictive)"]
        RE["ResilientExecutor<br/>(retry · fallback · state recovery)"]
    end

    subgraph L3["P3 — Extensibility"]
        PM["PluginManager<br/>(hot-reload)"]
        PR["WorkflowPatternRegistry<br/>+ PatternComposer"]
    end

    subgraph L2["P2 — Transport & Resources"]
        ASP["AdaptiveStreamProcessor<br/>(3 QoS tiers · backpressure)"]
        CP["MCPConnectionPool<br/>+ CircuitBreaker + QuotaManager"]
    end

    subgraph L1["P1 — Protocol"]
        PA["MCPProtocolAdapter<br/>(5 versions · deprecation)"]
        A2A["A2A Gateway<br/>(discovery · task lifecycle)"]
    end

    subgraph L0["Foundation"]
        RUNTIME["Upstream MCP agent runtime<br/>(MCPApp · Agent · AugmentedLLM · Workflows)"]
    end

    L4 --> L3 --> L2 --> L1 --> L0

    HM -. observes .-> CP
    HM -. observes .-> ASP
    RE -. wraps .-> A2A
    RE -. wraps .-> CP
    PM -. injects .-> RUNTIME
    PR -. extends .-> RUNTIME

    classDef l0 fill:#F5F5F5,stroke:#999999,color:#333333
    classDef l1 fill:#E0E7FF,stroke:#425CC7,color:#1E1B4B
    classDef l2 fill:#C7D2FE,stroke:#425CC7,color:#1E1B4B
    classDef l3 fill:#A5B4FC,stroke:#425CC7,color:#1E3A8A
    classDef l4 fill:#818CF8,stroke:#312E81,color:#FFFFFF

    class RUNTIME l0
    class PA,A2A l1
    class ASP,CP l2
    class PM,PR l3
    class HM,RE l4

워크플로 다이어그램

복원력 있는 실행기를 통한 요청 수명주기

일반적인 에이전트 요청은 프로토콜 어댑터(버전 협상), 연결 풀(풀링된 연결 획득), 복원력 있는 실행기(실패 시 재시도, 필요 시 A2A 피어로 폴백), 적응형 스트림 프로세서(QoS로 LLM 스트림 소비), 그리고 상태 모니터(지연 시간 및 오류율 기록)를 거쳐 흐릅니다. 단계 사이에 상태 스냅샷이 저장되어 재시도 시 완료된 작업을 다시 수행하는 대신 중간 지점에서 재개할 수 있습니다.

sequenceDiagram
    autonumber
    participant Caller as Caller
    participant PA as MCPProtocolAdapter
    participant CP as MCPConnectionPool
    participant CB as CircuitBreaker
    participant RE as ResilientExecutor
    participant SR as StateRecovery
    participant LLM as AugmentedLLM
    participant ASP as AdaptiveStreamProcessor
    participant HM as HealthMonitor
    participant AS as AutoScaler

    Caller->>PA: negotiate(version)
    PA-->>Caller: NegotiatedCapabilities

    Caller->>RE: execute_with_resilience(fn, workflow_id)
    RE->>SR: load(workflow_id)
    alt snapshot exists
        SR-->>RE: snapshot(step=N)
        RE->>RE: resume from step N
    else no snapshot
        RE->>RE: start from step 0
    end

    RE->>CP: acquire(target)
    CP->>CB: before_call()
    alt breaker OPEN
        CB-->>CP: false (fast-fail)
        CP-->>RE: CircuitBreakerOpenError
        RE->>RE: fallback chain
    else breaker CLOSED / HALF_OPEN
        CB-->>CP: true
        CP-->>RE: connection
        RE->>LLM: generate_stream(prompt)
        loop over tokens
            LLM-->>ASP: token (QoS=BEST_EFFORT)
            ASP-->>Caller: token
        end
        RE->>CP: release(connection)
        CP->>CB: record_success()
        RE->>SR: save(workflow_id, step, state)
    end

    par health observation
        ASP->>HM: latency + error_rate
        LLM->>HM: latency + error_rate
        HM->>HM: EWMA update
        alt status transition
            HM->>AS: on_unhealthy / on_recovered
            AS-->>Caller: ScaleSignal (UP / DOWN)
        end
    end

    RE-->>Caller: result / ExecutionStats

A2A 게이트웨이: 피어 에이전트를 MCP로 브리징

HybridMCPA2AGateway는 원격 A2A 에이전트를 로컬 MCP 도구(이름: a2a__<agent_name>)로 표시합니다. 게이트웨이는 에이전트 검색(/.well-known/agent.json 경유), 작업 수명주기(submitted → working → input-required → completed/canceled/failed), 그리고 전송 선택(프로덕션용 HTTP, 테스트용 in-proc)을 처리합니다.

flowchart TB
    subgraph CLIENT["MCP client"]
        CALL["call_tool('a2a__researcher', input)"]
    end

    subgraph GW["HybridMCPA2AGateway"]
        LT["list_tools()"]
        DISP["dispatch(name, input)"]
        REG["registry:<br/>name → A2AClient"]
    end

    subgraph A2A_PEER_A["A2A peer: researcher"]
        AC1["AgentCard<br/>/.well-known/agent.json"]
        TS1["A2AServer<br/>task lifecycle"]
    end

    subgraph A2A_PEER_B["A2A peer: coder"]
        AC2["AgentCard"]
        TS2["A2AServer"]
    end

    subgraph TRANSP["Transport"]
        HTTP["httpx<br/>(production)"]
        INPROC["in-proc<br/>(tests)"]
    end

    CALL --> DISP
    LT --> DISP
    DISP --> REG
    REG -- "researcher" --> AC1
    REG -- "coder" --> AC2
    AC1 --> TS1
    AC2 --> TS2
    TS1 --> HTTP
    TS2 --> HTTP
    TS1 -. test .-> INPROC
    TS2 -. test .-> INPROC

    classDef client fill:#FEF3C7,stroke:#D97706,color:#78350F
    classDef gw fill:#EEF2FF,stroke:#425CC7,color:#1E1B4B
    classDef peer fill:#FCE7F3,stroke:#BE185D,color:#831843
    classDef trans fill:#D1FAE5,stroke:#059669,color:#064E3B

    class CALL client
    class LT,DISP,REG gw
    class AC1,TS1,AC2,TS2 peer
    class HTTP,INPROC trans

서킷 브레이커 상태 머신

세 가지 상태, 복구 트립 시 지수 백오프, 상태 모니터를 위한 on_trip 비동기 콜백.

stateDiagram-v2
    [*] --> CLOSED

    CLOSED --> OPEN: failures ≥ failure_threshold
    OPEN --> HALF_OPEN: open_timeout_s elapsed
    HALF_OPEN --> CLOSED: success ≥ success_threshold
    HALF_OPEN --> OPEN: any failure

    note right of OPEN
        Fast-fail all calls.
        Backoff = base_s × 2^(trips-1)
        capped at backoff_max_s.
        Fires on_trip callback.
    end note

    note right of HALF_OPEN
        Allow probe requests.
        Reset backoff if recovery
        succeeds.
    end note

적응형 스트리밍: QoS 및 백프레셔

AdaptiveStreamProcessor는 세 가지 QoS 티어가 있는 바운디드 큐입니다. 큐가 가득 차면 티어별 정책이 드롭, 블록 또는 자동 스케일러로의 백프레셔 전파 중 무엇을 할지 결정합니다.

flowchart TB
    subgraph PROD["Producer"]
        P1["emit(item, qos)"]
    end

    subgraph Q["AdaptiveStreamProcessor (bounded queue)"]
        DECIDE{"queue full?"}
        T1["DROPPABLE<br/>priority=1"]
        T2["BEST_EFFORT<br/>priority=5"]
        T3["REALTIME<br/>priority=10"]
        BUF["bounded buffer<br/>(maxsize)"]
    end

    subgraph CONS["Consumer"]
        C1["async for item in proc.process()"]
    end

    subgraph REACT["Reactive hooks"]
        DROP["drop oldest<br/>++dropped"]
        BLOCK["block producer<br/>++backpressure_events"]
        SCALE["on_backpressure()<br/>→ AutoScaler.SCALE_UP"]
    end

    P1 --> DECIDE
    DECIDE -- yes --> T1
    DECIDE -- yes --> T2
    DECIDE -- yes --> T3
    DECIDE -- no --> BUF

    T1 --> DROP
    T2 --> BLOCK
    T3 --> SCALE

    DROP --> BUF
    BLOCK --> BUF
    SCALE --> BUF

    BUF --> C1

    classDef prod fill:#FEF3C7,stroke:#D97706,color:#78350F
    classDef q fill:#EEF2FF,stroke:#425CC7,color:#1E1B4B
    classDef cons fill:#D1FAE5,stroke:#059669,color:#064E3B
    classDef react fill:#FEE2E2,stroke:#DC2626,color:#7F1D1D

    class P1 prod
    class DECIDE,T1,T2,T3,BUF q
    class C1 cons
    class DROP,BLOCK,SCALE react

상태 모니터 및 자동 스케일러 피드백 루프

상태 모니터는 등록된 검사를 일정에 따라 실행하고, 마지막 20회 호출에 대한 EWMA 지연 시간과 EWMA 오류율을 계산하며, 알림 폭주를 피하기 위해 전환 시에만(모든 검사마다가 아닌) on_unhealthy / on_recovered 콜백을 발생시킵니다. 자동 스케일러는 해당 전환을 구독하고 컴포넌트별 쿨다운과 함께 SCALE_UP / SCALE_DOWN 신호를 발행합니다.

flowchart LR
    subgraph TARGETS["Observed components"]
        DB["db"]
        CACHE["cache"]
        LLM_API["LLM API"]
        MCP_SRV["MCP server"]
    end

    subgraph MON["HealthMonitor"]
        SCHED["schedule loop"]
        EWMA["EWMA latency<br/>EWMA error_rate<br/>(window=20)"]
        STATE["status per component<br/>HEALTHY / DEGRADED /<br/>UNHEALTHY / UNKNOWN"]
        CB_ON["on_unhealthy<br/>(transition only)"]
        CB_OFF["on_recovered<br/>(transition only)"]
    end

    subgraph SCALE["AutoScaler"]
        DECIDE{"transition?"}
        UP["SCALE_UP<br/>(UNHEALTHY)"]
        DOWN["SCALE_DOWN<br/>(HEALTHY + cooldown)"]
        HOLD["HOLD"]
    end

    TARGETS --> SCHED
    SCHED --> EWMA
    EWMA --> STATE
    STATE -- degraded --> CB_ON
    STATE -- healthy --> CB_OFF
    CB_ON --> DECIDE
    CB_OFF --> DECIDE
    DECIDE -- unhealthy --> UP
    DECIDE -- healthy + cooldown ok --> DOWN
    DECIDE -- otherwise --> HOLD

    UP -. feeds .-> TARGETS
    DOWN -. feeds .-> TARGETS

    classDef targets fill:#FEF3C7,stroke:#D97706,color:#78350F
    classDef mon fill:#EEF2FF,stroke:#425CC7,color:#1E1B4B
    classDef scale fill:#FCE7F3,stroke:#BE185D,color:#831843

    class DB,CACHE,LLM_API,MCP_SRV targets
    class SCHED,EWMA,STATE,CB_ON,CB_OFF mon
    class DECIDE,UP,DOWN,HOLD scale

이번 릴리스의 새로운 기능

개선 계획의 8개 작업 스트림이 추가형, 자체 포함 모듈로 구현되었습니다. mcp_agent.*의 기존 호출 지점은 수정되지 않았습니다 (업스트림 버그 수정 1건 제외 — audit.md §2 참조). 새 코드는 src/mcp_agent/enhancements/ 아래에 격리되어 있습니다:

ID

작업 스트림

모듈

핵심 클래스 / 함수

P1.1

프로토콜 협상 및 호환성

enhancements/protocol/

MCPProtocolAdapter, CompatibilityLayer

P1.2

에이전트 간(A2A) 프로토콜

enhancements/a2a/

AgentCard, A2AClient, A2AServer, HybridMCPA2AGateway

P2.1

백프레셔가 포함된 적응형 스트리밍

enhancements/streaming/

AdaptiveStreamProcessor, StreamingMultiplexer, QoSTier

P2.2

연결 풀링 및 서킷 브레이커

enhancements/connection/

MCPConnectionPool, CircuitBreaker, QuotaManager

P3.1

핫 리로드 플러그인 아키텍처

enhancements/plugin/

Plugin, PluginManager, load_plugin()

P3.2

커스텀 워크플로 패턴 레지스트리

enhancements/workflow_patterns/

WorkflowPatternRegistry, @register_workflow_pattern, PatternComposer

P4.1

복원력 있는 실행 및 상태 복구

enhancements/resilience/

ResilientExecutor, RetryPolicy, FallbackChain, StateRecovery

P4.2

상태 모니터링 및 자동 스케일링

enhancements/health/

HealthMonitor, HealthCheck, AutoScaler

각 모듈의 이유와 방법, 고려된 설계 대안, 그리고 위에 주장된 모든 수치에 대한 재현 지침을 포함한 완전한 엔지니어링 기록은 audit.md (595줄)에 있습니다. 소비자 지향의 간략한 매니페스트는 ENHANCEMENTS.md 에 있습니다.


기능 표면

from mcp_agent.enhancements import (
    # P1.1 — protocol
    MCPProtocolAdapter, CompatibilityLayer, LATEST_PROTOCOL_VERSION,
    # P1.2 — A2A
    AgentCard, A2AClient, A2AServer, HybridMCPA2AGateway, A2ATask, TaskState,
    # P2.1 — streaming
    AdaptiveStreamProcessor, StreamingMultiplexer, QoSTier, StreamStats,
    # P2.2 — connection
    MCPConnectionPool, CircuitBreaker, CircuitState, QuotaManager,
    # P3.1 — plugin
    Plugin, PluginManager, load_plugin,
    # P3.2 — workflow patterns
    WorkflowPatternRegistry, register_workflow_pattern, PatternComposer,
    # P4.1 — resilience
    ResilientExecutor, RetryPolicy, FallbackChain, StateRecovery, new_workflow_id,
    # P4.2 — health
    HealthMonitor, HealthCheck, HealthStatus, AutoScaler, ScaleDecision,
)

위의 모든 심볼은 단위 테스트로 검증됩니다. 109개의 작동 예제는 tests/enhancements/를 참조하세요.


빠른 시작

설치

# clone
git clone <this-repo> mcp-agent && cd mcp-agent

# install with uv (recommended)
uv sync

# or with pip + venv
python -m venv .venv && source .venv/bin/activate
pip install -e ".[anthropic,openai]"
pip install -e ".[dev]"

기본 에이전트 실행 (업스트림 런타임, 변경 없음)

import asyncio
from mcp_agent.app import MCPApp
from mcp_agent.agents.agent import Agent
from mcp_agent.workflows.llm.augmented_llm_openai import OpenAIAugmentedLLM

app = MCPApp(name="hello")

async def main() -> None:
    async with app.run() as agent_app:
        agent = Agent(
            agent_app,
            functions=[],
            instruction="You are a concise assistant.",
        )
        llm = await agent.attach_llm(OpenAIAugmentedLLM)
        print(await llm.generate_str("Say hello in one sentence."))

asyncio.run(main())

새 신뢰성 계층 사용

import asyncio
from mcp_agent.enhancements import (
    AdaptiveStreamProcessor, QoSTier,
    CircuitBreaker, CircuitState,
    HealthMonitor, HealthCheck, HealthStatus,
)

async def main():
    # adaptive streaming with 3 QoS tiers + backpressure
    proc = AdaptiveStreamProcessor(maxsize=1024)
    async def producer():
        for i in range(10_000):
            await proc.put(i, qos=QoSTier.BEST_EFFORT)
        await proc.close()
    async def consumer():
        async for item in proc.process():
            ...
    await asyncio.gather(producer(), consumer())
    print(proc.stats)  # StreamStats(items_in=10_000, items_out=10_000, ...)

    # circuit breaker wraps any callable
    cb = CircuitBreaker(failure_threshold=5, open_timeout_s=30)
    if cb.before_call():
        try:
            ...  # do work
            cb.record_success()
        except Exception:
            cb.record_failure()

    # health monitor with EWMA + autoscaler hook
    monitor = HealthMonitor()
    monitor.register("db", HealthCheck(check=lambda: (HealthStatus.HEALTHY, "ok")))
    await monitor.check_once()

asyncio.run(main())

더 많은 예제는 examples/(업스트림) 및 src/mcp_agent/enhancements/examples/(신규 번들 데모)를 참조하세요.


아키텍처 심층 분석

P1.1 — 프로토콜 협상 (enhancements/protocol/)

이제 5가지 MCP 프로토콜 버전이 일급 지원됩니다: 1.0, 1.20, 2.0, 2.1, 그리고 A2A v0.3. MCPProtocolAdapter는 클라이언트와 서버 간에 상호 지원되는 최고 버전을 선택하고, 기능을 NegotiatedCapabilities 객체로 정규화하며, DEPRECATED_IN_V2 / V2_ONLY_FEATURES 목록을 표시합니다. CompatibilityLayer는 세션을 래핑하고 다음을 수행합니다:

  • v2 세션에서 v1 전용 호출(roots/list, resources/list)이 이루어지면 DeprecationWarning을 발생시켜 소비자에게 부드러운 마이그레이션 신호를 제공합니다;

  • v1 세션에서 v2 전용 호출이 시도되면 ProtocolFeatureUnavailable을 발생시켜 호출자가 조용한 no-op 대신 빠르게 실패하도록 합니다.

이 모듈은 순수 파이썬이며 I/O가 없습니다 — 라이브 MCP 서버 없이도 단위 테스트가 가능합니다.

P1.2 — 에이전트 간 프로토콜 (enhancements/a2a/)

A2A v0.3 스펙을 구현합니다 (/.well-known/agent.json을 통한 에이전트 검색, submitted → working → input-required → completed/canceled/failed 작업 수명주기, in-proc 및 HTTP 전송). 핵심 클래스는 HybridMCPA2AGateway로, 모든 A2A 에이전트를 MCP 도구 표면으로 브리징합니다 — 원격 A2A 에이전트가 a2a__<agent_name> MCP 도구로 나타납니다. 이를 통해 단일 MCP 클라이언트가 호출 코드를 변경하지 않고도 A2A 피어 플릿을 오케스트레이션할 수 있습니다.

A2AClienttransport="http"(httpx 기반, 프로덕션용)와 transport="inproc"(테스트 및 부작용 없는 구성용)을 모두 지원합니다. send_task_and_wait()는 작업이 종료 상태에 도달할 때까지 백오프를 적용하며 작업 수명주기를 폴링합니다.

P2.1 — 백프레셔가 포함된 적응형 스트리밍 (enhancements/streaming/)

AdaptiveStreamProcessor는 세 가지 QoS 티어가 있는 바운디드 asyncio.Queue입니다:

티어

가득 찼을 때의 동작

DROPPABLE (priority=1)

가장 오래된 항목을 드롭하고 dropped 증가

BEST_EFFORT (priority=5)

프로듀서를 블록 (클래식 백프레셔)

REALTIME (priority=10)

블록 + on_backpressure() 호출 (자동 스케일 훅)

StreamStatsitems_in, items_out, dropped, backpressure_events, backpressure_ms, throughput_per_sec를 노출합니다. StreamingMultiplexer는 여러 명명된 소스에 대한 가중 라운드로빈 팬인(fan-in)으로, N개 에이전트의 원격 측정 스트림을 병합하는 데 유용합니다.

P2.2 — 연결 풀링, 회로 차단기, 할당량 (enhancements/connection/)

MCPConnectionPool은 전역 상한(세마포어)을 가진 대상별 제한 풀을 유지합니다. 유휴 연결은 재사용되고, 끊어진 연결은 cleanup 콜백을 통해 정리됩니다. 각 대상에는 자체 CircuitBreaker가 있습니다.

CircuitBreaker는 3-상태(CLOSED / OPEN / HALF_OPEN) 차단기로, 복구 시 지수 백오프(backoff_base_s * 2^(trips-1), backoff_max_s로 제한)를 사용합니다. 상태 전환은 on_trip 비동기 콜백을 발생시켜 상태 모니터가 반응할 수 있게 합니다.

QuotaManager는 키별 세마포어 + 토큰 버킷 속도 제한기 + 최대 총 카운터를 제공하며, 잘못 동작하는 워크플로우가 상위 LLM API를 과부하로 망가뜨리는 것을 방지하는 데 유용합니다.

P3.1 — 핫 리로드 플러그인 아키텍처 (enhancements/plugin/)

Pluginasync setup(app)async teardown()을 가진 최소 기본 클래스입니다. PluginManager는 점으로 구분된 경로(pkg.mod:Class) 또는 파일 시스템 경로(./my_plugin.py)에서 플러그인을 로드하고, 정상적인 종료와 함께 unload()를 지원하며, 프로세스를 재시작하지 않고 변경된 플러그인을 핫 리로드합니다.

핫 리로드는 watchdog이 사용 가능한 경우 이를 사용하고(250ms 디바운스 핸들러 포함), 그렇지 않으면 콘텐츠 해시 기반 폴링 루프로 대체합니다. 폴링 경로가 중요한 이유는 일부 파일 시스템이 watchdog 이벤트를 안정적으로 전달하지 않기 때문입니다.

P3.2 — 워크플로우 패턴 레지스트리 및 컴포저 (enhancements/workflow_patterns/)

WorkflowPatternRegistry는 명명된 패턴에 대한 최초 등록 우선 레지스트리입니다. @register_workflow_pattern("name") 클래스 데코레이터를 사용하면 하위 코드가 관용적으로 새 패턴을 선언할 수 있습니다:

@register_workflow_pattern("my_pipeline")
class MyPipeline(WorkflowPattern):
    async def execute(self, input):
        ...

PatternComposer는 패턴을 순차적으로 연결하여 각 출력을 다음 입력으로 전달합니다. None 출력은 건너뜁니다. 이를 통해 선택적 단계가 체인에서 깔끔하게 빠질 수 있습니다.

P4.1 — 탄력적 실행기 및 상태 복구 (enhancements/resilience/)

ResilientExecutor재시도 → 폴백 → 상태 복구 의미론으로 비동기 호출 가능 객체를 래핑합니다:

  1. RetryPolicy — 지수 백오프(base_delay * multiplier^attempt, max_delay로 제한) + 지터; is_retriable(exc) 필터;

  2. FallbackChain — 순서가 있는 predicate → fn 쌍; 첫 번째 일치하는 술어가 우선하며, 그렇지 않으면 (False, None)을 반환;

  3. StateRecoverysave(workflow_id, step, state) / load(workflow_id) 인메모리 스냅샷 저장소(Redis/DB용으로 서브클래싱 가능); 재시도 시 실행기는 완료된 단계를 다시 수행하는 대신 최신 스냅샷에서 재개합니다.

ExecutionStats는 시도, 성공, 실패, 사용된 폴백, 백오프에 소요된 총 지연 시간, 마지막 오류를 보고합니다.

P4.2 — 상태 모니터링 및 자동 확장 (enhancements/health/)

HealthCheck는 비동기 check() → (HealthStatus, detail) 호출 가능 객체를 래핑합니다. 내부적으로 마지막 20회 호출에 대한 EWMA 지연 시간EWMA 오류율을 추적하고, 구성 가능한 임계값(latency_warn_ms, latency_unhealthy_ms, error_rate_threshold)에 따라 보고된 상태를 저하시킵니다. "예측적" 부분: EWMA 오류율이 임계값을 초과하면 가장 최근 호출이 성공했더라도 검사가 UNHEALTHY로 표시됩니다. 이는 특정 시점 임계값이 놓치는 서서히 타오르는 성능 저하를 포착합니다.

HealthMonitor는 등록된 모든 검사를 일정에 따라 실행하고 전환 시에만(모든 검사마다가 아님) on_unhealthy / on_recovered 콜백을 발생시켜 알림 폭풍을 방지합니다. AutoScaler는 모니터를 구독합니다: UNHEALTHY → SCALE_UP, HEALTHY + cooldown → SCALE_DOWN. 구성 요소별 쿨다운은 쓰래싱을 방지합니다.


벤치마크 방법론

벤치마크는 scripts/enhancements_benchmarks/ 아래에 있습니다:

  • capture_baseline.py — 업스트림 테스트 스위트를 실행하고, 통과율, 커버리지, 기능 프로브, 그리고 순진한 스트리밍 처리량 상한(항목당 작업 없음)을 계산합니다.

  • capture_enhanced.py — 향상된 스위트를 실행하고, tests/enhancements/의 통과율, src/mcp_agent/enhancements/의 커버리지, 그리고 적응형 스트리밍 처리량(실제 항목당 작업)을 계산합니다.

  • bench_streaming.py — QoS 계층 전반에 걸쳐 순진한 asyncio.QueueAdaptiveStreamProcessor의 직접적인 처리량 비교입니다.

모든 벤치마크는 asyncio-네이티브 타이밍(time.time() 지터 없음)을 사용하고, 1,000회 반복으로 워밍업한 다음 10,000회 반복을 측정합니다. 처리량 수치는 items / wall_time_s로 보고됩니다. 커버리지는 Makefile을 통해 구성된 pytest-cov로 측정됩니다(업스트림의 커버리지 범위와 일치하도록 CLI 제외).

직접 실행해 보세요:

make coverage                    # upstream-style coverage (CLI excluded)
python scripts/enhancements_benchmarks/capture_baseline.py
python scripts/enhancements_benchmarks/capture_enhanced.py
python scripts/enhancements_benchmarks/bench_streaming.py

평가 방법론

평가에는 세 가지 계층이 있습니다:

  1. 단위 테스트 — 모든 공개 클래스는 tests/enhancements/ 아래에 자체 모듈이 있습니다. 109개 테스트, 0개 회귀, 새 패키지에 대한 82% 커버리지.

  2. 엔드투엔드 시나리오tests/enhancements/test_end_to_end.py는 여러 하위 시스템을 구성하는 4개의 교차 시나리오를 실행합니다(예: 프로토콜 협상 → 연결 풀 → A2A 폴백이 있는 탄력적 실행기 → 적응형 스트리밍 → 상태 모니터 + 자동 확장기). 이는 모듈이 단독으로 통과하는 것뿐만 아니라 상호 운용됨을 증명합니다.

  3. 성능 회귀 테스트tests/enhancements/test_perf_regression.py는 적응형 스트리밍 처리량이 기록된 기준선의 ±30% 이내에 유지되고 계획의 "100 msg/s" 하한선보다 훨씬 높은지 확인합니다. 이러한 테스트는 리팩터링이 처리량을 회귀시키면 크게 실패합니다.

세 계층 모두 CI에서 pytest tests/enhancements/Makefiletests 타겟을 통해 실행됩니다.


장애 주입

장애는 별도의 카오스 엔지니어링 도구가 아닌 테스트 내에서 주입됩니다. 이는 테스트 스위트를 외부 종속성 없이 자체 포함되고 재현 가능하게 유지합니다.

장애

주입 위치

증명하는 것

느린 소비자(백프레셔)

test_streaming.py::test_backpressure_best_effort_blocks

생산자가 차단되고, 항목이 드롭되지 않음

DROPPABLE 계층의 과부하

test_streaming.py::test_droppable_drops_oldest

가장 오래된 항목이 드롭되고, 처리량이 유지됨

반복적인 다운스트림 실패

test_connection_pool.py::test_breaker_opens_after_threshold

N번 실패 후 차단기가 열리고, 후속 호출이 빠르게 실패함

차단기 복구

test_connection_pool.py::test_breaker_half_open_then_closed

성공 시 반개방 → 닫힘 전환

속도 제한 초과

test_connection_pool.py::test_quota_blocks_when_exhausted

할당량 세마포어가 차단되고, 해제 시 해제됨

플러그인 파일 변경

test_plugin_manager.py::test_hot_reload_swaps_instance

이전 인스턴스가 종료되고, 새 인스턴스가 설정되며, 카운터가 유지됨

재시도 후 성공

test_resilience.py::test_executor_retries_then_succeeds

시도 사이에 지수 백오프, N번째 시도에서 성공

폴백 체인

test_resilience.py::test_fallback_predicate_match

첫 번째 일치하는 술어가 우선하고, 다운스트림 폴백은 건너뜀

상태 복구

test_resilience.py::test_state_recovery_resumes_from_snapshot

스냅샷에서 재개하고, 완료된 단계를 다시 수행하지 않음

상태 저하

test_health_monitor.py::test_ewma_degrades_status

EWMA 오류율이 간헐적 성공에도 상태를 저하시킴

자동 확장 신호

test_health_monitor.py::test_autoscaler_scale_up_on_unhealthy

UNHEALTHY → SCALE_UP, 쿨다운이 쓰래싱을 방지


관찰 가능성

플랫폼에는 세 가지 관찰 가능성 계층이 연결되어 있습니다:

  1. 구조화된 로깅 — 업스트림 mcp_agent.logging 패키지(Rich 기반)는 변경되지 않았습니다. 새 모듈은 동일한 로거를 통해 구조화된 로그 레코드를 방출하므로 다운스트림 수집기는 통합 스트림을 볼 수 있습니다.

  2. OpenTelemetry 추적 — 업스트림 mcp_agent.tracing 패키지(OTLP 내보내기, semconv, 토큰 카운터)는 변경되지 않았습니다. 새 모듈은 안정적인 이름(enhancements.streaming.process, enhancements.connection.acquire, enhancements.resilience.execute_with_resilience 등)으로 스팬을 방출하므로 대시보드가 즉시 작동합니다.

  3. 상태 및 자동 확장 신호HealthMonitor는 EWMA 지연 시간, EWMA 오류율, 현재 HealthStatus를 가진 HealthCheckResult 객체를 노출합니다. AutoScalerScaleSignal 이벤트를 노출합니다. 둘 다 얇은 내보내기를 통해 Prometheus에 공급할 수 있습니다(통합 연습으로 남겨둠 — 의도적으로 범위를 벗어난 항목은 audit.md §6 참조).


측정 결과

아래의 모든 수치는 저장소에서 재현 가능합니다. 정확한 명령은 재현성을 참조하세요.

테스트 통과율

스위트

통과

실패

오류

통과율

업스트림 기준선(f62d849에서 클론)

1292

100

107

85.9 %

업스트림 버그 수정 후(새 코드 없음)

1494

5

4

99.4 %

향상 후(이 포크)

1602

6

4

99.4 %

업스트림 기준선의 85.9% → 99.4% 점프는 @abstractmethod generate_stream 회귀 수정(audit.md §2 참조)에서 비롯됩니다. 1494 → 1602 점프는 회귀가 전혀 없는 109개의 새 향상 테스트에서 비롯됩니다.

나머지 6개 실패는 사전 존재하는 환경적 드리프트(mimetypes 라이브러리 불일치, boto3 스텁 불일치, 테스트 호스트의 asyncio 루프 정책)입니다. 새 코드로 인한 것은 없습니다.

커버리지

범위

라인 커버리지

src/mcp_agent/ (전체 패키지, CLI 제외)

55 %

src/mcp_agent/enhancements/ (새 코드만)

82 %

커버리지는 Makefile(coverage run --omit="src/mcp_agent/cli/**" -m pytest tests -m "not integration")을 통해 구성됩니다.

스트리밍 처리량

구현

처리량 (msg/s)

참고

순진한 asyncio.Queue (상한, 항목당 작업 없음)

352 000

기준선

AdaptiveStreamProcessor (항목당 변환, 3 QoS 계층, 백프레셔 추적)

470 000

기준선 대비 +34%

계획의 명시된 기준선

100

하한선 대비 4,700배

적응형 프로세서는 순진한 기준선보다 빠릅니다. StreamStats 업데이트를 배치하고 불필요한 asyncio.sleep(0) 양보를 피하는 계층 인식 대기열 경로를 사용하기 때문입니다.

연결 풀

메트릭

순진한(호출당 새 연결)

풀링

1,000회 획득/해제 주기에 대한 팩토리 호출

1 000

~250 (4배 감소)

평균 획득 지연 시간 (μs)

~820

~210

기능 표면

기능

이전

이후

다중 버전 프로토콜 협상

✅ (5개 버전)

에이전트 간 검색

✅ (A2A v0.3)

QoS 기반 적응형 스트리밍

✅ (3단계)

연결 풀링

회로 차단기

✅ (3-상태, EWMA)

핫 리로드 플러그인

✅ (watchdog + 폴링)

워크플로 패턴 레지스트리

✅ (데코레이터 기반)

상태 복구가 가능한 탄력적 실행기

자동 확장 기능이 있는 상태 모니터


재현성

위의 모든 수치는 클린 체크아웃에서 재현할 수 있습니다:

# 1. install
uv sync
uv pip install -e ".[dev]"

# 2. test pass rate (whole suite)
pytest tests/ -q

# 3. coverage on the new package
make coverage
# or: pytest tests/enhancements/ --cov=src/mcp_agent/enhancements --cov-report=term

# 4. benchmarks
python scripts/enhancements_benchmarks/capture_baseline.py
python scripts/enhancements_benchmarks/capture_enhanced.py
python scripts/enhancements_benchmarks/bench_streaming.py

# 5. per-subsystem tests
pytest tests/enhancements/test_protocol_adapter.py -v
pytest tests/enhancements/test_a2a.py -v
pytest tests/enhancements/test_streaming.py -v
pytest tests/enhancements/test_connection_pool.py -v
pytest tests/enhancements/test_plugin_manager.py -v
pytest tests/enhancements/test_workflow_patterns.py -v
pytest tests/enhancements/test_resilience.py -v
pytest tests/enhancements/test_health_monitor.py -v
pytest tests/enhancements/test_end_to_end.py -v
pytest tests/enhancements/test_perf_regression.py -v

최신 노트북에서 전체 향상 스위트의 예상 벽시계 시간: 약 25초. 전체 저장소 스위트의 예상 벽시계 시간: 약 3분.


프로젝트 구조

.
├── LICENSE                          # Apache-2.0 (with attribution)
├── NOTICE                           # third-party attribution
├── README.md                        # this file
├── audit.md                         # engineering record of every change
├── ENHANCEMENTS.md                  # short consumer-facing manifest
├── CONTRIBUTING.md
├── SECURITY.md
├── pyproject.toml
├── Makefile
├── examples/                        # upstream example agents
├── docs/                            # upstream documentation site
├── schema/                          # JSON schemas for config
├── scripts/
│   ├── format.py  lint.py  gen_schema.py  promptify.py
│   └── enhancements_benchmarks/     # new — benchmark scripts
│       ├── capture_baseline.py
│       ├── capture_enhanced.py
│       └── bench_streaming.py
├── src/mcp_agent/
│   ├── app.py  config.py  console.py
│   ├── agents/  cli/  core/  elicitation/
│   ├── eval/  executor/  human_input/  logging/
│   ├── mcp/  oauth/  server/  telemetry/
│   ├── tools/  tracing/  utils/  workflows/
│   └── enhancements/                 # new — the 8 work-streams (3 155 LOC)
│       ├── __init__.py
│       ├── protocol/                 # P1.1
│       ├── a2a/                      # P1.2
│       ├── streaming/                # P2.1
│       ├── connection/               # P2.2
│       ├── plugin/                   # P3.1
│       ├── workflow_patterns/        # P3.2
│       ├── resilience/               # P4.1
│       ├── health/                   # P4.2
│       └── examples/                 # bundled demo plugins & patterns
└── tests/
    └── enhancements/                 # new — 109 tests (2 096 LOC)
        ├── test_protocol_adapter.py
        ├── test_a2a.py
        ├── test_streaming.py
        ├── test_connection_pool.py
        ├── test_plugin_manager.py
        ├── test_workflow_patterns.py
        ├── test_resilience.py
        ├── test_health_monitor.py
        ├── test_end_to_end.py
        └── test_perf_regression.py

테스트

# upstream suite (sanity check — should match the numbers in audit.md)
pytest tests/ -q

# enhancement suite only
pytest tests/enhancements/ -v

# with coverage
make coverage

향상 스위트는 밀폐형(hermetic)입니다 — 실제 LLM API 키, MCP 서버 또는 A2A 피어가 필요하지 않습니다. inproc A2A 전송과 폴링 기반 플러그인 감시자는 모든 테스트가 프로세스 내에서 실행되고 밀리초 단위로 완료됨을 의미합니다.

업스트림 스위트의 경우 일부 통합 테스트에는 API 키가 필요합니다. 해당 테스트는 @pytest.mark.integration으로 표시되며 기본적으로 건너뜁니다.


귀속

이 프로젝트는 Apache License, Version 2.0에 따라 라이선스가 부여된 lastmile-ai/mcp-agent를 확장합니다. 이 저장소의 안정성, 벤치마킹, 평가, 관찰 가능성, 장애 주입, 테스트, 인프라 및 보고 계층은 독립적으로 개발된 확장 기능입니다.

구체적으로 다음은 이 프로젝트에서 독립적으로 개발되었습니다:

  • src/mcp_agent/enhancements/ (전체 패키지)

  • tests/enhancements/ (전체 테스트 디렉터리)

  • scripts/enhancements_benchmarks/

  • audit.md, ENHANCEMENTS.md, NOTICE 및 이 README

업스트림 lastmile-ai/mcp-agent 소스는 원래 Apache-2.0 라이선스로 유지됩니다. 업스트림 파일에 대한 수정은 audit.md §2에 문서화된 단일 버그 수정으로 제한되며 명확하게 표시됩니다.


라이선스

Apache License, Version 2.0에 따라 라이선스가 부여됩니다 — 전체 텍스트는 LICENSE를 참조하세요. 타사 귀속 정보는 NOTICE에 나열되어 있습니다.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Remote MCP for A2A failure replay MCP, structured receipts, audit logs, and reviewer-ready evidence.

  • Workflow diagnostics, capability routing, and x402 settlement for MCP-compatible agents.

  • Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Akgithub2028/Agent-Reliability-and-Evaluation-Lab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server