# 이미지 bytes 가 실리는 자리 — call 단위 목록 (#92 0단계)

2026-08-27

## 지시

> gpt sol vlm 은 성능이 안좋아. 다른곳에 사용되는 곳있어 찾아봐 /
> 무조건 gemini 3.1 pro 와 grok 최신 모델 둘을 사용해야해 / 아홉 전부 바꿔

Codex 판정: 「아홉」이라는 숫자보다 **「이미지 bytes 가 request 에 실리는가」**
를 기준으로 삼아야 한다.

## 도구를 네 번 고쳤고, 그때마다 목록이 바뀌었다

    8 → 12 → 15 → 2 → 9

| | 고친 것 | 왜 |
|---|---|---|
| ① | `completion` 정확 일치 → 부분 일치 | provider 넷이 `llm_completion` 을 부른다 — 글자가 달라 통째로 안 잡혔다 |
| ② | 물리 모델명(`openai/gpt-5.6-sol`) 추가 | alias 목록만 봤다 |
| ③ | `AnnAssign` 추가 | `X: str = "..."` 는 `Assign` 이 아니다 — 값을 못 읽어 「못 읽음」이 됐다 |
| ④ | **함수 공존 → 호출 단위 dataflow** | ★Codex 가 **거짓 양성**을 찾았다 |
| ⑤ | 인자 기본값을 지역 대입으로 | `model: str = PROVIDER_MODEL_DEFAULT` 를 못 읽어 8건이 사라졌다 |
| ⑥ | `project_config` 딕셔너리 읽기 | 이 저장소가 모델을 고르는 **주된 방식**이다 |

★**④가 이 판의 핵심 교훈이다.** 앞 판은 한 함수 안에 이미지 표식 하나 +
발송 하나 + 모델 이름 하나가 있으면 한 자리로 묶었다. 그래서
`_fitting_refs` 를 Sol VLM 으로 셌는데 **실제로는 그 GPT 호출이 이미지 없는
검색문 저작**이고 이미지는 같은 함수의 다른 호출(`FITTING_PICK_JUDGE=
gemini-pro`)에만 실린다. 상수부터 바꿨으면 text-only 검색 저작까지
바뀌었다.

★**⑤는 그 반대 방향의 실수다.** 거짓 양성을 잡으려 좁혔더니 provider 여덟
자리가 통째로 빠졌다(15 → 2). 한쪽을 고치면 반대편이 열린다.

## 확정 목록

### 도구가 읽은 Sol — 8 호출

| 자리 | 업무 | 기본 |
|---|---|---|
| `cine_verify.py:256 _ask` | binary defect gate | **ON** |
| `floor_plan_vlm_provider.py:776` | geometry (도면 읽기) | **ON** |
| `zoom_continuity_render_service.py:137 vlm_locate_bbox` | geometry (bbox) | **ON** |
| `ref_image_pipeline.py:127 _call_gpt_lvm` | 운반층 — 호출자가 둘 | ON |
| `dwelling_zone_map_provider.py:327` | geometry | off |
| `floor_plan_semantic_vlm_provider.py:283` | geometry | off |
| `indoor_shared_pose_provider.py:246` | 관찰/critique | off |
| `shot_projection_card_provider.py:225` | geometry | off |

### 도구가 못 읽어 **손으로 확인한** Sol — 1 호출

`outdoor_marker_map.py:625 run_marker_geometry_shot` (lane geometry, **ON**)
— 모델이 **다른 파일**에서 온다:
`shot_conti_light_step.py:1116` 의
`geometry_config = {"outdoor_marker_geometry": {"model": "gpt"}}`.
함수·파일 경계를 넘는 흐름이라 도구가 안 따라간다. Codex 가 특정해 주지
않았으면 빠졌다.

### 아직 「못 읽음」 — 6 호출

`background_unmanned:107` · `multiroll_gemini:1292 judge_fn` ·
`outdoor_marker_map:1675 pick_best_marker_map` · `text_cleaner:122` ·
`planning_doc_analysis_service:715` — 모델을 인자·콜백으로 받는다.
**배선 전에 호출부를 하나씩 봐야 한다.**

## ★「전부」라고 쓰지 않는다

도구를 여섯 번 고쳤고 그때마다 목록이 움직였다. 지금 값은
**「이 도구가 이렇게 세면 9」**이지 전수라는 보장이 아니다.

## `_call_gpt_lvm` 은 운반층이다

호출자가 둘인데 **업무 종류가 다르다**:

    validate_reference_image   severity=severe 면 **돈 내고 재생성**
    compare_two_images         이미 산 두 장 중 winner 선정

Codex 판정: **combine 을 운반층 안에 넣지 마라.** 하나는 재구매 gate,
하나는 ranking 이라 같은 합의로 묶으면 실패의 뜻이 섞인다. 공유할 수 있는
것은 「두 alias 를 fallback 없이 부르고 모델별 raw·물리 모델·오류·토큰·
비용을 같은 모양으로 기록하는 executor」까지다.

## 도구

`backend/tools/prompt_measure/audit_vlm_sites.py` — 렌즈 둘(호출 단위
dataflow · 파일 단위 후보). **함수 경계를 넘는 흐름은 안 따라간다**고
스스로 밝힌다.
