MQTT_SCHEMA FUTURE_CAR - zero1ne-26/doc GitHub Wiki

Future Car MQTT ์Šคํ‚ค๋งˆ (main-2026)

์ด ๋ฌธ์„œ๋Š” Future Car ํŒ€์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์œ„ํ‚ค MQTT_SCHEMA-FUTURE_CAR(2026-07-19ํŒ)๋ฅผ main-2026 ์‹ค์ œ ๊ตฌํ˜„ ๊ธฐ์ค€์œผ๋กœ ๊ฐฑ์‹ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ดˆ์•ˆ์ด ์•„๋‹ˆ๋ผ ํ˜„์žฌ ๋ฐฐํฌ๋˜์–ด ๋„๋Š” ์ฝ”๋“œ๋ฅผ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค โ€” ์Šคํ‚ค๋งˆ์™€ ์ฝ”๋“œ๊ฐ€ ์–ด๊ธ‹๋‚˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ •๋ณธ์ž…๋‹ˆ๋‹ค.

  • ๋Œ€์ƒ ๊ตฌํ˜„: zer01ne-future-car-server ๋ธŒ๋žœ์น˜ main-2026
  • ๋ฐฐํฌ: Mac Studio (Tailscale) ยท FastAPI + paho-mqtt
  • ์ตœ์ข… ์ˆ˜์ •์ผ: 2026-08-28 (์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ STT ํŠธ๋ฆฌ๊ฑฐ ยท task/start ยท basic ๋งŒ ์ˆ˜ํ–‰ ยท 8์žฅ ์ „์ฒด ํ๋ฆ„ ์„œ์ˆ )

ํ•œ๋ˆˆ์— โ€” ๋ฏธ๋ž˜์ฐจ๋Š” ๋ˆ„๊ตฌ์™€ ๋ฌด์—‡์„ ์ฃผ๊ณ ๋ฐ›๋‚˜

            plan ยท dashboard ยท me                          enter ยท exit
   OC  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ  ๋ฏธ๋ž˜์ฐจ  โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  ํƒœ๋ธ”๋ฆฟ
   OC  โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  ๋ฏธ๋ž˜์ฐจ  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ  ํƒœ๋ธ”๋ฆฟ
            task/start ยท task/complete ยท ai/mode        state ยท route ยท step ยท error ยท ai/response(์งˆ๋ฌธ) ยท ai/suggestions
                                                   โ–ฒ
                                      ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ(STT) โ€” ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๊ฐ€ ์Šคํ…์„ ์ด๋ˆ๋‹ค
์ƒ๋Œ€ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๋ฐ›๋Š” ๊ฒƒ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๋ณด๋‚ด๋Š” ๊ฒƒ
OC plan(ํŽ˜๋ฅด์†Œ๋‚˜ยท์žฅ์†Œ ์นดํƒˆ๋กœ๊ทธ) ยท dashboard(์ฐจ ์•ž๋’ค ์žฅ์†Œยทํƒœ์Šคํฌ) ยท me(๋™ํ–‰์ž ํ”„๋กฌํ”„ํŠธ) task/start ยท task/complete ยท ai/mode
ํƒœ๋ธ”๋ฆฟ enter ยท exit state ยท route ยท step ยท error ยท ai/responseยทai/suggestions(์ฑ„ํŒ… ์งˆ๋ฌธ๊ณผ ๋‹ต ํ›„๋ณด โ€” ์ง์ ‘ ๋ฐœํ–‰)
๊ด€๋žŒ๊ฐ(์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ) ๋ฐœํ™”(STT โ†’ POST /ambient/utterance) โ€” ์Šคํ… ์ง„ํ–‰ ํŠธ๋ฆฌ๊ฑฐ โ€”

2026-08-28 ์ •์ฑ…: ์Šคํ… ์ง„ํ–‰์€ ์ฐจ๋Ÿ‰ ํ™”๋ฉด์— ์—ฐ๊ฒฐํ•œ ๋งˆ์ดํฌ๋กœ๋งŒ ํ•œ๋‹ค. ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ(enter~exit) ๋™์•ˆ ํƒœ๋ธ”๋ฆฟ์€ ๋งˆ์ดํฌยทํƒ€์ดํ•‘ยท์ œ์•ˆ ์นฉ์„ ์ž ๊ทผ๋‹ค(tablet-fe ์ž‘์—…). ai/response.transcript ๊ตฌ๋…์€ ๋‚จ์•„ ์žˆ์ง€๋งŒ ์ •์‹ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹ˆ๋‹ค.

์ฆ‰ ๋ฐ์ดํ„ฐ๋Š” OC ์—์„œ ๋ฐ›๊ณ , ์กฐ์ž‘์€ ํƒœ๋ธ”๋ฆฟ์—์„œ ๋ฐ›๊ณ , ๊ฒฐ๊ณผ๋Š” ์–‘์ชฝ์— ๋ณด๋‚ธ๋‹ค. OC ์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ์ ์€ ๊ฒŒ ์•„๋‹ˆ๋ผ "๋ฐ›๋Š” ๊ฒƒ 4, ๋ณด๋‚ด๋Š” ๊ฒƒ 2~3" ์œผ๋กœ ์˜คํžˆ๋ ค OC ์ชฝ์ด ๋” ๋งŽ๋‹ค. ํƒœ๋ธ”๋ฆฟ๊ณผ๋Š” ์š”์ฒญ 2์ข…ยท์‘๋‹ต 4์ข…์ด ์ „๋ถ€๋‹ค.

๊ตฌํ˜„ ์ŠคํŽ™(๋‹ด๋‹น์ž ์ „๋‹ฌ์šฉ): OC ยท tablet-fe

๋ชฉ์ฐจ


0. 2026-07-19ํŒ ๋Œ€๋น„ ๋ณ€๊ฒฝ์ 

๋จผ์ € ์ฝ์–ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด ๋ฌธ์„œ๋ฅผ ์•Œ๊ณ  ๊ณ„์‹  ๋ถ„์€ ์—ฌ๊ธฐ๋งŒ ๋ด๋„ ์ฐจ์ด๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ํ•ญ๋ชฉ 2026-07-19ํŒ main-2026 (ํ˜„์žฌ)
1 RESPONSE ํƒ€์ž… state ยท reaction 2์ข… state ยท step ยท error 3์ข…. reaction ์€ ๊ณ„์•ฝ์— ๋‚จ์•„์žˆ์œผ๋‚˜ ๋ฐœํ–‰ํ•˜์ง€ ์•Š์Œ
2 ์Šคํ… ์ฝ˜ํ…์ธ  ์ „๋‹ฌ ๋ช…์‹œ ์—†์Œ step ๋ฉ”์‹œ์ง€๊ฐ€ ์ฃผ๋ ฅ. ๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด์ด ์žฌ์ƒํ•  ์—ฐ์ถœ ๋ฐ์ดํ„ฐ(data)๋ฅผ ํ†ต์งธ๋กœ ์‹ค์–ด ๋ณด๋ƒ„
3 plan.stops ์Šคํ… ์ˆ˜ยท์žฅ์†Œ๋ฅผ ๊ฒฐ์ • ์ƒ์„ฑ ์ž…๋ ฅ์œผ๋กœ ์“ฐ์ง€ ์•Š์Œ. plan.persona ๋งŒ ์‚ฌ์šฉ, ์Šคํ… ์ˆ˜๋Š” 4๊ฐœ ๊ณ ์ •
4 ์—ฌ์ • ์†Œ์žฌ plan.stops[].place orchestration/{sid}/dashboard ํ† ํ”ฝ์—์„œ ์ฐจ ์œ„์น˜์˜ ์ด์ „/๋‹ค์Œ ์žฅ์†Œยทํƒœ์Šคํฌ๋ฅผ ์ถ”์ถœ
5 start ๋…๋ฆฝ ํŠธ๋ฆฌ๊ฑฐ (step1 ์ง„์ž…) ํ๊ธฐ. ์ง„ํ–‰์€ advance ๋กœ ํ†ต์ผ. ์•„์›ƒ๋ฐ”์šด๋“œ(NextAction)์—์„œ๋Š” ์ œ๊ฑฐํ–ˆ๊ณ , ์ธ๋ฐ”์šด๋“œ๋งŒ ๋ณ„์นญ์œผ๋กœ ๋ฐ›์•„์ค€๋‹ค
6 context_action ๋ฏธ๋ž˜์ฐจ๊ฐ€ reaction ์ƒ์„ฑ no-op. ์ˆ˜์‹ ํ•ด๋„ ์•„๋ฌด ๋™์ž‘ ์—†์Œ(๋””์ŠคํŒจ์น˜ ์•ˆ์ •์„ฑ ์œ„ํ•ด ํ•ธ๋“ค๋Ÿฌ๋งŒ ์œ ์ง€)
7 phase=arrived ์ง„์ž… ๋ฏธ์ • ๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด์˜ ๋ Œ๋” ์™„๋ฃŒ ๋ณด๊ณ ๋กœ ์ง„์ž… (์•„๋ž˜ 6์žฅ)
8 retained request ์–ธ๊ธ‰ ์—†์Œ retain ์žฌ์ „์†ก๋ถ„์€ ๋ฌด์‹œ. ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ ๊ณผ๊ฑฐ ์„ธ์…˜ ๋Œ€๋Ÿ‰ ์žฌ์ƒ์„ฑ์„ ๋ง‰๊ธฐ ์œ„ํ•จ (์•„๋ž˜ 3์žฅ โš ๏ธ)
9 state ํ•„๋“œ โ€” prev_place ยท next_place ์ถ”๊ฐ€ (๋Œ€๊ธฐ ํ™”๋ฉด์ด "์–ด๋””์„œ ์™”๋Š”์ง€"๋ฅผ ํ‘œ์‹œ)
10 ์—๋Ÿฌ ํ†ต์ง€ ์—†์Œ error ํƒ€์ž… + ์ฝ”๋“œ 4์ข…
11 ์ง„ํ–‰ ํŠธ๋ฆฌ๊ฑฐ ํƒœ๋ธ”๋ฆฟ advance ๋ฒ„ํŠผ ๊ด€๋žŒ๊ฐ ๋ฐœํ™” โ€” ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ STT โ†’ POST /ambient/utterance. advance ํ๊ธฐ โ€” ํƒœ๋ธ”๋ฆฟ์€ enterยทexit ๋งŒ ๋ณด๋‚ธ๋‹ค
12 ์Šคํ… ์ƒ์„ฑ ์‹œ์  plan ์ˆ˜์‹  ์งํ›„ 4๊ฐœ ์ผ๊ด„ ๋ฐœํ™”๊ฐ€ ๋„์ฐฉํ•  ๋•Œ ํ•˜๋‚˜์”ฉ. ๋ฏธ๋ฆฌ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค
13 ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ… ๋ฌด๊ด€ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ai/responseยทai/suggestions ์— ์งˆ๋ฌธ๊ณผ ๋‹ต ํ›„๋ณด๋ฅผ ์ง์ ‘ ๋ฐœํ–‰ํ•œ๋‹ค(3-2-1). ๊ด€๋žŒ๊ฐ์˜ ๋‹ต์€ ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ๋กœ ๋ฐ›๋Š”๋‹ค
14 RESPONSE ํƒ€์ž… 3์ข… + route (์ด๋ฒˆ ๊ตฌ๊ฐ„์˜ ์ถœ๋ฐœ/๋„์ฐฉ stop_id)
15 state.next advance | exit exit ํ•˜๋‚˜. ๋งˆ์ง€๋ง‰ ์Šคํ… ๋„์ฐฉ ๋•Œ๋งŒ ์‹ค๋ฆฐ๋‹ค
16 ๊ตฌ๋… ํ† ํ”ฝ request ยท dashboard + ai/response ยท me
17 ์ฐจ๋Ÿ‰ ํƒœ์Šคํฌ ์ œ๋ชฉ๋งŒ ์†Œ์žฌ๋กœ ์‚ฌ์šฉ type=basic ๋งŒ step ๋‹น 1๊ฐœ์”ฉ AI ๊ฐ€ ๊ณจ๋ผ ์ˆ˜ํ–‰. ์Šคํ… ๋ฐœํ–‰ ์‹œ task/start, ๋ Œ๋” ์™„๋ฃŒ ์‹œ task/complete(์„œ๋ฒ„๋Š” ์™„๋ฃŒ๋ถ„์„ ๋นผ์„œ ์ค‘๋ณต ๋ฐฉ์ง€). ๊ทธ ์™ธ ํƒ€์ž…(๋‹๋ณด๊ธฐ ๋ชจ๋‹ฌํ˜•)์€ ํƒœ๋ธ”๋ฆฟ์—์„œ ๊ด€๋žŒ๊ฐ์ด ์™„๋ฃŒ โ€” ๋ฏธ๋ž˜์ฐจ๋Š” ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค
18 step4 ์งˆ๋ฌธ ์žˆ์Œ ์—†์Œ. ๋งˆ์ง€๋ง‰ step ๋’ค์—๋Š” ์งˆ๋ฌธ์„ ๋„์šฐ์ง€ ์•Š๋Š”๋‹ค
19 ai/request ์ง€์‹œ๋ฌธ ๋™๋ด‰ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. ์งˆ๋ฌธ์€ ai/response ์ง์ ‘ ๋ฐœํ–‰(Aโ€ฒ). passthrough ๋Š” OC ๊ฐ€ ์ง์ ‘ ๋ฐœํ–‰์„ ๊ฑฐ์ ˆํ–ˆ์„ ๋•Œ์˜ ๋Œ€์•ˆ์œผ๋กœ๋งŒ ๋‚จ๊น€(env OC_CHAT_PUBLISH=request)

1. ๊ฐœ์š”

