Skip to content

[Spec] SayPlan 통합 — Scene Graph 기반 숙고 트랙 (verify / replan) #2

Description

@Taeyoung96

대상: ZER01NE 백엔드 오케스트레이터 개발자
참고 위키: https://github.com/zero1ne-26/doc/wikiSYSTEM_DESIGN · OSS_INTEGRATION · LOCAL_LLM_HYBRID_ROUTING
첨부 다이어그램(FigJam): Figma 6월 1주차 논의 사항

요약

현재 오케스트레이터는 assemble → call_claude → guardrail → dispatch단발 반응형이다. 이 명세는 SayPlan을 프레임워크로 얹지 않고 패턴으로 이식하여, guardrailreject-only 에서 verify-and-replan 으로 승격하고, 그 중심에 offline 사전 구축한 scene graph를 두어 "탐색 → 실패 → 재탐색 → 실행"을 실제 로봇 행동 + UI 스트리밍으로 관측 가능하게 만든다.

핵심 결정 사항 (확정)

  1. 패턴으로 채택 — SayPlan 레포를 의존성/서비스로 얹지 않고, 2 스테이지·2 루프 패턴을 orchestrator 내부에 이식한다.
  2. 두 트랙 분리 — 기존 단발 반응 트랙은 유지(NFR < 1.5s), SayPlan은 숙고 트랙(신규)으로 분리.
  3. Scene Graph는 offline 사전 구축 — 런타임 구조는 정적. (SayPlan 원본의 pre-built 3DSG 가정과 일치)
  4. 로봇 명령 디스패치는 MCP(mcp-robot-adapter) 채택 — 직접 in-process 호출은 stop 등 초저지연 특수 케이스 fallback으로만.
  5. 재시도 캡 N = 1~2 / 신규 MQTT 토픽 0개 — 루프는 orchestrator 내부에서 종결.

1. SayPlan 개요 (개발자용)

SayPlan = 3D Scene Graph(JSON 그래프) + LLM으로 로봇 task plan을 생성하는 프레임워크. 2 스테이지, 2 루프. (FigJam ① 참조)

  • 입력: 자연어 명령 + 환경의 3D Scene Graph (계층 floor → room → asset → object, 각 노드에 state · affordance · predicate)
  • STAGE 1 — Semantic Search: 그래프를 collapse()(상위만 노출)한 뒤 LLM이 expand(node)/contract(node)로 task에 필요한 부분그래프만 탐색. 탐색 과정이 스텝 단위로 관측 가능.
  • STAGE 2 — Iterative Replanning: 부분그래프로 LLM이 action 시퀀스 생성 → Scene Graph Simulator가 affordance·predicate로 실행가능성 검증 → 실패 시 텍스트 피드백("cannot pick: fridge not open")을 되먹여 재계획. 경로는 전통 path planner에 위임.
  • 2 루프: ① 재계획(STAGE 2 내부): 계획이 막힘 → 계획만 수정. ② 재탐색(STAGE 2 → STAGE 1): 부분그래프에 필요한 객체가 없음 → 탐색으로 복귀해 다른 노드 펼침.

2. 왜 필요한가

guardrail은 잘못된 tool call을 거부 + 메트릭만 남긴다(SYSTEM_DESIGN §9.3). 단발 인사·옵션 노출엔 충분하나 세 지점에서 한계:

  1. 다단계 과업의 견고성bring, §16의 6단계 여정처럼 여러 행동이 엮인 task는 한 번의 tool call로 끝나지 않는다. 중간 제약 위반을 거부만 하지 말고 사유를 LLM에 되먹여 고친 계획을 받아야 한다 → 환각으로 인한 비실행 계획을 거의 0으로.
  2. 그라운딩 — LLM 단독은 "그 물체가 실제로 있는지/집을 수 있는지"를 모른다. scene graph의 state·affordance를 simulator가 검증하면 계획이 환경에 묶인다.
  3. 전시 연출 가치(핵심) — UI 오버레이는 이미 reasoning을 스트리밍한다. expand/contract·재계획 스텝을 흘리면 "AI가 공간을 뒤지며 생각하고, 막히면 다시 길을 찾는" 과정이 보인다. 탐색·재탐색은 비용이 아니라 콘텐츠.

단발 반응에는 SayPlan이 과하다. 하지만 보여줄 인지 과정 + 다단계 실행 보증이 필요한 순간엔 정확히 그 빈자리를 채운다.


3. 통합 전략

3.1 두 트랙 분리 (가장 중요한 결정)

트랙 용도 지연 scene graph
반응 트랙 (기존 유지) zone 입장 인사, look_at, 옵션 노출 NFR < 1.5s 사용 안 함
숙고 트랙 (신규, SayPlan) bring, 장기 시나리오, "생각하는 모습" 데모 NFR 미적용 (탐색이 곧 연출) 탐색·검증의 중심

라우팅: 트리거 시점에 숙고 필요?(task 종류·playbook 기준)로 분기. (FigJam ③ 참조)

