Google Antigravity에게 그림 그리는 법 가르치기: Gemini의 Interactions API와 MCP를 기반으로 구축된 상태
요약
Google의 Gemini Interactions API와 MCP를 활용하여 Antigravity CLI에서 상태 유지(stateful) 이미지 생성을 구현하는 방법을 소개합니다. 기존의 상태 비저장 방식과 달리, interaction_id를 통해 이전 이미지의 문맥을 유지하며 연속적인 편집이 가능합니다.
핵심 포인트
- Gemini Interactions API를 통한 상태 유지(stateful) 이미지 편집 가능
- interaction_id를 사용하여 시각적 문맥과 픽셀 연속성 유지
- FastMCP 서버를 활용한 Antigravity CLI 스킬 패키징
- 프롬프트 재입력 없이 자연어 명령만으로 이미지 수정 가능
요약 (TL;DR): nb2lite-skill-agy는 Google의 gemini-3.1-flash-lite-image 모델 (NB2Lite)을 FastMCP 서버로 래핑(wrap)하여 Antigravity CLI 스킬로 패키징합니다. Antigravity에 "사이버펑크 주방 이미지를 생성해줘"라고 입력하면, 그냥... 실행됩니다. 그다음 "네온 라멘 간판을 추가해줘"라고 말하면, 전체 장면을 다시 프롬프트로 입력할 필요 없이 _동일한 이미지_를 편집합니다. 아, 그리고 이 기사의 커버 이미지요? 이 기사에서 다루는 바로 그 도구로 생성되었습니다. 끝까지 제대로 된 도그푸딩(dogfooding)이죠. 자세한 내용은 마지막에 설명하겠습니다.
배경: 왜 또 다른 이미지 도구가 필요한가?
대부분의 이미지 생성 워크플로우는 상태 비저장(stateless) 방식입니다. 프롬프트를 보내면 픽셀을 돌려받고, 모델은 즉시 모든 것을 잊어버립니다. 결과를 수정하고 싶나요? 그러면 _전체 장면_을 다시 묘사하고 캐릭터, 조명, 구도가 이번 왕복 과정에서도 살아남기를 기도해야 합니다. (해설: 살아남지 못합니다.)
Google의 NB2Lite — gemini-3.1-flash-lite-image의 친근한 별명 — 는 다른 접근 방식을 취합니다. 이는 2초 미만의 생성 속도, 25개 이상의 언어에서 안정적인 텍스트 렌더링, 그리고 핵심 기능인 상태 유지(stateful) Interactions API 지원을 갖춘 고효율 이미지 모델입니다. 이 API를 통해 모델이 서버 측에서 시각적 문맥(visual context)을 유지하는 동안 여러 턴에 걸쳐 이미지를 반복적으로 수정할 수 있습니다.
이 저장소(repo)는 해당 기능을 Google Antigravity CLI에 직접 결합하여, 여러분의 코딩 에이전트가 페어 프로그래밍(pair-programming) 세션의 자연스러운 일부로서 이미지를 생성하고 반복적으로 개선할 수 있도록 합니다. 이 저장소는 한 저장소 내에 두 가지 형태로 제공됩니다:
- 4개의 도구(tools)를 노출하는 Model Context Protocol (MCP) 서버 (
nb2lite-agent,server.py에 있는 단일 파일 FastMCP 앱). - Antigravity가 해당 도구들을 언제 그리고 어떻게 잘 사용할 수 있는지 가르치는 스킬 정의 (
nb2lite-image).
Interactions API: 기억력을 가진 이미지
Interactions API는 Gemini의 상태 유지(stateful) 엔드포인트입니다. 핵심 루프는 다음과 같습니다:
- 프롬프트와
store=True를 포함하여client.interactions.create(...)를 호출합니다. - 응답에는 **
interaction_id**가 포함됩니다. 이는 Google 서버에 저장되어 해당 턴의 시각적 컨텍스트(visual context)를 제어할 수 있는 핸들(handle) 역할을 합니다. - 다음 호출 시
previous_interaction_id를 전달하면, 모델은 _기존 캔버스(existing canvas)_를 편집하며 캐릭터, 스타일, 조명 및 픽셀 연속성(pixel continuity)을 유지합니다.
따라서 다음과 같은 방식(상태 비저장(stateless) 방식의 고충) 대신:
"새벽녘 숲속의 수채화풍 여우, 안개, 부드러운 빛, 빨간 목도리를 두르고 있음, 왼쪽에 자작나무 세 그루, 그리고 이제는 랜턴도 들고 있음"
...Antigravity에서는 다음과 같이 작성합니다:
"발에 랜턴을 추가해줘."
그게 전부입니다. 저장된 컨텍스트가 나머지를 처리합니다.
서버가 대신 처리해 주는 몇 가지 실무적인 세부 사항은 다음과 같습니다:
- 매 턴마다 새로운 interaction ID가 반환됩니다. 가장 최신 ID를 체이닝(chain)하세요. 오래된 ID로 편집하면 세션이 이전 상태에서 조용히 분기(fork)됩니다.
- 종횡비(Aspect ratio)는 생성 시점에 결정되며 (
1:1,16:9,9:16,4:3,3:4), 상태 유지(stateful) 편집 시 이를 상속(inherited) 받습니다. 세션 중간에 종횡비를 변경하면 픽셀 연속성이 저하되므로, 편집 도구는 의도적으로 종횡비 변경을 허용하지 않습니다. - 사고 수준(Thinking levels):
low(기본값, 빠른 초안) 또는high(복잡한 렌더링, 정확한 텍스트 레이아웃, 캐릭터 구도). 일반적인 API 명세에는minimal과medium도 나열되어 있지만, 현재 모델의 라이브 API는 이를 HTTP 400 오류로 거부합니다. 서버가 여러분이 직접 시행착오를 겪으며 이를 발견하지 않도록 미리 막아주는 셈입니다.
MCP란 무엇인가, 1분 요약
**Model Context Protocol (MCP)**는 AI 어시스턴트를 도구 및 데이터와 연결하기 위한 개방형 표준입니다. MCP 이전에는 모델에 특정 서비스에 대한 접근 권한을 주려면 각 어시스턴트마다 맞춤형 통합(bespoke integration) 코드를 작성해야 했습니다. 즉, N개의 어시스턴트 × M개의 서비스만큼 모든 사람이 동일한 배관(plumbing) 작업을 새로 만들어야 했습니다. MCP는 이를 하나로 통합합니다. 도구 제작자가 타입이 지정된 도구(typed tools)를 노출하는 하나의 MCP 서버를 작성하면, Antigravity CLI와 같이 MCP를 지원하는 모든 클라이언트는 클라이언트별 연결 코드(glue code) 없이도 해당 도구를 찾아 호출할 수 있습니다.
MCP 서버는 일반적으로 stdio를 통해 JSON-RPC를 주고받는 작은 로컬 프로세스입니다. Antigravity는 이 서버를 실행하고 "어떤 도구들을 가지고 있나요?"라고 물으며, 그 이후부터 모델은 해당 도구들을 네이티브 함수처럼 호출할 수 있습니다.
nb2lite-agent 서버는 네 가지 핵심 도구를 노출합니다:
| 도구 (Tool) | 기능 |
|---|---|
generate_image | 텍스트 → 1k 이미지 생성. 로컬에 저장하며, 경로와 interaction ID를 반환함. |
| ... |
이미지는 gen_<timestamp>_<uuid8>.jpg (또는 edit_/edit_local_ 접두사 포함) 형식으로 디스크에 저장됩니다. UUID 접미사는 동시에 생성되는 이미지들이 서로를 덮어쓰지 않도록 보호합니다. 에러는 프로토콜 에러 대신 🔴 ... 텍스트 문자열로 반환되므로, Antigravity는 이를 읽고 유연하게 대응할 수 있습니다.
그리고 에이전트의 '스킬(skill)'이란 무엇인가?
MCP가 에이전트가 물리적으로 호출할 수 있는 도구인 '손'이라면, **스킬 (skill)**은 '근육 기억 (muscle memory)'입니다. 즉, Antigravity의 컨텍스트(context)로 로드되어 워크플로우를 가르치는 마크다운 파일(SKILL.md)과 번들된 리소스들의 집합입니다. 어떤 도구를 어떤 순서로, 어떤 제약 조건 하에 사용해야 하는지를 알려줍니다.
nb2lite-image의 경우, 스킬에는 다음과 같은 사항들이 인코딩되어 있습니다:
- 설정 문제를 진단할 때는 가장 먼저
get_help를 호출할 것 — API 키가 누락되었다면 다른 어떤 것도 작동하지 않습니다. - 편집 프롬프트는 **점진적 (incremental)**으로 유지할 것: 장면 전체가 아니라 변경 사항만을 설명하세요.
- 항상 최신 (latest) interaction ID를 체이닝(chain)할 것.
- 생성 작업은 비용이 발생함 — 관련 편집 작업은 배치(batch)로 처리하고, 초안 작업 시에는
thinking_level: low를 권장함.
또한 이 스킬은 MCP 서버 자체(mcp/server.py), 요구 사항, 설치 스크립드, 그리고 Interactions API 개발자 가이드의 벤더드(vendored) 복사본을 함께 묶어 제공하므로 완전히 독립적으로 작동합니다.
Antigravity CLI에 설치하기
세 가지가 필요합니다: Python 3.10+, Antigravity CLI, 그리고 Gemini API 키 (Google AI Studio에서 무료로 발급 가능)입니다. 아래 경로 중 하나를 선택하세요.
경로 A: 플러그인 마켓플레이스 (가장 적은 키 입력)
Antigravity 세션 내부에서 다음을 실행합니다:
/plugin marketplace add xbill9/nb2lite-skill-agy
/plugin install nb2lite-image@nb2lite-skill-agy
이 명령은 스킬을 설치함과 동시에 MCP 서버를 자동으로 등록합니다. 플러그인 매니페스트(manifest)에는 API 키가 포함되지 않습니다. 서버는 환경 변수에서 GEMINI_API_KEY를 읽어오므로, Antigravity CLI를 실행하기 전에 해당 키가 export 되어 있는지 확인하십시오.
경로 B: 클론(Clone) 및 부트스트랩 (이 리포지토리)
# 1. 코드 가져오기
git clone https://github.com/xbill9/nb2lite-skill-agy.git
cd nb2lite-skill-agy
...
init.sh는 멱등성(idempotent)을 가지므로 언제든 다시 실행해도 안전합니다.
경로 C: 사용자의 프로젝트에 설치
리포지토리를 클론한 상태에서 다음을 실행합니다:
make init TARGET=/path/to/your/project ARGS='--output-dir ./images'
이 명령은 스킬을 <project>/.gemini/antigravity-cli/skills/nb2lite-image/로 복사하고, 해당 프로젝트의 .mcp.json에 nb2lite-agent 항목을 작성합니다. ~/gemini.key 파일이 있다면 이를 재사용합니다. 프로젝트에서 Antigravity를 재시작하고 서버를 승인하면 완료됩니다.
경로 D: Docker (호스트에는 Docker만 설치된 경우)
서버는 xbill9/nb2lite-agent로 배포되어 있습니다:
antigravity mcp add nb2lite-agent --env GEMINI_API_KEY="$(cat ~/gemini.key)" -- \
docker run --rm -i -e GEMINI_API_KEY -v "$PWD:$PWD" -w "$PWD" xbill9/nb2lite-agent
-v "$PWD:$PWD" -w "$PWD" 마운트 설정을 통해 컨테이너가 워크스페이스 디스크에 이미지를 저장하고, edit_local_image를 위해 로컬 파일을 읽을 수 있도록 보장합니다.
문제 해결 (Troubleshooting)
/mcp명령에 서버가 목록에 나타나지 않음 → 프로젝트 디렉토리에서 Antigravity CLI를 재시작하십시오.- 도구가
🔴 GEMINI_API_KEY is not set을 반환함 →source set_env.sh를 실행(또는 키를 export)한 후 재시작하십시오. - 기타 문제 발생 시 → Antigravity에게
get_help를 호출하도록 요청하십시오. 현재 활성화된 설정 상태를 보고합니다.
예시: 실제 Antigravity 세션 활용
설치가 완료되면, 일상적인 영어(plain English)로 Antigravity와 대화할 수 있습니다. 실제 흐름은 다음과 같습니다:
사용자: _"해질녘 눈 내리는 숲속의 아늑한 오두막을 16:9 비율로 생성해줘."
Antigravity가 호출하는 내용:
generate_image(
prompt="A cozy log cabin in a snowy forest at dusk, warm light in the windows",
aspect_ratio="16:9",
...
사용자: "좋아요. 굴뚝에서 연기가 피어오르게 해주세요."
edit_image(
previous_interaction_id="v1_ChdpRU5...",
edit_prompt="add gentle smoke curling from the chimney",
...
사용자: "이제 밤으로 바꾸고, 하늘에 오로라를 넣어주세요."
동일한 도구, 최신 ID를 사용하며 오두막, 나무, 굴뚝 연기는 그대로 유지됩니다. 오직 하늘만 바뀝니다. 다시 프롬프트를 입력할 필요도, 연속성(continuity)을 위해 운에 맡길 필요도 없습니다.
그리고 모델에서 생성되지 않은 이미지의 경우:
사용자: "./whiteboard-sketch.png 파일을 가져와서 깔끔한 3D 제품 목업(mockup)으로 렌더링해줘."
edit_local_image(
image_path="./whiteboard-sketch.png",
edit_prompt="render this hand-drawn sketch as a high-fidelity 3D product mockup",
...
이 경우에도 상호작용 ID(interaction ID)를 반환하므로, 후속 수정 시에는 edit_image로 전환되어 그 시점부터 상태 유지(stateful) 방식으로 동작합니다.
Dogfooding: 커버 이미지에 대하여 🐕🍖
**"자신의 제품을 직접 사용하기 (Eating your own dog food)"**란 자신의 제품을 실제 업무에 사용하는 것을 의미합니다. 이는 "이건 작동할 거야"와 "나는 이걸 매일 사용하여 제품을 출시해"의 차이입니다.
이 리포지토리(repo)는 모든 계층에서 스스로를 Dogfooding 합니다:
- 기술(skill)이 자체 리포지토리 내부에서 활성화되어 있습니다 — 클론(clone)된 환경에서 Google Antigravity를 열면
nb2lite-image기술과nb2lite-agent서버가 이미 연결되어 있어, 모든 개발 세션이 통합 테스트(integration test) 역할을 겸하게 됩니다. - 통합 테스트 (
make test)는 실제 API를 대상으로 최종 사용자가 사용하는 것과 동일한 네 가지 MCP 도구를 구동합니다. - 그리고 이 기사의 커버 이미지는 이 기사에서 설명하는 바로 그 기술을 사용하여, 이 리포지토리 내의 Antigravity CLI 세션에서 생성되었습니다. 단 한 번의 도구 호출, 실시간 생성, 리터칭 없음:
generate_image(
prompt="넓은 기술 블로그 커버 일러스트레이션: 빛나는 안티그래비티(antigravity) 요소가 있는 친근한 AI 에이전트가 이젤 옆에 떠서 활기찬 은하계를 그리고 있으며, 그 뒤로 연결된 프레임 체인이 동일한 그림이 단계별로 진화하는 모습을 보여줌. 플랫 벡터 스타일 (Flat vector style), 짙은 인디고 배경, 네온 사이언 및 마젠타 강조색. 제목 텍스트 'NB2Lite + Antigravity', 부제 'Stateful image editing as an Antigravity skill'. 선명하고 정확한 레터링.",
aspect_ratio="16:9",
...
(해당 출력물은 영수증을 포함하여 devto-cover.jpg로 리포지토리에 커밋되었습니다.)
주목할 만한 점:
- 텍스트가 정확하게 렌더링되었습니다. "NB2Lite + Antigravity"가 오타 없이 선명하게 출력되었습니다. 이것이 바로 텍스트가 많은 레이아웃에서
thinking_level: "high"를 설정했을 때 얻을 수 있는 결과입니다. - 모델이 자신의 핵심 가치를 직접 시각화했습니다. 프레임의 체인(초기화(Initialize) → 성운 베이스(Nebula Base) → 세부 사항 강화(Enhance Detail) → 정교화(Refine) → 상태 유지 편집(Stateful Edit))은 바로 상태 유지 편집 루프(stateful edit loop) 그 자체입니다. 이 이미지는 매뉴얼 다이어그램보다 Interactions API를 더 잘 설명해 줍니다.
- 만약 강조색을 바꾸고 싶다면, 저는 이미지를 다시 생성하지 않을 것입니다. 대신 해당 상호작용 ID(interaction ID)를 사용하여
edit_image를 호출하고 "사이언(cyan) 강조색을 에메랄드(emerald)로 바꿔줘"라고 말할 것입니다. 이것이 바로 이 기술의 핵심입니다.
도그푸딩(Dogfooding, 자사 제품 직접 사용)은 가장 저렴하게 신뢰를 얻는 방법입니다. 이 도구의 실제 결과물이 말 그대로 여러분이 이 글을 열었을 때 처음 본 바로 그 것입니다.
링크
- 리포지토리 (Repo): github.com/xbill9/nb2lite-skill-agy (Apache-2.0)
- Docker 이미지: hub.docker.com/r/xbill9/nb2lite-agent
- Interactions API 레퍼런스: ai.google.dev/api/interactions-api
- Model Context Protocol (MCP): modelcontextprotocol.io
이 프로젝트는 Google과 제휴하거나 Google의 승인을 받은 것이 아닌 제3자 커뮤니티 프로젝트입니다. 본인의 Gemini API 키를 직접 사용하세요. 생성 시 비용이 발생하므로, 초안은 low 설정으로 작성하고 최종 결과물에만 high 설정을 사용하는 것을 권장합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기