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ํ ๋๋น ๋ณ๊ฒฝ์
- 1. ๊ฐ์
- 2. ํ ํฝ ๋ชฉ๋ก
- 3. REQUEST (
future-car/request) - 4. DASHBOARD (
orchestration/{sessionId}/dashboard) - 5. RESPONSE (
future-car/response) - 6. ๋น-MQTT ์ธ๋ฐ์ด๋ โ ๋ ๋ ์๋ฃ ๋ณด๊ณ ยท ๊ด๋๊ฐ ๋ฐํ
- 7. ์ํ๋จธ์ (phase)
- 8. ์ ์ฒด ํ๋ฆ โ ํ์น ์ง์ ๋ถํฐ ํ์ฐจ๊น์ง
- 9. tablet-fe ์ฐ๋ ๊ฐ์ด๋
- 10. QoS ยท retain ยท ๊ธฐํ ์ค์
- 11. ๋จ์ ํฉ์ ํญ๋ชฉ
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 ์ ๋ช ๋ น ์ฑ๋์ด๊ณ , ์ด๊ฑด ํ๋ฉด ์์ ์ ์ฌ์ค ๋ณด๊ณ ๋ค. ๋ธ๋ก์ปค๊ฐ ์ฃฝ์ด๋ ๋๋ฌํด์ผ ํ๊ณ , ํ๋ธ๋ฆฟ ์์ฒญ๊ณผ ์์ด๋ฉด ํธ๋ํฝ ํด์์ด ์ด๋ ค์์ง๋ค.
์ด ๋ณด๊ณ ๋ฅผ ๋ฐ์ผ๋ฉด ์๋ฒ๊ฐ ์ธ ๊ฐ์ง๋ฅผ ํ๋ค:
phase=arrived๋ก ์ฌ๋ฆฌ๊ณstate๋ฐํ (step 4 ๋ฉดnext=exit)- ๊ทธ ์คํ
์์ AI ๊ฐ ๊ณ ๋ฅธ ์ฐจ๋ ํ์คํฌ๋ฅผ
task/complete๋ก ๋ฐํ (step ๋น 1๊ฐ, ๋ชฐ์์ ์ฒ๋ฆฌ ์์. ์์์ ์คํ ๋ฐํ ๋task/start๋ก ์ด๋ฏธ ์๋ ธ๋ค) - ๊ทธ ์คํ
์
question์ai/response์,answer_suggestions๋ฅผai/suggestions์ ๋ฐํ โ ํ๋ธ๋ฆฟ ์ฑํ ์ ๋ค์ ์ง๋ฌธ๊ณผ ๋ต ํ๋ณด๊ฐ ๋ฌ๋ค. step 4 ๋ ๋ฐํํ์ง ์๋๋ค โ ๋ค์ step ์ด ์์ด ๋ต์ด ์๋ ๊ฐ ๊ณณ์ด ์๋ค - ์ฌ์ ์ค ๋ฏธ๋ค๋ ๊ด๋๊ฐ ๋ฐํ๊ฐ ์์ผ๋ฉด ๊ณง๋ฐ๋ก ๋ค์ ์คํ ์์ฑ์ ์์
โ ๏ธ ์์ ์๋ "๋ฒํผ์ ์ผ๋ ๋๋ค"๋ ์ ํธ์์ง๋ง, ์ด์ ์ด ๋ณด๊ณ ๊ฐ ์ ์ค๋ฉด ์ฌ์ ์ด ๊ทธ ์๋ฆฌ์์ ๋ฉ์ถ๋ค. ์ง๋ฌธ์ด ์ ๋จ๋ ๊ด๋๊ฐ์ด ๋ตํ ์ ์๊ณ , ๋ต์ด ์์ผ๋ ๋ค์ ์คํ ์ด ์ ๋ง๋ค์ด์ง๋ค.
์๋ฒ๊ฐ ๊ฑธ๋ฌ๋ด๋ ๊ฒ: ์ด๋ฏธ ๋ค์ ์คํ
์ผ๋ก ๋์ด๊ฐ ๋ค ๋์ฐฉํ ์ง๊ฐ ๋ณด๊ณ , ๊ฐ์ ์คํ
์ค๋ณต ๋ณด๊ณ , 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 4arrived์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. ์ฌ์ ์ด ์์๋๊ธฐ ์ ์ ์ด๋ฏธ ๊ฐ์ถฐ์ ธ ์๋ ๊ฒ
- ๊ด๋๊ฐ์ด ํ๋ธ๋ฆฟ์์ ํ๋ฅด์๋๋ฅผ ๋ง๋ค๋ฉด OC ๊ฐ
planยทdashboardยทme๋ฅผ retained ๋ก ๋ฐํํ๋ค. ์๋ฒ๋plan์ ๋ฐ๋ ์๊ฐ ์ธ์ (session_id)์ ๋ง๋ค๊ณstate phase=idle์ ๋ฐํํ๋ค(5-1). - ์๋ฒ๋
dashboard์์ ์ฐจ ์ฅ์(name์ด "์ฐจ"๋ก ์์)์ ์๋ค ์ฅ์(P0/P4)์ ํ์คํฌ๋ฅผ ๋ฝ์ ๋๋ค(4์ฅ). ํ์คํฌ ์คtype=basic๋ง ์ฐจ๊ฐ ์ํํ ํ๋ณด๋ค โ ํ๋ธ๋ฆฟ์ ์กฐ์ UI ๊ฐ ์์ด ์๋ฒ๊ฐ ์๋ฃํด์ผ ํ๋ ํ์ . ๊ทธ ์ธ(vehicle_readyยทdetailedยทquote_briefingโฆ)๋ ํ๋ธ๋ฆฟ ๋๋ณด๊ธฐ ๋ชจ๋ฌ์์ ๊ด๋๊ฐ์ด ์๋ฃํ๋ฏ๋ก ์ฐจ๋ ๊ฑด๋๋ฆฌ์ง ์๋๋ค. me.ai_companion.prompt๋ ์คํ ์์ฑ ํ๋กฌํํธ ๋งจ ์์ ๋ถ๋ ์ธ๊ฒฉ(๋ํ์)์ด๋ค.- ํ๋ฉด์ 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. ๋ฐ๋์ ์ง์ผ์ผ ํ ๊ฒ
step.data๋ฅผ ํด์ํ์ง ๋ง๋ผ. ๋ฏธ๋์ฐจ ํ๋ฉด ์ ์ฉ ์ฐ์ถ ๋ฐ์ดํฐ๋ค. ํ๋ธ๋ฆฟ์ด ๋ณผ ํ๋๋typeยทstepยทphaseยทnext์route์stop_idยทplace๋ฟ์ด๋ค.nullํ๋๋ ์๋ต๋์ด ์จ๋ค.nextํค์ ์กด์ฌ ์ฌ๋ถ๋ก ํ๋จํ๋ผ(next === null๋น๊ต ๊ธ์ง).route์stop_id๋ ๋ง์ฐฌ๊ฐ์ง.- ์ฑํ ์ง๋ฌธ์ ๋ฏธ๋์ฐจ๊ฐ ๋์ด๋ค. ํ๋ธ๋ฆฟ์ด "๋ค์์ผ๋ก" ์๋ด ๋ฌธ๊ตฌ๋ฅผ ๋ฐ๋ก ๋ง๋ค์ง ๋ง๋ผ โ ์ด์ค์ผ๋ก ๋ฌ๋ค.
- ๋ฏธ๋์ฐจ ๋ชจ๋์์๋ ์ ๋ ฅ์ ์ ๊ทผ๋ค(9-2-1). ๊ด๋๊ฐ์ด ๋ตํ์ง ์์ผ๋ฉด ์งํ๋์ง ์๋๋ค โ ํ์ฅ ์คํํ๊ฐ ์ฐจ์ ๋งํ๋๋ก ๊ฐ์ด๋ํ๋ค(์ค๊ณ ์ ์ ).
- ์ฐจ๋ ํ์คํฌ ์นด๋๋ ์๋์ง ์๋๋ค.
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 ๋ง ์์ด๋ผ ์ฐ์ ์์๋ ๋ฎ์ผ๋, ์ธ๋ถ ๋ ธ์ถ ์ ๋์ ํ์.