ํ•ญ๋ชฉ ๋‚ด์šฉ
๋ธŒ๋กœ์ปค MQTT_BROKER_URL (๊ธฐ๋ณธ tcp://127.0.0.1:1883)
๊ณ„์ • user future-car / MQTT_USERNAMEยทMQTT_PASSWORD ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ
client_id future-car (MQTT_CLIENT_ID) โ€” โš ๏ธ ์•„๋ž˜ ์ฃผ์˜ ์ฐธ๊ณ 
ํŽ˜์ด๋กœ๋“œ ํ‰๋ฌธ JSON ยท snake_case ยท session_id ๋Š” ํ† ํ”ฝ ๊ฒฝ๋กœ์—๋งŒ (ํŽ˜์ด๋กœ๋“œ์— ์—†์Œ)
๋ถ„๊ธฐ ๋ฐฉ์‹ request/response 2ํ† ํ”ฝ + type ํ•„๋“œ
MQTT ์ ‘์† ์ฃผ์ฒด ๋ฏธ๋ž˜์ฐจ FastAPI ์„œ๋ฒ„ 1๊ฐœ. ๋ธŒ๋ผ์šฐ์ €(์ „์‹œ ํ™”๋ฉด /ambient)๋Š” MQTT ๋ฏธ์ ‘์† โ†’ ์„œ๋ฒ„๊ฐ€ WebSocket ์œผ๋กœ ์ค‘๊ณ„
์Šคํ… ์ˆ˜ 4 ๊ณ ์ • (STEP_COUNT = 4). plan.stops ๊ฐœ์ˆ˜์™€ ๋ฌด๊ด€

โš ๏ธ client_id ์ถฉ๋Œ ์ฃผ์˜. ๊ฐ™์€ client_id ๋กœ ๋‘ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ถ™์œผ๋ฉด ๋ธŒ๋กœ์ปค๊ฐ€ ๋จผ์ € ๋ถ™์€ ์ชฝ์„ ๋Š์Šต๋‹ˆ๋‹ค(session taken over). ๋กœ์ปฌ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ๋„์šธ ๋• ๋ฐ˜๋“œ์‹œ MQTT_CLIENT_ID ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ฃผ์„ธ์š”. ์ฆ์ƒ์€ "๋ฉ”์‹œ์ง€๊ฐ€ ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง"์ด๋ผ ์›์ธ์„ ์ฐพ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.


2. ํ† ํ”ฝ ๋ชฉ๋ก

๊ตฌ๋ถ„ Topic ๋ฐฉํ–ฅ QoS Retain ์„ค๋ช…
REQUEST orchestration/{sessionId}/future-car/request OCยทํƒœ๋ธ”๋ฆฟ โ†’ ๋ฏธ๋ž˜์ฐจ 1 OC ๊ฐ€ plan ์„ retain ๋ฐœํ–‰ ์ค‘ type: plan ยท enter ยท exit (startยทadvance ํ๊ธฐยท๋ณ„์นญ ยท context_action no-op)
RESPONSE orchestration/{sessionId}/future-car/response ๋ฏธ๋ž˜์ฐจ โ†’ ํƒœ๋ธ”๋ฆฟยทOC 1 state ๋งŒ retain=true type: state ยท route ยท step ยท error
DASHBOARD orchestration/{sessionId}/dashboard OC โ†’ ์ „์ฒด 1 retain=true ๋ฐฉ๋ฌธ์ž์˜ ๋ชจ๋“  ์žฅ์†Œยทํƒœ์Šคํฌ. ๋ฏธ๋ž˜์ฐจ๋Š” ๊ตฌ๋…๋งŒ
ME orchestration/{sessionId}/me OC โ†’ ์ „์ฒด 1 retain=true ai_companion.prompt โ€” ์Šคํ… ์ƒ์„ฑ ํ”„๋กฌํ”„ํŠธ ์•ž์— ๋ถ™์ผ ์ธ๊ฒฉ. ๊ตฌ๋…๋งŒ
AI RESPONSE orchestration/{sessionId}/ai/response OC โ†’ ์ „์ฒด + ๋ฏธ๋ž˜์ฐจ โ†’ ํƒœ๋ธ”๋ฆฟ 1 false OC ๋ฐœํ–‰๋ถ„: transcript = ๊ด€๋žŒ๊ฐ ๋ฐœํ™”(STT) โ†’ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ์Šคํ… ์žฌ๋ฃŒ๋กœ. ๋ฏธ๋ž˜์ฐจ ๋ฐœํ–‰๋ถ„: message = ์ฑ„ํŒ…์— ๋„์šธ ์งˆ๋ฌธ(Aโ€ฒ)
AI SUGGESTIONS orchestration/{sessionId}/ai/suggestions ๋ฏธ๋ž˜์ฐจ โ†’ ํƒœ๋ธ”๋ฆฟ 1 false ๋ฏธ๋ž˜์ฐจ ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต ํ›„๋ณด ์นฉ 2๊ฐœ
AI MODE orchestration/{sessionId}/ai/mode ๋ฏธ๋ž˜์ฐจ โ†’ OC 1 true enter ์งํ›„ {"mode":"car","ttl_sec":1800}, exit ์งํ›„ {"mode":"chat"}. OC ๊ตฌํ˜„ ์™„๋ฃŒ(2026-08-24) โ€” car ๋™์•ˆ type=voice ๋Š” STT ๋งŒ, signout ์‹œ retained ์‚ญ์ œ
TASK START orchestration/{sessionId}/task/start ๋ฏธ๋ž˜์ฐจ โ†’ OC 1 false {"task_id"} โ€” ์Šคํ… ๋ฐœํ–‰(์ฃผํ–‰ ์‹œ์ž‘) ์‹œ ๊ทธ ์Šคํ…์˜ basic ํƒœ์Šคํฌ๋ฅผ ์ง„ํ–‰ ์ค‘์œผ๋กœ. OC ๊ฐ€ dashboard ๋ฅผ in_progress ๋กœ ์žฌ๋ฐœํ–‰ โ†’ ํƒœ๋ธ”๋ฆฟ ์นด๋“œ "์ง„ํ–‰ ์ค‘". TASK_START_ENABLED=false ๋กœ ๋Œ ์ˆ˜ ์žˆ๋‹ค
TASK COMPLETE orchestration/{sessionId}/task/complete ๋ฏธ๋ž˜์ฐจ โ†’ OC 1 false {"task_id"} โ€” ๋ Œ๋” ์™„๋ฃŒ ์‹œ ๊ฐ™์€ ํƒœ์Šคํฌ๋ฅผ ์™„๋ฃŒ๋กœ. ํƒœ๋ธ”๋ฆฟ์ด ๋ณด๋‚ด๋Š” ๊ฒƒ๊ณผ ๋™์ผ ํŽ˜์ด๋กœ๋“œ. OC ๊ฐ€ dashboardยทpoint ์žฌ๋ฐœํ–‰(์‘๋‹ต ํ† ํ”ฝ ์—†์Œ)

๊ตฌ๋…์€ ์ „๋ถ€ ์™€์ผ๋“œ์นด๋“œ๋‹ค โ€” session_id ๋Š” ํ† ํ”ฝ์—์„œ ์ถ”์ถœํ•œ๋‹ค.

orchestration/+/future-car/request
orchestration/+/dashboard
orchestration/+/me
orchestration/+/ai/response

3. REQUEST (future-car/request)

โš ๏ธ retained ์žฌ์ „์†ก๋ถ„์€ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค

OC ๊ฐ€ plan ์„ retain=true ๋กœ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฏธ๋ž˜์ฐจ ์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘ํ•ด ์žฌ๊ตฌ๋…ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ธŒ๋กœ์ปค๊ฐ€ ๊ณผ๊ฑฐ ๋ฐฉ๋ฌธ์ž๋“ค์˜ plan ์„ ์ „๋ถ€ ๋‹ค์‹œ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ์„ธ์…˜๋งˆ๋‹ค 4์Šคํ…์”ฉ LLM ์žฌ์ƒ์„ฑ์ด ๋Œ์•„, ์žฌ๋ฐฐํฌ 1ํšŒ์— 36์„ธ์…˜ ร— 4 โ‰ˆ 144ํšŒ ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(์‹ค์ธก).

๊ทธ๋ž˜์„œ retain ํ”Œ๋ž˜๊ทธ๊ฐ€ ์„  REQUEST ๋ฉ”์‹œ์ง€๋Š” ์ „๋ถ€ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

์ด๊ฒŒ ๋ผ์ด๋ธŒ ๋ฐœํ–‰์„ ๋ง‰์ง€ ์•Š๋Š” ์ด์œ : MQTT ๋ช…์„ธ์ƒ retain ํ”Œ๋ž˜๊ทธ๋Š” ์ƒˆ ๊ตฌ๋…์˜ ๊ฒฐ๊ณผ๋กœ ์žฌ์ „์†ก๋  ๋•Œ๋งŒ ์„ธ์›Œ์ง‘๋‹ˆ๋‹ค. ์ด๋ฏธ ๊ตฌ๋… ์ค‘์ธ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐฐ๋‹ฌ๋˜๋Š” ๋ฉ”์‹œ์ง€์—๋Š” ์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰ OC ๋Š” ์ง€๊ธˆ์ฒ˜๋Ÿผ retain=true ๋กœ ๊ณ„์† ๋ฐœํ–‰ํ•˜๋ฉด ๋˜๊ณ , ์ •์ƒ ์—ฌ์ •์€ ๊ทธ๋Œ€๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

3-1. plan (OC โ†’ ๋ฏธ๋ž˜์ฐจ)

ํŽ˜๋ฅด์†Œ๋‚˜ ์ƒ์„ฑ ์™„๋ฃŒ ์‹œ 1ํšŒ ๋ฐœํ–‰. ๋ฏธ๋ž˜์ฐจ๋Š” ์ด๊ฑธ ๋ฐ›๋Š” ์ฆ‰์‹œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ 4์Šคํ…์„ ์ˆœ์ฐจ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

{
  "type": "plan",
  "plan": {
    "persona": { "id": 12, "name": "์ง€ํ˜ธ", "summary": "์•ผ๊ทผ ์žฆ์€ ๊ฐœ๋ฐœ์ž" },
    "stops": []
  }
}
ํ•„๋“œ ํƒ€์ž… ํ•„์ˆ˜ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ์“ฐ๋Š”๊ฐ€
type string Y โ€”
plan.persona object Y โœ… ์ƒ์„ฑ ์ž…๋ ฅ. ๊ตฌ์กฐ๋Š” ์ž์œ (dict ํ†ต์งธ๋กœ LLM ์— ์ „๋‹ฌ)
plan.stops[] array Y (๋นˆ ๋ฐฐ์—ด ํ—ˆ์šฉ) โŒ ์“ฐ์ง€ ์•Š์Œ. ๊ณ„์•ฝ ํ˜ธํ™˜์„ ์œ„ํ•ด ํ•„๋“œ๋Š” ์œ ์ง€
  • ์Šคํ… ์ˆ˜๋Š” stops ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํ•ญ์ƒ 4๊ฐœ์ž…๋‹ˆ๋‹ค. ์ „์‹œ ์ •์ฑ…์ƒ ๊ณ ์ •์ž…๋‹ˆ๋‹ค.
  • ์—ฌ์ • ์†Œ์žฌ(์žฅ์†Œยทํƒœ์Šคํฌ)๋Š” stops ๊ฐ€ ์•„๋‹ˆ๋ผ dashboard ํ† ํ”ฝ์—์„œ ์˜ต๋‹ˆ๋‹ค(4์žฅ).
  • ๋™์ผ plan ์žฌ์ˆ˜์‹ ์€ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค(๊ฐ’ ๋น„๊ต). ์ง„ํ–‰ ์ค‘์ธ ์—ฌ์ •์ด ๋ฆฌ์…‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ ์ด๋ฏธ done ์ธ ์„ธ์…˜์€ ๋™์ผ plan ์ด์–ด๋„ ์ƒˆ ์—ฌ์ •์œผ๋กœ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค โ€” ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ๊ทธ session_id ๊ฐ€ ์˜๊ตฌํžˆ ์ž ๊น๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ plan ์ด ์˜ค๋ฉด ์ „์ฒด ๋ฆฌ์…‹ ํ›„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์žฌ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

3-2. enter

๋ฏธ๋ž˜์ฐจ ๊ณต๊ฐ„ ์ž…์žฅ. โ†’ ๋Œ€๊ธฐ ํ™”๋ฉด(step0)์œผ๋กœ ์ „ํ™˜. ๋ฐœํ–‰ ์ฃผ์ฒด: ํƒœ๋ธ”๋ฆฟ.

{ "type": "enter" }

์‘๋‹ต: state ยท phase=waiting (next ์—†์Œ)

๊ทธ๋ฆฌ๊ณ  ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๊ณง๋ฐ”๋กœ ai/response ์— ๊ณ ์ • ์งˆ๋ฌธ "์ถœ๋ฐœ ํ• ๊นŒ์š”?" ์™€ ai/suggestions ๋‹ต ํ›„๋ณด 2๊ฐœ๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ (3-2-1), ai/mode {car} ๋ฅผ retained ๋กœ ์˜ฌ๋ฆฐ๋‹ค. ์งˆ๋ฌธ์€ ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ…์— ๋œจ๊ณ , ๊ด€๋žŒ๊ฐ์ด ์ฐจ์— ๋Œ€๊ณ  ๋‹ตํ•˜๋ฉด ๊ทธ ๋‹ต์ด step1 ์ƒ์„ฑ์˜ ์žฌ๋ฃŒ๊ฐ€ ๋œ๋‹ค(6-2). โ†’ ์ง„ํ–‰ ํ๋ฆ„์€ 7์žฅยท8์žฅ ์ฐธ๊ณ .

3-2-1. ์—ฌ์ • ์ค‘ ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ… โ€” ๋ฏธ๋ž˜์ฐจ ์ง์ ‘ ๋ฐœํ–‰ + ์„ธ์…˜ ๋ชจ๋“œ

๊ฒฐ์ •(2026-08-23): ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

Aโ€ฒ โ€” ๋ฏธ๋ž˜์ฐจ ๋ฌธ์žฅ์€ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ์ง์ ‘ ์“ด๋‹ค (์ ์šฉ๋จ, OC ์ž‘์—… ์—†์Œ) ๋ฏธ๋ž˜์ฐจ๋Š” enter ์งํ›„์™€ ๊ฐ step ๋ Œ๋” ์™„๋ฃŒ ํ›„ orchestration/{sid}/ai/response ์— {ok:true, context_id, message:"์งˆ๋ฌธ"} ๊ณผ ai/suggestions {context_id, suggestions:[๋‹ต ํ›„๋ณด 2๊ฐœ]} ๋ฅผ ์ง์ ‘ ๋ฐœํ–‰ํ•œ๋‹ค. ํƒœ๋ธ”๋ฆฟ์€ ์ด๋ฏธ ๋ชจ๋ฅด๋Š” context_id ์˜ message ๋ฅผ AI ๋งํ’์„ ์œผ๋กœ, suggestions ๋ฅผ ์นฉ์œผ๋กœ ๊ทธ๋ฆฐ๋‹ค โ€” ํƒœ๋ธ”๋ฆฟ ๋ณ€๊ฒฝ ์—†์Œ. OC ๋Š” ์ด ํ† ํ”ฝ์„ ๊ตฌ๋…ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜ํ–ฅ ์—†์ง€๋งŒ, ๊ณ„์•ฝ์ƒ OC ๊ฐ€ ๋ฐœํ–‰์ž์ธ ํ† ํ”ฝ์ด๋ผ ๋™์˜๋ฅผ ๊ตฌํ•œ๋‹ค. ๊ฑฐ์ ˆ ์‹œ ๋Œ€์•ˆ: ai/request ์— passthrough:true(LLM ์—†์ด ๊ทธ๋Œ€๋กœ) ๊ตฌํ˜„ ์š”์ฒญ โ€” ๋ฏธ๋ž˜์ฐจ๋Š” env ํ•œ ์ค„๋กœ ๊ทธ ๊ฒฝ๋กœ๋กœ ๋Œ์•„๊ฐ„๋‹ค.

B โ€” ์„ธ์…˜ ๋ชจ๋“œ ai/mode (OC ๊ตฌํ˜„ ์™„๋ฃŒ 2026-08-24, ๋ฏธ๋ž˜์ฐจ ๋ฐœํ–‰ ์ค‘) enter ์งํ›„ {"mode":"car","ttl_sec":1800}, exit ์งํ›„ {"mode":"chat"} (retained). car ๋™์•ˆ OC ๋Š” ๊ด€๋žŒ๊ฐ ์Œ์„ฑ ๋ฐœํ™”(type=voice)์— STT ๋Š” ํ•˜๋˜ LLM ๋‹ต๋ณ€ยทํ›„์† ์ œ์•ˆ์„ ์ƒ๋žตํ•œ๋‹ค(transcript ๋งŒ, message ์—†์Œ). ์•ˆ์ „์žฅ์น˜: TTL ๋งŒ๋ฃŒยทexitยทsignout(retained ์‚ญ์ œ) ์„ธ ๊ฒน. โš ๏ธ OC ์˜ car ๋ถ„๊ธฐ๋Š” type=text(์นฉ ํƒญยทํƒ€์ดํ•‘)์—๋Š” ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ทธ๋ž˜์„œ ํƒœ๋ธ”๋ฆฟ์ด ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ ๋™์•ˆ ์ž…๋ ฅ์„ ์ž ๊ทธ๋Š” ๊ฒƒ(9-2-1)์ด 1์ฐจ ๋ฐฉ์–ด๊ณ , ai/mode ๋Š” 2์ฐจ๋‹ค. 2026-08-28 ์ •์ฑ…์œผ๋กœ ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๋Š” ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ๋กœ๋งŒ ๋ฐ›์œผ๋ฏ€๋กœ, ์—ฌ์ • ์ค‘ ํƒœ๋ธ”๋ฆฟ AI ์™€์˜ ๋Œ€ํ™”๋Š” ์—†๋‹ค.

3-3. advance ยท start (ํ๊ธฐ โ€” ์ธ๋ฐ”์šด๋“œ ๋ณ„์นญ์œผ๋กœ๋งŒ ๋‚จ์Œ)

๋‘˜ ๋‹ค ์“ฐ์ง€ ๋งˆ์„ธ์š”. ์Šคํ… ์ง„ํ–‰์€ ๋ฒ„ํŠผ์ด ์•„๋‹ˆ๋ผ ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๊ฐ€ ์ด๋ˆ๋‹ค(7์žฅ).

  • ์•„์›ƒ๋ฐ”์šด๋“œ์—์„œ๋Š” ์™„์ „ํžˆ ์ œ๊ฑฐ๋๋‹ค. NextAction ์€ exit ํ•˜๋‚˜๋ฟ์ด๋‹ค.
  • ์ธ๋ฐ”์šด๋“œ๋Š” ๋ฐ›์•„์ค€๋‹ค โ€” ๋ฐ›์œผ๋ฉด "๋ฐœํ™” ์—†์ด ๊ฐ•์ œ ์ง„ํ–‰" ํ•œ๋‹ค(ํ˜„์žฅ ๋น„์ƒ์šฉยท๋””๋ฒ„๊ทธ์šฉ). ์ง€์›Œ๋ฒ„๋ฆฌ๋ฉด ๊ตฌ ํƒœ๋ธ”๋ฆฟ์€ ์•„๋ฌด ์‘๋‹ต๋„ ๋ชป ๋ฐ›๊ณ  ๋ฉˆ์ถ˜๋‹ค(unknown type ์€ ์—๋Ÿฌ์กฐ์ฐจ ๋ฐœํ–‰ํ•˜์ง€ ์•Š์Œ).
  • ๋ฐ›์œผ๋ฉด /mqtt ํŠธ๋ž˜ํ”ฝ ๋กœ๊ทธ์— deprecated ๋กœ ๋‚จ๋Š”๋‹ค. ์ด ๊ธฐ๋ก์ด ๋”๋Š” ์•ˆ ๋ณด์ด๋ฉด ๋ณ„์นญ์„ ์ œ๊ฑฐํ•ด๋„ ์•ˆ์ „ํ•˜๋‹ค.
  • ๋ฏธ๋ž˜์ฐจ /mqtt ๋””๋ฒ„๊ทธ ํ™”๋ฉด์˜ ์ˆ˜๋™ ๋ฐœํ–‰์—์„œ advance ๋Š” ๊ฐ•์ œ ์ง„ํ–‰ ๋ฒ„ํŠผ์œผ๋กœ ์—ฌ์ „ํžˆ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

3-5. exit

์—ฌ์ • ์ข…๋ฃŒ. โ†’ ์ž‘๋ณ„ ํ™”๋ฉด ๊ณ ์ •.

{ "type": "exit" }

์‘๋‹ต: state ยท phase=done

์ดํ›„ ์ƒˆ plan ์ด ์˜ค๊ธฐ ์ „๊นŒ์ง€ ์–ด๋–ค ์š”์ฒญ๋„ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ์ง€ ๋ชปํ•˜๋ฉฐ, error ยท JOURNEY_ENDED ๊ฐ€ ๋Œ์•„์˜ต๋‹ˆ๋‹ค.

3-6. context_action (ํ˜„์žฌ no-op)

{ "type": "context_action", "context_id": "c1", "action_kind": "open_meeting_doc" }

ambient ๋Š” ์‚ฌ์ „ ์ƒ์„ฑ๋œ step/error ๋กœ๋งŒ ์‘๋‹ตํ•˜๋ฏ€๋กœ ์ˆ˜์‹ ํ•ด๋„ ์•„๋ฌด ๋™์ž‘์ด ์—†์Šต๋‹ˆ๋‹ค(๋กœ๊ทธ๋งŒ ๋‚จ๊น€). reaction ๋„ ๋ฐœํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


4. DASHBOARD (orchestration/{sessionId}/dashboard)

OC ๊ฐ€ ๋ฐฉ๋ฌธ์ž์˜ ๋ชจ๋“  ์žฅ์†Œ(์ง‘/๊ณต์›/๋งˆํŠธ/์ฐจ โ€ฆ)์™€ ํƒœ์Šคํฌ๋ฅผ retain ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฏธ๋ž˜์ฐจ๋Š” ๊ตฌ๋…๋งŒ ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ ์ฐจ๋Ÿ‰ ๋ถ€๋ถ„๋งŒ ๊ณจ๋ผ ์Šคํ… ์ƒ์„ฑ์˜ ์—ฌ์ • ์†Œ์žฌ๋กœ ์”๋‹ˆ๋‹ค.

๋ฏธ๋ž˜์ฐจ๊ฐ€ ์ฝ๋Š” ๋ถ€๋ถ„

{
  "locations": [
    { "name": "์ง‘",  "visit_order": 1, "tasks": [ { "title": "..." } ] },
    { "name": "์ฐจ",  "visit_order": 2, "tasks": [ { "title": "์ถฉ์ „์†Œ ๊ฒฝ์œ " } ] },
    { "name": "๋งˆํŠธ", "visit_order": 3, "tasks": [] }
  ]
}
ํ•„๋“œ ์šฉ๋„
locations[].name ์ฐจ๋Ÿ‰ ์žฅ์†Œ ํŒ๋ณ„ ๊ธฐ์ค€. ์ด๋ฆ„์ด ์ฐจ ๋กœ ์‹œ์ž‘ํ•˜๋ฉด ์ฐจ๋Ÿ‰์œผ๋กœ ๋ณธ๋‹ค
locations[].visit_order ์ •๋ ฌ ํ‚ค. ์ฐจ ๋ฐ”๋กœ ์•ž/๋’ค ์žฅ์†Œ๋ฅผ prev_place/next_place ๋กœ ๋ฝ‘๋Š”๋‹ค
locations[].tasks[] ์ฐจ์— ๊ฑธ๋ฆฐ ํƒœ์Šคํฌ. idยทtitleยทtypeยทdescriptionยทstatus ๋ฅผ ์ถ”๋ฆฐ๋‹ค. description ์€ planning ๋ฉ”ํƒ€(planning_task_id: โ€ฆ ๊ฐ™์€ key: value ์ค„)๋ฅผ ๊ฑท์–ด๋‚ธ ์ฒซ ๋ฌธ์žฅ๋งŒ ์“ด๋‹ค. type=basic ๋งŒ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ์ˆ˜ํ–‰ํ•œ๋‹ค(ํƒœ๋ธ”๋ฆฟ์— ์กฐ์ž‘ UI ๊ฐ€ ์—†๋Š” ํƒ€์ž… โ€” ๊ทธ ์™ธ๋Š” ๋‹๋ณด๊ธฐ ๋ชจ๋‹ฌ์—์„œ ๊ด€๋žŒ๊ฐ์ด ์™„๋ฃŒ). step ๋‹น 1๊ฐœ โ€” ์–ด๋А ๊ฒƒ์„ ํ• ์ง€๋Š” AI ๊ฐ€ ๊ณ ๋ฅธ๋‹ค. ์„œ๋ฒ„๋Š” ์•„์ง ์•ˆ ๋๋‚œ basic ํƒœ์Šคํฌ๋งŒ(tasks_remaining) ๋งค ํ„ด ๋„˜๊ธฐ๊ณ , AI ๊ฐ€ ๊ทธ์ค‘ ํ•˜๋‚˜๋ฅผ task_key ๋กœ ๋ณด๊ณ ํ•˜๋ฉด ์Šคํ… ๋ฐœํ–‰ ๋•Œ task/start, ๊ด€๋žŒ๊ฐ์ด ์—ฐ์ถœ์„ ๋ณธ ๋’ค(๋ Œ๋” ์™„๋ฃŒ) task/complete ๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ  ๋‹ค์Œ ํ„ด ๋ชฉ๋ก์—์„œ ๋บ€๋‹ค. 4 step ์ด๋ผ basic ์ด 1๊ฐœ๋ฉด ๋‚˜๋จธ์ง€ step ์€ ํƒœ์Šคํฌ ์—†์ด ๊ฐ„๋‹ค(๋ชฐ์•„์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ). status ๋Š” OC ์žฌ๋ฐœํ–‰์œผ๋กœ in_progressโ†’completed ๋กœ ๋Œ์•„์˜ค๋ฉฐ, completedยทskip ๋งŒ "๋๋‚จ" ์œผ๋กœ ๋ณธ๋‹ค

ํŒ๋ณ„ ๊ทœ์น™๊ณผ ๊ทธ ์ด์œ 

  • ์ด๋ฆ„์ด 1์ˆœ์œ„ ํŒ๋ณ„ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค. id ๋Š” ์‹œ๋“œ๋งˆ๋‹ค ์ •์ˆ˜/UUID ๋กœ ์ œ๊ฐ๊ฐ์ด๋ผ ๋ถˆ์•ˆ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ์šด์˜ ๋ธŒ๋กœ์ปค์˜ retain ๋ฉ”์‹œ์ง€ 193๊ฑด์„ ๊ฒ€์ฆํ•œ ๊ฒฐ๊ณผ ์ฐจ๋Ÿ‰ ์žฅ์†Œ ์ด๋ฆ„์€ ์ฐจ, ์ฐจ๋Ÿ‰, ์ฐจ๋Ÿ‰ - ์ด๋™ ์„ธ ๋ณ€ํ˜•์ด ๊ด€์ธก๋์Šต๋‹ˆ๋‹ค โ†’ ์ ‘๋‘์‚ฌ ์ฐจ ๋กœ ํŒ๋ณ„ํ•ฉ๋‹ˆ๋‹ค.
  • device.name ์€ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Physical AI Hub ๋ผ๋Š” device ๊ฐ€ ์ง‘ ๊ณผ ์ฐจ ์–‘์ชฝ์— ๋“ฑ์žฅํ•œ ์‚ฌ๋ก€๊ฐ€ ์žˆ์–ด ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ ‘๋‘์‚ฌ๋Š” ์ฝ”๋“œ ๋ฐฐํฌ ์—†์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ฒŒ DASHBOARD_VEHICLE_PREFIXES ํ™˜๊ฒฝ๋ณ€์ˆ˜(์ฝค๋งˆ ๊ตฌ๋ถ„)๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์˜

  • ์ฐจ๋Ÿ‰ ์žฅ์†Œ๊ฐ€ ์•„์˜ˆ ์—†๋Š” ์„ธ์…˜์ด ์ •์ƒ์ ์œผ๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค โ€” OC ๊ฐ€ ๊ด€๋žŒ๊ฐ๋งˆ๋‹ค ์žฅ์†Œ๋ฅผ ๋žœ๋ค ๋ฐฐ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ persona ๋งŒ์œผ๋กœ ์ƒ์„ฑํ•˜๋ฉฐ ๊ฒฝ๊ณ  ๋กœ๊ทธ๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค.
  • plan ๊ณผ dashboard ๋Š” ๋ณ„๋„ ํ† ํ”ฝ์ด๋ผ ๋„์ฐฉ ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฏธ๋ž˜์ฐจ๋Š” ์ƒ์„ฑ ์‹œ์ ์— "๊ทธ ์ˆœ๊ฐ„ ์ตœ์‹ ๊ฐ’"์„ ์กฐํšŒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค.
  • retain ์žฌ์ „์†ก๋ถ„์€ ๊ธฐ๋ก ์—†์ด ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค โ€” ๊ตฌ๋… ์งํ›„ ๊ณผ๊ฑฐ ์„ธ์…˜ 200๊ฑด๊ฐ€๋Ÿ‰์ด ํ•œ๊บผ๋ฒˆ์— ๋ฐ€๋ ค์™€ ๋””๋ฒ„๊ทธ ํ™”๋ฉด์˜ ๋ง๋ฒ„ํผ๋ฅผ ๋ฎ์–ด์“ฐ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

5. RESPONSE (future-car/response)

type 3์ข…์ž…๋‹ˆ๋‹ค. ์ „๋ถ€ ๊ฐ™์€ ํ† ํ”ฝ์œผ๋กœ ๋‚˜๊ฐ‘๋‹ˆ๋‹ค.

5-1. state โ€” ์ƒํƒœ ์ „์ด (retain=true)

{
  "type": "state",
  "step": 2,
  "phase": "arrived",
  "contexts": [],
  "next": "advance",
  "prev_place": "ํšŒ์‚ฌ",
  "next_place": "์ง‘"
}
ํ•„๋“œ ํƒ€์ž… ์„ค๋ช…
type string "state" ๊ณ ์ •
step integer ํ˜„์žฌ ์Šคํ… (0~4)
phase string idle | waiting | driving | arrived | done
next string | ์—†์Œ ํƒœ๋ธ”๋ฆฟ ์ฃผ ๋ฒ„ํŠผ ํŒ๋‹จ. ๊ฐ’์€ ํ•ญ์ƒ ํ•˜๋‚˜๋‹ค(์•„๋ž˜ ํ‘œ ์ฐธ๊ณ ). ํ•ด๋‹น ์—†์œผ๋ฉด ํ•„๋“œ ์ž์ฒด๊ฐ€ ์ƒ๋žต๋จ
prev_place string | ์—†์Œ dashboard ๊ธฐ์ค€ ์ฐจ ์ด์ „ ์žฅ์†Œ. ๋Œ€๊ธฐ ํ™”๋ฉด์ด "์–ด๋””์„œ ์™”๋Š”์ง€" ํ‘œ์‹œ
next_place string | ์—†์Œ dashboard ๊ธฐ์ค€ ์ฐจ ๋‹ค์Œ ์žฅ์†Œ. ๋งˆ์ง€๋ง‰ ์Šคํ…์—์„œ ๋‹ค์Œ ๊ณต๊ฐ„์œผ๋กœ ์ธ๊ณ„
scene ยท stop ยท contexts โ€” plan.stops ๋ฅผ ์•ˆ ์“ฐ๋ฏ€๋กœ ๋น„์–ด์„œ ๋‚˜๊ฐ‘๋‹ˆ๋‹ค. ๋ Œ๋”์— ์“ฐ์ง€ ๋งˆ์„ธ์š”

next ๋Š” exit ํ•˜๋‚˜๋ฟ์ด๊ณ , ๋งˆ์ง€๋ง‰ ์Šคํ…(4) ๋„์ฐฉ ๋•Œ๋งŒ ์‹ค๋ฆฐ๋‹ค. ๊ทธ ์™ธ์—๋Š” ํ•„๋“œ ์ž์ฒด๊ฐ€ ์—†๋‹ค. ์ง„ํ–‰ ๋ฒ„ํŠผ์ด ์‚ฌ๋ผ์กŒ์œผ๋ฏ€๋กœ ํƒœ๋ธ”๋ฆฟ์ด ๊ด€๋ฆฌํ•  ๋ฒ„ํŠผ์€ exit ํ•˜๋‚˜๋‹ค.

์ƒํ™ฉ phase next
plan ์ˆ˜์‹  idle (์—†์Œ)
enter ์งํ›„ waiting (์—†์Œ) โ€” ๋ฒ„ํŠผ ๋Œ€์‹  ์ฑ„ํŒ… ์งˆ๋ฌธ์ด ๋œฌ๋‹ค
step 1ยท2ยท3 ๋ Œ๋” ์™„๋ฃŒ arrived (์—†์Œ) โ€” ์ฑ„ํŒ… ์งˆ๋ฌธ์ด ๋œฌ๋‹ค
step 4 ๋ Œ๋” ์™„๋ฃŒ arrived exit
์žฌ์ƒ ์ค‘(step ๋ฉ”์‹œ์ง€) driving (state ๋ฅผ ๋ฐœํ–‰ํ•˜์ง€ ์•Š์Œ)
exit ์งํ›„ done (์—†์Œ)

์ง๋ ฌํ™” ์‹œ null ํ•„๋“œ๋Š” ์•„์˜ˆ ๋น ์ง‘๋‹ˆ๋‹ค(exclude_none). next ๊ฐ€ ์—†์œผ๋ฉด "๋‹ค์Œ ๋™์ž‘ ์—†์Œ"์ž…๋‹ˆ๋‹ค.

5-2. step โ€” ์Šคํ… ์ฝ˜ํ…์ธ  (retain=false)

{
  "type": "step",
  "step": 1,
  "phase": "driving",
  "data": { "step": 1, "bgv": {...}, "bgm": {...}, "assets_timeline": [...] }
}
ํ•„๋“œ ํƒ€์ž… ์„ค๋ช…
step integer ์Šคํ… ๋ฒˆํ˜ธ (1~4)
phase string ๋ฐœํ–‰ ์‹œ์  phase (๋ณดํ†ต driving)
data object ๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด ์ „์šฉ ์—ฐ์ถœ ๋ฐ์ดํ„ฐ(classic StepInfo ํ˜•์‹). ํƒœ๋ธ”๋ฆฟ์€ ํ•ด์„ํ•  ํ•„์š” ์—†์Œ

retain ํ•˜์ง€ ์•Š๋Š” ์ด์œ : step ์€ "์ง€๊ธˆ ์ด๊ฑธ ์žฌ์ƒํ•˜๋ผ"๋Š” 1ํšŒ์„ฑ ๋ช…๋ น์ž…๋‹ˆ๋‹ค. retain ํ•˜๋ฉด ๋‚˜์ค‘์— ์ ‘์†ยท์žฌ์ ‘์†ํ•œ ๊ตฌ๋…์ž์—๊ฒŒ ๋ธŒ๋กœ์ปค๊ฐ€ ์ง€๋‚œ step ์„ ์ž๋™ ์žฌ์ „๋‹ฌํ•ด ์—‰๋šฑํ•œ ์žฌ์ƒ์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

5-3. route โ€” ์ด๋ฒˆ ๊ตฌ๊ฐ„ (retain=false)

step ์ง์ „์— ๋ฐœํ–‰๋œ๋‹ค. ํƒœ๋ธ”๋ฆฟ์ด "์ง€๊ธˆ ์–ด๋””์„œ ์–ด๋””๋กœ ๊ฐ€๋Š” ์ค‘์ธ์ง€"๋ฅผ ๊ทธ๋ฆฐ๋‹ค.

{ "type": "route", "step": 2, "from_stop_id": "0199โ€ฆaaa", "from_place": "home", "to_stop_id": "0199โ€ฆbbb", "to_place": "mart" }
ํ•„๋“œ ์„ค๋ช…
step ์ด ๊ตฌ๊ฐ„์ด ์†ํ•œ ์Šคํ… (1~4)
from_stop_id ยท to_stop_id ํƒœ๋ธ”๋ฆฟ์ด ์“ฐ๋Š” ๊ธฐ์ค€. plan.stops[].id ์ค‘ ํ•˜๋‚˜
from_place ยท to_place ์‚ฌ๋žŒ์ด ๋กœ๊ทธ๋ฅผ ์ฝ์„ ๋•Œ์˜ ๋ณด์กฐ๊ฐ’. homeยทparkยทmartยทfactoryยทcharging_stationยทdrone
  • LLM ์ด ์ฑ„์šฐ์ง€ ๋ชปํ•œ ๊ฐ’์€ ํ•„๋“œ๊ฐ€ ์ƒ๋žต๋œ๋‹ค(null ์•„๋‹˜). stop_id ๊ฐ€ ์—†์œผ๋ฉด place ๋กœ ํด๋ฐฑํ•˜๊ฑฐ๋‚˜ ์ด์ „ ๊ตฌ๊ฐ„์„ ์œ ์ง€ํ•˜๋ผ.
  • ์—ฌ์ •์€ ์žฅ์†Œ 5๊ฐœ๋ฅผ ์ž‡๋Š” 4๊ตฌ๊ฐ„์ด๋‹ค. P0(์ตœ์ดˆ ์ถœ๋ฐœ)ยทP4(์ตœ์ข… ๋„์ฐฉ)๋Š” dashboard(์ฐจ ์•ž๋’ค ์žฅ์†Œ)์—์„œ, P1~P3 ๋Š” LLM์ด ๊ณ ๋ฅธ๋‹ค. ์„œ๋ฒ„๋Š” ์—ฐ์†์„ฑ์„ ๊ต์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์ฑ…์ž„์ง„๋‹ค.

5-3-1. error (retain=false)

{ "type": "error", "step": 2, "code": "STEP_NOT_READY", "message": "step 2 ์ค€๋น„ ์•ˆ ๋จ" }
code ์–ธ์ œ ํƒœ๋ธ”๋ฆฟ ๋Œ€์‘
STEP_NOT_READY ์ƒ์„ฑ์ด ์•„์ง ์•ˆ ๋๋‚ฌ๋Š”๋ฐ ์ง„ํ–‰ ์š”์ฒญ ์ž ์‹œ ํ›„ ์žฌ์‹œ๋„ ๊ฐ€๋Šฅ
GENERATION_FAILED LLM ์ƒ์„ฑ ์‹คํŒจ ์žฌ์‹œ๋„ํ•ด๋„ ์•ˆ ๋จ โ€” ์šด์˜์ž ๊ฐœ์ž…. ์š”์ฒญ ์—†์ด๋„ ์‹คํŒจ ์ฆ‰์‹œ ํ‘ธ์‹œ๋จ
PLAN_MISSING plan ์—†์ด ์ง„ํ–‰ ์š”์ฒญ OC ์˜ plan ๋ฐœํ–‰ ํ™•์ธ
JOURNEY_ENDED exit ์ดํ›„ ์š”์ฒญ / ๋งˆ์ง€๋ง‰ ์Šคํ… ์ดˆ๊ณผ ์ •์ƒ ์ข…๋ฃŒ ์ƒํƒœ. ์ƒˆ plan ๋Œ€๊ธฐ

5-4. reaction (๊ณ„์•ฝ์— ์กด์žฌํ•˜๋‚˜ ๋ฏธ๋ฐœํ–‰)

๊ณ„์•ฝ ๋ชจ๋ธ์€ ๋‚จ์•„์žˆ์ง€๋งŒ ambient ํŒŒ์ดํ”„๋ผ์ธ์€ ๋ฐœํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํƒœ๋ธ”๋ฆฟ์€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.


6. ๋น„-MQTT ์ธ๋ฐ”์šด๋“œ โ€” ๋ Œ๋” ์™„๋ฃŒ ๋ณด๊ณ  ยท ๊ด€๋žŒ๊ฐ ๋ฐœํ™”

6-1. ๋ Œ๋” ์™„๋ฃŒ ๋ณด๊ณ  โ€” ์—ฌ์ •์˜ ์‹ฌ์žฅ

๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด(/ambient)์ด ํ•ด๋‹น ์Šคํ…์˜ asset(๋Œ€์‚ฌยทํŒ์—…ยท์Œ์„ฑ)์„ ์ „๋ถ€ ์žฌ์ƒํ•˜๋ฉด ์„œ๋ฒ„์— ์•Œ๋ฆฐ๋‹ค.

POST http://creator-mac-studio.tail69930a.ts.net:8100/ambient/step-rendered
{ "session_id": "...", "step": 2 }

MQTT ๊ฐ€ ์•„๋‹ˆ๋ผ HTTP ์ธ ์ด์œ : request ํ† ํ”ฝ์€ ํƒœ๋ธ”๋ฆฟยทOC ์˜ ๋ช…๋ น ์ฑ„๋„์ด๊ณ , ์ด๊ฑด ํ™”๋ฉด ์ž์‹ ์˜ ์‚ฌ์‹ค ๋ณด๊ณ ๋‹ค. ๋ธŒ๋กœ์ปค๊ฐ€ ์ฃฝ์–ด๋„ ๋„๋‹ฌํ•ด์•ผ ํ•˜๊ณ , ํƒœ๋ธ”๋ฆฟ ์š”์ฒญ๊ณผ ์„ž์ด๋ฉด ํŠธ๋ž˜ํ”ฝ ํ•ด์„์ด ์–ด๋ ค์›Œ์ง„๋‹ค.

์ด ๋ณด๊ณ ๋ฅผ ๋ฐ›์œผ๋ฉด ์„œ๋ฒ„๊ฐ€ ์„ธ ๊ฐ€์ง€๋ฅผ ํ•œ๋‹ค:

  1. phase=arrived ๋กœ ์˜ฌ๋ฆฌ๊ณ  state ๋ฐœํ–‰ (step 4 ๋ฉด next=exit)
  2. ๊ทธ ์Šคํ…์—์„œ AI ๊ฐ€ ๊ณ ๋ฅธ ์ฐจ๋Ÿ‰ ํƒœ์Šคํฌ๋ฅผ task/complete ๋กœ ๋ฐœํ–‰ (step ๋‹น 1๊ฐœ, ๋ชฐ์•„์„œ ์ฒ˜๋ฆฌ ์—†์Œ. ์‹œ์ž‘์€ ์Šคํ… ๋ฐœํ–‰ ๋•Œ task/start ๋กœ ์ด๋ฏธ ์•Œ๋ ธ๋‹ค)
  3. ๊ทธ ์Šคํ…์˜ question ์„ ai/response ์—, answer_suggestions ๋ฅผ ai/suggestions ์— ๋ฐœํ–‰ โ†’ ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ…์— ๋‹ค์Œ ์งˆ๋ฌธ๊ณผ ๋‹ต ํ›„๋ณด๊ฐ€ ๋œฌ๋‹ค. step 4 ๋Š” ๋ฐœํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๋‹ค์Œ step ์ด ์—†์–ด ๋‹ต์ด ์™€๋„ ๊ฐˆ ๊ณณ์ด ์—†๋‹ค
  4. ์žฌ์ƒ ์ค‘ ๋ฏธ๋ค„๋‘” ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๊ฐ€ ์žˆ์œผ๋ฉด ๊ณง๋ฐ”๋กœ ๋‹ค์Œ ์Šคํ… ์ƒ์„ฑ์„ ์‹œ์ž‘

โš ๏ธ ์˜ˆ์ „์—๋Š” "๋ฒ„ํŠผ์„ ์ผœ๋„ ๋œ๋‹ค"๋Š” ์‹ ํ˜ธ์˜€์ง€๋งŒ, ์ด์ œ ์ด ๋ณด๊ณ ๊ฐ€ ์•ˆ ์˜ค๋ฉด ์—ฌ์ •์ด ๊ทธ ์ž๋ฆฌ์—์„œ ๋ฉˆ์ถ˜๋‹ค. ์งˆ๋ฌธ์ด ์•ˆ ๋œจ๋‹ˆ ๊ด€๋žŒ๊ฐ์ด ๋‹ตํ•  ์ˆ˜ ์—†๊ณ , ๋‹ต์ด ์—†์œผ๋‹ˆ ๋‹ค์Œ ์Šคํ…์ด ์•ˆ ๋งŒ๋“ค์–ด์ง„๋‹ค.

์„œ๋ฒ„๊ฐ€ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ๊ฒƒ: ์ด๋ฏธ ๋‹ค์Œ ์Šคํ…์œผ๋กœ ๋„˜์–ด๊ฐ„ ๋’ค ๋„์ฐฉํ•œ ์ง€๊ฐ ๋ณด๊ณ , ๊ฐ™์€ ์Šคํ… ์ค‘๋ณต ๋ณด๊ณ , exit ์ดํ›„ ๋ณด๊ณ  โ†’ ์ „๋ถ€ ๋ฌด์‹œ.

6-2. ๊ด€๋žŒ๊ฐ ๋ฐœํ™” (์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ STT) โ€” ์Šคํ… ์ง„ํ–‰์˜ ์ •์‹ ์œ ์ž…๊ตฌ

์ฐจ๋Ÿ‰ ํ™”๋ฉด(/ambient)์ด ๋งˆ์ดํฌ๋กœ ๋ฐ›์•„ STT ํ•œ ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๋ฅผ ๋ณด๋‚ธ๋‹ค. ํ™”๋ฉด์€ ๊ด€๋žŒ๊ฐ ์ฐจ๋ก€(๋Œ€๊ธฐ ํ™”๋ฉด, ์Šคํ… ๋ Œ๋” ์™„๋ฃŒ ๋’ค ~ ๋‹ค์Œ step ์ˆ˜์‹  ์ „, ์„œ๋ฒ„ error ๋’ค)์—๋งŒ ๋งˆ์ดํฌ๋ฅผ ์—ด๊ณ , ์žฌ์ƒ ์ค‘์—๋Š” ๋‹ซ๋Š”๋‹ค(์šฐ๋ฆฌ TTS ๋ฅผ ๋ฐ›์•„ ์ ๋Š” ์ž๊ธฐ์ˆ˜์‹  ๋ฐฉ์ง€).

POST /ambient/utterance      { "session_id": "...", "transcript": "์ปคํ”ผ ๋งˆ์‹œ๊ณ  ์‹ถ์–ด์š”", "source": "car-stt" }
                             โ†’ { "ok": true, "result": "collected" }       (closed / empty ๋ฉด ok:false)
GET  /ambient/utterance/{session_id}      โ† ์ง€๊ธˆ๊นŒ์ง€ ์ˆ˜์ง‘๋œ ๋ฐœํ™” ๋ชฉ๋ก

ai/response ์ˆ˜์‹ ๊ณผ ๊ฐ™์€ ํŒ์ • ๊ฒฝ๋กœ๋ฅผ ํƒ„๋‹ค โ€” ์ˆ˜์ง‘ ์ฐฝ(enter~exit)์ด ๋‹ซํ˜€ ์žˆ์œผ๋ฉด ๋˜‘๊ฐ™์ด ๋ฒ„๋ ค์ง„๋‹ค. ์ˆ˜์ง‘๋˜๋ฉด ๊ณง๋ฐ”๋กœ ๋‹ค์Œ ์Šคํ… ์ƒ์„ฑ์ด ์‹œ์ž‘๋˜๊ณ , ํ™”๋ฉด์€ ์„œ๋ฒ„๊ฐ€ ์ˆ˜์ง‘ํ–ˆ๋‹ค๋Š” ์‘๋‹ต์„ ๋ฐ›์œผ๋ฉด ๊ทธ ์ฐฝ์—์„œ๋Š” ๋” ๋“ฃ์ง€ ์•Š๋Š”๋‹ค(์ค‘๋ณต ํŠธ๋ฆฌ๊ฑฐ ๋ฐฉ์ง€). /mqtt ๋‚˜ curl ๋กœ ํ‰๋‚ด๋‚ผ ๋•Œ๋Š” source:"debug" ๋กœ ๋ณด๋‚ด๋ฉด ํŠธ๋ž˜ํ”ฝ ๋กœ๊ทธ์—์„œ ๊ตฌ๋ถ„๋œ๋‹ค.


7. ์ƒํƒœ๋จธ์‹  (phase)

์ง„ํ–‰์€ ํƒœ๋ธ”๋ฆฟ ๋ฒ„ํŠผ์ด ์•„๋‹ˆ๋ผ ๊ด€๋žŒ๊ฐ ๋ฐœํ™”๊ฐ€ ์ด๋ˆ๋‹ค โ€” ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ STT(6-2). ํƒœ๋ธ”๋ฆฟ์ด ๋ณด๋‚ด๋Š” ๊ฒƒ์€ enterยทexit ๋‘˜๋ฟ์ด๊ณ , ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ ๋™์•ˆ ํƒœ๋ธ”๋ฆฟ ์ž…๋ ฅ์€ ์ž ๊ธด๋‹ค.

stateDiagram-v2
    [*] --> idle: plan ์ˆ˜์‹ 
    idle --> waiting: enter (+ ์ฑ„ํŒ…์— "์ถœ๋ฐœ ํ• ๊นŒ์š”?")
    waiting --> driving: ๊ด€๋žŒ๊ฐ ๋ฐœํ™” โ†’ step1 ์ƒ์„ฑยท์†ก์ถœ
    driving --> arrived: ํ™”๋ฉด ๋ Œ๋” ์™„๋ฃŒ (+ ์ฑ„ํŒ…์— ๊ทธ ์Šคํ…์˜ question)
    arrived --> driving: ๊ด€๋žŒ๊ฐ ๋ฐœํ™” โ†’ step N+1 ์ƒ์„ฑยท์†ก์ถœ
    arrived --> done: exit (step 4 ๋„์ฐฉ ํ›„)
    done --> idle: ์ƒˆ plan
  • ์Šคํ…์€ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ๋ฐœํ™”๊ฐ€ ๋„์ฐฉํ•œ ๊ทธ ์‹œ์ ์— LLM ์ด ๋‹ค์Œ ์Šคํ… ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ ๋‹ค(์ˆ˜ ์ดˆ). ๊ทธ๋™์•ˆ ๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด์€ ์ง์ „ ์Šคํ… ํ™”๋ฉด์ด ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๋‹ค๊ฐ€ ์ƒˆ step ์ด ์˜ค๋ฉด ์ด์–ด ์žฌ์ƒํ•œ๋‹ค โ€” ๋Œ€๊ธฐ ํ™”๋ฉดยท์Šคํ”ผ๋„ˆ๋Š” ์—†๋‹ค.
  • ์žฌ์ƒ ์ค‘(driving)์— ๋ฐœํ™”๊ฐ€ ์˜ค๋ฉด ๋ฒ„๋ฆฌ์ง€ ์•Š๊ณ  ๋ฏธ๋ฃฌ๋‹ค. ๋ Œ๋” ์™„๋ฃŒ ์‹œ ๊ณง๋ฐ”๋กœ ๋‹ค์Œ ์ƒ์„ฑ์ด ์‹œ์ž‘๋œ๋‹ค.
  • ๋ฐœํ™” ์ˆ˜์ง‘ ์ฐฝ์€ enter ์ดํ›„ ~ exit ์ด์ „. ๊ทธ ๋ฐ–์˜ ๋ฐœํ™”ยท์ฑ„ํŒ…์€ ์—ฌ์ •๊ณผ ๋ฌด๊ด€ํ•˜๋ฏ€๋กœ ๋ฌด์‹œํ•œ๋‹ค.
  • ai/response.transcript ๊ตฌ๋…์€ ๋‚จ์•„ ์žˆ๋‹ค(ํƒœ๋ธ”๋ฆฟ ์ž ๊ธˆ ์ „ ํ…Œ์ŠคํŠธยท๋น„์ƒ์šฉ). ๋ฏธ๋ž˜์ฐจ ์ž์‹ ์ด ๋ฐœํ–‰ํ•œ ์งˆ๋ฌธ์€ context_id ๋กœ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค.
  • next ๊ฐ€ ์‹ค๋ฆฌ๋Š” ๊ณณ์€ step 4 arrived ์˜ exit ๋ฟ์ด๋‹ค.

8. ์ „์ฒด ํ๋ฆ„ โ€” ํƒ‘์Šน ์ง์ „๋ถ€ํ„ฐ ํ•˜์ฐจ๊นŒ์ง€

์ด ์ ˆ๋งŒ ์ฝ์–ด๋„ ํ•œ ์—ฌ์ •์ด ์–ด๋–ป๊ฒŒ ๊ตด๋Ÿฌ๊ฐ€๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ์“ด๋‹ค. ์„ธ๋ถ€ ์Šคํ‚ค๋งˆ๋Š” 3~6์žฅ์„ ์ฐธ์กฐ.

๋“ฑ์žฅ์ธ๋ฌผ์€ ๋„ท์ด๋‹ค.

๋ˆ„๊ตฌ ์—ญํ•  ์ด ๋ฌธ์„œ์—์„œ์˜ ํ‘œ๊ธฐ
OC (orchestration-server) ํŽ˜๋ฅด์†Œ๋‚˜ยท์žฅ์†Œยทํƒœ์Šคํฌ์˜ ์ •๋ณธ. planยทdashboardยทme ๋ฅผ ์ฃผ๊ณ , ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๋ณด๋‚ด๋Š” task/startยทtask/completeยทai/mode ๋ฅผ ๋ฐ›๋Š”๋‹ค OC
ํƒœ๋ธ”๋ฆฟ (tablet-fe) ๊ด€๋žŒ๊ฐ์ด ๋“ค๊ณ  ๋‹ค๋‹ˆ๋Š” ํ™”๋ฉด. ์ฐจ์— ํƒˆ ๋•Œ enter, ๋‚ด๋ฆด ๋•Œ exit ๋ฅผ ๋ณด๋‚ธ๋‹ค. ์ฐจ ์•ˆ์—์„œ๋Š” ์ž…๋ ฅ์ด ์ž ๊ธด๋‹ค ํƒœ๋ธ”๋ฆฟ
๋ฏธ๋ž˜์ฐจ ์„œ๋ฒ„ (์ด ๋ฌธ์„œ์˜ ์ฃผ์ธ๊ณต, Mac Studio :8100) ๋ฐœํ™”๋ฅผ ์žฌ๋ฃŒ๋กœ ์Šคํ…์„ LLM ์ƒ์„ฑํ•ด ํ™”๋ฉด์— ๋ฐ€์–ด ๋„ฃ๊ณ , ํƒœ์Šคํฌ ์™„๋ฃŒ์™€ ์ฑ„ํŒ… ์งˆ๋ฌธ์„ ๋ฐœํ–‰ํ•œ๋‹ค ์„œ๋ฒ„
๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด (/ambient, ์ฐจ ์•ˆ ๋””์Šคํ”Œ๋ ˆ์ด + ๋งˆ์ดํฌ) ์Šคํ…์„ ์žฌ์ƒํ•˜๊ณ , ์žฌ์ƒ์ด ๋๋‚˜๋ฉด ์„œ๋ฒ„์— ๋ณด๊ณ ํ•˜๊ณ , ๊ด€๋žŒ๊ฐ ์ฐจ๋ก€์— ๋งˆ์ดํฌ๋ฅผ ์—ด์–ด STT ํ•œ ๋ฐœํ™”๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ๋‹ค ํ™”๋ฉด

๊ด€๋žŒ๊ฐ์€ ํƒœ๋ธ”๋ฆฟ์„ ๋“ค๊ณ  ์ฐจ์— ํƒ€๊ณ , ์ฐจ ์•ˆ์—์„œ๋Š” ์ฐจ์— ๋Œ€๊ณ  ๋งํ•œ๋‹ค. ์Šคํ…์€ ๊ทธ ๋ง์ด ์ด๋ˆ๋‹ค.

8-0. ์—ฌ์ •์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ์ด๋ฏธ ๊ฐ–์ถฐ์ ธ ์žˆ๋Š” ๊ฒƒ

  1. ๊ด€๋žŒ๊ฐ์ด ํƒœ๋ธ”๋ฆฟ์—์„œ ํŽ˜๋ฅด์†Œ๋‚˜๋ฅผ ๋งŒ๋“ค๋ฉด OC ๊ฐ€ planยทdashboardยทme ๋ฅผ retained ๋กœ ๋ฐœํ–‰ํ•œ๋‹ค. ์„œ๋ฒ„๋Š” plan ์„ ๋ฐ›๋Š” ์ˆœ๊ฐ„ ์„ธ์…˜(session_id)์„ ๋งŒ๋“ค๊ณ  state phase=idle ์„ ๋ฐœํ–‰ํ•œ๋‹ค(5-1).
  2. ์„œ๋ฒ„๋Š” dashboard ์—์„œ ์ฐจ ์žฅ์†Œ(name ์ด "์ฐจ"๋กœ ์‹œ์ž‘)์˜ ์•ž๋’ค ์žฅ์†Œ(P0/P4)์™€ ํƒœ์Šคํฌ๋ฅผ ๋ฝ‘์•„ ๋‘”๋‹ค(4์žฅ). ํƒœ์Šคํฌ ์ค‘ type=basic ๋งŒ ์ฐจ๊ฐ€ ์ˆ˜ํ–‰ํ•  ํ›„๋ณด๋‹ค โ€” ํƒœ๋ธ”๋ฆฟ์— ์กฐ์ž‘ UI ๊ฐ€ ์—†์–ด ์„œ๋ฒ„๊ฐ€ ์™„๋ฃŒํ•ด์•ผ ํ•˜๋Š” ํƒ€์ž…. ๊ทธ ์™ธ(vehicle_readyยทdetailedยทquote_briefing โ€ฆ)๋Š” ํƒœ๋ธ”๋ฆฟ ๋‹๋ณด๊ธฐ ๋ชจ๋‹ฌ์—์„œ ๊ด€๋žŒ๊ฐ์ด ์™„๋ฃŒํ•˜๋ฏ€๋กœ ์ฐจ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.
  3. me.ai_companion.prompt ๋Š” ์Šคํ… ์ƒ์„ฑ ํ”„๋กฌํ”„ํŠธ ๋งจ ์•ž์— ๋ถ™๋Š” ์ธ๊ฒฉ(๋™ํ–‰์ž)์ด๋‹ค.
  4. ํ™”๋ฉด์€ WS(/ws/futurecar)๋กœ ์„œ๋ฒ„์— ๋ถ™์–ด ์žˆ๋‹ค. ์ƒˆ plan(state idle)์ด ์˜ค๋ฉด ๊ทธ ์„ธ์…˜์„ ๋”ฐ๋ผ๊ฐ„๋‹ค.

8-1. ๋‹จ๊ณ„๋ณ„ โ€” ๋ˆ„๊ฐ€ ๋ฌด์—‡์„ ์˜๊ณ , ๊ฐ์ž ๋ฌด์—‡์„ ํ•˜๋‚˜

# ์‹œ์  ยท ํŠธ๋ฆฌ๊ฑฐ ์„œ๋ฒ„๊ฐ€ ํ•˜๋Š” ์ผ ์„œ๋ฒ„๊ฐ€ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ ํ™”๋ฉด ํƒœ๋ธ”๋ฆฟ OC
โ‘  ํƒ‘์Šน โ€” ํƒœ๋ธ”๋ฆฟ์ด "์ฐจ๋กœ ์ด๋™"์„ ํ™•์ •ํ•˜๋ฉฐ enter ๋ฐœํ–‰ ๋ฐœํ™” ์ˆ˜์ง‘ ์ฐฝ ์—ด๊ธฐ, phase=waiting state waiting ยท ai/mode {car, ttl 1800}(retained) ยท ai/response message="์ถœ๋ฐœ ํ• ๊นŒ์š”?" + ai/suggestions ์นฉ 2๊ฐœ ๋Œ€๊ธฐ ํ™”๋ฉด. ๋งˆ์ดํฌ ์—ด๋ฆผ("๋“ฃ๊ณ  ์žˆ์–ด์š”") ์ฑ„ํŒ…์— "์ถœ๋ฐœ ํ• ๊นŒ์š”?" ํ‘œ์‹œ. ์ž…๋ ฅ ์ž ๊ธˆ(๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ) car ๋ชจ๋“œ ์ €์žฅ โ€” ์ดํ›„ ์Œ์„ฑ ๋ฐœํ™”๋Š” STT ๋งŒ
โ‘ก ๊ด€๋žŒ๊ฐ์ด ์ฐจ์— ๋งํ•จ ํ™”๋ฉด์ด STT ํ•œ ๋ฌธ์žฅ์„ POST /ambient/utterance ๋กœ ๋ฐ›์Œ โ†’ ์ฐฝ ์•ˆ์ด๋ฉด ์ˆ˜์ง‘ โ†’ ์ฆ‰์‹œ step 1 ์ƒ์„ฑ ์‹œ์ž‘ (์—†์Œ โ€” ์ƒ์„ฑ ์ค‘) ๋งˆ์ดํฌ ์ •์ง€("์ž ์‹œ๋งŒ์š”"). ๋Œ€๊ธฐ ํ™”๋ฉด ์œ ์ง€ โ€” โ€”
โ‘ข ์Šคํ… ์ƒ์„ฑ ์™„๋ฃŒ (LLM ์ˆ˜ ์ดˆ) ์ปจํ…์ŠคํŠธ(ํŽ˜๋ฅด์†Œ๋‚˜ยท์•ž๋’ค ์žฅ์†Œยท๋ˆ„์  ๋ฐœํ™”ยท๋‚จ์€ basic ํƒœ์Šคํฌยท๋™ํ–‰์ž ํ”„๋กฌํ”„ํŠธ) โ†’ LLM JSON. route ํ™•์ •(P0/P4 ๋Š” dashboard ์šฐ์„ , stop_id ๋Š” plan ์นดํƒˆ๋กœ๊ทธ ๋งคํ•‘), task_key ๊ฒ€์ฆ route โ†’ step(์—ฐ์ถœ ๋ฐ์ดํ„ฐ) โ†’ task/start {task_id}(๊ทธ ์Šคํ…์— basic ํƒœ์Šคํฌ๋ฅผ ๊ณจ๋ž์„ ๋•Œ) step ์žฌ์ƒ ์‹œ์ž‘. ๋งˆ์ดํฌ ๋‹ซํž˜(์šฐ๋ฆฌ TTS ์ž๊ธฐ์ˆ˜์‹  ๋ฐฉ์ง€) ๊ตฌ๊ฐ„(fromโ†’to) ํ‘œ์‹œ. basic ์นด๋“œ "์ง„ํ–‰ ์ค‘" dashboard ๋ฅผ in_progress ๋กœ ์žฌ๋ฐœํ–‰. ์ด๋ฒคํŠธ ํƒ€์ด๋ฐ ํŒ๋‹จ(task_started ํŠธ๋ฆฌ๊ฑฐ)
โ‘ฃ ๋ Œ๋” ์™„๋ฃŒ โ€” ํ™”๋ฉด์ด POST /ambient/step-rendered phase=arrived. step 4 ๋ฉด next=exit. ๊ทธ ์Šคํ…์˜ basic ํƒœ์Šคํฌ task/complete. step 1~3 ์ด๋ฉด ๊ทธ ์Šคํ…์˜ question ์„ ์ฑ„ํŒ…์— state arrived ยท task/complete {task_id} ยท ai/response message=question + ai/suggestions ๋งˆ์ง€๋ง‰ ์žฅ๋ฉด ์œ ์ง€. ๋งˆ์ดํฌ ์—ด๋ฆผ(step 1~3) ์นด๋“œ "์™„๋ฃŒ", ์ฑ„ํŒ…์— ๋‹ค์Œ ์งˆ๋ฌธ dashboard completedยทpoint ์žฌ๋ฐœํ–‰. ์ด๋ฒคํŠธ ํƒ€์ด๋ฐ ํŒ๋‹จ(task_completed ํŠธ๋ฆฌ๊ฑฐ)
โ‘ค โ‘ก~โ‘ฃ ๋ฐ˜๋ณต (step 2 โ†’ 3 โ†’ 4) ๋ฐœํ™” ํ•˜๋‚˜ = ์Šคํ… ํ•˜๋‚˜. ๋ฏธ๋ฆฌ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค
โ‘ฅ step 4 ๋ Œ๋” ์™„๋ฃŒ phase=arrived next=exit. ์งˆ๋ฌธ ์—†์Œ. ํƒœ์Šคํฌ ์™„๋ฃŒ๋งŒ state arrived step=4 next=exit ยท task/complete ์—”๋”ฉ ํ™”๋ฉด("์ฒดํ—˜์ด ๋ชจ๋‘ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค"). ๋งˆ์ดํฌ ์•ˆ ์—ด๋ฆผ ํ•˜์ฐจ(์ฐจ๋ฅผ ๋– ๋‚˜ ๋‹ค์Œ ์žฅ์†Œ๋กœ ์ด๋™) ํ™•์ • ๊ฐ€๋Šฅ
โ‘ฆ ํ•˜์ฐจ โ€” ํƒœ๋ธ”๋ฆฟ์ด exit ๋ฐœํ–‰ ์ฐฝ ๋‹ซ๊ธฐ, phase=done state done ยท ai/mode {chat} ์ž‘๋ณ„ ํ™”๋ฉด ์ž…๋ ฅ ์ž ๊ธˆ ํ•ด์ œ chat ๋ชจ๋“œ ๋ณต๊ท€
โ€” ๋‹ค์Œ ๊ด€๋žŒ๊ฐ์˜ plan ์ƒˆ ์„ธ์…˜ idle state idle ๋Œ€๊ธฐ

์ฝ๋Š” ๋ฒ• ์„ธ ๊ฐ€์ง€:

  • "๋‹ค์Œ์œผ๋กœ"๋Š” ๊ด€๋žŒ๊ฐ์˜ ๋ง์ด๋‹ค. ๋ฒ„ํŠผ์ด ์•„๋‹ˆ๋‹ค. ๋ฐœํ™”๊ฐ€ ์—†์œผ๋ฉด ์—ฌ์ •์€ ๊ทธ ์ž๋ฆฌ์— ๋ฉˆ์ถ˜๋‹ค(๊ด€๋žŒ๊ฐ์ด ๋‹ต์„ ์•ˆ ํ•˜๋Š” ์ƒํ™ฉ์€ ์ „์‹œ ์šด์˜์ด ๋ง‰๋Š”๋‹ค).
  • ๋ Œ๋” ์™„๋ฃŒ ๋ณด๊ณ (โ‘ฃ)๊ฐ€ ์—ฌ์ •์˜ ์‹ฌ์žฅ์ด๋‹ค. ์ด๊ฒŒ ์•ˆ ์˜ค๋ฉด ํƒœ์Šคํฌ ์™„๋ฃŒ๋„, ๋‹ค์Œ ์งˆ๋ฌธ๋„, ๋‹ค์Œ ์Šคํ…๋„ ์—†๋‹ค(6-1).
  • ํƒœ์Šคํฌ๋Š” ์Šคํ… ํ•˜๋‚˜์— ํ•˜๋‚˜. ์‹œ์ž‘์€ ์Šคํ… ๋ฐœํ–‰ ๋•Œ(โ‘ข), ์™„๋ฃŒ๋Š” ๋ Œ๋” ์™„๋ฃŒ ๋•Œ(โ‘ฃ). ๊ทธ๋ž˜์„œ ํƒœ๋ธ”๋ฆฟ์—๋Š” ์Šคํ… ๋‚ด๋‚ด "์ง„ํ–‰ ์ค‘"์ด ๋ณด์ธ๋‹ค. ๋ชฐ์•„์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

8-2. ๋ฉ”์‹œ์ง€ ์ˆœ์„œ (์ •ํ™•ํ•œ ํ† ํ”ฝ)

โ‘   plan               OC โ†’ ์„œ๋ฒ„                     orchestration/{sid}/future-car/request   (retain=true)
   dashboard ยท me     OC โ†’ ์„œ๋ฒ„                     orchestration/{sid}/dashboard ยท /me      (retain=true)
   โ† state            phase=idle                    orchestration/{sid}/future-car/response  (retain=true)

โ‘ก  enter              ํƒœ๋ธ”๋ฆฟ โ†’ ์„œ๋ฒ„                  orchestration/{sid}/future-car/request   {"type":"enter"}
   โ† state            phase=waiting
   โ†’ ai/mode          {"mode":"car","ttl_sec":1800}  orchestration/{sid}/ai/mode              (retain=true)  [์„œ๋ฒ„ โ†’ OC]
   โ†’ ai/response      message="์ถœ๋ฐœ ํ• ๊นŒ์š”?"          orchestration/{sid}/ai/response          โ˜… ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ…
   โ†’ ai/suggestions   ["๋„ค, ์ถœ๋ฐœํ•ด์š”!", โ€ฆ]            orchestration/{sid}/ai/suggestions       โ˜… ์นฉ(ํ‘œ์‹œ๋งŒ, ํƒญ ์ž ๊ธˆ)

โ‘ข  (๊ด€๋žŒ๊ฐ์ด ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ์— ๋Œ€๊ณ  ๋งํ•จ)
   โ‡ข POST /ambient/utterance  {session_id, transcript:"๋„ค, ์ถœ๋ฐœํ•ด์š”", source:"car-stt"}   [ํ™”๋ฉด โ†’ ์„œ๋ฒ„, HTTP]
   โŸณ step 1 ์ƒ์„ฑ (LLM, ์ˆ˜ ์ดˆ)
   โ† route            step=1 ยท from/to stop_id ยท from/to place                          โ˜… ํƒœ๋ธ”๋ฆฟ ๊ตฌ๊ฐ„ ํ‘œ์‹œ
   โ† step             step=1 ยท phase=driving ยท data={assets_timelineโ€ฆ}                  [ํ™”๋ฉด ์žฌ์ƒ]
   โ†’ task/start       {"task_id":โ€ฆ}                 orchestration/{sid}/task/start           [์„œ๋ฒ„ โ†’ OC] basic ๋งŒ
   โ€ฆ ํ™”๋ฉด์ด step 1 ์žฌ์ƒ (๋งˆ์ดํฌ ๋‹ซํž˜) โ€ฆ
   โ‡ข POST /ambient/step-rendered  {session_id, step:1}                                   [ํ™”๋ฉด โ†’ ์„œ๋ฒ„, HTTP]
   โ† state            step=1 ยท phase=arrived
   โ†’ task/complete    {"task_id":โ€ฆ}                 orchestration/{sid}/task/complete        [์„œ๋ฒ„ โ†’ OC]
   โ†’ ai/response      message=<step1 question>      + ai/suggestions                         โ˜… ํƒœ๋ธ”๋ฆฟ ์ฑ„ํŒ…

โ‘ฃ  โ‘ข ๋ฐ˜๋ณต (step 2, 3)

โ‘ค  step 4 ๋ Œ๋” ์™„๋ฃŒ
   โ† state            step=4 ยท phase=arrived ยท next=exit            (์งˆ๋ฌธ ์—†์Œ)              โ˜… ํ•˜์ฐจ ๊ฐ€๋Šฅ
   โ†’ task/complete    (step 4 ์— basic ํƒœ์Šคํฌ๋ฅผ ๊ณจ๋ž๋‹ค๋ฉด)

โ‘ฅ  exit               ํƒœ๋ธ”๋ฆฟ โ†’ ์„œ๋ฒ„                  {"type":"exit"}
   โ† state            phase=done
   โ†’ ai/mode          {"mode":"chat"}                                                       [์„œ๋ฒ„ โ†’ OC]

โ†’ ์„œ๋ฒ„๊ฐ€ OC/ํƒœ๋ธ”๋ฆฟ ํ† ํ”ฝ์— ๋ฐœํ–‰, โ† ์„œ๋ฒ„๊ฐ€ future-car/response ์— ๋ฐœํ–‰, โ‡ข ํ™”๋ฉด์ด ์„œ๋ฒ„์— HTTP.

8-3. ํ•œ ์Šคํ…์˜ ์•ˆ์ชฝ โ€” ์‹œ๊ฐ„ ์ˆœ

 arrived(N-1)         driving(N)                              arrived(N)
 โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ
    โ”‚ ๋ฐœํ™” ์ˆ˜์ง‘  โ”‚ ์ƒ์„ฑ   โ”‚ step N ์žฌ์ƒ                 โ”‚ ๋ Œ๋” ์™„๋ฃŒ โ”‚ ์งˆ๋ฌธ ยท ๋ฐœํ™” ์ˆ˜์ง‘
    โ”‚ (๋งˆ์ดํฌ ON)โ”‚ (OFF) โ”‚ (๋งˆ์ดํฌ OFF ยท task ์ง„ํ–‰ ์ค‘)  โ”‚ ๋ณด๊ณ       โ”‚ (๋งˆ์ดํฌ ON)
    โ”” utterance โ”˜       โ”” route โ†’ step โ†’ task/start โ”˜          โ”” state โ†’ task/complete โ†’ question
  • ์ƒ์„ฑ ์ค‘์—๋Š” state ๋ฅผ ๋”ฐ๋กœ ๋‚ด๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค. ํ™”๋ฉด์€ ์ง์ „ ์žฅ๋ฉด์„ ์œ ์ง€ํ•˜๊ณ , ํƒœ๋ธ”๋ฆฟ์€ route ๊ฐ€ ์˜ฌ ๋•Œ๊นŒ์ง€ ์ด์ „ ๊ตฌ๊ฐ„์„ ๋ณด์—ฌ์ค€๋‹ค. ์ƒ์„ฑ์€ ๋ณดํ†ต 10~30์ดˆ(๊ตฌ์กฐํ™” ์ถœ๋ ฅ ์‹คํŒจ ์‹œ ์ž์œ  ํ˜•์‹์œผ๋กœ 1ํšŒ ์žฌ์‹œ๋„, 120์ดˆ ํƒ€์ž„์•„์›ƒ).
  • ํ™”๋ฉด์€ ์„œ๋ฒ„๊ฐ€ ๋ฐœํ™”๋ฅผ ์ˆ˜์ง‘ํ–ˆ๋‹ค๋Š” ์‘๋‹ต(result:"collected")์„ ๋ฐ›์œผ๋ฉด ๊ทธ ์ฐฝ์—์„œ๋Š” ๋” ๋“ฃ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ฐ™์€ ์ฐฝ์—์„œ ๋‘ ๋ฌธ์žฅ์ด ๋‘ ๋ฒˆ ์ƒ์„ฑ์„ ๊ฑธ์ง€ ์•Š๊ฒŒ. ๋‹ค์Œ ์ฐฝ(๋‹ค์Œ ๋ Œ๋” ์™„๋ฃŒ)์— ๋‹ค์‹œ ์—ฐ๋‹ค.
  • ์„œ๋ฒ„ ์ชฝ ์ฐฝ์€ enter~exit ํ•˜๋‚˜๋‹ค. ๊ทธ ์•ˆ์—์„œ ์Šคํ…๋ณ„ ๋ฐœํ™”๋Š” step_at ์œผ๋กœ ํƒœ๊น…๋ผ ๋ˆ„์ ๋˜๊ณ , ๋งค ์ƒ์„ฑ์— ์ง€๊ธˆ๊นŒ์ง€์˜ ๋ฐœํ™” ์ „๋ถ€๊ฐ€ ์žฌ๋ฃŒ๋กœ ๋“ค์–ด๊ฐ„๋‹ค.

8-4. ์˜ˆ์™ธ์™€ ๊ทธ๋•Œ์˜ ๋™์ž‘

์ƒํ™ฉ ๋™์ž‘
์Šคํ… ์ƒ์„ฑ ์‹คํŒจ(LLM ์˜ค๋ฅ˜ยทํŒŒ์‹ฑ ์‹คํŒจ) error {code:"GENERATION_FAILED"} ๋ฐœํ–‰. ํ™”๋ฉด์€ ๋งˆ์ดํฌ๋ฅผ ๋‹ค์‹œ ์—ด๊ณ , ๊ด€๋žŒ๊ฐ์ด ๋‹ค์‹œ ๋งํ•˜๋ฉด ์žฌ์‹œ๋„ํ•œ๋‹ค. ํƒœ๋ธ”๋ฆฟ์€ JOURNEY_ENDED ์ด์™ธ์˜ ์—๋Ÿฌ๋งŒ ํ‘œ์‹œ
์ฐฝ ๋ฐ– ๋ฐœํ™”(enter ์ „, exit ํ›„) result:"closed" โ€” ๋ฒ„๋ฆฐ๋‹ค. ํ™”๋ฉด์€ ๊ณ„์† ๋“ฃ์ง€๋งŒ enter ์ „์—” ๋งˆ์ดํฌ๋ฅผ ์—ด์ง€ ์•Š๋Š”๋‹ค
์žฌ์ƒ ์ค‘ ๋ฐœํ™” ํ™”๋ฉด ๋งˆ์ดํฌ๊ฐ€ ๋‹ซํ˜€ ์žˆ์–ด ์ •์ƒ์ ์œผ๋ก  ์ƒ๊ธฐ์ง€ ์•Š๋Š”๋‹ค. ai/response ๊ฒฝ์œ (ํƒœ๋ธ”๋ฆฟ ์ž ๊ธˆ ์ „ยท๋น„์ƒ)๋กœ ๋“ค์–ด์˜ค๋ฉด ๋ฒ„๋ฆฌ์ง€ ์•Š๊ณ  ๋ฏธ๋ค„ ๋‘์—ˆ๋‹ค๊ฐ€ ๋ Œ๋” ์™„๋ฃŒ ์งํ›„ ๋‹ค์Œ ์ƒ์„ฑ์— ์“ด๋‹ค โ€” ์ด๋•Œ๋Š” ์งˆ๋ฌธ ์—†์ด ๋„˜์–ด๊ฐ„๋‹ค
๋ Œ๋” ์™„๋ฃŒ ๋ณด๊ณ  ์ง€๊ฐยท์ค‘๋ณต ๋ฌด์‹œ(ignored_staleยทignored_duplicateยทignored_done). ์ด๋ฏธ ๋‹ค์Œ ์Šคํ…์œผ๋กœ ๋„˜์–ด๊ฐ”๊ฑฐ๋‚˜ ๊ฐ™์€ ์Šคํ…์„ ๋‘ ๋ฒˆ ๋ณด๊ณ ํ•œ ๊ฒฝ์šฐ
ํƒœ๋ธ”๋ฆฟ์ด enter ๋ฅผ ๋‘ ๋ฒˆ ๋‘ ๋ฒˆ์งธ๋Š” ๋ฌด์‹œ(ํƒœ๋ธ”๋ฆฟ๋„ phase ๊ฐ€๋“œ๋กœ ์•ˆ ๋ณด๋‚ธ๋‹ค). exit ๋Š” waitingยทdrivingยทarrived ์–ด๋””์„œ๋“  ๋ฐ›๋Š”๋‹ค โ†’ ๊ทธ ์ž๋ฆฌ์—์„œ done
advanceยทstart ๊ฐ€ ์˜ค๋ฉด ํ๊ธฐ๋œ ๋ณ„์นญ โ€” ๋ฐ›์œผ๋ฉด ๋ฐœํ™” ์—†์ด ๊ฐ•์ œ ์ƒ์„ฑํ•œ๋‹ค(ํ˜„์žฅ ๋น„์ƒยท๋””๋ฒ„๊ทธ์šฉ, /ambient dev ํŒจ๋„)
์„œ๋ฒ„ ์žฌ์‹œ์ž‘ stateยท์Šคํ… ๊ฒฐ๊ณผ๋Š” DB ์—์„œ ๋ณต์›๋˜์ง€๋งŒ ๋ฐœํ™” ๋ˆ„์ ยท๋Œ€ํ™” ํžˆ์Šคํ† ๋ฆฌ๋Š” ๋ณต์›๋˜์ง€ ์•Š๋Š”๋‹ค(๋‹ค์Œ ์Šคํ… ํ’ˆ์งˆ ์ €ํ•˜). dashboardยทmeยทplan ์€ retained ๋ผ ์žฌ๊ตฌ๋…์œผ๋กœ ๋Œ์•„์˜จ๋‹ค
OC ์ด๋ฒคํŠธ ํŒ์—…์ด ์ฐจ ์Šคํ… ์ค‘์— ๋œธ OC ๋Š” task/startยทtask/complete ๋ฅผ ์ด๋ฒคํŠธ ๋ฐœํ–‰ ํŒ๋‹จ์˜ ํŠธ๋ฆฌ๊ฑฐ๋กœ ์“ด๋‹ค. ํŒ์—…์€ ํƒœ๋ธ”๋ฆฟ์—๋งŒ ๋œจ๊ณ  ์ฐจ๋Š” ๋ชจ๋ฅธ๋‹ค โ€” ์ฐจ๊ฐ€ ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ• ์ง€๋Š” ๋ฏธ์ •(11์žฅ)
๋งˆ์ดํฌ ๊ถŒํ•œ ๊ฑฐ๋ถ€ยทSTT ์˜ค๋ฅ˜ ํ™”๋ฉด ํ•˜๋‹จ ์•Œ์•ฝ์ด ๋ถ‰๊ฒŒ ํ‘œ์‹œ๋œ๋‹ค(not-allowedยทnetwork). ์šด์˜์ž๋Š” /ambient dev ํŒจ๋„์˜ advance(๊ฐ•์ œ ์ง„ํ–‰)๋กœ ์—ฌ์ •์„ ์ด์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค

9. tablet-fe ์—ฐ๋™ ๊ฐ€์ด๋“œ

tablet-fe 60d353c ๊ธฐ์ค€ 1ยท2ยท3 ์€ ๊ตฌํ˜„๋ผ ์žˆ๋‹ค(future-car-store, TaskCompleteDialog ์˜ enter/exit). ๋‚จ์€ ๊ฒƒ์€ 9-2-1 ์ž…๋ ฅ ์ž ๊ธˆ์ด๋‹ค.

9-1. ๊ตฌ๋…

orchestration/{session_id}/future-car/response      QoS 1

session_id ๋Š” ํŽ˜๋ฅด์†Œ๋‚˜ ์ƒ์„ฑ ์‹œ ๋ฐœ๊ธ‰๋ฐ›์€ ๊ฐ’์ด๋‹ค. ํƒœ๋ธ”๋ฆฟ์ด ์—ฌ๋Ÿฌ ๋Œ€๋ฉด ๋ฐ˜๋“œ์‹œ ์ž๊ธฐ ์„ธ์…˜์œผ๋กœ ๊ณ ์ •ํ•œ๋‹ค. state ๋Š” retain=true ๋ผ ๋Šฆ๊ฒŒ ๋ถ™์–ด๋„ ๋งˆ์ง€๋ง‰ ์ƒํƒœ๋ฅผ ์ฆ‰์‹œ ๋ฐ›๋Š”๋‹ค. routeยทstepยทerror ๋Š” retain ์ด ์—†๋‹ค.

์ฑ„ํŒ…์€ ์ถ”๊ฐ€ ๊ตฌ๋…์ด ํ•„์š” ์—†๋‹ค. ๋ฏธ๋ž˜์ฐจ๊ฐ€ orchestration/{sid}/ai/response ์— {ok, context_id, message} ๋กœ ์งˆ๋ฌธ์„, ai/suggestions ์— {context_id, suggestions[]} ๋กœ ๋‹ต ํ›„๋ณด๋ฅผ ์ง์ ‘ ๋ฐœํ–‰ํ•œ๋‹ค โ€” ํƒœ๋ธ”๋ฆฟ์ด ์ด๋ฏธ ๊ตฌ๋…ํ•˜๋Š” ํ† ํ”ฝ์ด๊ณ , ๋ชจ๋ฅด๋Š” context_id ์˜ message ๋ฅผ AI ๋งํ’์„ ์œผ๋กœ, suggestions ๋ฅผ ์นฉ์œผ๋กœ ๊ทธ๋ฆฌ๋Š” ๊ธฐ์กด ๋กœ์ง์ด ๊ทธ๋Œ€๋กœ ๋™์ž‘ํ•œ๋‹ค.

9-2. ์ƒํƒœ โ†’ ํ™”๋ฉด

๋ฐ›์€ ๋ฉ”์‹œ์ง€ ํƒœ๋ธ”๋ฆฟ
state ยท phase=idle ์ƒˆ ์—ฌ์ •. ์ง€๋‚œ ๊ตฌ๊ฐ„ยท์—๋Ÿฌ ๋น„์šฐ๊ธฐ
state ยท phase=waiting ํƒ‘์Šน๋จ. ๊ณง ์ฑ„ํŒ…์— "์ถœ๋ฐœ ํ• ๊นŒ์š”?" ๊ฐ€ ๋œฌ๋‹ค. ์ž…๋ ฅ ์ž ๊ธˆ ์‹œ์ž‘(9-2-1)
route ๊ตฌ๊ฐ„ ํ‘œ์‹œ ๊ฐฑ์‹  (from_stop_id โ†’ to_stop_id, ์—†์œผ๋ฉด placeยท์ด์ „ ๊ตฌ๊ฐ„ ์œ ์ง€)
step ยท phase=driving ๋ฏธ๋ž˜์ฐจ ์žฌ์ƒ ์ค‘ โ€” data ๋Š” ๋ฌด์‹œ, phaseยทstep ๋งŒ ์ทจํ•œ๋‹ค
state ยท phase=arrived (step 1~3) ๊ณง ์ฑ„ํŒ…์— ๋‹ค์Œ ์งˆ๋ฌธ์ด ๋œฌ๋‹ค. ๊ด€๋žŒ๊ฐ์€ ์ฐจ์— ๋Œ€๊ณ  ๋‹ตํ•œ๋‹ค
state ยท phase=arrived ยท next=exit ํ•˜์ฐจ ๊ฐ€๋Šฅ(canExit). ๊ด€๋žŒ๊ฐ์ด ์ฐจ๋ฅผ ๋– ๋‚˜ ๋‹ค์Œ ์žฅ์†Œ๋กœ ์ด๋™์„ ํ™•์ •ํ•˜๋ฉด exit
state ยท phase=done ์—ฌ์ • ๋. ์ž…๋ ฅ ์ž ๊ธˆ ํ•ด์ œ
error 5-3-1 ํ‘œ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌ (JOURNEY_ENDED ๋Š” ํ‘œ์‹œํ•˜์ง€ ์•Š์Œ)

advance ๋ฒ„ํŠผ์€ ์—†๋‹ค. ๋‹ค์Œ ์Šคํ…์€ ๊ด€๋žŒ๊ฐ์ด ์ฐจ์— ๋งํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค.

9-2-1. ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ ์ž…๋ ฅ ์ž ๊ธˆ (โฌœ ๋ฏธ๊ตฌํ˜„ โ€” 2026-08-28 ์ •์ฑ…)

phase โˆˆ {waiting, driving, arrived} ์ธ ๋™์•ˆ ์ฑ„ํŒ… ํ…์ŠคํŠธ ์ž…๋ ฅยท๋งˆ์ดํฌยท์ œ์•ˆ ์นฉ ํƒญ์„ ์ž ๊ทผ๋‹ค. ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๋„์šด ์งˆ๋ฌธ๊ณผ ์นฉ์€ ํ‘œ์‹œ๋งŒ ํ•œ๋‹ค(์นฉ disabled). ์•ˆ๋‚ด ๋ฌธ๊ตฌ ์˜ˆ: "์ฐจ๋Ÿ‰ ์•ˆ์—์„œ๋Š” ์ฐจ์— ์ง์ ‘ ๋ง์”€ํ•ด ์ฃผ์„ธ์š”". phase=done(๋˜๋Š” idle) ์—์„œ ํ‘ผ๋‹ค.

์ด์œ : ์Šคํ… ์ง„ํ–‰์€ ์ฐจ๋Ÿ‰ ๋งˆ์ดํฌ๋กœ๋งŒ ํ•œ๋‹ค. ํƒœ๋ธ”๋ฆฟ์—์„œ ๋‹ตํ•˜๋ฉด OC ์˜ AI ๋™๋ฐ˜์ž๊ฐ€ ๋”ฐ๋กœ ๋‹ต์„ ํ•ด ์ฐจ์™€ ํƒœ๋ธ”๋ฆฟ์ด "๋”ฐ๋กœ ๋…ธ๋Š”" ์ƒํ™ฉ์ด ์ƒ๊ธฐ๊ณ  (OC ai/mode=car ๋Š” ์Œ์„ฑ๋งŒ ๋ง‰๋Š”๋‹ค), ๋ฏธ๋ž˜์ฐจ๋„ ๊ทธ ๋‹ต์„ ์Šคํ… ์žฌ๋ฃŒ๋กœ ๋ฐ›์•„ ๋ฒ„๋ฆฐ๋‹ค.

9-3. ๋ฐœํ–‰

orchestration/{session_id}/future-car/request       QoS 1 ยท retain=false
์–ธ์ œ ํŽ˜์ด๋กœ๋“œ
๋‹ค์Œ ๋ชฉ์ ์ง€๊ฐ€ ์ฐจ๋Ÿ‰์ด๊ณ  ์ด๋™์„ ํ™•์ •ํ•  ๋•Œ(ํƒ‘์Šน) {"type":"enter"}
์ง€๊ธˆ ์žฅ์†Œ๊ฐ€ ์ฐจ๋Ÿ‰์ด๊ณ  ๋‹ค์Œ ์žฅ์†Œ๋กœ ์ด๋™์„ ํ™•์ •ํ•  ๋•Œ(ํ•˜์ฐจ) {"type":"exit"}

์ด๊ฒŒ ์ „๋ถ€๋‹ค. advanceยทstart ๋Š” ํ๊ธฐ๋๋‹ค(๋ฐ›์•„์ฃผ๊ธด ํ•˜์ง€๋งŒ deprecated ๋กœ ๊ธฐ๋ก๋˜๊ณ  ๊ฐ•์ œ ์ง„ํ–‰๋œ๋‹ค). plan ์€ OC ๊ฐ€ ๋ฐœํ–‰ํ•œ๋‹ค. ์ค‘๋ณต ๋ฐœํ–‰ ๊ฐ€๋“œ: enter ๋Š” phase ๊ฐ€ ๋ฏธ์ˆ˜์‹ /idle ์ผ ๋•Œ๋งŒ, exit ๋Š” waitingยทdrivingยทarrived ์—์„œ๋งŒ.

โš ๏ธ retain=false ๋กœ ๋ฐœํ–‰ํ•œ๋‹ค. ํƒœ๋ธ”๋ฆฟ ์š”์ฒญ์„ retain ํ•˜๋ฉด ๋ฏธ๋ž˜์ฐจ ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ ๋ธŒ๋กœ์ปค๊ฐ€ ์žฌ์ „์†กํ•˜๋Š”๋ฐ, ์„œ๋ฒ„๋Š” retained REQUEST ๋ฅผ ์ „๋ถ€ ๋ฒ„๋ฆฌ๋ฏ€๋กœ ์กฐ์šฉํžˆ ๋ฌด์‹œ๋œ๋‹ค.

9-4. ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผ ํ•  ๊ฒƒ

  1. step.data ๋ฅผ ํ•ด์„ํ•˜์ง€ ๋งˆ๋ผ. ๋ฏธ๋ž˜์ฐจ ํ™”๋ฉด ์ „์šฉ ์—ฐ์ถœ ๋ฐ์ดํ„ฐ๋‹ค. ํƒœ๋ธ”๋ฆฟ์ด ๋ณผ ํ•„๋“œ๋Š” typeยทstepยทphaseยทnext ์™€ route ์˜ stop_idยทplace ๋ฟ์ด๋‹ค.
  2. null ํ•„๋“œ๋Š” ์ƒ๋žต๋˜์–ด ์˜จ๋‹ค. next ํ‚ค์˜ ์กด์žฌ ์—ฌ๋ถ€๋กœ ํŒ๋‹จํ•˜๋ผ(next === null ๋น„๊ต ๊ธˆ์ง€). route ์˜ stop_id ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€.
  3. ์ฑ„ํŒ… ์งˆ๋ฌธ์€ ๋ฏธ๋ž˜์ฐจ๊ฐ€ ๋„์šด๋‹ค. ํƒœ๋ธ”๋ฆฟ์ด "๋‹ค์Œ์œผ๋กœ" ์•ˆ๋‚ด ๋ฌธ๊ตฌ๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์ง€ ๋งˆ๋ผ โ€” ์ด์ค‘์œผ๋กœ ๋œฌ๋‹ค.
  4. ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ์—์„œ๋Š” ์ž…๋ ฅ์„ ์ž ๊ทผ๋‹ค(9-2-1). ๊ด€๋žŒ๊ฐ์ด ๋‹ตํ•˜์ง€ ์•Š์œผ๋ฉด ์ง„ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค โ€” ํ˜„์žฅ ์Šคํƒœํ”„๊ฐ€ ์ฐจ์— ๋งํ•˜๋„๋ก ๊ฐ€์ด๋“œํ•œ๋‹ค(์„ค๊ณ„ ์ „์ œ).
  5. ์ฐจ๋Ÿ‰ ํƒœ์Šคํฌ ์นด๋“œ๋Š” ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค. type=basic ํƒœ์Šคํฌ์˜ in_progressโ†’completed ๋Š” ๋ฏธ๋ž˜์ฐจ๊ฐ€ task/startยทtask/complete ๋กœ ๋ฐ”๊พธ๊ณ  OC ๊ฐ€ dashboard ๋กœ ๋‚ด๋ ค์ค€๋‹ค. ๊ทธ ์™ธ ํƒ€์ž…(๋‹๋ณด๊ธฐ ๋ชจ๋‹ฌ)์€ ์ง€๊ธˆ์ฒ˜๋Ÿผ ๊ด€๋žŒ๊ฐ์ด ํƒœ๋ธ”๋ฆฟ์—์„œ ์™„๋ฃŒํ•œ๋‹ค.

9-5. ์—ฐ๋™ ํ…Œ์ŠคํŠธ

์ฃผ์†Œ ์šฉ๋„
http://creator-mac-studio.tail69930a.ts.net:8100/mqtt ์ฃผ๊ณ ๋ฐ›์€ MQTT ์›๋ฌธ์„ ์‹œ๊ฐ„์ˆœ์œผ๋กœ ํ™•์ธ + ์ˆ˜๋™ ๋ฐœํ–‰ (DB ์ด๋ ฅ ํ† ๊ธ€๋กœ ์žฌ์‹œ์ž‘ ์ „ ๊ฒƒ๋„)
POST โ€ฆ:8100/ambient/utterance {session_id, transcript, source:"debug"} ๊ด€๋žŒ๊ฐ ๋ฐœํ™” ํ‰๋‚ด โ€” ์ฐจ๋Ÿ‰ ํ™”๋ฉด ์—†์ด ์—ฌ์ •์„ ํ•œ ์Šคํ…์”ฉ ๋Œ๋ ค๋ณผ ์ˆ˜ ์žˆ๋‹ค
GET โ€ฆ:8100/ambient/session/{session_id} ์„ธ์…˜ ์Šค๋ƒ…์ƒท(phaseยทstepยท์™„๋ฃŒ ํƒœ์Šคํฌยท์ˆ˜์ง‘ ๋ฐœํ™”)
GET โ€ฆ:8100/logs?session_id=โ€ฆ ์„œ๋ฒ„ ์ง„ํ–‰ ๋กœ๊ทธ(DB)
http://creator-mac-studio.tail69930a.ts.net:8100/docs REST API (Swagger)

์ „์‹œ๋ง(Tailscale) ์•ˆ์—์„œ๋งŒ ์—ด๋ฆฐ๋‹ค. ๋ฏธ๋ž˜์ฐจ ์„œ๋ฒ„ ์ฃผ์†Œ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์ด ํ‘œ๋ฅผ ๊ฐฑ์‹ ํ•  ๊ฒƒ.

/mqtt ์—์„œ enter ๋ฅผ ๋ˆ„๋ฅด๊ณ  /ambient/utterance ๋กœ ๋ฐœํ™”๋ฅผ ๋„ฃ์œผ๋ฉด ์–ด๋–ค ๋ฉ”์‹œ์ง€๊ฐ€ ์–ด๋–ค ์ˆœ์„œ๋กœ ๋‚˜๊ฐ€๋Š”์ง€ 8-2 ๊ทธ๋Œ€๋กœ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


10. QoS ยท retain ยท ๊ธฐํƒ€ ์„ค์ •

ํ•ญ๋ชฉ ๊ฐ’
QoS 1 (๋ชจ๋“  ํ† ํ”ฝ)
retain โ€” REQUEST plan OC ๋ฐœํ–‰ true (๋ฏธ๋ž˜์ฐจ๋Š” ์žฌ์ „์†ก๋ถ„๋งŒ ๋ฌด์‹œ)
retain โ€” REQUEST ํƒœ๋ธ”๋ฆฟ ํŠธ๋ฆฌ๊ฑฐ false
retain โ€” RESPONSE state true (์‹ ๊ทœ ๊ตฌ๋…์ž ์ฆ‰์‹œ ์ตœ์‹  ์ƒํƒœ)
retain โ€” RESPONSE route ยท step ยท error false
retain โ€” AI REQUEST (๋ฏธ๋ž˜์ฐจ ๋ฐœํ–‰) false
retain โ€” DASHBOARD OC ๋ฐœํ–‰ true
ํŽ˜์ด๋กœ๋“œ ํ‰๋ฌธ JSON ยท snake_case ยท null ํ•„๋“œ ์ƒ๋žต
์—ฐ๊ฒฐ ์˜ต์…˜ AutoReconnect (reconnect_delay 1~30์ดˆ). ๋ธŒ๋กœ์ปค๊ฐ€ ์ฃฝ์–ด ์žˆ์–ด๋„ ์„œ๋ฒ„ ๋ถ€ํŒ…์„ ๋ง‰์ง€ ์•Š์Œ
ACL orchestration/# ํ•˜์œ„๋ผ ํ˜„ ACL(future-car ๊ณ„์ •)๋กœ ํ†ต๊ณผ โ€” ๋ณ€๊ฒฝ ๋ถˆํ•„์š”

11. ๋‚จ์€ ํ•ฉ์˜ ํ•ญ๋ชฉ

  • โœ… enter ๋ฐœํ–‰ ์ฃผ์ฒด โ€” ํƒœ๋ธ”๋ฆฟ(2026-08-20). tablet-fe ๊ตฌํ˜„ ์™„๋ฃŒ(TaskCompleteDialog).
  • โœ… OC ์„ธ์…˜ ๋ชจ๋“œ ai/mode โ€” OC ๊ตฌํ˜„ ์™„๋ฃŒ(2026-08-24). ai/response ์ง์ ‘ ๋ฐœํ–‰์€ OC ๊ฐ€ ๊ตฌ๋…ํ•˜์ง€ ์•Š๋Š” ํ† ํ”ฝ์ด๋ผ ์˜ํ–ฅ ์—†์Œ(์ •์‹ ๋™์˜๋Š” ๋ฐ›์•„ ๋‘˜ ๊ฒƒ).
  • โฌœ tablet-fe: ๋ฏธ๋ž˜์ฐจ ๋ชจ๋“œ ์ž…๋ ฅ ์ž ๊ธˆ(9-2-1) โ€” 2026-08-28 ์ •์ฑ…. ์ด๊ฒŒ ์—†์œผ๋ฉด ํƒœ๋ธ”๋ฆฟ ๋‹ต๋ณ€์ด ์Šคํ… ์žฌ๋ฃŒ๋กœ ์„ž์—ฌ ๋“ค์–ด๊ฐ„๋‹ค.
  • โฌœ ์ด๋ฒคํŠธ(๋Œ๋ฐœ ํŒ์—…)์™€ ์ฐจ์˜ ๊ด€๊ณ„ โ€” ๋ฏธ์ •. OC ๋Š” task/startยทtask/complete ๋ฅผ ์ด๋ฒคํŠธ ๋ฐœํ–‰ ํŒ๋‹จ ํŠธ๋ฆฌ๊ฑฐ๋กœ ์“ฐ๋ฏ€๋กœ ์ฐจ ์Šคํ… ์ค‘ ํƒœ๋ธ”๋ฆฟ์— ํŒ์—…์ด ๋œฐ ์ˆ˜ ์žˆ๋‹ค. ์ฐจ๊ฐ€ ๋ฐ˜์‘ํ•˜๋ ค๋ฉด orchestration/{sid}/event ๊ตฌ๋…์ด ํ•„์š”ํ•œ๋ฐ, ํŽ˜์ด๋กœ๋“œ์— ์žฅ์†Œ ์ฐธ์กฐ๊ฐ€ ์—†์–ด OC ์— location_id ์ถ”๊ฐ€(๋˜๋Š” dashboard.locations[].event ์š”์•ฝ)๋ฅผ ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค.
  • โฌœ ์ถฉ์ „์†Œ ํ•˜๋“œ์›จ์–ด ์—ฐ๋™ โ€” route.to_place=charging_station ์ธ ์Šคํ…์˜ ๋ Œ๋” ์™„๋ฃŒ = ์ถฉ์ „์†Œ ๋„์ฐฉ. ์–ด๋А ๋ธŒ๋กœ์ปคยทํ† ํ”ฝยทํŽ˜์ด๋กœ๋“œ๋กœ ์•Œ๋ฆด์ง€ ๋‹ด๋‹น ํŒ€๊ณผ ๋ฏธ์ •.
  • โฌœ exit ์ดํ›„ ๋‹ค์Œ ๊ณต๊ฐ„ ์ „ํ™˜ ์‹ ํ˜ธ โ€” ์ฃผ์ฒด/ํ† ํ”ฝ ๋ฏธํ™•์ •. ๋ฏธ๋ž˜์ฐจ๋Š” state.next_place ๋กœ "๋‹ค์Œ ์žฅ์†Œ๊ฐ€ ์–ด๋””์ธ์ง€"๊นŒ์ง€๋งŒ ์•Œ๋ ค์ค€๋‹ค.
  • โฌœ ์šด์˜ ๊ทœ์น™: ์ฐจ๊ฐ€ ์™„๋ฃŒํ•ด์•ผ ํ•˜๋Š” ์ฐจ ํƒœ์Šคํฌ๋Š” ๋ฐฑ์˜คํ”ผ์Šค์—์„œ type=basic ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค(ํƒ€์ž…์ด ๊ณง ์™„๋ฃŒ ์ฃผ์ฒด ์Šค์œ„์น˜).
  • โฌœ AsyncAPI ๋ฐ˜์˜ โ€” RESPONSE 4์ข…(stateยทrouteยทstepยทerror)์„ Orchestration MQTT API ์˜ future-car ์ฑ„๋„์— ๋ฐ˜์˜.
  • โ„น๏ธ reaction ํ๊ธฐ ์—ฌ๋ถ€ โ€” ๊ณ„์•ฝ์—๋งŒ ๋‚จ์•„์žˆ๊ณ  ๋ฐœํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • โ„น๏ธ ์ธ์ฆ ์—†์Œ โ€” /mqtt/publishยท/ambient/utterance ๋กœ ์ „์‹œ ์ค‘์ธ ์—ฌ์ •์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. Tailscale ๋ง ์•ˆ์ด๋ผ ์šฐ์„ ์ˆœ์œ„๋Š” ๋‚ฎ์œผ๋‚˜, ์™ธ๋ถ€ ๋…ธ์ถœ ์‹œ ๋Œ€์‘ ํ•„์š”.