cody-vision — 코디 정밀 시각 도구 (handoff)
C:\dev\tools\cody-vision= 이미지를 넣으면 사물의 형태·종류·위치·개수·문자를 텍스트 감정서로 풀어주는 CLI. 코디가 Bash로 돌리고 stdout을 읽어 자기 눈과 대조한다(두 번째 의견 + 수치 근거). devplan 추적 페이지 =C:\dev\devplan\cody-vision.html(http://localhost:8799/cody-vision.html) — 매 답변 끝 동시 갱신 대상. 계획 원본 =C:\Users\delix\.claude\plans\warm-twirling-blanket.md.
🔶 루트 NOW 이관 — 진행·미결 (2026-08-19 대청소, 페페 지시)
루트
HANDOFF.md를 pncad 만 남기고 비웠다. 아래는 그때 옮겨온 원문(문구 무변경).
- cody-vision 코디 정밀 시각 도구 [코디] 26.7.29 ✅완료(원문 cut →
projects/cody-vision/handoff.md).gemini-3.1-flash-lite+ enum 전략 · MCPcody-vision등록. ⏳페페 = 새 세션 열어야 툴 목록에 뜬다. →projects/cody-vision/handoff.md
NOW
- ✅26.7.29(수) 개명
see→cody-vision(페페 지시 — "see"는 너무 범용). 폴더·devplan 페이지·시드 프로젝트·매니페스트 전부 이관, P1 진입점은vision.py. - ✅26.7.29(수) P0 완료 — 후보 전수 조사(상용+오픈소스) → 실측 벤치로 모델·전략 확정, devplan 페이지 신설·허브 등록.
- ✅26.7.29(수) P1 완료 —
vision.py구현·검증(단일 파일, 신규 pip 0). 합성 이미지 3회 연속 만점(원12·사각5·한글4, 좌표오차 1~3px, 5.0~5.4초), 긴 스크린샷 1400×38941 타일링에서 환각 문자 5건 제거·실문자 284건 추출,--selftest14항목 PASS(API 호출 0). 경로 전수 확인 = 5개 모드·-q·--deep·--json·캐시·없는 파일. - ✅26.7.29(수) P2 완료 — MCP 래핑(페페 지시 "어차피 자주 쓸 거니 MCP로"). 서버
cody-vision(user 스코프,claude mcp list→ Connected), 툴 1개vision(path, question?, mode?, deep?, tiles?, style?, raw?).mcp패키지·인터프리터는autocad-plot과 동일(Python312 site-packages, 신규 설치 0). E2E = 실제 stdio 프로토콜로 툴목록·실호출(정답 17개 재현)·raw구조화·에러 3종·에러 후 세션 유지 확인. ⏳새 세션부터 툴 목록에 뜬다(등록 직후 세션에는 안 보임).
불변 핵심 (실측 26.7.29, bench.py/bench_real.py)
- 기본 모델 =
gemini-3.1-flash-lite— 합성 이미지(원12·사각5·13px 한글4종) 2.83초 / 6점 만점. 실사진(가구 현장 하자) 2.2~3.0초.--deep=gemini-3.6-flash(2~3배 느림·503 간헐, 서술은 촘촘). - enum 전략이 카운트를 고친다. group("같은 종류 묶고 count에 개수") → enum("물체 하나당 항목 하나,
세지 말고 보이는 것마다 좌표를 찍어라") 로 바꾸니 원 11→12 교정. 비용 +0.2초.
→
count필드를 아예 두지 않고len(objects)로 센다. 모델에게 셈을 안 시키는 게 요점. - enum/group 자동 선택: 기본 enum /
-m doc·자유질의(-q)는 group / enum 응답 잘림(finishReason != STOP)이면 group 1회 재시도 /--enum·--group강제. 매직넘버 없이 잘림 신호로만 판단. - 축소가 환각을 부른다. 세로 긴 스크린샷이 57×1599px로 뭉개지자
3.6-flash가 "CloudWatch 로그 스트림"이라고 확언했다(3.1-flash-lite는 "데이터 테이블"로 뭉뚱그림). → 가로세로비 >2.5:1이면 무조건 타일 분할, 긴 변 >1600px면 2×2 오버랩 10%, 타일은ThreadPoolExecutor병렬(4타일이어도 벽시계 ~3초). 출력 스키마에uncertain배열 필수 — 모르는 걸 지어내는 게 유일한 실패모드. - 출력 = stdout 마크다운. 중간 파일 안 만든다. 스키마 =
scene/objects[]/text[]/layout/uncertain[]. - 모드 프리셋 5종 =
auto(enum)doc(group)photo(enum)field(enum)qa(enum, deskpet 좌우반전 검수용).
사용법
MCP(기본) — 툴 목록의 vision 호출. vision(path, question?, mode?, deep?, tiles?, style?, raw?).
raw=true면 마크다운 대신 구조화 JSON(좌표를 코드로 쓸 때). 서버가 죽지 않게 모든 실패는 {ok:false, error}로 온다.
Bash(같은 코드)
PYTHONUTF8=1 python C:/dev/tools/cody-vision/vision.py <이미지…> [-q "질문"]
[-m auto|doc|photo|field|qa] [--deep] [--enum|--group] [--tiles N] [--json] [--no-cache]
PYTHONUTF8=1 python C:/dev/tools/cody-vision/vision.py --selftest # API 0, 14항목
- 캐시 =
%TEMP%\cody-vision-cache(이미지+프롬프트 해시). 잘린 응답은 캐시하지 않는다. - 타일을 나눠도 여전히 길쭉하면 출력 맨 위에 경고 +
--tiles권장값을 찍는다(자동 28등분은 안 한다 — 호출 수 폭증).
함정 (실측으로 이미 밟음)
- 🔑"빠짐없이" 같은 재촉 부사가 없는 물체를 만든다(26.7.29 P1 실측). 모드 프롬프트에 "빠짐없이 서술하라"가 있을 때
원 12개 이미지에서 13개(오탐 1)가 2회 재현, 단어만 빼니 12/12 만점 2회 재현. 반대로 "같은 물체를 두 번 쓰지 마라"를
추가하면 11/10으로 과억제. → 재촉도 억제도 하지 말고 시킬 일만 담백하게. 프롬프트 문구 바꿀 땐
bench.py로 숫자 확인. - 🔑축소본에 세부를 물으면 지어낸다 — 프롬프트로는 못 막는다(26.7.29 P1 실측). "확신하지 말고 uncertain에 넣어라"를
명시했는데도 축소본이 "Search/Name/Type/Size/Last Modified"를 확언(실제는 한국어 화면). → 타일링이 걸리면
축소본엔
objects/text를 빈 배열로 요구하고 돌아온 값도 파이썬이 통째로 버린다(scene·layout만 채택). enum과 같은 원리. gemini-2.5-flash/2.5-flash-lite= 신규 사용자 404(더 이상 못 씀).gemini-3.5-flash= JSON 스키마 무시 + 503 잦음 → 후보 제외.- 응답 최상위가 배열로 오는 경우 실제로 있음 →
list면{"objects": …}로 감싸는 파싱 가드 필요. - 429/500/503 지수 백오프 3회. 소진 시 조용히 죽지 말고 사유 출력.
- ✅26.7.29 API 키 단일 출처 =
C:\dev\.secrets\.env(GEMINI_API_KEY·GROQ_API_KEY).ytmine\.env·ainews-insta\.env의 중복 키는 제거했고, 세 로더(ytmine.py·web.py·ainews-insta/env.py)가 로컬.env다음에.secrets\.env를 읽는다(setdefault라 로컬 노브가 우선).vision.py도 이 경로만 본다. - 🔴"Groq 키 403 만료"는 오진이었다(26.7.29 정정). 원인 =
urllib기본 User-Agent를 Cloudflare가 차단(403error code: 1010). 같은 키에 브라우저 UA만 붙이니 HTTP 200 — 구 키도 살아 있었다. 전역 규칙으로 승격 =rules/tooling.md"API 403을 키 만료로 오진하지 말 것". 현재.secrets\.env의GROQ_API_KEY= 페페 재발급본, 200 확인(whisper-large-v3/-turbo노출). - Groq 탈락 사유는 키가 아니라 모델 — 계정 모델 목록 15종에 비전 모델이 없다(scout/maverick 미노출). STT 전용으로만 쓴다.
- PowerShell 인라인에서
$변수 쓰면 Bash 도구가 먹어서 파서 에러 →$없는 형태로 쓰거나 python으로.
탈락 후보 (재투입 조건 명시 — 상세는 devplan 페이지)
| 후보 | 사유 / 재투입 조건 |
|---|---|
| Groq (Llama 4 Scout) | 키 403 + 무료 6K TPM = 분당 3~4장 한계. Gemini 쿼터(1,500 RPD) 모자랄 때만 |
| Cerebras | 최속이나 이미지는 gemma-4-31b만 + 무료 컨텍스트 8,192 상한 |
| GCV / Azure Dense Captions | 라벨만 나오고 서술 없음 / 리전 제한 |
| 로컬 VLM 전부(Qwen3-VL+llama.cpp Vulkan) | 780M Vulkan으로 실제로 돈다(3B Q4 30~50 tok/s). 폐기 사유는 느려서지 못 돌아서가 아니다 — 페페 결정 |
| RapidOCR(ONNX 한국어, 80MB) | Gemini보다 빠르고 torch 불필요. 견적·도면 숫자를 실제로 오독하면 그때 투입 |
| Florence-2 / moondream2 / YOLOE | 영역별 상세 서술 또는 겹친 물체 정밀 카운트가 enum+타일링으로도 막힐 때 |
| RAM++/Grounded-SAM, DAM-3B, CountGD | torch 수GB 스택 / 연구코드 |
참고 — 이 PC 하드웨어 (26.7.29 실측)
AMD Ryzen 7 8745HS / Radeon 780M (RDNA3 12CU) / RAM 32GB / vulkan-1.dll ✓ / 디스크 733GB.
"NVIDIA 없어서 로컬 불가"는 오판이었다 — Vulkan 경로로 4B~8B 비전모델이 넉넉히 돈다.
HANDOFF 에서 이관 (2026-08-18)
- cody-vision(구
see— 26.7.29 개명, "see"는 너무 범용이라 구분 안 됨) 🆕26.7.29 신규 — 코디 정밀 시각 도구(이미지→사물·개수·좌표·문자 텍스트 감정서 CLI). 폴더C:\dev\tools\cody-vision\·P1 진입점vision.py. P0 완료 = 후보 전수 조사(상용+오픈소스) → 실측 벤치로 확정:gemini-3.1-flash-lite+ enum 전략 = 2.83초/6점 만점(합성 이미지 원12·사각5·13px 한글). 🔑모델에게 개수를 세라고 하면 틀린다 — 인스턴스마다 bbox 찍게 하고(enum) 파이썬이len()으로 세면 원 11→12 교정(+0.2초). enum/group 자동선택 = 기본 enum /-m doc·자유질의는 group / 응답 잘림(finishReason != STOP)이면 group 재시도. ⚠축소가 환각을 부른다(세로 긴 스크린샷 57px 뭉갬 →3.6-flash가 "CloudWatch 로그 스트림" 확언) → 가로세로비 >2.5:1 무조건 타일 분할 +uncertain필드 필수. 로컬 VLM은 780M Vulkan으로 돌긴 하나(3B Q4 30~50 tok/s) Gemini 2.8초를 못 이겨 페페 결정으로 폐기. ✅26.7.29 P1vision.py구현·검증 완료(단일 파일·신규 pip 0) — 합성 이미지 3회 연속 만점(원12·사각5·한글4·좌표오차 1~3px·5초대), 긴 스크린샷 1400×38941 타일링에서 환각 문자 5건 제거·실문자 284건,--selftest14항목, 5개 모드·-q·--deep·--json·캐시 전수 확인. 🔑새 함정 2개 = "빠짐없이" 같은 재촉 부사가 오탐을 만든다(2회 재현, 빼니 만점 / 반대로 "중복금지" 추가하면 과억제 11/10) · 축소본 세부 환각은 프롬프트로 못 막아 파이썬이 결과를 버리게 강제(enum과 같은 원리 — 못하는 일은 안 맡긴다). ✅API 키 단일 출처화 =C:\dev\.secrets\.env. ✅P2 MCP 래핑 완료(페페 지시 "자주 쓸 거니 MCP로") — 서버cody-vision(user 스코프) Connected, 툴vision(path, question?, mode?, deep?, tiles?, style?, raw?), 신규 pip 0, stdio E2E 검증. 🔑함정 = 라이브러리의sys.exit()은BaseException이라 MCP 서버를 죽인다(except Exception통과) →VisionError로 교체. ⏳페페 몫 = 새 세션 열어야 툴 목록에 뜬다(등록 직후 세션엔 안 보임). →projects/cody-vision/handoff.md· devplancody-vision.html