Skip to content

SYSTEM_DESIGN

playground edited this page Jun 10, 2026 · 4 revisions

Physical AI Exhibition — 시스템 설계 문서

프로젝트 코드명: 2026-zerone 버전: 0.1 (Initial Draft) 작성일: 2026-04-28


1. 개요

1.1 목적

하나의 전시 공간을 4개의 테마 영역(카페, 공원, 차량, 집안 실내)으로 분할하고, 2대의 이종(異種) 로봇과 3대의 체험자 태블릿, 그리고 CCTV 기반 비전 추적을 결합하여 사용자의 컨텍스트(기분·동선·환경)에 적응적으로 반응하는 Physical AI 인터랙션을 연출한다.

1.2 핵심 도전 과제

  • 이종 로봇 추상화: SPOT(Boston Dynamics)과 미정 로봇을 단일 명령 인터페이스로 통합.
  • 실시간 컨텍스트 융합: CCTV 추적, 사용자 입력, 환경 데이터, 로봇 텔레메트리를 하나의 일관된 상태(state)로 유지.
  • LLM(Large Language Model, 대규모 언어 모델)의 결정론적 운영: 비결정적 LLM 출력을 안전한 로봇 명령 집합으로 제약(guardrail).
  • 물리적 안전성: 사용자와 로봇이 물리적으로 같은 공간에 존재하는 환경에서의 e-stop(emergency stop, 긴급 정지)·충돌 회피.

1.3 비기능 요구사항 (NFR)

항목 목표
사용자 입장 감지 → 로봇 반응 시작 < 1.5s end-to-end
태블릿 명령 → 로봇 동작 시작 < 800ms
LLM 의사결정 (도구 호출 포함) p95 < 2.5s
시스템 가용성 (전시 운영시간 기준) 99.5%
CCTV 추적 정확도 (공간 단위 in/out) > 98%
동시 체험자 최대 3명 (태블릿 수와 동일)

2. 상위 아키텍처

┌─────────────────────────────────────────────────────────────────────┐
│                       Exhibition Site (LAN)                         │
│                                                                     │
│  ┌────────────┐   ┌─────────────┐   ┌──────────────┐               │
│  │ CCTV (n)   │   │ Tablets x3  │   │ Robots x2    │               │
│  │ Cameras    │   │ (체험자)     │   │ SPOT + TBD   │               │
│  └─────┬──────┘   └──────┬──────┘   └──────┬───────┘               │
│        │ RTSP            │ WSS              │ gRPC/ROS2              │
│        ▼                 ▼                  ▼                        │
│  ┌────────────┐   ┌─────────────┐   ┌──────────────┐               │
│  │  Vision    │   │  Tablet     │   │  Robot       │               │
│  │  Tracker   │   │  Gateway    │   │  Adapter     │               │
│  └─────┬──────┘   └──────┬──────┘   └──────┬───────┘               │
│        │                 │                 │                         │
│        ▼                 ▼                 ▼                         │
│  ┌─────────────────────────────────────────────────┐                │
│  │              Event Bus (MQTT)                   │                │
│  └─────────────────────┬───────────────────────────┘                │
│                        │                                             │
│        ┌───────────────┼───────────────┐                            │
│        ▼               ▼               ▼                            │
│  ┌──────────┐   ┌────────────┐  ┌───────────────┐                  │
│  │ Context  │   │ LLM        │  │ Monitoring    │                  │
│  │ Store    │◄──┤ Orchestra  │  │ & Dashboard   │                  │
│  │ (SQLite) │   │ -tor       │  │ (live only)   │                  │
│  │          │   │            │  │               │                  │
│  └──────────┘   └─────┬──────┘  └───────────────┘                  │
│                       │                                              │
│                       ▼ (Tool Calls → Robot/Tablet)                 │
└─────────────────────────────────────────────────────────────────────┘

2.1 도메인 분리

  • Perception 도메인: CCTV 영상 → 사용자 ID·위치·동선 이벤트.
  • Interaction 도메인: 태블릿 UI·사용자 상태(기분 등) 입력.
  • Cognition 도메인: LLM 기반 의사결정, 도구 호출(tool use), 안전 검증.
  • Actuation 도메인: 로봇 명령 디스패치, 텔레메트리 수집.
  • State 도메인: 모든 도메인의 단일 진실 공급원(SoT).

3. 주요 컴포넌트

3.1 Central Context Server (추상 책임)

책임: 사용자·공간·로봇 상태의 실시간 단일 진실 공급원(SoT).

⚠️ OSS 구현 매핑: 본 절은 추상 책임을 정의한다. OSS 채택(OSS_INTEGRATION.md §1, §9)에 따라 이 책임은 Home Assistant가 흡수한다 — services/context-server라는 별도 서비스를 만들지 않는다. 아래 데이터 모델·저장소 설명은 **HA의 entity state + recorder(SQLite)**로 매핑된다.

추상 저장소 모델

  • 활성 세션: sessions 테이블 개념 → HA의 sensor.session_<id>_* 엔티티 그룹.
  • 로봇 스냅샷: robots 테이블 개념 → HA의 sensor.<robot_id>_* 엔티티 그룹 (MQTT(Message Queuing Telemetry Transport, 메시지 큐 텔레메트리 전송 프로토콜) Discovery로 자동 등록).
  • 영속성: HA recorder가 SQLite(/config/home-assistant_v2.db)에 자동 기록, purge_keep_days: 3.
  • 세션 종료: session/end 수신 시 자동화가 해당 엔티티를 unavailable로 표시 + 임베딩 폐기 트리거 (SCRUB 의미).
  • 통계·이력은 본 단계 범위 외 — 향후 archiver 서비스나 별도 분석 DB 도입 가능.

추상 인터페이스 → 실제 매핑

추상 인터페이스 실제 구현
GET /context/user/{session_id} HA REST(Representational State Transfer, 표현 상태 전이) GET /api/states/sensor.session_<id>_*
PATCH /context/user/{session_id} MQTT publish context/user/<session_id>/update (HA가 수신 후 entity 갱신)
WS /context/stream HA WebSocket API subscribe_events: state_changed
  • 변경 이벤트는 모두 Event Bus로 publish → 모든 다른 서비스는 구독으로만 반응.
  • 별도 캐시 계층(Redis 등)은 두지 않음: 단일 사이트·동시 3 세션 규모에서 HA recorder의 SQLite로 충분.

데이터 모델(§4.1, §4.2)의 TypeScript 인터페이스는 그대로 유효 — 직렬화 형식·필드 구조의 정의이며, 저장 위치는 HA로 매핑된다.

3.2 Vision Tracking Service (services/vision)

