harness/plugins/zio-harness/knowledge/kintex/tools/nanobanana/README.md
DESKTOP-TKLFCPR\ython 1ef2235939 feat(zio-harness): v1.1.0 — auto source analysis + GUARDiA/KINTEX knowledge base
- SessionStart hook (scripts/graphify_setup.py): auto-install graphifyy[sql],
  build knowledge graph on first run (graphify extract --code-only, local AST),
  incremental graphify update thereafter — install-only smartness
- knowledge/kintex/: all 183 KINTEX md docs bundled (planning/design/analysis)
- knowledge/guardia/: distilled GUARDiA-wide knowledge from 2,483 md files
  (solutions-catalog, standard-framework, operations-cicd, lessons-learned;
  credentials/IP-free curated)
- SKILL.md: graph-first codebase query rules + knowledge base loading guide

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:15:35 +09:00

72 lines
3.8 KiB
Markdown

# tools/nanobanana — Gemini 이미지 생성(나노바나나) 연동 모듈
부스/인테리어/배선/조명 설계 데이터를 "시공 후 결과 사진"으로 렌더링한다.
설계 기준: ReRoomAI 실증 패턴(`docs/analysis/reroomai-source.md`) + PLANNING §6.
## 준비
```bash
pip install google-genai Pillow
export GEMINI_API_KEY=발급받은_키 # https://aistudio.google.com
```
- 모델 기본값: `gemini-3.1-flash-image-preview`(나노바나나 2). `NANOBANANA_MODEL`로 오버라이드.
- ★ 실제 Gemini 호출은 소유자 승인 대기(reroomai-source.md §8). 키/네트워크 없이도 import·구조는 성립.
## 빠른 시작 (§6-2 scene 스키마)
```python
from tools.nanobanana.client import NanoBananaClient
scene = {
"hall": {"id": "제1전시장 7홀", "dims_m": [126, 90], "ceiling_m": 12},
"booth": {"id": "A-102", "size_m": [6, 3], "type": "independent"},
"design": {
"signage": {"text": "주식회사 가디아"},
"brand_color": "#0052A5",
"zones": [{"type": "demo"}, {"type": "consult"}],
"materials": [{"part": "wall", "finish": "matte_white"}],
},
"lighting": {"mode": "night", "color_temp_k": 4000},
"wiring": {"power": [{"from_trench": [1, 1], "to": [5, 2], "kw": 3}]},
"render_hints": {"style": "tech"},
}
c = NanoBananaClient()
img = c.render_shot(scene, shot_preset="S2",
reference_image="empty_booth.jpg", # 빈 부스 실측 → 구조 보존
seed=12345) # 컷 간 일관성(B-12)
img.save("output/visualizations/booth_S2.png") # 사이드카 .meta.json 동시 기록
```
## 표준 샷 세트 S1~S7 (PLANNING §6-3)
| 샷 | 호출 | 용도 |
|---|---|---|
| S1 정면 주간 | `render_shot(scene,"S1")` | 기본 시안 확인 |
| S2 정면 야간 | `render_shot(scene,"S2")` | 조명 연출 평가 |
| S3 통로 뷰 | `render_shot(scene,"S3")` | 관람객 시점 동선 |
| S4 내부 뷰 | `render_shot(scene,"S4")` | 인테리어/집기 배치 |
| S5 Before/After | S1 결과 + `reference_image`(빈 부스 실측) 쌍 | 시공 전/후 비교 |
| S6 배선 오버레이 | `render_wiring_overlay_raster(wiring, hall_dims_m, kinds)` ★래스터 합성 | 시공 검증(좌표 정합) |
| S7 홀 전경 조감 | `render_shot(scene,"S7")` | 배치안 비교(SCR-04) |
### S6 — 생성형 아님 (B-02)
시공 검증용 S6는 좌표 정합이 보장되는 **백엔드 래스터 합성**이다(로컬 PIL):
```python
from tools.nanobanana.client import render_wiring_overlay_raster
ov = render_wiring_overlay_raster(scene["wiring"], hall_dims_m=(6, 3),
kinds=["power", "network", "plumbing"],
base_image="floorplan.png") # 선택
ov.save("output/visualizations/booth_S6_wiring.png")
```
`generate_wiring_overlay(layout, kind)`(생성형)는 발표/설명용 보조 이미지 전용 — 시공 검증 사용 금지.
## 하위호환
평면 `booth_spec` dict를 쓰던 기존 코드는 `generate_booth_photo(booth_spec, view, time_of_day)`
내부적으로 §6-2 scene 으로 변환 후 `render_shot`에 위임한다(그대로 동작).
## 방어·정책
- 입력 이미지 8MB 상한 + 긴 쪽 1024px 다운스케일/JPEG 0.85(`downscale_for_upload`).
- 에러 분기: `NanoBananaAuthError`(키 무효) / `NanoBananaQuotaError`(429·쿼터) / `NanoBananaSafetyError`(SAFETY).
- 쿼터/카운트는 **성공 시에만** 차감(`usage_recorder` 훅).
- 모든 산출 이미지에 "AI 생성 예상 이미지 — 실제 시공 결과와 다를 수 있음" 워터마크(계약 서류 사용 금지).
- 메타데이터(생성일·스키마 해시·모델 버전·seed)는 사이드카 `.meta.json` + PNG tEXt 청크로 임베드(B-03).
- API 키는 환경변수 `GEMINI_API_KEY`에서만 로드 — 코드/로그/커밋에 절대 기록 금지.