3.2 채택 / 비채택

SayPlan 요소 채택 비고
Iterative replanning + simulator 피드백 가장 큰 가치. guardrailverify 승격
Scene graph 표현 + 탐색/재탐색 ◎ (숙고 트랙) 전시 연출 + bring 그라운딩
collapse/expand (토큰 절감 목적) 4 zone은 토큰 문제 없음 → 탐색 연출 용도로만 사용
Dijkstra path planner SPOT SDK/ROS2 + world↔odom 정합(SYSTEM_DESIGN §8.3.2)이 담당
Semantic search (스케일 목적) 소규모 환경엔 무가치

3.3 경계·주의 (충돌 방지)

  • 안전은 mcp-robot-adapter에 그대로. simulator는 과업 실현가능성만 판단(피드백 생성). 물리 안전(e-stop·proximity·zone fence)의 권위는 어댑터다. 이중 구현 금지.
  • 지연 예산: 재계획 1회 = Claude 호출 1회. 반응 트랙 단발 유지, 숙고 트랙도 재시도 캡 N = 1~2(원본 5회는 실시간엔 과함). LOCAL_LLM_HYBRID_ROUTING 채택 시 재검증 re-prompt는 저렴/로컬 티어로, 메인 결정만 Opus로.
  • 신규 MQTT 토픽 0개 — 루프는 orchestrator 내부에서 종결(SYSTEM_DESIGN §16.6 정신 유지).
  • HA vs LangGraph 경계(OSS_INTEGRATION §7): 단순 룰은 HA, 컨텍스트 의존 결정은 orchestrator. simulator는 후자.

4. 디스패치 방식 결정 — MCP 채택

기준 MCP (mcp-robot-adapter) 직접 in-process 호출
아키텍처 일관성 전 시스템이 MCP → 일관 특례 발생
안전 인터록·명령 큐·이종 로봇 추상화 어댑터가 소유 (설계대로) shim 재구현 필요
권한 분리·테스트성 용이 (orchestrator만 호출, ACL) 약함
지연 SSE 홉 (LAN, 수 ms) 더 빠름

결론: MCP 채택. 숙고 트랙은 NFR에 묶이지 않고, 안전·이종 로봇 책임이 어댑터에 모이는 것이 설계(SYSTEM_DESIGN §3.3·§7.3·§7.4)와 일치. 직접 호출은 stop 같은 초저지연 케이스에서만 fallback으로 문서화.


5. Scene Graph 명세 (offline 사전 구축)

5.1 형식

  • 직렬화: JSON (NetworkX 호환). 경로: config/scene_graph/<site>.json (PoC: config/scene_graph/home.json).
  • 계층(노드 종류): site → zone → asset → object (+ pose/waypoint, agent).
  • 빌드: offline 도구로 1회 구축 → 검수 → 고정. 런타임 중 구조 변경 없음.

5.2 노드 스키마

노드 주요 필드
zone id, name, polygon_world, connected_waypoints[]
asset id, zone, pose_world, state(open/closed/...), affordances[](open, close, release...)
object id, parent(asset|zone), state, affordances[](pickup...), attributes
pose/waypoint id, xy_world, links[] — GraphNav waypoint와 정합
agent robot_id, location(zone/pose) — 런타임 overlay

5.3 정적 / 동적 분리 (중요)

  • 정적 (offline 고정): zone·asset·object 구조, pose, affordance, 위치. 전시 prop은 움직이지 않는다는 전제.
  • 동적 (런타임 overlay): 로봇 위치(robot/+/state), zone 점유(Frigate). 정적 구조 위에 얇게 덮음.
  • SayPlan의 "정적 맵 가정" 한계는 본 프로젝트에서 의도된 설계가 된다. live re-mapping 불필요.

5.4 collapse / expand 처리

  • 4 zone 규모라 그래프 전체가 LLM 컨텍스트에 들어감 → 토큰 절감 목적의 collapse 불필요.
  • expand/contract관측 가능한 탐색 연출 용도로만 유지(숙고 트랙 UI 스트리밍). 정적 그래프 위를 스텝 단위로 훑는 형태.

6. 로봇 명령 명세 (mcp-robot-adapter 노출)

공통 규약

  • robot_idconfig/robots.yaml 레지스트리로 런타임 검증 (literal 박지 말 것).
  • 모든 명령은 결과 반환: { status, detail, observations?, pose? }. fire-and-forget 금지 — 반환이 곧 verify/replan 피드백.
  • 안전 인터록은 어댑터 소유(orchestrator는 whitelist·clamp만). stop은 항상 큐 최우선·즉시 preempt.
  • status enum: ok | arrived | blocked | failed | rejected | stopped.