책임: 다중 CCTV 스트림에서 인물 감지·추적·재식별(re-id), 공간 in/out 이벤트 생성.

  • 파이프라인: RTSP(Real Time Streaming Protocol, 실시간 스트리밍 프로토콜) 입력 → 디코딩(GPU) → YOLO(You Only Look Once, 단일 패스 객체 탐지 모델)v8 detection → ByteTrack(Byte-level Multi-Object Tracking, 바이트 단위 다중 객체 추적 알고리즘)/BoT-SORT(Bootstrapped Object Tracking with SORT, 부트스트랩 기반 객체 추적 알고리즘) tracking → cross-camera re-id (OSNet(Omniscale Feature Network, 옴니스케일 특징 네트워크) 임베딩) → zone polygon 매칭.
  • 공간 정의: 각 공간(카페·공원·차량·실내)을 카메라 좌표 polygon으로 사전 정의.
  • 체험자 식별: 입장 시 태블릿 페어링 단계에서 의류/외형 임베딩을 캡처해 session_id에 바인딩.
  • 출력 이벤트 (MQTT 토픽):
    • vision/zone/enter / vision/zone/exit (session_id, zone_id, timestamp, confidence)
    • vision/position/update (저빈도 ~5Hz, 평면 좌표)

주의: 안면 인식이 아닌 외형 임베딩 기반 단기 추적을 사용해 개인정보 영향을 최소화. 임베딩은 세션 종료 시 즉시 폐기.

3.3 Robot Adapter Layer (services/robot-adapter)

책임: 이종 로봇을 단일 명령 인터페이스로 추상화.

  • 공통 명령 스키마 (Robot Capability Model):
    capabilities:
      - locomotion: { goto, follow, stop, sit, stand }
      - expression: { gesture, look_at, sound }
      - perception: { detect_person, read_qr }
  • 어댑터 구현:
    • SpotAdapter: Boston Dynamics SDK(Software Development Kit, 소프트웨어 개발 키트) (gRPC(Google Remote Procedure Call, 구글 원격 프로시저 호출)), bosdyn-client Python wrapper.
    • GenericAdapter: ROS2 기반 추상화 (미정 로봇 결정 후 구현). 토픽: /cmd_vel, /pose, action server move_to.
  • 명령 큐 + 인터록:
    • 우선순위 큐 (Safety > Operator > LLM).
    • Safety Interlock: e_stop 또는 proximity_violation 이벤트 발생 시 큐 fence — 이후 모든 명령은 거부, 운영자 reset 필요.
  • 텔레메트리: 1Hz로 robot/{robot_id}/state 발행 (battery, pose, current_action, fault).

3.4 LLM Orchestrator (services/llm-orchestrator)

책임: 컨텍스트를 종합해 LLM에 질의하고, 도구 호출(tool use)을 통해 로봇·태블릿 액션을 결정.

  • 모델: Claude (Anthropic API). 의사결정 품질이 중요하면 Opus, 지연이 중요하면 Sonnet.
  • 트리거:
    • vision/zone/enter 이벤트 (MQTT)
    • 태블릿에서 자연어/의도성 명령 입력 (tablet/{id}/intent)
    • 사용자 컨텍스트 유의미 변화 (context/user/{id}/update)
  • 컨텍스트 어셈블리:
    system_prompt + space_state + user_context + robot_state + zone_playbook
    
    공간별 playbook(카페=음료 추천 인터랙션, 공원=동행 산책 등)을 prompt에 주입.
  • Tool Use 정의 (LLM이 호출 가능한 MCP(Model Context Protocol, 모델 컨텍스트 프로토콜) 도구, snake_case):
    • robot_command(robot_id, capability, params)mcp-robot-adapter
    • show_options(tablet_id, options[])mcp-tablet-gateway
    • show_message(tablet_id, text, media)mcp-tablet-gateway
    • context_update(session_id, patch) — orchestrator 내부 (MQTT publish)
  • 가드레일:
    • JSON 스키마 검증 (도구 인자).
    • 화이트리스트: capability·target은 사전 정의된 enum만 허용.
    • 좌표·속도 한계값(velocity_max, zone polygon 내부) hard clamp.
    • 거부된 호출은 Prometheus counter(llm_tool_call_rejected_total)로 카운트하고 운영 로그(Loki)에 한 줄 남김. 이벤트 영속 저장은 하지 않음.
  • 프롬프트 캐싱: system prompt + zone playbook은 stable → Anthropic prompt cache로 비용·지연 절감.

3.5 Tablet Application (apps/tablet)

책임: 체험자에게 현재 가능한 액션을 제시하고 입력을 받음.

  • 스택: React Native (권장 1순위 — HA WebSocket·MQTT 클라이언트·라이브러리 생태계가 풍부). Flutter는 옵션이지만 본 시스템 기본값 아님. iOS·Android 동시 대응.
  • 세션 페어링: 시작 시 QR 스캔 → session_id 발급 → vision 임베딩 캡처.
  • UI 상태 모델:
    • 가능 명령은 LLM이 show_options 도구 호출로 push (사용자 상태에 따라 동적). 결과는 tablet/{id}/show_options 토픽으로 게이트웨이가 WSS(WebSocket Secure, 보안 웹소켓) 전달.
    • 사용자가 옵션 선택 → tablet/{id}/intent 이벤트 발행 → LLM이 다시 평가.
  • 연결: WSS over TLS(Transport Layer Security, 전송 계층 보안), 자동 재연결 + 로컬 큐 (네트워크 단절 대비).

3.6 Monitoring & Dashboard (apps/dashboard)

책임: 운영자가 모든 로봇·체험자·시스템 상태를 현재 시점 기준으로 감시. (이력 분석 기능은 미포함.)

  • (전부 라이브 상태만 표시):
    • 로봇별 헬스(배터리·연결·현재 동작·고장 코드)
    • 활성 세션 목록(현재 공간, 마지막 인터랙션) — 세션 종료 시 목록에서 제거
    • 이벤트 스트림 라이브 테일 (메모리 ring buffer, 디스크 저장 없음)
  • 알림: 로봇 fault, e-stop, LLM 거부율 임계 초과 시 운영자 콘솔 + 사운드.
  • 수단: Grafana(메트릭) + 자체 React 대시보드(도메인 뷰), Loki(로그), Prometheus(메트릭).
    • 메트릭/로그는 운영용 단기 보존 (Prometheus 기본 15d, Loki 7d 등) — 분석/통계 목적 아님.

4. 데이터 모델

4.1 User Context (도메인 모델)

본 절의 인터페이스·DDL(Data Definition Language, 데이터 정의 언어)은 추상 데이터 모델이다. 실제 저장은 §3.1 매핑에 따라 HA entity·recorder가 담당한다. DDL은 데이터 형태 명세 용도로만 참고.

