Skip to content

chore(S15P11A705-57): 2026-08-03 릴리스 — 프리셋 표시명 명사형 통일 - #103

Closed
colosair wants to merge 3 commits into
mainfrom
dev
Closed

chore(S15P11A705-57): 2026-08-03 릴리스 — 프리셋 표시명 명사형 통일#103
colosair wants to merge 3 commits into
mainfrom
dev

Conversation

@colosair

@colosair colosair commented Aug 3, 2026

Copy link
Copy Markdown
Member

요약

2026-08-03 두 번째 릴리스. dev 의 3커밋을 main 으로 올려 이미지 빌드를 트리거한다.

핵심은 프리셋 표시명 개정이고, 그것이 운영 화면에 닿으려면 이 릴리스가 선행이다. image-publish job 이 main push 조건이므로 dev 병합만으로는 이미지가 만들어지지 않는다.

Jira

S15P11A705-57 — [AI] 통합 검증 및 배포 준비

포함된 것

커밋 무엇을 · 왜
d288a37 feat(S15P11A705-292) 프리셋 표시명 명사형 통일 (#102) — display_name 21개. 화면 라벨의 품사가 조사형·부사형·관형형으로 섞여 있던 것을 명사·명사구로 통일한다. id·code·category·visibility·description·examples 는 불변
ef878cc feat(S15P11A705-253) GMS 이미지 생성·분석 실사용 조건 실측 (#101) — app/ 무변경. 측정 도구와 리포트만
f452862 docs(S15P11A705-61) dev 배포 미반영 구간 판정과 새 프리셋 봉인 값 (#95)

배포에 미치는 영향

표시명이 임베딩 입력과 판정 프롬프트 양쪽에 들어가므로 bootstrap 이 프리셋을 재임베딩한다. 판정 결과가 바뀔 수 있고 이번 범위에서 재평가하지 않았다 — 표시명 통일이 목적이고 판정 품질 개선은 별건이다.

프리셋 파일이 바뀌었으므로 infrabootstrap.version 표기가 낡는다.

새 값   preset-9459bfc7b19a
이전    preset-ab321360b0df

다만 그 값은 판 표기이지 재실행 조건이 아니다 — Argo 의 BeforeHookCreation 이 같은 이름의 Job 을 지우고 다시 만들고, 적재는 ON CONFLICT DO UPDATE 라 매번 최신으로 덮는다. 표기 정합성은 별건으로 남는다.

ef878ccf452862app/ 을 건드리지 않아 런타임 동작에 영향이 없다.

검증

실행한 것 — 세 PR 각각에서 ai-ci / checkai-ci / embedding profile parity 가 통과했다. 이 PR 에서 다시 돌린다.

못 한 것 — 운영 반영 여부는 배포 후 화면에서 확인한다. 클러스터 관측 경로가 없어 bootstrap Job 의 실행 결과를 직접 볼 수 없다.

표시명 개정의 회귀 검증은 하지 않았다. 재임베딩 후 판정이 어떻게 달라지는지는 재야 알고, 그 측정은 이 릴리스 범위 밖이다.

리뷰 포인트

  1. 표시명 21개가 서로 겹치지 않는다. 백엔드의 Keyword 조회가 표시값 기준으로 중복을 흡수하므로, 두 프리셋이 같은 이름을 가지면 하나가 조용히 사라진다. #102 에서 확인했다.

  2. 응답 정렬이 바뀐다. 백엔드 일부 쿼리가 표시명 기준으로 정렬하므로 Keyword 순서가 달라진다. 기능 결함은 아니나 화면 순서가 바뀌는 것을 인지하고 배포한다.

  3. data/keyword_preset.yamlVIEW_GOOD 주석이 낡았다. 그 주석은 "표시명은 화면에 나가므로 못 고친다" 를 전제로 예문에서 음식 어휘를 피한다고 적어 두었는데, #102 가 그 전제를 없앴다(「뷰맛집」 → 「전망」). 고치지 않았다 — diff 를 21줄로 유지해 「표시명만 바꿨다」를 검증 가능하게 두는 쪽을 골랐다. 별건으로 정리한다.

미결

  • 기존 판정은 옛 정의로 남는다. 이미 붙은 Keyword 는 자동으로 다시 판정되지 않고, 되돌리는 수단이 지금 없다. 별건이다.
  • bootstrap.version 표기 갱신 — 배포 동작에는 영향이 없으나 기록 정합성 문제로 남는다.
  • VIEW_GOOD 예문의 우회 근거가 사라졌다 — 리뷰 포인트 3. 표시명에서 음식 신호를 걷어냈으므로 예문의 제약도 다시 볼 수 있다.

colosair and others added 3 commits August 3, 2026 15:39
`dev` 에 병합한 것이 배포에 닿지 않는 원인을 가르고, 프리셋 봉인 값을 다시 산출했다.

`ai-image / publish` 가 SKIPPED 인 것은 고장이 아니라 설계다. `ai-ci.yml` 안의
`image-publish` job 이고 `push` × `refs/heads/main` 두 조건이 모두 필요하다.
근거가 주석·계약 테스트·infra 어서션·CONTRIBUTING 넷이라 한 곳의 실수일 수 없다.
`apps/dev/ai` 가 pin 하는 것은 `ai` 의 `main` HEAD 이므로 끊긴 것은 파이프라인이
아니라 릴리스 PR 이다.

봉인 값 산출 방식은 실측으로 확정했다 — infra 문서의 64자와 파일 해시가 전량
일치하므로 파일 전체 바이트 SHA-256 의 앞 12자다. 새 값은 `preset-ab321360b0df`.

`bootstrap.version` 은 `update_ai_image.py` 의 갱신 범위 밖이라 사람이 갱신해야
하고, 틀려도 실패하는 검사가 없다.
* feat(S15P11A705-253): GMS 이미지 측정 하네스와 축 A 탐색 회차

측정 시각 2026-08-03 17:07 KST · root=https://gms.ssafy.io/gmsapi · 호출 7회.

`synth.py` 는 치수와 바이트를 따로 움직이는 합성 PNG 를 만든다 — 실제 이미지로는
둘 중 무엇이 토큰을 움직였는지 가를 수 없다. `gateway.py` 는 호출 상한을 코드로
강제하고 응답을 한 건씩 append 한다(세션이 죽어도 쓴 쿼터가 남는다).

축 A 탐색 결과: 이미지 생성은 두 경로에서 200 이다.

  openai:gpt-image-1     200 · 14.4s · 1024x1024 PNG
  gemini:flash-image     200 ·  5.6s · 1024x1024 PNG
  openai:dall-e-3        400 · [GMS 에러] Model ... is not available in Model
  gemini:imagen-3        400 · 같은 형태
  GET .../models (3벤더) 400 · [GMS 에러] Model not found in request for domain ...

게이트웨이가 경로가 아니라 요청 본문의 model 로 라우팅한다는 것이 마지막 줄에서
드러난다 — 모델 목록 조회는 구조상 프록시되지 않는다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(S15P11A705-253): 축 A 프로파일 회차 — 지연·토큰·비율·정책 거절

측정 시각 2026-08-03 17:12~17:16 KST · root=https://gms.ssafy.io/gmsapi · 호출 13회
(축 A 누적 20/20, 상한 소진).

지연 5표본씩. gpt-image-1 12.6~17.3s · gemini-2.5-flash-image 5.0~6.5s.
연속 호출에서 429 는 한 번도 없었다 — 분당 한도의 하한만 관측된다.

정사각형은 둘 다 직접 지원한다. gpt-image-1 은 size 가 실제로 먹고(1024x1536 요청에
2.23 MB 세로 이미지), gemini 는 기본 출력이 정확히 1024x1024 다. gemini 의
imageConfig.aspectRatio=3:4 는 864x1184 로 왔다 — 비율은 먹지만 정확한 픽셀은
모델이 정한다.

오류 구분이 벤더마다 **다른 층에서** 갈린다.

  OpenAI   정책 거절 → HTTP 400 · [OpenAI 에러] 접두 · code=moderation_blocked
  Gemini   정책 거절 → HTTP 200 · finishReason=PROHIBITED_CONTENT · parts 없음

Gemini 쪽은 상태 코드만 보는 호출부가 거절을 성공으로 읽는다.

gateway.call 에 inspect 훅을 더해 blob 을 접기 전 생성 이미지의 치수·바이트를
꺼낸다 — 요청한 size·비율이 실제로 먹었는지는 그것 말고 확인할 방법이 없다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(S15P11A705-253): 축 B 하네스 — 치수와 바이트를 가르는 조건표

아직 GMS 를 부르지 않았다. 조건표만 굳힌다(총 23회 계획, 상한 30).

핵심은 대조쌍이다 — px512-solid(2,004 B)와 px512-noise(787,252 B)는 치수가 같고
바이트가 393배 차이 난다. 크기 순으로만 늘어놓으면 -253 의 세 가설이 전부 같은
곡선을 내므로 갈리지 않는다.

detail=low 를 함께 잰다. OpenAI 경로에서 우리 손에 있는 유일한 비용 손잡이라
ai#98 에 대안을 제시하려면 수치가 있어야 한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(S15P11A705-253): 축 B 1·2회차 — 치수 사다리로 가설 C 확정, 상한 발견

측정 시각 2026-08-03 17:19~17:22 KST · root=https://gms.ssafy.io/gmsapi · 호출 27회.

토큰은 **치수에 반응하고 바이트에는 반응하지 않는다** — 가설 C.

  openai   512x512(2 KB) 8,523 · 1024x1024(5.6 KB) 25,524 · 2048x2048(17 KB) 25,524
           차이 17,001 = 3 x 5,667. gpt-4o-mini 타일 규칙(2,833 + 5,667/타일)과
           1 타일 -> 4 타일이 정확히 맞는다. 게이트웨이 가산이 아니다
  anthropic 1x1 39 · 512x512 399 · 1024x1024 1,407 — (w*h)/750 규칙과 일치
  gemini    셋 다 258 — 치수와 무관하게 평탄, 세 경로 중 가장 싸다

-227 의 8,524 는 8,523 으로 재현됐다(텍스트 23 + 이미지 8,500).

그리고 더 급한 것이 나왔다. **base64 본문이 커지면 게이트웨이가 본문을 못 읽는다.**

  통과 최대 23,056 B(base64) · 거부 최소 133,580 B — 그 사이에 상한이 있다
  openai·anthropic  [GMS 에러] Model not found in request for domain ...
  gemini            [Gemini 에러] contents is not specified — 본문이 잘린 채 전달된다

크기 거부가 「모델을 못 찾겠다」로 온다 — -205 T62 와 같은 얼굴이고 -225(긴 Context 가
모델 오류로 오진)와 같은 원인이다. 첫 회차의 787 KB 조건이 전부 여기 걸려 토큰을
하나도 주지 못해, 상한 아래를 훑는 바이트 사다리를 synth 에 더했다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(S15P11A705-253): 축 B 상한 이분 탐색과 오프라인 재판정 도구

측정 시각 2026-08-03 17:25~17:26 KST · 호출 3회 (축 B 누적 30/30, 상한 소진).

상한을 좁혔다 — 요청 본문 96,024 B 통과 · 129,564 B 거부. 구간에 드는 흔한 값이
100,000 · 102,400 · 128,000 이라 실측만으로는 못 가른다. 실무 환산으로 이미지
원본 약 70 KB 까지가 확인된 통과 대역이다.

같은 호출이 바이트 사다리도 겸했다. 512x512 고정에서 2,004 B 와 71,776 B 의
prompt_tokens 가 **둘 다 8,523** 이다 — 바이트 36배에 토큰 불변. 치수 사다리와
무관하게 가설 B 가 여기서 단독으로 죽는다.

report.py 는 GMS 를 부르지 않는다. 판정 규칙을 고칠 때마다 다시 부르면 T27 때문에
수치가 흔들려 「규칙을 고쳐 결론이 바뀐 것」과 「다시 재서 값이 달라진 것」이
구분되지 않는다. 벤더 공개 공식은 판정에서 분리해 보강 증거로만 쓴다 — 판정에
넣으면 「공식대로 나왔으니 C」라는 순환이 된다.

OpenAI 타일 공식 대조는 7개 조건 전부 잔차 0 이다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(S15P11A705-253): GMS 이미지 실사용 조건 리포트와 색인

측정 시각 2026-08-03 17:07~17:26 KST · root=https://gms.ssafy.io/gmsapi · 호출 50회
(축 A 20/20 · 축 B 30/30, 양쪽 상한 소진). 이 커밋은 GMS 를 부르지 않는다.

리포트에 측정 시각·경로·호출 횟수를 머리말에 못 박고 「이 수치는 상수가 아니다」를
T27 근거와 함께 앞에 뒀다 — 없으면 다음 사람이 상수로 읽는다.

축 A 는 -253 본문의 범위 밖이라는 것을 리포트에 적었다. 티켓 분리 여부는 §6 에
중앙이 정할 것으로 남긴다.

문서 색인 두 표에 I49 를 넣고 WORKLOG 에 한 줄 더했다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(S15P11A705-253): 8,524 대 8,523 의 1 토큰 귀속 정정

「1×1 이미지가 68 B 냐 69 B 냐의 차이」로 적었는데, 같은 문서 §2.3 이 **바이트는
토큰에 안 붙는다**를 보인다 — 자기 결론과 어긋나는 설명이었다.

둘 다 1×1(1 타일)이므로 이미지 기여분은 양쪽 8,500 으로 같고 차이는 텍스트 쪽이다.
출처는 이 측정이 답하지 못한다는 것을 그대로 적었다 — 두 회차의 요청 본문을 나란히
비교한 것이 아니라 프롬프트 차이인지 토크나이저 갱신인지 가를 근거가 없다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
화면에 나가는 프리셋 라벨의 품사가 섞여 있었다. 조사형(`친구와`)·부사형
(`간단하게`)·관형형(`조용한`)·명사(`식사`)가 한 목록 안에 공존했다. 각각을 따로
보면 읽히지만 목록 전체를 선택 칩으로 읽으면 언어 규칙이 없고, 이후 프리셋을
추가할 때 기준이 될 것도 없다.

`display_name` 21개를 명사·명사구로 바꾼다. 6개(`혼자`·`식사`·`디저트`·`산책`·
`쇼핑`·`기념일`)는 이미 명사형이라 유지한다.

`RETRO` 는 품사로는 이미 명사였으나 함께 고친다 — 같은 `ATMOSPHERE` 축의 나머지가
전부 순우리말·한자어 추상명사(`조용함`·`아늑함`·`감성`·`활기`·`공간감`·`전망`)인데
이것만 외래어라 어휘 층위가 섞인다. `description` 이 이미 「옛 느낌이나 복고
분위기」로 「복고」를 쓰고 있어 정의와도 맞는다.

`id`·`code`·`category`·`visibility`·`description`·`examples` 는 손대지 않는다.
표시 계층만 바꾸고 식별자와 의미 정의는 그대로 둔다. diff 는 21줄이다.

`display_name` 은 표시 전용이 아니다. `preset_embed_text()` 가 임베딩 입력의 첫
토막으로 쓰고(`display_name. description examples`) 판정 프롬프트의 후보 목록에도
실린다. 따라서 재임베딩이 따라오고 판정 결과가 바뀔 수 있다 — 재평가는 이번
범위 밖이다.

표시명 중복은 `back` 의 Keyword 조회가 표시값 기준으로 흡수하므로 27개가 전부
서로 달라야 한다. 프로그램으로 확인했다(고유 27/27).

배포 봉인 값이 바뀐다.

  preset-ab321360b0df  ->  preset-9459bfc7b19a

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@colosair

colosair commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

base 검사에 걸렸다. main 을 base 로 하는 PR 은 release/* 또는 hotfix/* 만 허용하는데 head 를 dev 로 열었다. release/2026-08-03-preset-display-name 브랜치로 다시 낸다.

@colosair colosair closed this Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant