SYSTEM_DESIGN - zero1ne-26/doc GitHub Wiki

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-adapter์˜ robot_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 ๋„๊ตฌ ํ˜ธ์ถœ orchestrator โ†’ mcp-robot-adapter, orchestrator โ†’ mcp-tablet-gateway
HA REST ์ปจํ…์ŠคํŠธ ์กฐํšŒยท์„œ๋น„์Šค ํ˜ธ์ถœ orchestrator โ†’ HA /api/states/*, /api/services/*
HA WebSocket ์—”ํ‹ฐํ‹ฐ ๋ณ€๊ฒฝ ๊ตฌ๋… orchestrator ๋˜๋Š” tablet-app โ†’ HA /api/websocket
WSS (์ž์ฒด) ํƒœ๋ธ”๋ฆฟ ์–‘๋ฐฉํ–ฅ ์ฑ„๋„ tablet-app โ†” mcp-tablet-gateway
HTTP UI ์ ‘๊ทผ ์šด์˜์ž PC โ†’ HA Lovelace(8123), Frigate UI(5000), Grafana(3000)
RTSP ์นด๋ฉ”๋ผ ์ž…๋ ฅ CCTV โ†’ Frigate(detect) / CCTV โ†’ cctv-relay(๋ผ์ด๋ธŒ)
WebRTC (WHEP ์‹œ๊ทธ๋„๋ง + SRTP ๋ฏธ๋””์–ด) ๋ธŒ๋ผ์šฐ์ € CCTV ๋ผ์ด๋ธŒ ์˜์ƒ (์ „์‹œ์žฅ ํ•œ์ •) ๋ธŒ๋ผ์šฐ์ € โ†” cctv-relay(go2rtc, ๋…๋ฆฝ ์„œ๋น„์Šค); ์‹œ๊ทธ๋„๋ง์€ tablet-fe BFF ๊ฒฝ์œ  โ€” ยง8.4
๋กœ๋ด‡ SDK ์ „์šฉ ๋กœ๋ด‡ ์ œ์–ด mcp-robot-adapter โ†’ SPOT(bosdyn-client/gRPC) / ๋ฏธ์ • ๋กœ๋ด‡

๋‚ด๋ถ€ ์„œ๋น„์Šค ๊ฐ„ gRPC๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. SPOT SDK๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ gRPC๋ฅผ ์“ฐ์ง€๋งŒ, ์šฐ๋ฆฌ ์ฝ”๋“œ ๊ฒฝ๊ณ„์—์„  bosdyn-client Python API๋งŒ ๋…ธ์ถœ๋˜๋ฏ€๋กœ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š์Œ. WebRTC ๋ผ์ด๋ธŒ ์˜์ƒ์€ ๋ช…์‹œ์  ์˜ˆ์™ธ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ RTSP๋ฅผ ์ง์ ‘ ๋ชป ๋ฐ›์œผ๋ฏ€๋กœ ๋…๋ฆฝ cctv-relay(go2rtc)๋ฅผ ๋‘”๋‹ค โ€” ์ „์‹œ์žฅ LANยทread-only ํ•œ์ •์˜ ๋ณ„๋„ ๋ฏธ๋””์–ด ํ‰๋ฉด์ด๋ฉฐ, MQTT ์ด๋ฒคํŠธ ๋ฐฑ๋ณธยท๋กœ๋ด‡ ๋ช…๋ น ๊ฒฝ๋กœ์™€ ๋ฌด๊ด€ํ•˜๋‹ค(ยง8.4).

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.yaml์— world ์ขŒํ‘œ๋กœ 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.yml์˜ zones.<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์— ์—ญ๋ณ‘ํ•ฉ ํ›„ ์žฌ์ƒ์„ฑ.

8.4 ๋ผ์ด๋ธŒ ์˜์ƒ ์ค‘๊ณ„ (WebRTC relay) โ€” ์ „์‹œ์žฅ ๋ฐ๋ชจ ํ•œ์ •

โš ๏ธ ์ „์‹œ์žฅ ์ „์šฉ(๋น„๊ณต๊ฐœยทLAN) ์˜ˆ์™ธ. ๋ธŒ๋ผ์šฐ์ €๋Š” RTSP๋ฅผ ์ง์ ‘ ์žฌ์ƒํ•  ์ˆ˜ ์—†๋‹ค(raw TCP/UDP socket ๋ถˆ๊ฐ€). CCTV ๋ผ์ด๋ธŒ ์˜์ƒ์„ ํ™”๋ฉด์— ๋„์šฐ๋ ค๋ฉด RTSP๋ฅผ ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜ ์ „์†ก์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์ค‘๊ฐ„์—์„œ ์ „๋‹ฌํ•˜๋Š” ์ค‘๊ณ„์„œ๋ฒ„(relay) ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•˜๋‹ค. ๋ณธ ์‹œ์Šคํ…œ์€ ์ด๋ฅผ ๋…๋ฆฝ ์„œ๋น„์Šค cctv-relay(go2rtc ๊ธฐ๋ฐ˜) ๋กœ ๋‘”๋‹ค โ€” Frigate(detect/์ด๋ฒคํŠธ)์™€ ๋ถ„๋ฆฌํ•ด ๋ผ์ด๋ธŒ ์˜์ƒ๋งŒ ์ฑ…์ž„์ง„๋‹ค. ์ด๋Š” ยง6.1์˜ "๋‚ด๋ถ€ ์„œ๋น„์Šค ๊ฐ„ HTTP/gRPC ๊ธˆ์ง€" ๋ถˆ๋ณ€์‹์„ ๋ผ์ด๋ธŒ ์˜์ƒ(read-only) ํ•œ์ •์œผ๋กœ ์˜๋„์ ์œผ๋กœ ์™„ํ™”ํ•œ ๊ฒƒ์ด๋ฉฐ, MQTT ์ด๋ฒคํŠธ ๋ฐฑ๋ณธยท๋กœ๋ด‡ ๋ช…๋ น๊ณผ ๋ฌด๊ด€ํ•œ ๋ณ„๋„ ๋ฏธ๋””์–ด ํ‰๋ฉด(media plane) ์ด๋‹ค. ์˜์ƒ ๋ณธ์ฒด๋Š” ๋””์Šคํฌ์— ๋‚จ๊ธฐ์ง€ ์•Š๋Š”๋‹ค(ยง11.3, ๋…นํ™”ยท์Šค๋ƒ…์ƒท ๋ฏธ์‚ฌ์šฉ โ€” ๋ผ์ด๋ธŒ ํ†ต๊ณผ๋งŒ). ์„œ๋น„์Šคยท์„ค์ • ์ƒ์„ธ๋Š” SERVICES.md ยง2.5.

8.4.1 ์ „์†ก ๋ฐฉ์‹ ์„ ํƒ โ€” ์™œ WebRTC

๋ฐฉ์‹ ์ง€์—ฐ(latency) ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜ ์ฑ„ํƒ
WebRTC (WHEP) ~0.2โ€“0.5s ์ „ ๋ธŒ๋ผ์šฐ์ € (H.264๋งŒ, HEVC ๋ถˆ๊ฐ€) 1์ˆœ์œ„ โ€” ๋ผ์ด๋ธŒ ๋ชจ๋‹ˆํ„ฐ๋ง ์ตœ์ 
MSE (fMP4 over WS) ~0.5โ€“1.5s Chrome/Edge/FF (iOS Safari ์ œ์•ฝ) ํด๋ฐฑ
LL-HLS / HLS ~2โ€“4s / 6โ€“20s ์ „ ๋ธŒ๋ผ์šฐ์ € (iOS ๋„ค์ดํ‹ฐ๋ธŒ) ์ง€์—ฐ ๊ณผ๋‹ค โ€” ๋ฏธ์ฑ„ํƒ
JSMpeg (MPEG-TS over WS) ~1s ์ „ ๋ธŒ๋ผ์šฐ์ € JS ๋””์ฝ”๋”ฉยท๋ฌด์˜ค๋””์˜คยท์ €ํšจ์œจ โ€” ๋ฏธ์ฑ„ํƒ

8.4.2 ์ค‘๊ณ„ ๊ตฌ์กฐ (data plane vs signaling plane)

   RTSP (n๊ฐœ ์†Œ์Šค, config ๊ตฌ๋™)
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ CCTV n โ”‚                    โ”‚ 1 (go2rtc, ๋…๋ฆฝ)     โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ”‚  config/cctv-relay.yaml ์˜    โ”‚
                                โ”‚  streams ๋งต โ†’ ์ž๋™ ๋“ฑ๋กยท์—ฐ๊ฒฐ  โ”‚
                                โ”‚  RTSP โ†’ WebRTC/MSE restream   โ”‚
                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                        โ”‚ โ‘  WHEP ์‹œ๊ทธ๋„๋ง (SDP offer/answer, HTTP)
                                        โ”‚    ๋ธŒ๋ผ์šฐ์ € โ†’ tablet-fe BFF(same-origin) โ†’ cctv-relay
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”‚
   โ”‚ ๋ธŒ๋ผ์šฐ์ €          โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   โ”‚ (tablet-fe ํ™”๋ฉด)  โ”‚
   โ”‚                  โ”‚ โ—„โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ–บ  cctv-relay
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ‘ก ๋ฏธ๋””์–ด(SRTP)๋Š” ICE๋กœ ๋ธŒ๋ผ์šฐ์ € โ†” cctv-relay ์ง์ ‘(P2P)
  • n-stream config ๊ตฌ๋™: ์นด๋ฉ”๋ผ ์†Œ์Šค๋Š” config/cctv-relay.yaml์˜ streams: ๋งต์— ์›๋ณธ RTSP ์ฃผ์†Œ๋ฅผ ํ•œ ์ค„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ž๋™ ๋“ฑ๋กยท์—ฐ๊ฒฐ๋œ๋‹ค(์ฝ”๋“œ ๋ณ€๊ฒฝ ๋ถˆํ•„์š”). n๋Œ€ ํ™•์žฅ = ํ•ญ๋ชฉ n๊ฐœ. ์„ค์ •ยท์ƒ์„ฑ ์Šคํฌ๋ฆฝํŠธ๋Š” SERVICES.md ยง2.5.
  • ์‹œ๊ทธ๋„๋ง(โ‘ ): ๋ธŒ๋ผ์šฐ์ €๋Š” RTSP ์ž๊ฒฉ์ฆ๋ช…ยทrelay ์ฃผ์†Œ๋ฅผ ๋ชจ๋ฅธ ์ฑ„, same-origin์œผ๋กœ tablet-fe BFF(/api/cctv/webrtc/<cam>)์— WHEP offer(SDP)๋ฅผ ๋ณด๋‚ธ๋‹ค. BFF๊ฐ€ cctv-relay API(/api/webrtc?src=<cam>)๋กœ ํ”„๋ก์‹œํ•˜๊ณ  answer(SDP)๋ฅผ ๋Œ๋ ค์ค€๋‹ค. ์นด๋ฉ”๋ผ ์ž๊ฒฉ์ฆ๋ช…์€ cctv-relay(์„œ๋ฒ„)๋งŒ ๋ณด์œ  โ†’ ๋ธŒ๋ผ์šฐ์ € ๋ฒˆ๋“ค์— ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค(๊ธฐ์กด CCTV SSE ๋ธŒ๋ฆฌ์ง€์™€ ๋™์ผํ•œ ์ž๊ฒฉ์ฆ๋ช… ๊ฒฉ๋ฆฌ ์›์น™).
  • ๋ฏธ๋””์–ด(โ‘ก): SDP ํ˜‘์ƒ ํ›„ ์˜์ƒ(SRTP)์€ ๋ธŒ๋ผ์šฐ์ € โ†” cctv-relay ๊ฐ„ ICE๋กœ ์ง์ ‘(P2P) ํ๋ฅธ๋‹ค. Node BFF๋Š” ์‹œ๊ทธ๋„๋ง๋งŒ ์ค‘๊ณ„ํ•˜๊ณ  ๋ฏธ๋””์–ด๋Š” ๊ฑฐ์น˜์ง€ ์•Š๋Š”๋‹ค(Node๊ฐ€ SRTP๋ฅผ relayํ•˜์ง€ ์•Š์Œ โ†’ BFF ๋ถ€ํ•˜ยท์ง€์—ฐ ํšŒํ”ผ).
  • LAN ํ•œ์ • โ†’ STUN/TURN ๋ถˆํ•„์š”: cctv-relay๊ฐ€ host candidate(์ „์‹œ์žฅ LAN IP:8555)๋งŒ ๊ด‘๊ณ ํ•˜๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค. ๊ณต๊ฐœ ์„œ๋น„์Šค ์ „ํ™˜ ์‹œ์—๋งŒ TURN์„ ๊ฒ€ํ† ํ•œ๋‹ค.
  • RTSP pull ํ† ํด๋กœ์ง€: ๊ธฐ๋ณธ์€ cctv-relay๊ฐ€ ์นด๋ฉ”๋ผ์—์„œ ๋…๋ฆฝ pull(Frigate detect์™€ ๋ถ„๋ฆฌ โ†’ ์žฅ์•  ๊ฒฉ๋ฆฌ). ์นด๋ฉ”๋ผ ๋™์‹œ ์—ฐ๊ฒฐ ์ œํ•œ์ด ๋นก๋นกํ•˜๋ฉด ๋‹จ์ผ-pull ๋ณ€ํ˜• ๊ฐ€๋Šฅ(ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋Š” SERVICES.md ยง2.5).

8.4.3 ์ฝ”๋ฑยท์˜ค๋””์˜ค ์ฃผ์˜

  • WebRTC๋Š” H.264๋งŒ ์‹ค์งˆ ์ง€์›(HEVC/H.265 ๋ถˆ๊ฐ€). ์นด๋ฉ”๋ผ๊ฐ€ H.265 ์†ก์ถœ์ด๋ฉด go2rtc์—์„œ H.264 transcode๊ฐ€ ํ•„์š” โ†’ CPU/GPU ๋น„์šฉ ๋ฐœ์ƒ. ๋„์ž… ์ „ ffprobe rtsp://...๋กœ ์ฝ”๋ฑ ํ™•์ธ์ด ์„ ๊ฒฐ.
  • ์˜ค๋””์˜ค๋Š” WebRTC ํ˜ธํ™˜(OPUS/PCMU)์œผ๋กœ transcode๊ฐ€ ํ•„์š”ํ•˜๋‚˜, CCTV ๋ชจ๋‹ˆํ„ฐ๋ง์€ ํ†ต์ƒ ์˜ค๋””์˜ค ๋น„ํ™œ์„ฑ์œผ๋กœ ๋‘”๋‹ค.

8.4.4 ํด๋ฐฑ

  • WebRTC ํ˜‘์ƒ ์‹คํŒจ(์ฝ”๋ฑยทICE) ์‹œ MSE(fMP4 over WS) ๋กœ ํด๋ฐฑ โ†’ ์ตœํ›„ HLS.
  • ์šด์˜์ž ์ฝ˜์†”์€ Frigate ์ž์ฒด UI(:5000)๋กœ๋„ ๋ผ์ด๋ธŒ ํ™•์ธ ๊ฐ€๋Šฅ(ยง6.1).

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๋Š” ephemeral โ€” bridge(๋˜๋Š” ๋ณ„๋„ ์ธํผ๋Ÿฐ์Šค ์„œ๋น„์Šค)๊ฐ€ frame ๋‹จ์œ„๋กœ ํ‰๊ฐ€ํ•˜์—ฌ context/user/<session_id>/update์˜ moodยท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.intent์˜ intent_type์— intro_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๊ฐœ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