interface UserContext {
  session_id: string;           // ULID, PK
  paired_tablet_id: string;
  visual_embedding_ref: string; // 메모리상 ID, 세션 종료 시 폐기 (DB에 저장 안 함)
  mood: "calm" | "excited" | "tired" | "neutral";
  preferences: {
    music_genre?: string;
    drink?: string;
  };
  current_zone: ZoneId | null;
  zone_history: { zone_id: ZoneId; entered_at: ISO8601; exited_at?: ISO8601 }[];
  environmental: {
    weather: { temp_c: number; condition: string };
    time_of_day: "morning" | "afternoon" | "evening";
  };
  created_at: ISO8601;
  updated_at: ISO8601;
  ended_at: ISO8601 | null;     // 세션 종료 시각, 미종료 시 null
}

DDL:

CREATE TABLE sessions (
  session_id        TEXT PRIMARY KEY,
  paired_tablet_id  TEXT NOT NULL,
  mood              TEXT,
  preferences       TEXT,        -- JSON
  current_zone      TEXT,
  zone_history      TEXT,        -- JSON array
  environmental     TEXT,        -- JSON
  created_at        TEXT NOT NULL,
  updated_at        TEXT NOT NULL,
  ended_at          TEXT
);

4.2 Robot State (도메인 모델)

interface RobotState {
  robot_id: string;              // 런타임에 config/robots.yaml 레지스트리로 검증 (§7.2)
  capabilities: Capability[];
  pose: { x: number; y: number; yaw: number; zone_id: ZoneId };
  battery_pct: number;
  current_action: { type: string; started_at: ISO8601; eta_s?: number } | null;
  faults: Fault[];
  connection: "online" | "degraded" | "offline";
  updated_at: ISO8601;
}

DDL:

CREATE TABLE robots (
  robot_id        TEXT PRIMARY KEY,
  pose            TEXT,         -- JSON
  battery_pct     INTEGER,
  current_action  TEXT,         -- JSON
  faults          TEXT,         -- JSON
  connection      TEXT NOT NULL,
  updated_at      TEXT NOT NULL
);

capabilities는 정적이라 DB에 저장하지 않고 설정 파일(YAML)로 관리.

4.3 Event Schema (CloudEvents 1.0 호환)

CloudEvents 표준 자체에 대한 배경(CNCF 졸업 표준·오픈소스·참고 링크)은 MQTT_SCHEMA.md §1 참조.

{
  "specversion": "1.0",
  "type": "vision.zone.enter",
  "source": "/services/vision",
  "id": "01HXYZ...",
  "time": "2026-04-28T10:00:00Z",
  "subject": "session/01HXYZ",
  "data": { "session_id": "...", "zone_id": "cafe", "confidence": 0.97 }
}

4.4 토픽 네이밍 (MQTT)

표기 규칙: MQTT 토픽은 슬래시(/) 구분, CloudEvents type 필드는 점(.) 구분. 예) topic = vision/zone/enter ↔ CloudEvents type = vision.zone.enter.

전체 토픽 카탈로그·payload 스키마·QoS(Quality of Service, 서비스 품질 등급)는 MQTT_SCHEMA.md 참조.

요약:

  • vision/zone/enter, vision/zone/exit, vision/position/update
  • tablet/{tablet_id}/{intent|show_options|show_message|ack}
  • robot/{robot_id}/{command|state|ack|fault}
  • session/start, session/end
  • context/user/{session_id}/update, context/environmental/update
  • safety/estop, safety/proximity
  • system/heartbeat/{service}

LLM 결정·거부는 별도 토픽 발행 없이 메트릭(Prometheus)과 로그(Loki)로만 처리.


5. 핵심 시퀀스

5.1 사용자 입장 → 자동 인터랙션 시작

CCTV ──► Vision Tracker
            │ publish: vision/zone/enter  (data: session=A, zone=cafe)
            ▼
        Event Bus
            │
   ┌────────┴────────┐
   ▼                 ▼
Context Store   LLM Orchestrator
(zone update)        │ assemble(context, zone_playbook)
                     │ Anthropic API call (with tools)
                     ▼
               Tool Calls:
                 • robot_command(spot-01, "look_at", target=session_A)   [MCP]
                 • show_options(tablet_A, ["커피 추천 받기", "음악 듣기"])  [MCP]
                     │
              ┌──────┴───────┐
              ▼              ▼
        Robot Adapter   Tablet Gateway
              │              │
              ▼              ▼
            SPOT          Tablet UI

5.2 태블릿 명령 → 로봇 실행

  1. 사용자가 태블릿에서 옵션 선택 → tablet/{id}/intent 이벤트.
  2. LLM Orchestrator가 의도+현 컨텍스트 재평가.
  3. Claude tool call → orchestrator가 MCP로 mcp-robot-adapterrobot_command 도구 호출 (MQTT 미경유).
  4. Robot Adapter: 안전 인터록 검증 → SPOT SDK 호출 → 실행.
  5. 1Hz robot/{id}/state 텔레메트리가 대시보드·태블릿(action progress)으로 전파.

폴백 경로: orchestrator/Claude가 응답 못 하는 경우 HA 자동화가 robot/{id}/command MQTT publish → 동일 큐로 수렴. 자세한 경로 정책은 MQTT_SCHEMA.md robot/+/command 참조.

5.3 사용자 상태 변화 → 가능 명령 갱신

  1. 환경 서비스 또는 사용자 입력으로 context/user/{session_id}/update 발행.
  2. LLM Orchestrator가 변경된 컨텍스트로 zone playbook 재평가.
  3. tablet/{id}/show_options를 갱신된 옵션으로 다시 push.

6. 인터페이스 / API

6.1 프로토콜 매트릭스