명령 input 반환 안전/비고 구현 출처
describe_scene robot_id, target? observations[] { label, rel_pos, affordances, confidence } 신규 (VLM/GroundingDINO)
goto robot_id, destination(zone/waypoint) arrived / blocked(detail) / failed, pose proximity·zone fence 검증 GraphNav
stop robot_id stopped 최우선, 즉시 SPOT SDK
look_at robot_id, target ok SPOT SDK
gesture robot_id, name(enum) ok SDK 프리셋
follow robot_id, target, max_distance_m status proximity 지속 검증 SPOT SDK
(later) bring robot_id, object, destination status object affordance=pickup 그래프 검증 후 STAGE 2 KAIST + grasping

각 명령의 상세 input_schema(JSON)는 mcp-robot-adapter에 정의. 위 표는 계약 요약.

6.1 describe_scene의 역할 (offline 그래프 전제)

그래프를 offline으로 완성했으므로 describe_scene그래프 빌더가 아니다. 두 용도:

  1. 그라운딩 검증 — 행동 전 "그래프상 object가 실제로 앞에 있나" 대조. 불일치 시 detail로 피드백 → 재계획/재탐색.
  2. 전시 연출 — "AI가 앞을 보고 묘사하는" 스텝을 UI 스트리밍.

정적 그래프 = 계획의 기준, describe_scene = 현실과의 대조. 어긋나는 순간이 재탐색 트리거.


7. 디스패치 · 피드백 규약 (숙고 트랙)

  1. dispatch 노드 → MCP 호출 → CommandResult 수신.
  2. observations가 있으면 그래프의 동적 overlay만 갱신(구조 불변).
  3. status ∈ {blocked, failed, rejected}detail을 LLM 피드백으로 주입:
    • 제약 위반/실패 → STAGE 2 재계획 (재시도 캡 N = 1~2).
    • 객체 불일치/도달 불가 → STAGE 1 재탐색.
  4. 캡 초과 → rule-based 폴백(SYSTEM_DESIGN §9.4).
  5. 신규 MQTT 토픽 0개 — 루프는 orchestrator 내부에서 종결.

8. SayPlan ↔ ZER01NE 매핑

SayPlan ZER01NE 대응
LLM Claude (Anthropic API) — call_claude
3D Scene Graph config/scene_graph/<site>.json → NetworkX (offline 구축, orchestrator 로드)
Scene Graph Simulator simulate 노드 (과업 실현가능성 검증)
Semantic Search (expand/contract) semantic_search 노드 (숙고 트랙, UI 스트리밍)
Iterative Replanning verifycall_claude 피드백 루프 (캡 N회)
Path Planner (Dijkstra) SPOT SDK / GraphNav (채택 안 함)
실행 dispatchmcp-robot-adapter → 로봇

9. 로드맵 (마일스톤 연계)

단계 작업 비고
M3 반응 트랙 + verify-and-replan 루프(평평한 상태 검증 버전) guardrailverify 승격. scene graph 없이도 재계획 루프 동작
M3+ / bring 결정 후 offline scene graph + semantic_search/simulate 노드 추가 → 숙고 트랙 완성 KAIST 로봇·bring 확정과 동기화(SYSTEM_DESIGN §15)
M4~M5 숙고 트랙 UI 스트리밍 연출, 폴백·캡 튜닝, 부하 리허설

10. 구현 산정

항목 신규/기존 비고
offline scene graph 빌드 도구 신규 1회성, 검수 후 고정
config/scene_graph/home.json 신규 PoC 인스턴스
mcp-robot-adapter 명령 노출 기존 확장 §6 명령 등록 + 안전 인터록
describe_scene perceiver 신규 VLM/GroundingDINO — 유일한 무거운 신규 작업
orchestrator 숙고 서브그래프 신규 STAGE 1/2 + 2 루프 + 캡/폴백 (§7)
goto/stop/look_at/gesture/follow 기존 SPOT SDK·GraphNav 제공

11. 작업 체크리스트 (이슈 트래킹)

  • offline scene graph 빌드 도구 작성
  • config/scene_graph/home.json 구축 → 검수 → 고정
  • mcp-robot-adapterdescribe_scene / goto / stop 등록 (+ 안전 인터록)
  • describe_scene perceiver (VLM/GroundingDINO) 구현
  • orchestrator 숙고 서브그래프: semantic_searchplansimulate + 2 루프 + 캡(N=1~2) + 폴백
  • 반응/숙고 트랙 라우팅(숙고 필요?) 구현
  • 숙고 트랙 스텝 → UI 오버레이 스트리밍 연동
  • PoC 시연 루프 end-to-end 검증

12. 수용 기준 (Acceptance Criteria)

  • home zone에서 goto → describe_scene → (불일치/없음) 재탐색 goto → describe_scene → 실행이 동작한다.
  • 제약 위반·실패 시 detail 피드백으로 재계획/재탐색이 트리거되고, 캡(N) 초과 시 rule-based 폴백으로 수렴한다.
  • 탐색·재탐색·재계획 스텝이 UI 오버레이에 실시간 스트리밍된다.
  • 물리 안전(e-stop·proximity·zone fence)은 mcp-robot-adapter에서만 강제되며 orchestrator에 중복 구현되지 않는다.
  • 신규 MQTT 토픽이 추가되지 않는다.

13. 참고

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions