Index
2026-08-18 — Plan · E6 설계 v2

VLM eval 설계 v2 — 후보 리스트 누출 제거, 전역 어휘 전환

scene_bench | 사용자 지적("위치를 이미 다 알려주고 있다") 실측 검증 → 전면 재설계 · 프롬프트 전문

TL;DR

66.6%
구 리스트 누출
100%
distractor 누출
57
전역 물체 어휘
95.4%
방 이름 커버리지
1/5
위치 chance
목차   1 무엇이 잘못됐나 (실측) 2 새 답 계약 3 프롬프트 전문 4 전역 어휘 5 메모리 턴 6 채점·chance 7 남는 한계 8 예산·구현

1 무엇이 잘못됐나 — 누출 실측 (답 835개 전수)

구 설계가 프롬프트에 넣던 것

[Irishpotato_7c3f16774c3f2d6de70e09dd23897534_1_0_6] irish potato, room 6 [atomizer_e0cab0ef1fe80f6fe596048b9bc862a1_1_0_5] atomizer, room 5 [bowl_46a21212675e4d90993a86b1232e6f40_1_0_4] bowl, room 4 [bowl_6befd62f08fd322391939c2b44d3f839_1_0_7] bowl, room 7 [bowl_9087df6907f975021e5d8ac01d4c2557_1_0_6] bowl, room 6 [bread_ce14aa444cff8c5279772caf1fa3df7a_1_0_6] bread, room 6 … (24줄)
질의 종류초기 방 = 최종 정답 위치판정
find_distractor (안 건드린 물체)400 / 400100% 누출 — 정의상 안 움직이므로 초기 방이 곧 정답
find_target (로봇이 옮긴 물체)156 / 43535.9% 누출 — 같은 방 안에서만 옮긴 경우
전체556 / 835 (66.6%)리스트만 읽어도 3분의 2가 정답
표기를 지워도 안 된다: uid 접미사가 방 번호다 (bowl_46a2…_1_0_4 → room 4). uid를 답으로 요구하는 한 방 정보가 따라온다. uid 기반 선택형 계약 자체를 버려야 누출이 끝난다.
추가로 누출되던 것들: ① 이 집에 어떤 물체가 몇 개 있는지(24줄 = 닫힌 집합) → multi 질의의 개수 힌트 ② 동일 카테고리 인스턴스 수 → 후보 폭 노출 ③ "여기 없는 물체는 답이 아니다"라는 배제 추론 무료 제공.

2 새 답 계약 — "무엇을 골라라"에서 "어디에 있나"로

{"reasoning": "...", "selections": [{"category": "bowl", "room": "floor", "surface": null}, {"category": "bowl", "room": "living room", "surface": "dining table"}], "abstain": false}
구 설계 (v1)새 설계 (v2)이유
물체 지목에피소드 24개 uid 중 선택카테고리 이름 (전역 어휘)uid 선택은 방 누출 + 닫힌 집합 힌트
위치방 번호 (리스트가 이미 알려줌)방 이름 또는 "floor"이게 메모리의 실제 내용
표면없음 (누출 우려로 삭제)표면 카테고리 (전역 15종)전역 어휘라 누출 없음 + 인스턴스 해소에 필요
개수리스트로 유추 가능모델이 기억에서 판단multi 질의의 핵심 과제

즉 답은 "몇 개가, 어느 방 어떤 가구 위에 있는가"가 된다 — 로봇이 실제로 그 물체를 가지러 가려면 알아야 하는 바로 그 정보이고, 프롬프트가 미리 알려줄 수 없는 정보다.

3 프롬프트 전문

3.1 system_v3 — 에피소드 정보 0, 전역 어휘만

