← Docs hub
A2A Planner Cleanup Backlog
이 문서는 A2A Planner Deep Dive의 18. 남은 정리 과제를 실행 가능한 backlog로 풀어쓴 것이다. 목적은 단순 문서 보강이 아니라, planner prompt, response schema, registry, agent catalog, second pass, schedule slot, ODL task contract 사이의 drift를 줄이는 것이다.

1. 전체 우선순위
| 우선순위 |
과제 |
왜 먼저 해야 하는가 |
결과물 |
| P0 |
main_router.response_schema.json vs prompt step 계약 점검 |
planner가 token_text, input_from, execution_target 같은 필드를 실제로 낼 수 있는지 확인하지 않으면 multi-step/device task가 흔들린다. |
Schema/Prompt Drift Report |
| P0 |
ODL token/task contract 안전 경계 보강 |
Planner가 SK token을 임의 생성하면 device execution 안전 경계가 깨진다. |
ODL Token Safety Contract |
| P1 |
capability_registry.v2.json contract 문서화 |
ODL/SCH/DQR/UNS 판단 근거가 registry에 있으므로 kind/scheduling/visibility의 의미를 고정해야 한다. |
Capability Registry Contract |
| P1 |
skill_registry.json agent/skill/flow 표 자동 추출 |
planner가 고르는 agent/skill/flow 목록을 사람이 확인 가능한 표로 유지해야 한다. |
Agent Skill Catalog Table |
| P1 |
Schedule workflow slot schema 연결 |
SCH planner, schedule agent, on-device relay가 같은 slot 이름을 써야 multi-turn schedule이 안정된다. |
Schedule Slot Contract |
| P1 |
Plan Expansion / Dynamic Replanning Contract |
실행 중 plan이 부족해지거나 추가 planning이 필요한 경우의 event, workflow, replan 계약을 고정해야 한다. |
Dynamic Replanning Contract |
| P2 |
Second pass benchmark 영향 문서화 |
DEF/STT_NULL/FRG 회색지대 개선이 실제 성능에 도움이 됐는지 수치로 분리해야 한다. |
Second Pass Benchmark Report |
| P2 |
planner-routing.md와 Deep Dive 중복 정리 |
읽는 사람이 개요와 상세를 혼동하지 않도록 reader path를 정리한다. |
Reader Path/Dedup PR |
2. 실행 순서
P0-1 Schema/Prompt Drift를 먼저 한다.
P0-2 ODL Token Safety를 같이 본다. step schema와 device task contract가 같은 경계에 있기 때문이다.
P1-1 Capability Registry Contract를 만든다.
P1-2 Skill Registry Auto Table을 만든다.
P1-3 Schedule Slot Contract를 만든다.
P1-4 Dynamic Replanning Contract를 만든다.
P2-1 Second Pass Benchmark Report로 성능 영향을 분리한다.
P2-2 Reader Path/Dedup으로 wiki 흐름을 정리한다.
3. P0-1 Schema/Prompt Drift 점검
목적
main_router.system_prompt.txt가 요구하는 steps[] 필드와 main_router.response_schema.json이 허용하는 필드가 같은지 확인한다. 현재 확인된 주요 관심점은 prompt가 token_text와 device step 규칙을 강하게 지시하지만, schema의 steps.items.properties에는 token_text와 device_task가 명시되어 있지 않다는 점이다.
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/planner/assets/main_router.response_schema.json |
steps[].properties, required 필드, turn_mode enum |
gemini/a2a/planner/assets/main_router.system_prompt.txt |
input_from, execution_target, wait_policy, token_text, multi_step 규칙 |
gemini/a2a/planner/main_router_api.py |
planner output normalize와 ranked alignment가 step 필드를 보존하는지 |
gemini/a2a/runtime/task_manager.py |
token_text, execution_target, wait_policy, depends_on, input_from 소비 방식 |
test/ 하위 planner/task 관련 test |
schema field 보존 regression fixture 존재 여부 |
점검 항목
| 항목 |
확인 질문 |
완료 기준 |
token_text |
prompt는 허용하지만 schema가 막거나 누락하지 않는가? |
schema와 prompt 양쪽에 동일하게 명시하거나, ODL agent만 생성한다는 정책을 문서화한다. |
device_task |
planner step에서 허용할지, agent result에서만 허용할지 명확한가? |
planner step field인지 agent output field인지 contract가 분리된다. |
input_from |
data-dependent step에서 비어 있으면 reject/보정되는가? |
Cloud-only/mixed sample에서 input_from이 보존되는 test가 있다. |
execution_target |
cloud/device default와 runtime 해석이 일치하는가? |
prompt, schema, task_manager default가 같은 표로 정리된다. |
wait_policy |
submitted/completed/event의 의미가 prompt와 runtime에서 같은가? |
physical ordering과 semantic event dependency가 분리된다. |
multi_step |
schema enum과 prompt 지시가 일치하는가? |
multi_step sample fixture가 schema validation을 통과한다. |
산출물
planner-schema-prompt-drift.md
- 필요한 경우
main_router.response_schema.json patch
- 필요한 경우
main_router.system_prompt.txt patch
- Cloud-only, mixed cloud/device, device-only step fixture
4. P0-2 ODL Token/Task Contract 안전 경계
목적
Planner, ODL agent, runtime task manager, on-device bridge 사이에서 token_text와 device_task_request를 누가 만들 수 있는지 고정한다.
현재 기준
| 레이어 |
허용 |
금지 |
| Main Planner |
step 순서, dependency, execution target, wait policy 표현 |
SK token 임의 생성, device API 직접 호출 |
| ODL Agent |
지원 capability와 contract에 근거한 device payload 생성 |
capability에 없는 task method 생성 |
| Runtime Task Manager |
planner/agent 결과를 device_task_requests로 변환 |
의미 해석을 새로 해서 다른 task로 바꾸기 |
| On-device Bridge |
device_intent_step 실행, DeviceAgent TaskManager 전달 |
Cloud LLM 없이 임의 replan |
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/planner/assets/main_router.system_prompt.txt |
Never invent token_text 지시 |
gemini/a2a/runtime/task_manager.py |
_step_token_text, _device_intent_requests_from_plan, build_device_task_requests |
gemini/a2a/agents/odl/* |
ODL agent가 device payload를 어디까지 생성하는지 |
docs/a2a/device-task-flow.md |
wiki contract와 구현의 일치 여부 |
| on-device bridge docs/source |
device_intent_step, CloudIntentWorkflowRunner 수신 계약 |
완료 기준
token_text는 catalog/contract 또는 ODL/device-token contract에서 제공된 경우에만 planner output에 존재한다.
- token이 없으면 planner는
execution_target=device만 표시하고, ODL agent 또는 bridge가 executable task를 구성한다.
- device step이 전부 token을 갖는 경우에만
task_manager.py가 plan-level device_intent_step으로 변환한다는 정책이 문서화된다.
- 실패/차단/사용자 결정 필요 이벤트만 Cloud replan 대상으로 올라간다는 경계가 유지된다.
5. P1-1 Capability Registry Contract 문서화
목적
capability_registry.v2.json의 필드를 router 판단 계약으로 문서화한다. 특히 kind, scheduling, visibility는 ODL/SCH/DQR/UNS 경계에 직접 영향을 준다.
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/registry/capability_registry.v2.json |
capability 목록, kind, aliases, scheduling, visibility |
gemini/a2a/registry/loader.py |
build_router_excerpt(...)가 어떤 필드를 planner에 노출하는지 |
gemini/a2a/planner/preclassifier.py |
execution/state/settings/device_qna/unsupported 매칭 방식 |
gemini/a2a/registry/build_capability_registry_v2.py |
v2 registry 생성/변환 로직 |
contract로 분리할 필드
| 필드 |
의미 |
라우팅 영향 |
function |
사람이 이해하는 capability 이름 |
문서/디버깅 |
kind |
device_execution, device_status, environment_check, device_setting 등 기능 성격 |
ODL/DQR/SCH/UNS candidate 생성 |
aliases |
발화 매칭용 표현 목록 |
preclassifier anchor 생성 |
scheduling.schedulable |
스케줄로 예약 가능한 기능인지 |
SCH 후보 생성 |
scheduling.allowed_schedule_types |
허용 schedule type 범위 |
schedule payload validation |
scheduling.prefer_schedule_route_when_time_semantics_exist |
시간 의미가 있으면 SCH를 우선할지 |
ODL vs SCH 경계 |
visibility.user_exposed |
사용자에게 노출 가능한 기능인지 |
UX/응답 문구 |
visibility.planner_exposed |
planner 후보로 노출할지 |
candidate pool 생성 |
산출물
capability-registry-contract.md
- capability kind별 예시 표
- schedulable capability 목록
- planner exposed false 항목이 있을 경우 별도 표
6. P1-2 Skill Registry / Flow Catalog 자동 표 추출
목적
skill_registry.json에서 agent/skill/flow 목록을 사람이 볼 수 있는 wiki 표로 자동 생성한다. 수동 문서와 registry가 어긋나는 문제를 줄인다.
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/registry/skill_registry.json |
agents, skills, when_to_use, when_not_to_use, execution_mode |
gemini/a2a/registry/loader.py |
build_skill_catalog_excerpt, build_flow_catalog_excerpt |
gemini/a2a/planner/flow_selection_core.py |
flow catalog filtering과 ranked selector 입력 |
추출할 표
| 표 |
컬럼 |
| Agent table |
route_family, agent_id, purpose, when_to_use, when_not_to_use, skill_count |
| Skill table |
route_family, agent_id, skill_id, purpose, execution_mode, required_capabilities |
| Flow table |
flow_id, route_family, agent_id, skill_id, execution_mode |
산출물
agent-skill-flow-catalog.md
- 가능하면
tools/export_skill_registry_wiki.py 또는 동등한 생성 스크립트
- wiki build 시 stale 여부를 확인할 수 있는 검증 명령
7. P1-3 Schedule Workflow Slot Schema 연결
목적
Planner의 missing_slots, schedule agent의 resolved_slots, on-device schedule relay payload가 같은 slot 의미를 쓰도록 연결한다.
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/agents/schedule/assets/schedule_expert.system_prompt.txt |
schedule type/action/target/params/slots 지시 |
gemini/a2a/agents/schedule/expert_api.py |
response schema, normalize, preferred skill |
gemini/a2a/planner/main_router_api.py |
active SCH workflow short-circuit, slot_state 처리 |
gemini/a2a/runtime/session_state.py |
slot_state 저장과 owner_selection derive |
| on-device schedule relay docs/source |
Cloud schedule response를 실제 relay/API로 연결하는 구조 |
정리할 slot 이름
| Slot |
의미 |
사용 위치 |
schedule_type |
fixed/whole_space/alarm/timer/reminder 등 schedule 종류 |
schedule agent, relay payload |
schedule_target |
고정청정, 웰컴, 웨이크업 등 예약 대상 |
schedule agent, device capability mapping |
schedule_action |
start/stop/on/off/create/update/delete 등 대상에 적용할 action |
schedule agent, relay/API action |
schedule_params |
공간, 모드, 풍량 같은 기능별 추가 파라미터 |
schedule agent, payload builder |
date |
실행 날짜 |
schedule agent, slot_state |
time |
실행 시간 |
schedule agent, slot_state |
repeat |
반복 주기/요일 |
schedule agent, slot_state |
timezone |
시간대 |
schedule agent, payload builder |
confirmation_required |
side effect 전 확인 필요 여부 |
multi_turn/session state |
완료 기준
- Planner와 schedule agent가 같은 slot 이름을 사용한다.
고정청정 예약해줘 -> 언제/어디/반복 multi-turn 예시가 문서화된다.
- 등록/삭제/수정/조회가 같은 slot schema에서 action만 달라지는 구조로 정리된다.
8. P1-4 Plan Expansion / Dynamic Replanning Contract
목적
처음 planner가 만든 plan이 최종 목적까지 충분하지 않거나, 실행 중 결과를 보고 추가 plan이 필요해지는 경우를 명확한 계약으로 고정한다. 이 과제의 핵심은 Cloud LLM을 매 task event마다 다시 돌리는 것이 아니라, “판단이 필요한 순간”만 workflow context와 event reason을 근거로 replan하게 만드는 것이다.
현재 구현 기준
| 상황 |
현재 처리 |
관련 source |
| 처음부터 복합 목적이 명확함 |
planner가 turn_mode=multi_step과 ordered steps[] 생성 |
main_router.system_prompt.txt, main_router_api.py |
| 필수 slot/user input 부족 |
agent가 needs_user_input 반환, runtime이 pending_follow_up_text와 missing_slots 저장 |
orchestrator.py, workflow_state.py, schedule agent |
| specialist route mismatch |
agent가 change_request 반환, runtime이 1회 조건부 replan 수행 |
orchestrator.py::_maybe_conditional_replan |
| device task 실패/차단 |
task event의 reason_code/requires_cloud_decision 기준으로 replan decision 생성 |
workflow_state.py::_build_task_replan_decision |
| 정상 task 진행 |
QUEUED/RUNNING/PROGRESS/COMPLETED는 Cloud LLM replan 없이 상태만 반영 |
workflow_state.py, TaskManager event policy |
| step 완료 후 다음 semantic 판단 필요 |
WORKFLOW_STEP_COMPLETED + requires_semantic_next_step=true이면 cloud replan/resume 후보 |
workflow_state.py::_task_event_requires_cloud_replan |
구분해야 할 planning 종류
| 종류 |
의미 |
예시 |
Cloud LLM 개입 여부 |
| Initial planning |
첫 발화에서 최종 목적을 향한 route/step을 만든다. |
“교통 안 좋은 곳 찾고 오늘 정보 줘” |
필요 |
| Slot continuation |
사용자가 빠진 값을 채우는 중이다. |
“매일 오후 6시” |
route 유지, 필요 시 agent만 |
| Conditional replan |
agent가 내 route가 아니거나 실행 불가라고 판단한다. |
SCH가 public schedule로 판단해 FRG 제안 |
제한적 필요 |
| Device recovery replan |
device task가 실패/차단되어 대체 입력이나 중단 판단이 필요하다. |
path_blocked, position_not_found |
필요 |
| Plan expansion |
앞 step 결과를 보고 새 step을 추가해야 한다. |
“찾은 장소 중 제일 가까운 곳으로 이동해”에서 장소 확정 후 ODL step 필요 |
조건부 필요 |
| Normal resume |
dependency가 풀려 다음 기존 step을 실행한다. |
이동 완료 후 청정 step 시작 |
불필요 |
Plan expansion에서 필요한 계약
현재 구조에는 requires_semantic_next_step, pending_cloud_steps, resume_workflow가 있어 다음 step resume의 기반은 있다. 다만 “새 step을 추가 생성해야 하는 경우”는 더 명확한 planner/runtime contract가 필요하다.
정리해야 할 필드 후보:
{
"requires_cloud_decision": true,
"requires_semantic_next_step": true,
"plan_expansion_reason": "prior_step_result_requires_new_action",
"available_outputs": {
"step_1": {"output_key": "candidate_places", "result_ref": "candidate_places.result"}
},
"allowed_next_routes": ["FRG", "DEF", "ODL"],
"blocked_routes": ["STT_NULL"],
"user_input_required": false
}
확인 대상
| 파일 |
확인할 내용 |
gemini/a2a/planner/assets/main_router.system_prompt.txt |
failed-task recovery, workflow_context, requires_semantic_next_step 관련 지시가 충분한지 |
gemini/a2a/planner/main_router_api.py |
replan_count, replan_previous_route, escape policy, multi_step repair |
gemini/a2a/runtime/orchestrator.py |
_maybe_conditional_replan, _execute_pending_cloud_steps, route change handling |
gemini/a2a/runtime/workflow_state.py |
task event -> replan decision, resume_workflow, pending_cloud_steps |
gemini/a2a/runtime/task_manager.py |
dependency, wait_policy, device_task_requests 변환 |
| On-device bridge / DeviceAgent event contract |
어떤 event가 Cloud decision을 요구하는지 |
완료 기준
- task event 중 Cloud LLM replan이 필요한 이벤트와 불필요한 이벤트가 표로 고정된다.
FAILED/BLOCKED/NEEDS_USER_INPUT과 requires_semantic_next_step의 차이가 문서화된다.
- 기존 plan의 다음 step을 resume하는 경우와 새 step을 생성해야 하는 plan expansion 경우가 분리된다.
workflow_context.last_replan_decision을 planner가 어떻게 읽는지 예시가 있다.
- Cloud-only, mixed cloud/device, device recovery, semantic next-step expansion fixture가 생긴다.
예시 1: 정상 resume
사용자: 거실로 가서 청정하고 안방으로 가
plan: step_1 move(living_room) -> step_2 clean(living_room) -> step_3 move(bedroom)
이벤트: step_1 COMPLETED
처리: 기존 plan의 step_2를 resume. Cloud LLM replan 불필요.
예시 2: 실패 recovery replan
이벤트: step_1 BLOCKED, reason_code=path_blocked, requires_cloud_decision=true
처리: workflow_state가 replan_action=ask_user 생성
사용자: 그럼 안방으로 가
planner: workflow_context.last_replan_decision을 보고 ODL recovery step 생성
예시 3: semantic next-step expansion
사용자: 오늘 혼잡한 곳을 찾고, 그중 가까운 곳으로 이동해
step_1 FRG: 혼잡한 곳 후보와 위치 정보 반환
이벤트: WORKFLOW_STEP_COMPLETED, requires_semantic_next_step=true
처리: Cloud가 step_1 결과와 device_context를 보고 다음 ODL 이동 step을 생성할 수 있어야 함
이 예시는 단순 resume이 아니다. 최초 plan에 정확한 목적지가 없었고, 앞 step 결과를 보고 새 device action step을 구체화해야 하므로 plan expansion contract가 필요하다.
9. P2-1 Second Pass Benchmark 영향 문서화
목적
second_pass_family_judge가 실제 성능에 준 영향을 정량적으로 분리한다. 특히 DEF/STT_NULL/FRG 회색지대에서 얻은 이득과 specialist family 손실이 있는지 확인한다.
확인 대상
| 파일/데이터 |
확인할 내용 |
gemini/a2a/planner/assets/second_pass_family_judge.system_prompt.txt |
pairwise judge 기준 |
gemini/a2a/planner/main_router_api.py |
_choose_second_pass_strategy(...), judge 적용 위치 |
| benchmark 결과 파일 |
second pass 적용 전/후 family accuracy |
| benchmark export |
needs_second_pass, runner_up_family, second_pass_* 컬럼 존재 여부 |
비교할 지표
| 지표 |
의미 |
| Overall family accuracy |
전체 family routing 정확도 |
| DEF accuracy |
일반 대화 rescue 여부 |
| STT_NULL accuracy |
broken STT 방어 여부 |
| FRG accuracy |
public target survival 여부 |
| DEF↔STT_NULL accepted rate |
자연스러운 오차 허용 반영 시 개선폭 |
| second_pass_invocation_rate |
2차 호출 비율과 비용 |
| second_pass_flip_rate |
2차가 실제로 family를 바꾼 비율 |
| harmful_flip_count |
맞았던 1차를 2차가 틀리게 바꾼 수 |
산출물
second-pass-benchmark-impact.md
- benchmark summary table
- 대표 flip 사례 10개
- harmful flip 사례 10개
- 최종 채택/롤백 판단 기준
10. P2-2 Planner Routing / Deep Dive 중복 정리
목적
planner-routing.md는 개요, planner-deep-dive.md는 소스 기준 상세라는 역할을 분리한다. 같은 설명이 두 문서에 반복되면 최신화가 어렵다.
정리 원칙
| 문서 |
유지할 내용 |
제거/링크 처리할 내용 |
planner-routing.md |
family 정의, 큰 판단 흐름, 독자가 처음 볼 개요 |
소스 레벨 함수명/세부 field 표는 deep dive로 링크 |
planner-deep-dive.md |
실제 source path, field contract, evidence/catalog/second pass/runtime detail |
family 기본 정의의 긴 반복은 routing으로 링크 |
book-roadmap.md |
읽는 순서 |
상세 설명 중복 금지 |
index.md |
진입 링크 |
본문 설명 과다 금지 |
완료 기준
Planner and Routing을 읽으면 개념이 잡힌다.
A2A Planner Deep Dive를 읽으면 실제 코드와 field가 잡힌다.
- 두 문서가 서로 링크하지만 같은 표를 중복 유지하지 않는다.
book-roadmap.md의 Part 4/4-1 설명과 일치한다.
11. 추적 보드
| ID |
과제 |
우선순위 |
상태 |
다음 액션 |
| PL-CLEAN-01 |
Schema/Prompt Drift 점검 |
P0 |
대기 |
schema와 prompt step field diff 표 작성 |
| PL-CLEAN-02 |
ODL Token/Task Safety Contract |
P0 |
대기 |
planner/ODL/runtime/on-device 책임 표 확정 |
| PL-CLEAN-03 |
Capability Registry Contract |
P1 |
대기 |
kind/scheduling/visibility 문서 분리 |
| PL-CLEAN-04 |
Skill Registry Auto Table |
P1 |
대기 |
registry export script 또는 수동 1차 표 생성 |
| PL-CLEAN-05 |
Schedule Slot Contract |
P1 |
대기 |
schedule agent slots와 relay payload 연결 |
| PL-CLEAN-06 |
Dynamic Replanning Contract |
P1 |
대기 |
event/replan/resume/plan expansion 계약 확정 |
| PL-CLEAN-07 |
Second Pass Benchmark Impact |
P2 |
대기 |
benchmark artifact 수집 및 before/after 비교 |
| PL-CLEAN-08 |
Planner Docs Dedup |
P2 |
대기 |
routing/deep dive 역할 분리 패치 |
12. 지금 바로 착수할 때의 권장 순서
가장 먼저 PL-CLEAN-01을 한다. 이유는 schema가 prompt를 따라가지 못하면 planner가 올바른 multi-step field를 내도 runtime까지 전달되지 않을 수 있기 때문이다. 그 다음 PL-CLEAN-02를 이어서 처리하면 device execution 안전 경계까지 같이 닫을 수 있다.
그 이후 PL-CLEAN-03, PL-CLEAN-04, PL-CLEAN-05는 registry/catalog/schedule 계약 정리다. PL-CLEAN-06은 runtime replan과 plan expansion 경계를 닫는 작업이므로 schedule/device task 계약과 함께 진행하는 것이 좋다. PL-CLEAN-07은 benchmark artifact가 필요하므로 테스트 결과가 쌓인 뒤 진행하는 것이 낫다. PL-CLEAN-08은 앞 문서들이 만들어진 뒤 마지막에 정리한다.