# A2A-gRPC 이중 계층 엣지 AIoT 멀티 에이전트 통신 프레임워크 ## 시스템 설계 명세 (System Design Specification) **버전**: 1.0.0 **작성일**: 2026-06-07 **대상 독자**: 분산 시스템 설계자, 엣지 AIoT 아키텍트, AI 에이전트 개발자 --- ## 목차 1. [설계 원칙](#1-설계-원칙-design-principles) 2. [시스템 아키텍처 개요](#2-시스템-아키텍처-개요) 3. [계층별 설계 명세](#3-계층별-설계-명세) 4. [T2 엣지 게이트웨이 상세 설계](#4-t2-엣지-게이트웨이-상세-설계) 5. [에이전트 상호작용 프로토콜](#5-에이전트-상호작용-프로토콜) 6. [데이터 흐름 설계](#6-데이터-흐름-설계) 7. [장애 내성 설계](#7-장애-내성-설계) 8. [멀티테넌시 설계](#8-멀티테넌시-설계) 9. [관측성 설계](#9-관측성-설계) 10. [사례별 설계 적용](#10-사례별-설계-적용) --- ## 1. 설계 원칙 (Design Principles) 본 시스템의 모든 아키텍처 결정은 다음 7가지 guiding principle에 근거한다. 각 원칙은 엣지 AIoT의 물리적 이질성과 다중 에이전트 협업의 복잡성에서 도출되었다. ### P1. Tier-Appropriate Protocol (계층 적합 프로토콜) 각 tier는 자신의 자원·연결성·전력 제약에 최적화된 프로토콜을 사용한다. T1 클라우드에는 gRPC/HTTP-2, T2 엣지에는 gRPC over QUIC, T3 현장 디바이스에는 MQTT/CoAP/BLE를 적용한다. **단일 프로토콜로 3-tier 전체를 포괄하려는 설계는 거부한다.** 이는 임베디드 디바이스에 gRPC 풀스택을 강제할 때 발생하는 RAM·Flash 초과 문제와, 클라우드 서버에 MQTT를 사용할 때 발생하는 스키마 안전성 부재 문제를 동시에 해결하는 근거다. ### P2. Semantic-Transport Separation (시맨틱-전송 분리) 에이전트 간 "무엇을 할 것인가(Task 위임·역량 광고)"와 "어떻게 전달할 것인가(Byte 전송)"를 명확히 분리한다. A2A/MCP는 시맨틱 계층에서 동작하고, gRPC/MQTT/CoAP는 전송 계층에서 동작한다. 이 분리는 전송 프로토콜을 교체해도 에이전트 협업 로직이 영향받지 않도록 보장한다. ### P3. Hardware-Rooted Identity (하드웨어 기반 신원) 네트워크 주소(IP, MAC)나 소프트웨어 토큰만으로는 물리적 디바이스의 신원을 보장할 수 없다. 모든 신원 클레임은 TPM/Secure Element의 하드웨어 attestation 또는 Kubernetes Service Account 바인딩에 뿌리를 두어야 한다. SPIFFE/SPIRE가 이 하드웨어 신원을 동적 SVID로 추상화하여 상위 계층에 전달한다. ### P4. Fail-Locally, Resume-Globally (국소 실패, 전역 재개) T3 디바이스와 T2 게이트웨이 사이의 단절은 예외가 아닌 정상 운영 조건이다. 단절 발생 시 T3 디바이스는 로컬 큐에 데이터를 보존하고, 재접속 시 Resume Token으로 마지막 위치부터 이어받는다. 이 원칙은 단절을 "복구해야 할 장애"가 아닌 "흡수해야 할 물리적 현실"로 취급한다. ### P5. Defense in Depth (다층 보안) 보안 통제는 인프라 계층(Envoy Service Mesh, mTLS)과 애플리케이션 계층(gRPC Interceptor, RBAC)에 중복 배치한다. 어느 한 계층이 우회되더라도 다른 계층이 보호를 지속한다. T3 디바이스의 물리적 접근 가능성을 고려하여, 디바이스 변조 시 즉시 SVID를 폐기할 수 있는 동적 인증서 회전 메커니즘을 포함한다. ### P6. Observable by Default (기본 관측성) 관측성(Tracing, Metrics, Logging)은 사후에 추가하는 기능이 아니라 프레임워크의 기본 구성 요소다. W3C traceparent는 T1→T2→T3 전 경로에 걸쳐 gRPC Metadata로 전파되며, T2 게이트웨이는 trace context의 fan-out 지점으로 작동한다. 관측성 없는 배포는 설계상 불가능하다. ### P7. Schema-First Interoperability (스키마 우선 상호운용) 다수의 디바이스 클래스, 언어, 런타임이 공존하는 환경에서 상호운용성은 Protocol Buffers `.proto` 파일을 단일 진실 원천(Single Source of Truth)으로 삼는 Contract-First 접근으로만 보장된다. Buf Schema Registry(BSR)와 `buf breaking` CI 검증이 OTA 업데이트 중에도 하위 호환성을 자동으로 강제한다. --- ## 2. 시스템 아키텍처 개요 ### 2.1 3-Tier 전체 조감도 ``` ╔══════════════════════════════════════════════════════════════════════════════╗ ║ T1: CLOUD TIER (k8s / GPU 서버 / 데이터센터) ║ ║ ║ ║ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ ║ ║ │ LLM Agent │ │ PM / Planner│ │ Analytics │ │ A2A Orchestrator │ ║ ║ │ (GPT/Claude│ │ Agent │ │ Agent │ │ (Task Registry) │ ║ ║ │ /Gemini) │ │ │ │ │ │ │ ║ ║ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ └────────┬─────────┘ ║ ║ └────────────────┴─────────────────┴──────────────────┘ ║ ║ │ A2A Protocol (Agent Cards / Tasks) ║ ║ ┌──────────────────────────────────────────────────────────────────────┐ ║ ║ │ Istio Service Mesh + Envoy Proxy + OTel Collector + SPIRE Server │ ║ ║ │ OAuth2 + JWKS mTLS (k8s SA SPIFFE ID) Prometheus + Jaeger │ ║ ║ └──────────────────────────────────────────────────────────────────────┘ ║ ╚══════════════════════════════════════════╦═══════════════════════════════════╝ ║ gRPC over QUIC (HTTP/3) / gRPC over HTTP/2 W3C traceparent in gRPC Metadata mTLS + SPIFFE SVID ║ ╔══════════════════════════════════════════╩═══════════════════════════════════╗ ║ T2: EDGE TIER (Jetson / RK3588 / 산업용 PC / 5G MEC) ║ ║ ║ ║ ┌──────────────────────────────────────────────────────────────────────┐ ║ ║ │ T2 EDGE GATEWAY (핵심 컴포넌트) │ ║ ║ │ │ ║ ║ │ ┌────────────┐ ┌─────────────┐ ┌──────────┐ ┌────────────────┐ │ ║ ║ │ │ Protocol │ │ Message │ │ Buffer / │ │ Resume Token │ │ ║ ║ │ │ Translator │ │ Normalizer │ │ Batcher │ │ Manager │ │ ║ ║ │ │ MQTT↔gRPC │ │ JSON↔Protob │ │ Fan-in │ │ (disconnect) │ │ ║ ║ │ └────────────┘ └─────────────┘ └──────────┘ └────────────────┘ │ ║ ║ │ ┌────────────┐ ┌─────────────┐ │ ║ ║ │ │ Device │ │ Metrics │ A2A Endpoint (SSE / Webhook) │ ║ ║ │ │ Auth Relay │ │ Collector │ gRPC Interceptor (Trace Inject) │ ║ ║ │ │ SVID Verify│ │ Prom→OTel │ │ ║ ║ │ └────────────┘ └─────────────┘ │ ║ ║ └──────────────────────────────────────────────────────────────────────┘ ║ ║ ║ ║ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────────────┐ ║ ║ │ Edge Infer. │ │ Local LLM │ │ Envoy Edge Proxy (xDS Light) │ ║ ║ │ Agent │ │ Agent │ │ SPIRE Agent + mTLS │ ║ ║ └──────────────┘ └──────────────┘ └──────────────────────────────────┘ ║ ╚══════════════════════════════════════════╦═══════════════════════════════════╝ ║ MQTT 5.0 / CoAP (Confirmable) ║ gRPC-Lite / nanopb BLE / Wi-Fi / LoRa / 5G NR ║ (고성능 임베디드) TPM/SE X.509 SVID ║ ║ ╔══════════════════════════════════════════╩═══════════════════════════════════╗ ║ T3: FIELD TIER (MCU / 임베디드 Linux / 로봇 / 센서 / AGV) ║ ║ ║ ║ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ ║ ║ │ Cortex-M │ │ AGV / │ │ CCTV / │ │ Smart │ │ Wearable / │ ║ ║ │ Sensor │ │ Robot │ │ Vision │ │ Meter │ │ Vital Mon. │ ║ ║ │ MQTT Pub │ │ gRPC-Lite│ │ gRPC │ │ MQTT │ │ BLE/MQTT │ ║ ║ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ ║ ║ ║ ║ [TPM/SE attestation] [X.509 SVID] [Offline Queue] [nanopb Protobuf] ║ ╚══════════════════════════════════════════════════════════════════════════════╝ ``` ### 2.2 3계층 프로토콜 스택 ``` ┌─────────────────────────────────────────────────────────────┐ │ Layer 3: Semantic Layer (시맨틱 계층) │ │ - A2A Protocol: Agent Card 광고, Task 위임·탐색 │ │ - MCP (Model Context Protocol): 도구/데이터 바인딩 │ │ - SSE / Webhook: 비동기 Task 상태 업데이트 │ ├─────────────────────────────────────────────────────────────┤ │ Layer 2: Transport Layer (전송 계층) │ │ - T1↔T2: gRPC over QUIC (HTTP/3) + Bidi Streaming │ │ - T2↔T2: gRPC Bidi Streaming (엣지 합의) │ │ - T2↔T3: MQTT 5.0 / CoAP Confirmable / gRPC-Lite │ │ - Retry Policy: Exponential Backoff + Jitter │ ├─────────────────────────────────────────────────────────────┤ │ Layer 1: Security / Identity Layer (보안/신원 계층) │ │ - T1: OAuth2 + mTLS (k8s SA 기반 SPIFFE ID) │ │ - T2: SPIFFE SVID + 하드웨어 시리얼 기반 identity │ │ - T3: TPM/SE attestation + X.509 SVID │ │ - 2계층 거버넌스: Envoy Service Mesh + gRPC Interceptor │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.3 Tier 간 연결 특성 요약 | 구간 | 전송 프로토콜 | 보안 | 지연 목표 | 단절 내성 | |------|------------|------|----------|----------| | T1 ↔ T2 | gRPC over HTTP/2 or QUIC | mTLS + SPIFFE SVID | < 100ms | Resume Token + QUIC conn-migration | | T2 ↔ T2 | gRPC Bidi Streaming | mTLS + SPIFFE SVID | < 10ms | 로컬 재연결 + Bidi 재확립 | | T2 ↔ T3 (임베디드) | MQTT 5.0 / CoAP | X.509 SVID + TLS-PSK | < 1s | MQTT Last Will + QoS 1/2 | | T2 ↔ T3 (고성능) | gRPC-Lite / nanopb | mTLS Lite | < 50ms | Resume Token | | T3 ↔ T3 | MQTT / C-V2X / BLE Mesh | 디바이스 pairwise key | < 10ms | 로컬 큐 | --- ## 3. 계층별 설계 명세 ### 3.1 시맨틱 계층 (A2A / MCP) #### 3.1.1 A2A Protocol 통합 A2A(Agent-to-Agent) Protocol은 에이전트가 서로의 역량을 발견하고 Task를 위임하는 표준 시맨틱 계층이다. 본 프레임워크에서 A2A는 다음과 같이 통합된다. **Agent Card 구조 (JSON)** ```json { "agent_id": "edge-inference-agent-t2-site-a", "tier": "T2", "capabilities": [ {"name": "visual_inspection", "modality": "vision", "latency_ms": 50}, {"name": "anomaly_detection", "modality": "timeseries", "latency_ms": 200} ], "endpoint": { "grpc": "grpcs://edge-site-a.internal:50051", "a2a_sse": "https://edge-site-a.internal:8443/a2a/events", "a2a_webhook": "https://edge-site-a.internal:8443/a2a/webhook" }, "device_class": "edge-gateway", "spiffe_id": "spiffe://edge/org/site-a/gateway/uuid-1234", "schema_version": "v1.2.0" } ``` **Task 위임 흐름** - T1 Orchestrator가 Agent Card Registry를 조회하여 대상 T2 에이전트 선택 - `POST /a2a/tasks` 로 Task 객체 전송 (submitted 상태) - T2 에이전트가 Task 수신 후 processing 상태로 전환 - SSE 또는 Webhook으로 상태 변화(submitted → working → completed/failed) 비동기 전달 - T2는 하위 T3 디바이스에 대해 동일한 A2A 엔드포인트를 노출하여, T3 디바이스도 A2A Task로 모델링 가능 **Rationale**: A2A가 직접 gRPC 메소드가 아닌 HTTP(S)/SSE 기반으로 설계된 이유는, 방화벽 통과 용이성과 브라우저 호환성을 확보하기 위함이다. 반면 실제 데이터 전송(모델 업데이트, 센서 스트리밍)은 gRPC를 통해 이루어져 성능을 보장한다. #### 3.1.2 MCP (Model Context Protocol) 통합 MCP는 LLM 에이전트가 외부 도구(Tool)와 데이터 소스에 바인딩되는 표준 인터페이스를 제공한다. ``` T1 LLM Agent │ ├── MCP Tool: "query_sensor_data" │ └── gRPC call → T2 Gateway → T3 Sensor │ ├── MCP Tool: "send_ota_command" │ └── gRPC Unary → T2 Gateway → T3 Device │ └── MCP Resource: "device_telemetry_stream" └── gRPC Server Streaming → T2 Gateway fan-out ``` MCP 도구 호출은 T2 게이트웨이의 gRPC 인터셉터를 통해 traceparent가 자동 주입되어, LLM 추론 요청부터 T3 센서 응답까지의 전체 경로가 단일 trace로 연결된다. ### 3.2 전송 계층 (gRPC / QUIC / MQTT) #### 3.2.1 gRPC 4대 RPC 모드 매핑 | RPC 모드 | 사용 시나리오 | Proto 예시 | |---------|------------|----------| | **Unary** | OTA 명령, 상태 조회, 설정 변경, A2A Task 결과 조회 | `rpc SendOTA(OTARequest) returns (OTAResponse)` | | **Server Streaming** | T1→T2 모델 업데이트, T1→T2 LLM 토큰 스트리밍, T2→T3 펌웨어 청크 | `rpc StreamModel(ModelRequest) returns (stream ModelChunk)` | | **Client Streaming** | T3→T2 센서 배치 업로드, OTA 청크 전송, 비디오 프레임 업로드 | `rpc UploadTelemetry(stream SensorData) returns (UploadResult)` | | **Bidi Streaming** | T2↔T2 엣지 합의, AGV 충돌 회피, V2V 안전 메시지 | `rpc Negotiate(stream ConsensusMsg) returns (stream ConsensusMsg)` | **Rationale**: Bidi Streaming을 T2↔T2 엣지 합의에 사용하는 이유는, 다수 엣지 노드가 단일 소켓을 통해 ms 단위의 상호 메시지 교환을 진행할 수 있어 소켓 수를 O(n²)에서 O(n)으로 줄이기 때문이다. #### 3.2.2 gRPC over QUIC (T1↔T2) T1↔T2 광역 무선 구간에서는 gRPC를 QUIC(HTTP/3) 위에 실어 다음 이점을 얻는다. - **Connection Migration**: 모바일 IP 변경 시(5G→Wi-Fi) TCP 연결 단절 없이 마이그레이션 - **0-RTT Handshake**: 재연결 시 0-RTT로 즉시 재개 (Resume Token과 시너지) - **HOLB-Free Multiplexing**: 여러 gRPC 스트림이 패킷 손실 시 상호 blocking 없이 독립적으로 재전송 ``` gRPC Frame └── HTTP/3 Frame └── QUIC Packet └── UDP Datagram └── 5G NR / LTE / Wi-Fi Physical ``` #### 3.2.3 T2↔T3 프로토콜 선택 기준 ``` T3 디바이스 특성 분류: RAM > 2MB? / \ YES NO (MCU/LoRa) │ │ gRPC-Lite? MQTT 5.0 or CoAP (nanopb) │ / \ QoS 요구도 높음? YES NO / \ │ │ YES NO gRPC-Lite MQTT 5.0 CoAP MQTT QoS 0 (고성능 임베디드) (일반 IoT) (Confirmable) (저전력 센서) ``` ### 3.3 보안/신원 계층 (SPIFFE/SPIRE) #### 3.3.1 SPIFFE ID 체계 각 tier의 SPIFFE ID는 계층적 네임스페이스로 설계하여, 정책 적용 시 와일드카드 매칭이 가능하도록 한다. ``` T1 클라우드 에이전트: spiffe://cluster.local/ns//sa//agent/ 예: spiffe://cluster.local/ns/ai-agents/sa/pm-agent/agent/pm-001 T2 엣지 게이트웨이: spiffe://edge///gateway/ 예: spiffe://edge/acme/factory-line-a/gateway/550e8400-e29b T3 현장 디바이스: spiffe://iot///device/ 예: spiffe://iot/acme/factory-line-a/device/agv-motor-ctrl-0042 ``` #### 3.3.2 Attestation 메커니즘 ``` T1: Kubernetes Service Account Token 검증 → SPIRE Server가 k8s API 통해 SA 존재 확인 → SVID 발급 (단기 X.509, TTL: 1시간) T2: 하드웨어 시리얼 + TPM PCR 측정값 attestation → SPIRE Agent가 TPM Quote 생성 후 SPIRE Server에 전송 → Server가 제조사 TPM EK Certificate Chain 검증 → SVID 발급 (TTL: 4시간, 자동 갱신) T3: TPM 2.0 / Secure Element attestation → Device가 SE에서 서명된 Device Certificate 생성 → T2 SPIRE Agent가 중계하여 SPIRE Server에 전송 → SVID 발급 (TTL: 24시간, 오프라인 시 Local CA 위임 가능) ``` #### 3.3.3 2계층 통신 거버넌스 ``` ┌──────────────────────────────────────────────────────┐ │ Layer 1: Infrastructure (Envoy / Service Mesh) │ │ - mTLS 종단(SPIFFE SVID 기반 인증서 자동 교체) │ │ - 카나리 라우팅, 글로벌 Rate Limiting │ │ - xDS Light로 T2 게이트웨이에 정책 push │ │ - Circuit Breaker, Health Check │ ├──────────────────────────────────────────────────────┤ │ Layer 2: Application (gRPC Interceptor) │ │ - 디바이스 클래스별 페이로드 크기·빈도 검증 │ │ - 디바이스 컨텍스트 전파 (battery_level, link_rssi) │ │ - 단절 시 Resume Token 발급·검증 │ │ - W3C traceparent 주입·추출 │ │ - Deadline 강제 주입 (디바이스 클래스별 정책) │ └──────────────────────────────────────────────────────┘ ``` **Rationale**: 2계층 분리의 핵심 이점은 관심사 분리다. Service Mesh는 인프라 팀이 제어하여 앱 변경 없이 네트워크 정책을 배포할 수 있고, gRPC Interceptor는 개발팀이 비즈니스 로직 수준에서 디바이스 컨텍스트를 활용할 수 있게 한다. T2 엣지 노드는 전체 Istio 대신 Envoy Mobile(xDS Light)로 경량화하여 제한된 자원 안에서 메쉬 기능을 구현한다. --- ## 4. T2 엣지 게이트웨이 상세 설계 T2 엣지 게이트웨이는 본 아키텍처의 핵심 허브다. 이 컴포넌트 하나가 3-tier 전체의 프로토콜 이질성, 보안 경계, 단절 복구, 관측성 집약을 담당한다. ### 4.1 컴포넌트 다이어그램 ``` T1 방향 (gRPC over QUIC / HTTP-2) │ ┌───────────────▼───────────────────────────────┐ │ gRPC Server (T1 facing) │ │ Unary / Server-Streaming / Client-Streaming │ └───────────────┬───────────────────────────────┘ │ ┌───────────────▼───────────────────────────────┐ │ Interceptor Chain (공통) │ │ [Auth] → [Trace Inject] → [Deadline] → │ │ [Rate Limit] → [Resume Token] → [Metrics] │ └───────────────┬───────────────────────────────┘ │ ┌──────────┬───────────┼───────────┬──────────────┐ ▼ ▼ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐ │Protocol│ │Message │ │ Buffer │ │ Resume │ │ Device │ │Transltr│ │Normalzr│ │Batcher │ │ Token │ │ Auth │ │ │ │ │ │ │ │ Manager │ │ Relay │ │MQTT │ │JSON │ │T3 fan-in│ │Offset │ │SVID │ │topic → │ │↕ │ │N msgs → │ │store │ │verify │ │gRPC │ │Protobuf│ │1 Stream │ │(Redis) │ │→ T1 mTLS │ │method │ │ │ │ │ │ │ │ │ └────┬───┘ └────────┘ └────┬────┘ └─────────┘ └──────────┘ │ │ └──────────┬───────────┘ ▼ ┌───────────────────────┐ ┌───────────────────────┐ │ MQTT Broker (Mosq.) │ │ CoAP Server │ │ T3 Pub/Sub 처리 │ │ Confirmable/Observe │ └───────────┬───────────┘ └───────────┬───────────┘ │ │ └──────────┬─────────────────┘ ▼ T3 방향 (MQTT / CoAP / BLE) ┌──────────────────────────────────────────────────┐ │ A2A Endpoint Server (HTTP/S) │ │ GET /a2a/agents → Agent Card 응답 │ │ POST /a2a/tasks → Task 위임 수신 │ │ GET /a2a/events (SSE) → Task 상태 스트리밍 │ │ POST /a2a/webhook → Task 상태 콜백 수신 │ └──────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────┐ │ Metrics Collector │ │ Prometheus Exporter → OTel Collector → Jaeger │ │ Custom Metrics: resume_token_count, │ │ protocol_translation_latency_ms, │ │ t3_connection_drops_total │ └──────────────────────────────────────────────────┘ ``` ### 4.2 6대 모듈별 책임 명세 #### Module 1: Protocol Translator (프로토콜 변환기) **책임**: T3 디바이스의 MQTT publish 메시지를 T1 방향 gRPC 메소드 호출로 변환, 반대 방향도 지원. **변환 규칙 예시**: ``` MQTT topic: iot/{org}/{site}/{device_serial}/telemetry ↓ 매핑 테이블 조회 gRPC method: SensorService.UploadTelemetry (Client Streaming) MQTT topic: iot/{org}/{site}/{device_serial}/command/ota ↓ gRPC method: DeviceService.SendOTA (Unary) ``` **구현**: Buf transcoding filter (`google.api.http` annotation 기반)를 사용하여 MQTT JSON 페이로드를 gRPC Protobuf로 자동 변환. 매핑 규칙은 YAML 설정 파일로 외부화하여 재배포 없이 업데이트 가능. #### Module 2: Message Normalizer (메시지 정규화기) **책임**: T3 디바이스의 JSON 페이로드와 T1/T2의 Protobuf 메시지 간 양방향 변환. 스키마 버전 불일치 처리. **스키마 진화 처리**: ``` 디바이스 펌웨어 v1.0 (구버전 JSON 스키마) ↓ Message Normalizer - BSR에서 현재 .proto 스키마 로드 - JSON 필드를 proto 필드에 매핑 - 신규 필드: proto default 값 채움 - 구버전 필드: Protobuf Any + schema descriptor로 보존 ↓ T1 에이전트 (최신 Protobuf) ``` #### Module 3: Buffer / Batcher (버퍼·배치 처리기) **책임**: T3 다수 노드의 fan-in 메시지를 집계하여 T1으로의 gRPC Streaming 효율을 최대화. **배치 정책**: - `max_batch_size`: 기본 100개 메시지 (디바이스 클래스별 재정의 가능) - `max_wait_ms`: 기본 50ms (지연 민감도 기준) - 배치 조건: `max_batch_size` 도달 OR `max_wait_ms` 경과 중 먼저 발생하는 조건 ``` T3 센서 x 10,000개 (각 1Hz) → Buffer: 50ms 수집 → 배치 = 최대 500개 메시지 → 단일 gRPC Client Streaming으로 T1 전달 (소켓 수: 10,000개 → 1개) ``` #### Module 4: Resume Token Manager (재개 토큰 관리자) **책임**: T3↔T2 또는 T2↔T1 단절 발생 시 스트리밍 위치를 저장하고, 재접속 시 이어받기를 지원. **Resume Token 구조**: ```json { "stream_id": "telemetry-stream-agv-0042-20260607T120000Z", "last_offset": 8192, "last_sequence": 1024, "traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "device_id": "spiffe://iot/acme/line-a/device/agv-0042", "issued_at": "2026-06-07T12:00:00Z", "ttl_seconds": 300 } ``` Resume Token은 Redis(T2 로컬)에 저장되어 게이트웨이 재시작 후에도 유효하다. TTL 초과 시 클라이언트는 전체 재동기화(full resync)를 수행한다. #### Module 5: Device Auth Relay (디바이스 인증 중계기) **책임**: T3 디바이스의 X.509 SVID를 T2에서 검증하고, T1에는 T2 자체 SVID로 mTLS 재인증을 수행. ``` T3 Device (X.509 SVID) → TLS 핸드셰이크 │ T2 Auth Relay 1. T3 SVID 인증서 Chain 검증 (SPIRE CA 루트) 2. SPIFFE ID SAN 추출 및 권한 확인 3. 디바이스 클래스 / 테넌트 매핑 4. gRPC Metadata에 X-Device-SPIFFE-ID 주입 │ T1 방향 gRPC (T2 SVID로 mTLS) ``` **Rationale**: T3 디바이스가 T1까지 직접 mTLS 연결을 맺을 경우, 클라우드 SPIRE Server가 수만 개 T3 디바이스의 SVID를 직접 관리해야 한다. T2가 인증 중계를 담당함으로써 T1은 T2 수준의 소수 연결만 관리하고, T3의 신원 폭발적 증가를 T2에서 흡수한다. #### Module 6: Metrics Collector (메트릭 수집기) **책임**: T2 게이트웨이의 운영 메트릭을 수집하여 T1 OTel Collector로 전송. **수집 메트릭 목록**: ``` # Gateway 운영 메트릭 grpc_requests_total{method, status, device_class} grpc_request_duration_seconds{method, p50, p95, p99} protocol_translation_latency_ms{from_protocol, to_protocol} buffer_queue_depth{device_class} resume_token_issued_total resume_token_consumed_total t3_connection_active{protocol} t3_connection_drops_total{reason} # 디바이스 상태 메트릭 (T3 telemetry 집계) device_battery_level{device_id, class} device_link_rssi{device_id, interface} device_message_rate_hz{device_id} ``` --- ## 5. 에이전트 상호작용 프로토콜 ### 5.1 A2A Task 생명주기 ``` 상태 전이: submitted → working → completed → failed → cancelled (T1 요청 또는 타임아웃) ``` ### 5.2 T1 Orchestrator → T2 Edge Agent Task 위임 시퀀스 ``` T1 Orchestrator T2 Edge Gateway T3 AGV Agent │ │ │ │ 1. GET /a2a/agents │ │ │ ───────────────────> │ │ │ <─ Agent Card (JSON) ──│ │ │ │ │ │ 2. POST /a2a/tasks │ │ │ {task: "visual_inspection", │ │ input: {zone: "line-a"}, │ │ deadline: "2026-06-07T12:00:30Z"} │ │ ───────────────────> │ │ │ <─ {task_id, status: "submitted"} ── │ │ │ │ │ 3. GET /a2a/events │ │ │ (SSE connection) │ │ │ ───────────────────> │ │ │ │ 4. gRPC Unary │ │ │ SendCommand │ │ │ (start_inspection) │ │ │ ──────────────────────> │ │ │ <── (ack) ─────────────-│ │ │ │ │ 5. SSE event: │ │ │ {status: "working"} │ │ │ <─────────────────── event stream ── │ │ │ │ │ │ │ (검사 수행) │ │ │ │ │ 6. gRPC Client Stream │ │ │ UploadInspectionData │ │ │ <────────────────────── │ │ │ (프레임 x N chunks) │ │ │ │ │ 7. SSE event: │ │ │ {status:"completed",│ │ │ result: {defects: │ │ │ [{zone: "A2", ...}]│ │ │ <─────────────────── event stream ── │ │ │ │ │ 8. POST /a2a/tasks │ │ │ /{task_id}/ack │ │ │ ───────────────────> │ │ ``` ### 5.3 T2↔T2 엣지 합의 시퀀스 (AGV 충돌 회피) ``` T2 Gateway A T2 Gateway B (AGV 라인 A 담당) (AGV 라인 B 담당) │ │ │ gRPC Bidi Streaming: Negotiate() │ │ ─────────────────────────────────────> │ │ <──────────────── (stream established) ─ │ │ │ │ ConsensusMsg { │ │ type: POSITION_CLAIM, │ │ zone: "intersection-01", │ │ agv_id: "agv-0042", │ │ priority: EMERGENCY │ │ } │ │ ─────────────────────────────────────> │ │ │ │ ConsensusMsg { │ │ type: ACK_DEFER, │ │ zone: "intersection-01", │ │ deferred_agv: "agv-0099",│ │ wait_ms: 200 │ │ } │ │ <───────────────────────────────────── │ │ │ │ [T2-A: AGV-0042에 통과 명령 전송] │ │ [T2-B: AGV-0099에 대기 명령 전송] │ ``` **지연 보장**: T2↔T2 Bidi Streaming은 엣지 LAN 내에서 동작하며, p99 latency < 10ms 목표를 달성하기 위해 gRPC Keepalive 간격을 5초, deadline을 10ms로 설정한다. --- ## 6. 데이터 흐름 설계 ### 6.1 T3 센서 → T1 LLM 에이전트 전체 경로 ``` T3: 진동 센서 (Cortex-M, MQTT) │ │ [1] MQTT Publish │ Topic: iot/acme/line-a/vib-sensor-0017/telemetry │ Payload: {"ts":1749298800, "axis_x": 2.31, "axis_y": 1.05} │ QoS: 1, Retained: false │ ▼ T2: Edge Gateway (MQTT Broker 수신) │ │ [2] Protocol Translator 처리 │ MQTT topic → gRPC method 매핑 │ device_serial: vib-sensor-0017 추출 │ │ [3] Message Normalizer 처리 │ JSON → SensorTelemetry Protobuf 변환 │ message SensorTelemetry { │ string device_id = 1; // spiffe://iot/... │ int64 timestamp_ms = 2; │ repeated float values = 3; │ DeviceContext context = 4; // battery, rssi │ } │ │ [4] Device Auth Relay │ T3 SVID 검증 완료 │ gRPC Metadata 추가: │ x-device-spiffe-id: spiffe://iot/acme/line-a/device/vib-sensor-0017 │ x-device-class: sensor-vibration │ x-site-id: line-a │ traceparent: 00---01 │ │ [5] Buffer / Batcher │ 수집: vib-sensor-0001 ~ vib-sensor-5000 (50ms 대기) │ 배치 크기: 3,200개 메시지 → 1개 gRPC Client Stream │ │ [6] Interceptor Chain │ Deadline: 5,000ms 주입 │ Rate Limit: site-a 쿼터 확인 (500k msg/s 이하) │ Resume Token: 이전 스트림 위치 확인 │ ▼ gRPC Client Streaming → T1 (HTTP/3 over QUIC) │ Service: TelemetryIngestionService.BatchUpload │ gRPC Metadata: traceparent, x-tenant-id, x-site-id │ ▼ T1: Telemetry Ingestion Service (k8s Pod) │ │ [7] Stream Receiver │ Protobuf Deserialize │ DB Write: TimescaleDB / ClickHouse │ Publish: Kafka topic "telemetry.line-a.vibration" │ ▼ T1: Anomaly Detection Agent (subscribes Kafka) │ │ [8] Feature Extraction │ FFT 분석, 통계 특징 추출 │ │ [9] LLM 에이전트 호출 (MCP Tool) │ Tool: "analyze_vibration_anomaly" │ Input: {features: [...], device_id: "vib-sensor-0017"} │ │ [10] LLM 추론 │ "vib-sensor-0017 베어링 마모 징후 감지 (p=0.92)" │ │ [11] A2A Task 발행 │ POST /a2a/tasks → T2 Maintenance Agent │ {task: "schedule_maintenance", device: "vib-sensor-0017"} │ ▼ T2: Maintenance Agent → T3: Maintenance Robot 파견 ``` ### 6.2 긴급 이벤트 역방향 경로 (T3 → T1, < 1s) 긴급 이벤트(낙상 감지, 이상 전압, 충돌 위험)는 배치 경로를 우회하여 직접 전달된다. ``` T3 Emergency Event → MQTT QoS 2 (exactly-once) Publish → T2 Buffer/Batcher: EMERGENCY flag 감지 → 즉시 flush (배치 대기 없음) → T2 Interceptor: Priority Header 주입 (grpc-priority: critical) → gRPC Unary: EmergencyService.Alert (Deadline: 500ms) → T1 Alert Service → PagerDuty / SMS / LLM 에이전트 즉시 호출 ``` --- ## 7. 장애 내성 설계 ### 7.1 Resume Token 상세 설계 Resume Token은 단순 offset이 아닌, 재접속 시 trace 연속성까지 보장하는 복합 구조체다. ```protobuf message ResumeToken { string stream_id = 1; string device_spiffe_id = 2; int64 last_offset = 3; int64 last_sequence_number = 4; string traceparent = 5; // W3C traceparent (trace 연속성) int64 issued_at_ms = 6; int32 ttl_seconds = 7; bytes hmac_signature = 8; // T2 비밀키로 서명 (위조 방지) } ``` **재접속 시퀀스**: ``` T3 Device (재접속) │ │ gRPC Metadata: resume-token: │ ─────────────────────────────────────────────────> │ T2 Resume Token Manager 1. HMAC 서명 검증 (위조 방지) 2. TTL 만료 확인 3. SPIFFE ID 일치 확인 4. last_offset 이후부터 스트림 재개 5. 기존 traceparent 유지 (단절 구간도 같은 trace로 연결) │ │ <── {status: "resumed", from_offset: 8193} ───── ``` ### 7.2 Deadline 정책 디바이스 클래스별 기본 Deadline은 gRPC Interceptor에서 자동 주입된다. 애플리케이션 코드에서 Deadline을 설정하지 않아도 인터셉터가 강제 적용한다. | 디바이스 클래스 | RPC 유형 | 기본 Deadline | 근거 | |--------------|---------|-------------|------| | AGV / Robot | Bidi Streaming (합의) | 10ms | 충돌 회피 SLA | | AGV / Robot | Unary (명령) | 50ms | 제어 루프 주기 | | IoT 센서 | Client Streaming (배치) | 5,000ms | 배치 처리 허용 | | IoT 센서 | Unary (상태 조회) | 1,000ms | 단순 조회 | | 차량 (V2X) | Unary (안전 메시지) | 10ms | ETSI ITS 요구 | | 웨어러블 | Unary (긴급 알림) | 500ms | 헬스케어 SLA | | 웨어러블 | Client Streaming (일반) | 10,000ms | 배터리 절약 배치 | ### 7.3 Retry Policy ```yaml # gRPC Service Config (T1 클라이언트에 적용) methodConfig: - name: [{service: "TelemetryIngestion"}] retryPolicy: maxAttempts: 4 initialBackoff: "0.1s" maxBackoff: "2s" backoffMultiplier: 2.0 retryableStatusCodes: [UNAVAILABLE, RESOURCE_EXHAUSTED] timeout: "10s" - name: [{service: "EmergencyAlert"}] retryPolicy: maxAttempts: 3 initialBackoff: "0.01s" maxBackoff: "0.1s" backoffMultiplier: 2.0 retryableStatusCodes: [UNAVAILABLE] timeout: "0.5s" # 긴급 알림은 짧은 timeout ``` **Hedging Policy** (지연 민감 경로용): 안전 메시지나 긴급 알림처럼 첫 번째 응답이 중요한 경우, hedgedDelay 내 응답이 없으면 두 번째 요청을 병렬 전송한다. ```yaml hedgingPolicy: maxAttempts: 2 hedgingDelay: "5ms" nonFatalStatusCodes: [UNAVAILABLE] ``` ### 7.4 Circuit Breaker (장애 전파 차단) T3 디바이스 군집 중 일부가 비정상 상태일 때, 장애가 T2→T1으로 전파되는 것을 차단한다. ``` Envoy Circuit Breaker 설정: - max_connections: 1024 (T2↔T1) - max_pending_requests: 512 - max_requests: 2048 - max_retries: 50 - consecutive_5xx: 5 → OPEN (10s 후 HALF-OPEN) ``` T2 게이트웨이 자체 Circuit Breaker는 T3 디바이스 클래스별로 독립 인스턴스를 운용하여, 특정 디바이스 클래스의 대량 실패가 다른 클래스에 영향주지 않도록 격리한다. --- ## 8. 멀티테넌시 설계 ### 8.1 테넌트 식별 구조 ``` gRPC Metadata 필수 헤더 (모든 RPC): x-tenant-id: x-site-id: x-device-class: [sensor|robot|agv|vehicle|wearable|gateway] x-device-spiffe-id: ``` SPIFFE ID의 계층 구조가 테넌트 분리와 직결된다. `spiffe://iot//...` 패턴에서 ``가 테넌트 경계를 정의하고, Envoy의 RBAC 정책이 이를 기반으로 크로스-테넌트 접근을 차단한다. ### 8.2 디바이스 클래스별 쿼터 ``` T3 IoT 센서: - 메시지 빈도: 분당 120건/디바이스 (2Hz) - 페이로드 크기: 최대 4KB/메시지 - OTA 업데이트: 시간당 1회 - 초과 시: gRPC RESOURCE_EXHAUSTED (코드 8) 반환 T3 AGV / 산업 로봇: - 안전 메시지: 초당 100건 (우선 처리, 쿼터 예외) - 일반 텔레메트리: 분당 600건 - 동시 Bidi 스트림: 최대 4개 - 초과 시: 일반 메시지만 throttle, 안전 메시지 보장 T3 차량 (V2X): - V2I 안전 메시지: 쿼터 없음 (항상 우선) - HD맵 업데이트 다운로드: 100MB/시간 - 진단 데이터 업로드: 10MB/시간 T3 웨어러블: - 연속 모니터링: 분당 60건 (1Hz) - 긴급 이벤트: 쿼터 없음 - 배터리 절약 배치: 6시간마다 일괄 업로드 허용 T2 엣지 게이트웨이: - 동시 추론 세션: 최대 8개 (NPU 점유) - T3 동시 접속 디바이스: 최대 10,000개 - T1 방향 gRPC 연결: 최대 16개 (멀티플렉싱으로 충분) ``` ### 8.3 RBAC 설계 ``` 역할 계층: system:admin → 전체 테넌트 관리 tenant:admin → 단일 테넌트 전체 site:operator → 특정 사이트 운영 device:reader → 읽기 전용 (모니터링) device:controller → 명령 전송 가능 agent:orchestrator → A2A Task 위임 가능 agent:executor → A2A Task 실행 가능 (수신 전용) gRPC Method → Role 매핑 예시: DeviceService.SendOTA → device:controller 이상 TelemetryService.StreamRead → device:reader 이상 AgentService.DelegateTask → agent:orchestrator 이상 EmergencyService.Alert → device:controller 이상 또는 T3 device 본인 ``` RBAC 정책은 Envoy의 External Authorization (ext_authz) 필터를 통해 OPA(Open Policy Agent)로 위임하여 동적 업데이트를 가능하게 한다. --- ## 9. 관측성 설계 ### 9.1 분산 추적 (Distributed Tracing) **traceparent 전파 경로**: ``` T1 LLM Agent [trace-id: aabbccdd, span-id: 0001] │ │ gRPC Metadata: traceparent: 00-aabbccdd-0001-01 ▼ T2 Edge Gateway (Interceptor: extract → span 생성) [trace-id: aabbccdd, span-id: 0002, parent: 0001] │ ├── A2A Task 위임 → T2 Agent │ [trace-id: aabbccdd, span-id: 0003, parent: 0002] │ └── MQTT Publish → T3 Device (traceparent을 MQTT User Property로 전달) [trace-id: aabbccdd, span-id: 0004, parent: 0002] │ │ T3 응답 수신 시 span 종료 └── Resume Token에 traceparent 임베드 (단절 후 재접속 시 동일 trace로 연속) ``` T2 게이트웨이는 **trace fan-out 지점**으로, T3 디바이스가 OTel SDK를 탑재하지 않아도 T2가 T3 span을 대신 생성하여 전체 호출 그래프에 포함시킨다. ### 9.2 메트릭 체계 **수집 계층**: ``` T3 디바이스: 자체 메트릭 없음 (T2가 대행) ↓ T2 게이트웨이: Prometheus Exporter (포트 9090) ↓ (scrape 또는 OTLP push) T2 OTel Collector: 집계 + 샘플링 + 재전송 ↓ (OTLP gRPC) T1 OTel Collector: 중앙 집계 ↓ Prometheus (장기 저장) ← Grafana Dashboard Jaeger (트레이스 저장) ← Grafana Tempo ``` **SLO 알람 기준**: | 메트릭 | 경고 임계 | 심각 임계 | |--------|---------|---------| | T2 Gateway p99 translation latency | > 50ms | > 100ms | | T3 connection drop rate | > 5% / min | > 20% / min | | Resume token TTL 만료율 | > 1% | > 5% | | gRPC UNAVAILABLE error rate | > 1% | > 5% | | A2A Task failure rate | > 2% | > 10% | ### 9.3 구조화 로그 모든 로그는 JSON 구조화 형식으로 출력하며, traceparent와 SPIFFE ID를 필수 필드로 포함한다. ```json { "timestamp": "2026-06-07T12:00:00.123Z", "level": "INFO", "service": "t2-edge-gateway", "site_id": "factory-line-a", "trace_id": "aabbccdd1122334455667788", "span_id": "0002aabb", "device_spiffe_id": "spiffe://iot/acme/line-a/device/agv-0042", "event": "protocol_translation_completed", "from_protocol": "mqtt", "to_protocol": "grpc", "latency_ms": 1.2, "batch_size": 1024 } ``` --- ## 10. 사례별 설계 적용 ### 10.1 스마트 팩토리 (Industry 4.0) **핵심 통신 요구**: AGV 충돌 회피 p99 < 10ms, 다수 센서 fan-in (10k 노드 × 1Hz), OTA 결함 내성 | 구성 요소 | 설계 선택 | 근거 | |---------|---------|------| | AGV↔T2 | gRPC Bidi Streaming | ms 단위 충돌 회피 합의, 단일 소켓 재활용 | | 센서→T2 | MQTT QoS 1 + T2 Batcher | 10k 동시 접속, 배치로 gRPC fan-out 최소화 | | T2↔T1 | gRPC Client Streaming | 배치 업로드, 백프레셔로 T1 과부하 방지 | | OTA | gRPC Server Streaming + Resume Token | 네트워크 단절 시 청크 이어받기 | | 디바이스 신원 | TPM + SPIRE | 로봇 물리 변조 대응, 동적 SVID 폐기 | | 합의 Deadline | 10ms | AGV 충돌 회피 SLA 준수 | **A2A 역할 분담**: - T1 PM Agent: 생산 계획 → T2 Line Agent에 작업 Task 위임 (A2A) - T2 Line Agent: 라인별 AGV 집단 제어, 품질 이상 감지 시 T1에 알림 - T3 AGV Agent (경량): gRPC-Lite로 T2와 통신, 로컬 충돌 회피 실행 ### 10.2 스마트 빌딩 / 에너지 **핵심 통신 요구**: 저전력 무선(LoRa/Zigbee) 지원, 피크 수요 절감을 위한 HVAC 협업, 5~15분 주기 배치 | 구성 요소 | 설계 선택 | 근거 | |---------|---------|------| | 스마트 미터→T2 | MQTT QoS 0 + LoRa 브릿지 | 저전력, 1회/5분 허용 | | HVAC 협업 | gRPC Unary (빠른 명령) + T2 내부 합의 | 피크 절감 응답 < 100ms | | PV 인버터→T2 | Modbus/MQTT 브릿지 → T2 변환 | 레거시 프로토콜 통합 | | T2↔T1 | gRPC Server Streaming | 에너지 최적화 모델 실시간 수신 | | 긴급 차단 | gRPC Unary Deadline 50ms | 과전압 즉시 차단 | **A2A 역할 분담**: - T1 Energy Optimizer Agent: DR(수요 반응) 신호 수신 → T2 Building Agent에 절감 목표 Task 위임 - T2 Building Agent: HVAC/조명/EV 충전기 협업, 피크 절감 최적화 ### 10.3 커넥티드 차량 / V2X **핵심 통신 요구**: 핸드오버 무중단(QUIC), V2V 안전 메시지 < 10ms, HD맵 OTA | 구성 요소 | 설계 선택 | 근거 | |---------|---------|------| | T3 차량↔T2 RSU | C-V2X / ITS-G5 + gRPC at RSU | ETSI ITS 표준 준수 | | T2 RSU↔T1 | gRPC over QUIC | 5G 핸드오버 시 connection migration | | V2V (차량간) | QUIC datagram 멀티캐스트 | 브로드캐스트 안전 메시지, HOLB 없음 | | HD맵 업데이트 | gRPC Server Streaming + Resume Token | 대용량 맵 데이터, 단절 이어받기 | | 디바이스 신원 | V2X PKI + SPIRE 통합 | ITS 인증서 표준과 SPIFFE ID 브릿지 | **A2A 역할 분담**: - T1 Traffic Management Agent: 교통 흐름 최적화 → T2 RSU Agent에 속도 제한 Task 위임 - T2 RSU Agent: 실시간 V2I 메시지 배포, 사고 감지 시 T1 긴급 알림 ### 10.4 헬스케어 / 원격 모니터링 **핵심 통신 요구**: 배터리 수명 최대화, 24h 연속 모니터링, 이상 이벤트 < 1s T1 전달 | 구성 요소 | 설계 선택 | 근거 | |---------|---------|------| | 웨어러블→T2 | BLE/Wi-Fi + MQTT QoS 1 | 저전력, Last Will로 연결 단절 감지 | | 연속 데이터 | Client Streaming + 6시간 배치 | 배터리 절약 duty cycle | | 긴급 이벤트 | MQTT QoS 2 → 즉시 flush → gRPC Unary | exactly-once + < 1s T1 도달 보장 | | 환자 데이터 보호 | HIPAA-ready: AES-256 in-transit + at-rest | 의료 데이터 컴플라이언스 | | 디바이스 신원 | TPM/SE + SPIRE | 환자 안전 디바이스 변조 방지 | **A2A 역할 분담**: - T1 Clinical AI Agent: EHR 데이터 + T2 집계 데이터로 임상 추론 - T2 Hospital Edge Agent: 낙상/부정맥 로컬 감지(< 100ms), T1에 A2A Task로 알림 - T3 Wearable: 센서 수집 + 로컬 오프로드 큐 (BLE 단절 대비) ### 10.5 사례별 프로토콜 매트릭스 종합 | 설계 항목 | 스마트 팩토리 | 스마트 빌딩 | V2X | 헬스케어 | |---------|------------|-----------|-----|--------| | T1↔T2 백본 | gRPC + HTTP/2 | gRPC + 유선/4G | gRPC + QUIC (5G) | gRPC + 유선 | | T2↔T3 현장 | MQTT 5.0 / gRPC-Lite | MQTT + LoRa 브릿지 | C-V2X / ITS-G5 | BLE + MQTT | | 저지연 합의 | gRPC Bidi (AGV) | gRPC Unary (HVAC) | QUIC datagram | gRPC Unary (이벤트) | | 핸드오버 | Resume Token | Resume Token | QUIC conn-migration | Resume Token | | 디바이스 신원 | TPM + SPIRE | SE + SPIRE | V2X PKI + SPIRE | TPM/SE + SPIRE | | 저전력 대응 | N/A | MQTT QoS 0 + sleep | N/A | BLE duty cycle | | 긴급 이벤트 | gRPC Stream 알림 | gRPC Unary 알림 | C-V2X CAM/DENM | gRPC Unary < 1s | | A2A 위임 방향 | T1→T2→T3 계층 | T1→T2 목표 기반 | T1 교통→T2 RSU | T2 감지→T1 임상 | --- ## 부록: Proto 설계 가이드라인 본 프레임워크에서 `.proto` 파일을 작성할 때 준수해야 할 설계 원칙은 다음과 같다. 1. **모든 메시지에 `DeviceContext` 포함**: 배터리 수준, RSSI, 펌웨어 버전을 표준 필드로 정의하여 관측성을 기본화한다. 2. **`oneof` 활용**: 디바이스 클래스별 가변 페이로드는 `oneof payload { SensorData sensor = 10; RobotStatus robot = 11; ... }` 구조로 타입 안전하게 설계한다. 3. **필드 번호 예약**: 삭제된 필드 번호를 `reserved`로 표시하여 OTA 업데이트 중 구버전 디바이스의 역직렬화 오류를 방지한다. 4. **BSR 등록 필수**: 모든 `.proto`는 Buf Schema Registry에 등록하고, `buf breaking` CI 체크를 PR 조건으로 강제한다. 5. **서비스별 패키지 분리**: `iot.telemetry.v1`, `iot.command.v1`, `agent.a2a.v1` 등 기능 도메인별로 패키지를 분리하여 독립적 버전 관리를 가능케 한다. --- *본 설계 문서는 FINAL_REPORT.md의 연구 결과를 바탕으로 작성되었으며, 실제 구현 시 각 사이트의 물리적 환경과 규제 요구사항에 맞게 조정되어야 한다.*