[system] You are the memory module of a household robot. The earlier turns of this conversation are your memory of one episode in this house — what the robot did and saw. The final image is the robot's CURRENT view at the end of the episode. The user will ask you to pick up an object, described by its category and by what happened to it. Answer WHERE that object is now. The object is usually not in the current view, and nobody will tell you what is in this house: recall it. Output a single JSON object, nothing else: {"reasoning": "...", "selections": [{"category": "...", "room": "...", "surface": "..."}], "abstain": false} Rules: - One entry in "selections" per object the query refers to. If the query says "all the ...", decide how many there are from your memory. Otherwise give exactly one. - "room": one of bathroom | bedroom | kitchen | living room — or "floor" if the object ended up lying on the floor rather than on a surface. - "surface": the kind of thing it is resting on, from the surface list below. Use null when the object is on the floor. - Use the category and surface names exactly as spelled in the lists. - If your memory genuinely cannot determine the answer, set "abstain": true. Object categories: CD | alarmclock | apple | atomizer | bar soap | baseballbat | basketball | boiler bottle | bowl | box | bread | butter knife | candle | cell phone | coffeemaker cooking pan | cup | desktopcomputer | egg | fabric | fork | house plant | irish potato knickknack | knife | ladle | laptop | lettuce | microwaveoven | mug | newspaper papertowel | pen | pencil | pepper shaker | pillow | plate | plunger | pot remote control | safe | saltshaker | soapdispenser | spatula | sponge | spoon | statue tablelamp | teddybear | tennisracket | tissue box | toaster | toilet tissue | tomato vase | winebottle Surfaces: armchair | bed | cart | chair | clothes dryer | countertop | desk | dining table dresser | shelf | sink | sofa | toilet | tv stand | washing machine

3.2 질의 턴 — 대폭 축소 (val_101__0 multi 질의)

[user] (질의 턴 — 메모리 턴 뒤) <image: 마지막 프레임 (exo_camera_1, frame 13749)> Query: "Pick up all the bowls I moved earlier" Reply with the JSON object only.

구 설계에서 여기 붙던 24줄 물체 리스트 + 방 리스트가 전부 사라졌다. 어휘는 system에 한 번만 실리고(전 질의 공유·캐시 가능), 질의 턴은 이미지 1장 + 질의문뿐이다 — 토큰도 줄고 누출도 없다.

3.3 기대 출력 (GT 대응)

{"reasoning": "I moved two bowls. The first one I tried to put on the bed but dropped it — it is on the floor. The second I carried from the kitchen countertop to the dining table in the living room.", "selections": [{"category": "bowl", "room": "floor", "surface": null}, {"category": "bowl", "room": "living room", "surface": "dining table"}], "abstain": false}

이 에피소드 GT: bowl 2개 — 하나는 침대에 놓다 떨어뜨려 floor, 하나는 living room 식탁. 씬에는 bowl이 3개지만 모델은 그 사실조차 모른다: 몇 개를 옮겼는지, 어디로 옮겼는지 전부 기억에서 나와야 한다.

4 전역 어휘 — 프롬프트에 들어가는 유일한 리스트

물체 카테고리 57종 (데이터셋 153 eps 전체, 물체 3,346개에서 수집)

CD | alarmclock | apple | atomizer | bar soap | baseballbat | basketball | boiler bottle | bowl | box | bread | butter knife | candle | cell phone | coffeemaker cooking pan | cup | desktopcomputer | egg | fabric | fork | house plant | irish potato knickknack | knife | ladle | laptop | lettuce | microwaveoven | mug | newspaper papertowel | pen | pencil | pepper shaker | pillow | plate | plunger | pot remote control | safe | saltshaker | soapdispenser | spatula | sponge | spoon | statue tablelamp | teddybear | tennisracket | tissue box | toaster | toilet tissue | tomato vase | winebottle

방 4종 + floor

bathroom | bedroom | kitchen | living room (+ "floor")

표면 15종

armchair | bed | cart | chair | clothes dryer | countertop | desk | dining table dresser | shelf | sink | sofa | toilet | tv stand | washing machine
왜 이건 누출이 아닌가: 셋 다 데이터셋 전역이라 특정 에피소드에 무엇이 있는지 알려주지 않는다. 오히려 답의 표기법을 통일해 채점을 결정론적으로 만든다(모델이 "cell phone"과 "cellulartelephone" 중 무엇을 쓸지 고민할 필요 없음). 어휘 크기가 곧 chance 분모가 되어 G1 게이트가 정확히 계산된다.

5 메모리 턴 (전략별) — 변경 없음