프로토콜 용도 사용처
MQTT 도메인 이벤트 백본 모든 서비스 ↔ Mosquitto
MCP (JSON-RPC over HTTP/SSE) LLM 도구 호출 orchestratormcp-robot-adapter, orchestratormcp-tablet-gateway
HA REST 컨텍스트 조회·서비스 호출 orchestrator → HA /api/states/*, /api/services/*
HA WebSocket 엔티티 변경 구독 orchestrator 또는 tablet-app → HA /api/websocket
WSS (자체) 태블릿 양방향 채널 tablet-appmcp-tablet-gateway
HTTP UI 접근 운영자 PC → HA Lovelace(8123), Frigate UI(5000), Grafana(3000)
RTSP 카메라 입력 CCTV → Frigate
로봇 SDK 전용 로봇 제어 mcp-robot-adapter → SPOT(bosdyn-client/gRPC) / 미정 로봇

내부 서비스 간 gRPC는 사용하지 않는다. SPOT SDK가 내부적으로 gRPC를 쓰지만, 우리 코드 경계에선 bosdyn-client Python API만 노출되므로 직접 다루지 않음.

6.2 메시징

  • MQTT (QoS 1): 모든 도메인 이벤트의 단일 버스. 모든 메시지는 휘발성으로 처리 — 영속 저장이나 재처리는 본 단계에서 제공하지 않음.
  • 추후 통계·재처리 요구가 생기면 MQTT 구독자로 별도 archiver 서비스를 추가하는 형태로 점진 도입 (현 시점 범위 외).

7. 로봇 제어 상세

7.1 SPOT 통합

  • bosdyn-client (Python) 기반, e-stop은 SDK의 EstopClient 사용.
  • 명령은 RobotCommandClient로 전송, async future로 완료 대기.
  • 자세·동작 라이브러리: 사전에 정의된 행동 프리셋(예: wave, sit_and_look)을 capability로 노출.

7.2 미정 로봇 통합 전략

결정 매트릭스

  • ROS2 Humble 기반 추상화를 우선 가정. 결정 시점에 다음 매트릭스로 평가:
    • SDK 안정성, 실시간 제어 latency, 카메라/센서 노출, 안전 기능(e-stop, bumper).
  • 어댑터 구현 시 SPOT과 동일한 Capability Model을 만족하도록 갭(gap) 분석.

식별자 정책 — robot_id 미래 안전성

현재 문서·스키마는 robot-02를 placeholder로 사용하나, 결정 후 변경 비용을 최소화하기 위해:

  1. literal 사용 최소화: RobotId 타입을 strict literal("spot-01" | "robot-02")이 아닌 string + 런타임 검증으로 변경.
    type RobotId = string;   // 런타임에 ROBOT_REGISTRY로 검증
  2. 단일 소스 레지스트리: config/robots.yaml에 모든 로봇 정의:
    robots:
      spot-01:
        model: boston_dynamics_spot
        capabilities: [goto, follow, stop, sit, stand, gesture, look_at]
        max_velocity_mps: 1.6
      spot-02:                            # 결정 후 실제 ID로 교체
        model: <vendor>_<model>
        capabilities: [...]
  3. 검증 위치:
    • orchestrator: Claude tool 호출 시 robot_id가 레지스트리에 있는지 확인.
    • mcp-robot-adapter: 시작 시 레지스트리 로드 + 어댑터 인스턴스 생성.
    • guardrail: 화이트리스트는 레지스트리에서 동적 생성.
  4. 변경 시 영향 범위:
    • config/robots.yaml 편집 (1곳).
    • mcp-robot-adapter에 새 어댑터 클래스 추가 (adapters/<vendor>.py).
    • 캘리브레이션 (§8.3.2) 수행.
    • HA 엔티티 자동 등록 (MQTT Discovery)이라 별도 작업 불필요.
  5. 하지 말 것: 코드·prompt·테스트 fixture에 robot_id를 literal로 박아넣지 말 것. 항상 레지스트리 조회.

7.3 동시성·자원 경합 정책

체험자는 동시 최대 3명, 로봇은 2대. 자원 경합이 발생하는 두 경우와 정책:

A. 같은 로봇에 여러 명령 동시 도착

  • mcp-robot-adapter단일 priority queue로 직렬화.
  • 우선순위: safety > operator(HA) > llm(orchestrator).
  • 동일 priority 내: FIFO + 다음 규칙으로 redundant 명령 dedupe:
    • 동일 robot_id + 동일 capability + 인자 차이 < 임계값 (예: goto 좌표 < 0.3m) → 후행 명령은 선행을 대체 (큐에 1개만 유지).
    • stop은 동급 명령 없으면 즉시 실행 (큐 앞으로 이동).
  • expires_at 만료 시 자동 폐기.

B. 한 로봇이 여러 사용자에게 동시 반응 요구

  • 시나리오: 사용자 A가 카페에 있고 B가 공원에 들어옴 — SPOT은 한 명만 응대 가능.
  • 세션 단위 잠금 (orchestrator):
    • 로봇이 어떤 세션을 응대 중인지 attached_session: spot-01 → session_A를 in-memory + HA sensor.spot_01_attached_session에 기록.
    • 사용자 A 응대 중 사용자 B의 트리거 도착 시:
      • 선택 1 (정책 기본): 다른 로봇(robot-02)으로 응대 — orchestrator의 도구 호출에서 가용 로봇 풀 조회 후 결정.
      • 선택 2: 모든 로봇이 점유 중이면 B는 태블릿 인터랙션만 (로봇 없이 옵션·메시지) + "곧 로봇이 합류할 예정" 안내.
    • 응대 종료 (사용자가 zone exit 또는 명시적 끝)은 attached_session=null로 해제.
  • attached_session 정보는 orchestrator의 시스템 프롬프트에 포함 → Claude가 가용 로봇만 선택하도록 유도.

C. orchestrator의 그래프 동시 실행

  • LangGraph는 인스턴스가 stateless하므로 이벤트 단위 동시 실행 OK (asyncio).
  • 잠금 단위는 (session_id, zone_id) — 같은 사용자(session)라도 다른 zone이면 병렬 실행한다. 각 zone에는 전용 로봇이 배치되므로(예: park=spot-01, home=kaist-01), 한 사용자가 여러 영역에서 서로 다른 로봇의 독립 동작을 동시에 받을 수 있다. 직렬화는 같은 (session, zone) 에 대해서만 적용 — 같은 로봇에 모순된 결정이 동시에 가는 것을 방지.
    # 잠금 키: (session_id, zone_id) — 다른 zone(=다른 로봇)이면 병렬 허용
    zone_locks: dict[tuple[str, str], asyncio.Lock] = defaultdict(asyncio.Lock)
    async def handle(event):
        key = (event["session_id"], event["zone_id"])
        async with zone_locks[key]:
            await flow.ainvoke(...)

    ⚠️ 멀티 로봇 병렬 동작의 근거 결정. 사용자가 실외(park)에 있어도 실내(home)의 돌발상황에 따라 해당 영역 로봇이 즉시 반응해야 한다 — 그래서 same-session cross-zone을 직렬화하지 않는다. 단 같은 robot에 대한 명령 순서·충돌 방지는 별개 보장으로, §7.3.A의 mcp-robot-adapter 단일 priority queue가 책임진다(잠금 단위와 무관).

  • session 생명주기 이벤트(session/end SCRUB §11.3)는 zone 무관 — 모든 (session, *) 잠금을 가로지르는 배리어로 처리해 잔여 결정과 경합하지 않게 한다.

D. NFR 영향

  • 동시 3명 시 가장 느린 path latency는 그대로 < 1.5s 유지 (LLM 호출 병렬 + Anthropic API rate limit 여유).
  • Anthropic API 호출 동시성 한계는 max_concurrent: 5로 안전 마진 확보.

7.4 안전 인터록

  • Hardware e-stop: 운영자 물리 버튼 → 모든 로봇 즉시 정지.
  • Software fence: zone polygon 외부 좌표 명령 거부.
  • Proximity guard: vision tracker가 발행하는 사용자-로봇 거리 < 임계 시 모든 이동 명령 일시 차단.
  • Watchdog: 로봇 텔레메트리 끊김 > 2s → 자동 stop 명령.

8. 비전 / CCTV 추적

8.1 카메라 배치

  • 각 공간 최소 2대(겹치는 시야각으로 점유 검증), 천장 + 사선 조합.
  • 공간 간 전이 영역에 1대씩(re-id 정확도 향상).

8.2 모델 구성

  • Detection: YOLOv8m TensorRT.
  • Tracking: ByteTrack (single cam).
  • Re-ID: OSNet 임베딩 + Hungarian matching across cams.
  • 인프라: NVIDIA Jetson AGX Orin × n (카메라 그룹별) 또는 단일 GPU 서버 + DeepStream.

8.3 좌표계 및 캘리브레이션

본 시스템에는 3개의 좌표계가 공존하며, 모두 명시적 변환을 통해 매핑된다.

좌표계 단위 사용 위치
Camera pixel px (u, v) Frigate 입력·zone polygon
World plane (전시장 평면) meters (x, y) bridge가 발행하는 vision/* payload, zone polygon (world), HA picture-elements
Robot odom frame meters (x, y, yaw) 로봇 SDK 호출 (SPOT goto, ROS2 /cmd_vel)

8.3.1 Camera ↔ World 캘리브레이션 (homography)

  1. 전시장 바닥에 ArUco 마커 4개 이상을 알려진 world 좌표(예: (0,0), (5,0), (0,3), (5,3) m)에 배치.
  2. 각 카메라가 마커를 모두 촬영할 수 있도록 위치·각도 조정.
  3. OpenCV cv2.findHomography 로 카메라별 3x3 행렬 H_c 산출.
  4. 결과를 config/calibration/cameras.yaml에 저장:
    cafe_cam_01:
      homography: [[h11, h12, h13], [h21, h22, h23], [h31, h32, h33]]
      calibrated_at: 2026-04-30T10:00:00Z
  5. bridge 서비스가 시작 시 이 파일을 로드하여 픽셀 → world 변환에 사용.

8.3.2 World ↔ Robot odom 정합

  1. 로봇을 world 원점((0,0))에 배치 후 body frame yaw=0 자세로 정렬.
  2. 로봇 SDK에서 odom frame의 현재 pose를 캡처 → T_odom_to_world 4x4 변환 행렬 산출.
  3. 결과를 config/calibration/robots.yaml에 저장:
    spot-01:
      odom_to_world:
        translation: [tx, ty, 0]
        yaw: theta
      calibrated_at: 2026-04-30T11:00:00Z
  4. mcp-robot-adapter가 시작 시 로드. orchestrator가 world 좌표로 명령하면 어댑터가 odom으로 변환 후 SDK 호출.
  5. 로봇이 충전 도크 등으로 odom 누적 오차 발생 시: 도크 위치를 world 기준점으로 두고 도크 진입 시마다 자동 재교정.

8.3.3 Zone polygon 정의 — 단일 소스

  • config/zones.yamlworld 좌표로 polygon 정의 (단일 진실 공급원):
    zones:
      cafe:
        polygon_world: [[0,0], [5,0], [5,3], [0,3]]   # meters
      park:   [[5,0], [10,0], [10,3], [5,3]]
      vehicle: [[0,3], [5,3], [5,6], [0,6]]
      home:    [[5,3], [10,3], [10,6], [5,6]]
  • 빌드 시점에 변환 스크립트 (scripts/gen-frigate-zones.py)가:
    • 카메라별 H_c⁻¹로 world polygon → camera pixel polygon 변환
    • Frigate config.ymlzones.<name>.coordinates를 자동 생성
  • 이로써 zone 정의가 한 곳에만 존재 → 변경 시 Frigate·로봇 양쪽 동시 갱신.

8.3.4 재캘리브레이션 트리거

  • 카메라 위치 변경 시: 해당 카메라만 §8.3.1 재실행.
  • 전시장 floor plan 좌표 원점 이동 시: 모든 카메라·로봇 재캘리브레이션.
  • 로봇 fault 후 odom 누적 오차 의심 시: §8.3.2 재실행 (도크 자동 재교정으로 일상 운영 중에는 불필요).

8.3.5 운영자 도구

  • Frigate 자체 UI에 zone editor 내장 — 운영 중 미세 조정 시 사용.
  • 단 §8.3.3 단일 소스를 깨지 않도록 편집 결과는 config/zones.yaml에 역병합 후 재생성.

9. LLM 의사결정 상세

9.1 시스템 프롬프트 골격 (요약)

당신은 전시장 Physical AI의 결정 엔진이다.
입력: 사용자 컨텍스트, 공간 상태, 로봇 상태, zone playbook.
출력: 도구 호출만 (자연어 응답 금지, 단 show_message의 인자로는 허용).
제약: capability 화이트리스트, zone 경계, robot fault 시 해당 로봇 명령 금지.

9.2 도구 스키마 (예시)

{
  "name": "robot_command",
  "input_schema": {
    "type": "object",
    "properties": {
      "robot_id": { "type": "string" },   // 런타임에 config/robots.yaml 레지스트리로 검증
      "capability": { "enum": ["goto", "follow", "stop", "gesture", "look_at"] },
      "params": { "type": "object" }
    },
    "required": ["robot_id", "capability"]
  }
}

9.3 결정 관측 (운영 한정)

  • LLM 호출의 latency, 거부율, 토큰 사용량은 Prometheus 메트릭으로만 수집.
  • 가드레일에서 거부된 호출은 구조화 로그(Loki, 단기 보존)에 한 줄씩 기록 — 운영 중 디버깅 용도.
  • 호출 본문(input/response 전문)은 영속 저장하지 않음 — 통계·튜닝 목적의 보관은 본 단계 범위 외.

9.4 폴백

  • LLM 호출 실패/타임아웃 → zone playbook의 정적 디폴트 시나리오(rule-based)로 폴백.
  • 동일 zone에서 N초 내 LLM 호출 dedup (debounce).

10. 운영 / 관측 (Observability)

신호 도구 핵심 지표
메트릭 Prometheus + Grafana latency p95/p99, LLM 거부율, 로봇 fault 횟수
로그 Loki 구조화 JSON 로그, trace_id 전파
트레이싱 OpenTelemetry → Tempo vision→bus→llm→robot 전체 트레이스

모든 관측 신호는 운영 디버깅용 단기 보존. 분석·통계·재처리를 위한 이벤트 ledger는 본 단계에 포함하지 않음.

알림 정책:

  • 로봇 offline > 10s → P1
  • LLM 거부율 5분 평균 > 10% → P2
  • 비전 추적 신뢰도 평균 < 0.85 (5분) → P2

11. 보안 및 안전

11.1 네트워크

  • 전시장 내부 LAN은 외부와 분리 (Anthropic API·ghcr.io outbound만 허용).
  • 로봇 제어 트래픽은 가능하면 별도 VLAN(Virtual Local Area Network, 가상 로컬 네트워크)(태블릿·관람객 Wi-Fi와 분리).
  • TLS 적용 범위 (단일 사이트·풀 로컬 운영 기준):
    • 필수: 외부 노출되는 인터페이스 — Cloudflare Tunnel/Tailscale 통한 원격 운영자 접근(HA·Grafana), 태블릿 ↔ tablet-gateway WSS(자체 인증서 또는 LAN 내부에서 wss 생략 허용).
    • 선택: 내부 LAN 한정 통신은 user/password + ACL(Access Control List, 접근 제어 목록)로 충분 (mosquitto, MCP, HA REST). mTLS(mutual TLS, 상호 인증 TLS)는 운영 부담 대비 효익 낮음.
    • 시스템 격상 시: 다중 사이트로 확장하거나 외부 노출 면적이 늘면 모든 서비스 간 mTLS 도입 재검토.
  • 자체 서비스(orchestrator/bridge/...)는 모두 별도 비-root uid로 실행 (Dockerfile USER).

11.2 인증/인가

  • 태블릿: 디바이스 인증서 + 세션 페어링 토큰.
  • 운영자 대시보드: SSO(Single Sign-On, 단일 로그인 인증) + RBAC(Role-Based Access Control, 역할 기반 접근 제어) (운영자/관람자 권한 분리).

11.3 개인정보

  • 임베딩 폐기 트리거: 별도 SCRUB 토픽을 두지 않고 session/end 메시지가 SCRUB을 겸한다. 모든 구독자는 session/end 수신 즉시 다음을 수행:
    • bridge: session_id에 바인딩된 외형 임베딩 메모리에서 삭제 + ReID(Re-identification, 보행자 재식별) registry에서 unbind.
    • mcp-tablet-gateway: 페어링 토큰 무효화, WSS 연결 종료.
    • home-assistant: 해당 sensor.session_<id>_* 엔티티를 unavailable로 표시 (자동화 또는 template).
    • orchestrator: in-memory 컨텍스트 캐시 evict.
  • 검증: 운영 후 임베딩이 메모리에 남아 있지 않은지 SIGUSR1 핸들러로 self-audit (서비스별 디버그 엔드포인트).
  • 영상 원본은 디스크 저장하지 않음(Frigate record.enabled: false, snapshots.enabled: false 강제).
  • 데이터 흐름·보존 정책을 전시 입구에 고지 (개인정보 보호법 준수).

11.3.1 표정·자세(Expression·Pose) 분석 정책

§16의 "선제적 인식·러닝 페이스 코칭" 시나리오를 위해 도입 검토 시 적용.

  • 신원(identity) 추출은 영구 금지 — face recognition 모델은 도입하지 않는다 (CLAUDE.md invariant). 외형(appearance) 식별은 OSNet 임베딩만 사용.
  • 표정(facial expression)·자세(pose) feature는 ephemeralbridge(또는 별도 인퍼런스 서비스)가 frame 단위로 평가하여 context/user/<session_id>/updatemood·posture 필드만 갱신. raw feature·embedding은 디스크/DB에 저장하지 않음.
  • SCRUB 트리거 동일session/end 수신 시 in-memory의 표정·자세 상태를 즉시 폐기 (§11.3 본문의 임베딩 폐기와 같은 핸들러에 묶음).
  • 모델 후보: pose는 YOLOv8-pose / MediaPipe BlazePose 중 GPU(Graphics Processing Unit, 그래픽 처리 장치) 부하 측정 후 선정. expression은 FER+(Facial Expression Recognition Plus, Microsoft 공개 표정 분류 모델) 등 7-class classifier로 충분 (mood enum과 매핑).

11.3.2 세션 회고 텍스트(동행일기) 보존 정책

  • session/end 시 orchestrator가 LLM에 요약을 요청하여 생성한 텍스트만 보존 가능 — 영상·임베딩·페어링 토큰은 SCRUB 정책 그대로.
  • 보존 위치: HA recorder의 별도 text sensor (sensor.session_<id>_diary) 또는 /data/diaries/<session_id>.json.
  • 보존 기간: 최대 7일 후 자동 삭제 (HA recorder purge_keep_days: 3보다 길면 별도 cleanup cron 필요).
  • 일기 텍스트는 LLM이 생성 단계에서 PII(Personally Identifiable Information, 개인 식별 정보 — 이름·정확한 외모 묘사·체류 시간 외 식별 단서)를 제거하도록 system prompt에 가드 명시.

11.3.3 물리 보안 명령(lock·unlock·alarm) 정책

  • LLM이 자율적으로 발행할 수 있는 capability whitelist에서 분리. orchestrator의 도구 스키마(§9.2)에서 physical_security 카테고리는 노출하지 않음.
  • 발행 가능 경로:
    • HA rule-based automation: 사전 정의된 조건(예: session_id=null AND vehicle.zone=home AND unknown_visitor=true)에서만 트리거.
    • operator console: 운영자 명시 승인.
  • Figma "가전 기사가 일찍 와서 AI가 안전히 잠금" 시나리오는 위 HA rule 경로로만 시연 — LLM 자율 결정 금지.

11.4 물리적 안전

  • §7.4 인터록 + 운영자 상시 모니터링 + 로봇별 물리 e-stop 비치.

12. 배포 / 인프라

12.1 토폴로지 (전시장 온프레미스)

  • 권장: 통합 워크스테이션 1대 (CPU 8C16T / RAM 32GB / GPU RTX 4060 8GB / NVMe(NVM Express, 고속 저장 인터페이스) 1TB) — 모든 컨테이너 호스팅. 자세한 사양·산정 근거는 DEPLOYMENT.md §0 참조.
  • 분리형 옵션: GPU 노드(Frigate) + CPU 노드(나머지)로 2 노드.
  • Jetson 엣지: 카메라 수가 늘거나 GPU 부하 분산이 필요하면 그룹별 추가 (선택).
  • 무선: 태블릿용 별도 SSID(Service Set Identifier, 무선 네트워크 식별자) (5GHz, AP 2대로 커버리지).
  • 유선: 로봇은 가능한 무선이지만 SPOT은 5GHz Wi-Fi 또는 Ethernet over robot dock 활용.

12.2 패키징

  • 모든 서비스 컨테이너화(Docker), Compose로 구동(전시 단일 사이트라 K8s 오버킬).
  • 인프라 as Code: docker-compose + Ansible (전시장 셋업 자동화).

12.3 스테이징

  • 사무실에 미니 미러 환경(카메라 1, 태블릿 1, SPOT 단독)으로 통합 테스트.

13. 리스크 & 완화

리스크 영향 완화
LLM 지연/실패 인터랙션 끊김 rule-based 폴백, 캐시
비전 re-id 실패(혼잡 시) 잘못된 사용자 인식 동시 체험 인원 3명 제한, 태블릿 QR 재페어링 동선
로봇 fault 시연 중단 이중화 시나리오(다른 로봇으로 대체) + 운영자 수동 모드
Wi-Fi 혼선 태블릿/로봇 통신 끊김 별도 SSID + 채널 플래닝, 로봇 전용 AP
LLM 환각 → 위험 명령 안전 사고 화이트리스트·스키마·하드 클램프 + 거부 메트릭 알림
미정 로봇 SDK 미성숙 통합 일정 지연 어댑터 패턴으로 인터페이스 격리, ROS2 표준 우선

14. 마일스톤 (제안)

  1. M0 — 인프라 부트스트랩 (2주): Event Bus, Context Server, 대시보드 스켈레톤.
  2. M1 — 비전 + 단일 공간 (3주): 1개 공간(cafe) 기준 enter/exit 이벤트 → 태블릿 옵션 노출.
  3. M2 — SPOT 통합 (3주): SPOT 어댑터, 안전 인터록, 1개 공간 인터랙션 end-to-end.
  4. M3 — LLM Orchestrator (2주): 도구 호출, 가드레일, zone playbook 2개.
  5. M4 — 4개 공간 + 2번째 로봇 (4주): 미정 로봇 어댑터, 멀티 공간 re-id.
  6. M5 — 운영 강화 (2주): 알림, 폴백, 부하 시연 리허설.

15. 미결 이슈 (To Decide)

  • 2번째 로봇 모델 선정 (휴머노이드 / 휠형 / 협동로봇).
    • Figma 1차 기획(2026-05-04 회의)에서 KAIST 로봇이 후보로 언급됨 — 집안 보조(외출 준비물 챙김·약/음료 준비·낙상 감지). 결정은 §7.2 결정 매트릭스에 따라 진행, 본 항목은 후보 추가만.
  • LLM 모델 선택 (Opus vs Sonnet) — 인터랙션 품질·지연 측정 후 결정.
    • Figma 시나리오의 강한 선제적 추론·맥락 연속성 요구는 Opus 4.7 우호적 신호. NFR p95 < 2.5s 측정 시 평가 항목으로 포함 필요.
  • 사용자 mood 입력 방식 (태블릿 self-report vs 비전·음성 추론).
    • Figma는 vision(표정·자세 분석, §11.3.1)과 self-report(인트로 4테마 선택, §16.2 인트로 단계) 둘 다 시사. 양쪽 병행 가능성 검토 필요.
  • 영상 저장 정책(완전 미저장 vs 익명화 후 단기 보관).
    • Figma "동행일기 아카이빙" 요구는 LLM 텍스트 요약에 한정되며 영상 본체 보존을 시사하지 않음 — 현 정책(완전 미저장) 유지하면서 §11.3.2 일기 정책으로 충족 가능.
  • 운영자 인원 (단독 vs 2인 교대).
    • Figma VIP 시나리오(15분, 동선 안 움직임)와 일반 자유관람 동시 진행 가능성 → 2인 교대(시연 + 모니터링) 우호적 신호.

16. 시연 시나리오 적용 매핑 (Figma 1차 기획안)

출처: Figma tTC1SxVaA9D3Be1ghF1QLR — 2026-05 기획·디자인 1차 회의 산출물. 채택안: 성건우 매니저 안 "Physical AI Companion: Traveling Soul" — 2026-05-04 회의에서 중심축으로 결정. 홍대팀(SOUL/연속성)·이승엽(러닝/건강)·허화영(대리수행) 아이디어를 가지(枝)로 덧붙이는 방식.

본 절은 기획안의 6단계 사용자 여정·디바이스 구성을 본 시스템의 컴포넌트·토픽·MCP 도구·playbook으로 매핑한다. 신규 MQTT 토픽은 0개(§16.6)이며, 핵심 변경은 ① intro/outro playbook 2개 신설 ② 신규 capability 2개(bring·lock) 추가에 한정된다. 그 외 모든 흐름은 §5의 일반 패턴(트리거 → assemble → guardrail → dispatch)에 수렴한다.

16.1 핵심 메시지 ↔ 시스템 정합성

Figma 키 메시지 6개를 그룹화하여 매핑.

키 메시지 (Figma 원문) 시스템 대응
"언제 어디서나 함께" / "나를 기억하고 이해하는" / "하나의 인격체로 느껴지는" session_id 단위 컨텍스트 누적 — vision/zone/{enter,exit} + context/user/<id>/update (retain:true) + HA sensor.session_<id>_* SoT (§3.1, §4.1)
"나와 함께 성장하는" / "맥락이 행동의 가치를 부여" orchestrator가 zone playbook을 컨텍스트로 어셈블 → Claude tool use → MCP dispatch (§5.1, OSS_INTEGRATION.md §3.3). Anthropic prompt cache로 system prompt + zone playbook 재사용 (§9.1).
"대체 불가능한 동반자" 체험 종료 시 SCRUB(§11.3)로 영구 동반자는 구현 불가. 시연 한정으로 동행일기(§11.3.2)가 회고 형태의 연속성 환상 제공.

16.2 사용자 여정 6단계 ↔ 시스템 시퀀스

# 단계 zone 트리거 playbook 핵심 도구 (MCP·HA) 주요 산출 토픽
1 인트로 (4테마 선택) 시연 시작 zone (현 cafe — 카페→마트/회사 변경 시 zones.yaml 1곳만 수정) vision/zone/enter (sess 신규 페어링) intro.md ★신설 mcp-tablet-gateway.show_options tablet/<id>/show_options
2 (아침 출근 준비) home tablet/<id>/intent (테마 응답 수신) home.md (sub: morning) show_message, robot_command(KAIST: bring) †, HA light.turn_on tablet/<id>/show_message, robot/<kaist>/command
3 (자차 출근) vehicle vision/zone/enter (zone=vehicle, sess 동일) vehicle.md show_message(차량 디스플레이), HA light.turn_on / media_player.play_media / climate.set_temperature tablet/<vehicle_disp>/show_message
4 (공원 러닝 + 집 돌발상황) park (메인) ∥ home (병행) vision/zone/enter (zone=park) ∥ Frigate 미등록 인물 detect park.md + 표정·자세(§11.3.1) robot_command(spot-01: follow), HA automation lock.lock (§11.3.3 rule 경로) robot/spot-01/{command,state}, HA service call
5 (귀가 후 회복) home (재진입) vision/zone/enter (zone=home, sess 동일, prev_zone≠home) home.md (sub: evening) HA climate.set_temperature / media_player.play_media, robot_command(KAIST: bring) †, show_message robot/<kaist>/command, tablet/<id>/show_message
6 아웃트로 (동행일기) (zone 무관) session/end outro.md ★신설 LLM 텍스트 생성 + HA text.set_value + show_message tablet/<id>/show_message, sensor.session_<id>_diary

★ = 신설 playbook (§16.5). † = 본 단계 capability enum(§9.2)에 없음 — KAIST 결정 후 추가 (§16.5).

단계 구분 노트:

  • 같은 home zone을 사용하는 ②기와 ⑤결은 prev_zone 컨텍스트로 구별한다 — 인트로 직후 첫 enter면 , 다른 zone 경유 후 재진입이면 . orchestrator의 assemble 단계에서 zone_history(§4.1) 마지막 항목 비교로 분기.
  • ④전은 메인 시연자가 park에 있는 동안 home의 돌발상황 detect가 병렬 실행. 동일 session_id라도 zone이 다르므로(park=spot-01, home=kaist-01) §7.3.C의 (session, zone) 잠금에서 병렬 처리 — 사용자가 실외에 있어도 실내 로봇이 돌발상황에 독립 반응한다. 같은 robot에 대한 명령 충돌은 §7.3.A 단일 priority queue가 별도 방지.
  • 5/8 실장님 피드백(다중 일정 충족 의상 추천)은 ②기의 home.md morning sub-prompt에 반영 — 일정 2~3건의 드레스 코드를 동시에 만족하는 옵션을 show_options로 push.

16.3 디바이스/공간 추상화

Figma 디바이스 시스템 매핑 비고
SPOT (공원 동행) robot_id: "spot-01" (§7.1) 변경 없음 — capability follow·look_at 그대로
KAIST 로봇 (집안 보조) robot_id: "kaist-01" (후보, §15 미결) robots.yaml에 placeholder 추가. 어댑터는 §7.2 결정 매트릭스에 따라 ROS2 우선 가정
차량 디스플레이/오디오 paired_tablet_id: "vehicle_disp_01"로 추상화 별도 mcp-vehicle-gateway 신설하지 않음 — 기존 tablet 토픽(show_message·intent) 재사용. 라이트·디퓨저·음악은 HA smart-home integration
모바일·스마트워치 HA Companion App + Wear OS / Apple Health integration (도입 결정 시) §15 mood 입력 결정과 연동. 미도입 시 vision rPPG(remote PhotoPlethysmoGraphy, 원격 광용적맥파 측정) 추정으로 대체 — 체험자 무착용 시연 가능
CCTV (선제적 인식) Frigate + bridge OSNet appearance + pose(§11.3.1) 옷 색상·소지품·자세 메타데이터를 context/user/<id>/update patch로 전달. identity·성별·나이는 추출하지 않음 (§11.3.1)
인프라존 (가운데 미니어쳐) HA Lovelace 운영자 view + Grafana(§10) — §16.4 참조 시연 사용자 컨텍스트는 없는 운영 표현 공간

16.4 시연 운영 고려사항

기획안에 포함된 운영 차원 요구는 본 시스템의 운영(§10)·안전(§11.4)·배포(§12) 정책 위에 다음과 같이 얹는다.

  • VIP 시나리오 (15분, 동선 안 움직임) — VIP-전용 태블릿 1대를 별도 paired_tablet_id로 페어링하고, tablet/<vip>/show_message로 본 시연자의 zone 전환·로봇 동작·LLM 결정 진행도를 풍부 정보로 push. NFR(§1.3)의 "동시 체험자 3명" 외 추가 청중 슬롯으로 분리 운영.
  • 인프라존 (가운데 미니어쳐) — 4 zone 외 표현 공간. 사용자 컨텍스트 없음. ① HA Lovelace 별도 view에 충전·생산·출고 모의 entity 표시, ② Grafana 대시보드로 전체 AI 의사결정·로봇 텔레메트리 조감. 신규 컴포넌트 없음.
  • 돌발상황 표현 장치 — 가전 기사·낙상·반려동물·아이 등은 집 zone 내 창문형 디스플레이에 외부 영상을 재생하고, 그 디스플레이를 향한 Frigate 카메라가 영상 속 person을 감지하는 방식으로 자율 시연 가능 (실제 외부 인원 동원 불요). 카메라 1대 추가 배치만 필요.
  • 동시성·대리수행 (5/4 허화영 제안) — "사용자가 직접 가지 않아도 SPOT이 대신 쇼핑/심부름" 시나리오. 본 단계 범위 외이지만 MCP 아키텍처 자체는 도구 추가만으로 자연 확장 가능 — §16.5 작업 항목에만 표기.
  • 3rd party 락인 생태계 시사 — 차량 앱 → 로봇 전체 앱 생태계 메시지는 MCP 서버 추가 데모로 운영자 브리핑에서 시연. 별도 구현물 없음.

16.5 추가 작업 항목 (마일스톤 매핑)

본 매핑이 함의하는 신규/확장 작업. 마일스톤은 §14 기준.

항목 영향 위치 마일스톤
prompts/playbooks/intro.md, outro.md 신설 SERVICES.md §5 (orchestrator) M3
pose estimation 통합 (YOLOv8-pose / MediaPipe) SERVICES.md §4 (bridge) 또는 별도 인퍼런스 service M2 직후
expression(FER+) 통합 — §11.3.1 정책 적용 후 SERVICES.md §4 (bridge) M3
tablet.intentintent_typeintro_theme 추가 MQTT_SCHEMA.md §3.5 M3
신규 capability bring (물건 핸들링) — KAIST 결정 후 §9.2 도구 스키마, mcp-robot-adapter §15 결정 후
신규 capability lock 분리 — LLM 자율 발행 금지(§11.3.3) §9.2, mcp-robot-adapter 가드 M2
차량 디스플레이용 tablet-app 변형 (full-screen, 음성 우선) SERVICES.md §6 (mcp-tablet-gateway) M4
sensor.session_<id>_diary text sensor + 7일 cleanup cron SERVICES.md §3 (home-assistant) M5
KAIST 로봇 어댑터 adapters/kaist.py SERVICES.md §6 (mcp-robot-adapter), config/robots.yaml §15 결정 후
동시성·대리수행 시나리오 (5/4 허화영) OSS_INTEGRATION 신규 시퀀스 본 단계 범위 외

16.6 정합성 체크

본 §16의 모든 매핑은 CLAUDE.md의 설계 invariant를 위배하지 않는다. 핵심 보호 장치는 §11.3.1·11.3.2·11.3.3에서 새로 명문화한 정책 — 표정·자세 ephemeral / 동행일기 텍스트 한정·7일 보존 / 물리 보안 명령 LLM 자율 발행 금지 — 로 확보된다. zones.yaml(4 zone)·robots.yaml·MQTT 토픽 카탈로그·MCP 도구 스키마는 신규 capability 2개(bring·lock) 외 모두 변경 없이 사용 가능하며, MQTT 신규 토픽은 0개다.

Clone this wiki locally