메모리 주입 방식은 파일럿과 동일하다. 단 rollforward-v2의 ingest 프롬프트에서도 에피소드 인벤토리(uid 목록) 제공을 전역 어휘로 교체한다 — 기록 시점에 "이 집에 뭐가 있는지"를 알려주면 같은 누출이 재발한다.

[user] (textlog 메모리 턴 — val_101__0 실제 생성문) Here is the record of what I did in this house during the episode: [ 0s– 81s] I tried to move the bowl from the dining table in the bedroom to the bed in the bedroom, but I failed to place it. [ 81s– 198s] I picked up the remote control from the dining table in the bedroom and placed it on the toilet in the bathroom. [ 198s– 342s] I picked up the bowl from the countertop in the kitchen and placed it on the dining table in the living room. [ 342s– 550s] I picked up the remote control from the toilet in the bathroom and placed it on the sofa in the living room.

첫 줄이 "…but I failed to place it"로 끝나 떨어진 bowl의 최종 위치는 안 알려준다 — floor 답을 맞히려면 로그 너머 추론이 필요하다(오라클 textlog의 자연 상한).

6 채점 · chance

지표정의chance
loc_acc (헤드라인)selections의 위치 집합 == GT 위치 집합 (single은 1개, multi는 개수까지 일치)1/5 (방4+floor) — 개수까지 맞춰야 하므로 multi는 더 낮음
place_strict위치 ∧ 표면 일치≈1/75
count_accselections 개수 == 정답 개수 (multi 진단)
body-id 해소율(category, room, surface)가 유일 물체로 해소되는 비율공식 지표 대응 — twin_nearby 98건(12.9%)은 원리적 모호로 분리
기권율유효 질의 기권 = 오답 (A5 2×2)

계층화 축: kind(target/distractor) × steps(single/multi) × misplaced(no/on_floor/wrong_surface) × twin_nearby × seen_s 분위 × 동일 카테고리 인스턴스 수. concealment/needs_open은 이번 릴리즈에서 퇴화(전부 seen/0건).

방 이름 미유도 38건(4.6%): 이벤트 조인으로 이름이 안 나오는 방 — 해당 답은 위치 채점에서 제외하고 별도 집계(조인 확장은 후속 개선). 조인 모순 에피소드 3건도 동일 처리.

7 남는 한계 (숨기지 않고 명시)

① 공식 body-id 채점과 간접 대응 — Tier A(심볼릭)는 "어디에"를 재고, 실제 잡은 body는 Tier B(실행형)에서 잰다. 사후 해소로 근사하되 twin 98건은 원리적으로 구분 불가임을 명시.
② 상식 누출은 남는다 — "knife는 kitchen"처럼 카테고리-방 상식으로 풀리는 질의가 있다. 이건 리스트 누출과 달리 blind 대조군이 정확히 측정해 주므로(공리 A1), 층화 보고에서 blind 대비 상승분만 메모리 신호로 읽는다.
③ 방 4종은 거친 해상도 — 같은 방 안 다른 위치는 표면으로만 구분된다. 표면이 null인 floor 답(64건)은 위치 해상도가 "floor"까지.

8 예산 · 구현

전략 5종 (blind / textlog / frames-uniform / rollforward-v2 / vis-pure) × 2모델 단계: S1 검증 3 eps ~$6 → S2 층화 파일럿 15 eps ~$35 → S3 전량 759질의 ~$155 (생존 조합, 승인 후) 질의 턴이 짧아져(리스트 삭제) 구 추정 대비 질의 토큰 ~30% 감소 — 위 금액은 보수적 유지

구현 변경schema.py: selections[{category, room, surface}] ② vocab.py 신설: 전역 어휘 3종 + 표시명 매핑(데이터셋에서 1회 생성, 버전 고정) ③ candidates.py 폐기(에피소드 리스트 자체가 누출원) ④ query_runner.py: system_v3, 질의 턴 축소 ⑤ scorer.py: 위치 집합 일치 + 표면 + 개수 + body-id 사후 해소 ⑥ stratify.py: 계층화 라벨러 ⑦ rollforward-v2 ingest 프롬프트도 전역 어휘로 교체 ⑧ tests: 누출 회귀 테스트(프롬프트 문자열에 에피소드 uid·방번호가 등장하면 실패) 추가.