하고자 한 것
저는 바이브코딩으로 세일즈 랜딩페이지를 자주 만드는데요,
그렇게 랜딩페이지용 이미지를 만들 때마다 매번 반복되는 일이 있습니다.
프롬프트 작성
이미지 생성
로컬 다운로드
URL 복사해서 클코한테 던지거나 Git에 업로드
웹페이지에 반영
👉 이미지는 AI가 만들고 있는데, 관리와 연결은 전부 수작업인 셈이죠.
“이 흐름을 하나의 자동 파이프라인으로 만들 수 없을까?”
그래서 목표를 이렇게 정의했어요:
“이미지가 생성되는 순간, 자동으로 저장되고 → 공개 URL이 만들어지고 → 스프레드시트에 기록되며 → 웹에서 바로 쓸 수 있게 만들자.”
과정
이를 위해 선택한 툴은 에이전트 빌더 Lindy !
우선 어떻게 구현하는 게 좋을지 .. GPT한테 아이디어를 달라고 했어요. GPT 왈, 실제 파일은 오브젝트 스토리지(R2/S3)에 두는 구조가 운영과 확장에 가장 안정적이라고 하네요.
ㅋㅋㅋㅋㅋㅋ 클로드한테 쪼르르 달려가서 설명해달라고 했습니다.
(설명을 야무지게 잘 해줘요)
이제 대충 이해했으니 Lindy 워크플로우를 만들어 볼게요. 아래와 같이 자연어로 요청했습니다.
바이브코딩으로 구현된 랜딩페이지 안에 삽입될 이미지 에셋을 자동생성하는 워크플로우를 lindy ai를 활용해서 구축해볼까 해.
구글 스프레드시트 DB 컬럼은 row_id landing_section_text aspect_ratio brand_mood must_include must_avoid status public_url 이렇게 구성되어있어.
1) 트리거: 스프레드 시트에 "landing_section_text", "aspect_ratio"를 채워넣고, status 컬럼을 Generate으로 바꾸면 워크플로우가 시작됨
2) 이미지 생성 프롬프트 작성 에이전트: 사용자가 입력한 "landing_section_text", "aspect_ratio" 를 읽고 이미지 생성을 위한 프롬프트를 작성함.
3) Image Generator 노드(Nanobanana) 호출 → 이미지 생성하고 나서 Temp_Image_URL 임시링크 획득
4) Lindy Function?을 실행해서 Temp_Image_URL의 이미지를 다운로드 → R2 버킷에 업로드
5) R2에서 발급된 public_url을 반환
6) 스프레드시트 DB의 지정된 레코드(Row)에 public_url 업데이트지금 단계에서 DB 구조는 너무 복잡하지 않은 게 좋다고 생각해서, GPT가 제안한 것들 중 일부만 선택해서 만들었어요.
row_id: 고유 ID + 시트 업데이트용landing_section_text: 이미지가 들어갈 랜딩페이지 섹션 텍스트aspect_ratio: 이미지 비율status: Generate / Done
워크플로우 생성은 5분 컷 ! Lindy가 알아서 다음 단계도 안내해줍니다.
그런데 사실 저는 Lindy에 이미 익숙해서,
이 귀여운 자식(?)이 “이미지 생성 API를 설정 하자”고 하길래 이렇게 말했어요.
“이미 너한테 Image Generator 노드 있잖아.
그거 쓰자. API 키도 없고, 설정도 단순하잖아.”
(이 부분은 Lindy 초보자분들에겐 조금 헷갈릴 수도 있겠다는 생각이 드네요.)
몇 번 테스트하다 보니,
텍스트 + 비율만으로는 프롬프트가 너무 모호하더라고요.
그래서 DB에 image_type 컬럼을 추가했습니다.
A. Hero/Banner Type (가로로 긴 배너)
- 용도: 웹사이트 최상단(Hero Section), 섹션 중간 띠 배너B. Spot/Icon Type (오브젝트 중심)
- 용도: 특징 소개(Feature), 3단 칼럼, 강조 포인트C. Context/Card Type (상황/장면 중심)
- 용도: 블로그 썸네일, 후기 카드 (사람이 무언가를 하고 있거나, 기기 화면이 보이는 등 '맥락'이 담기는 이미지)
이 타입 정보 하나만 추가해도 프롬프트 품질이 확 좋아졌어요.
Lindy로 만든 워크플로우를 조금 더 자세히 보여드릴게요.
전체 구조는:
구글 시트에
landing_section_text적고aspect_ratio이랑image_type고르고status=Generate로 바꾸면
프롬프트 작성 → 이미지 생성 → 업로드 → Pubilc URL 생성 → 시트 업데이트까지 한 번에 처리됩니다.
<프롬프트 작성 에이전트 노드>
: 이름 그대로 구글 시트의 정보를 읽어와서 이미지 생성을 위한 프롬프트를 만들어 내요.
<이미지 생성 노드>
: 이전 단계에서 만들어진 프롬프트를 넣고 모델만 Gemini 3.0 Pro로 골라주면 끝!
<R2 업로드 노드 - Python Code>
: 이 노드에서 하는 일은 딱 세 가지예요.
임시 이미지 URL 다운로드
Generate Image 노드에서 받은
(Temp)Image_URL사용
Cloudflare Worker로 PUT 요청
이미지를 직접 R2에 올리는 게 아니라
Worker 엔드포인트에 PUT 요청 → Worker가 R2에 저장
public_url 반환
저장된 파일의 공개 URL을 그대로 리턴
이 구조를 쓰면 좋은 점이:
boto3 같은 라이브러리 필요 없음
Lindy 실행 환경 제약 회피
R2를 CDN처럼 안정적으로 서빙 가능
어쨌든 Cloudflare 설정하고 코드 오류 없을 때까지 수정하는 작업이 제법 걸렸지만, 우선 전체 시스템이 동작한다는 사실을 두 눈으로 확인했으니 ! 의미 있는 시도였습니다 ㅎㅎ
테스트 결과
https://calm-cloud-0676r2-image-proxy.gkhan-f1c.workers.dev/landing_images/20251219_072318.png
이제 바이브코 딩으로 만들어진 웹페이지가 시트 내의 “public_url을 읽어서 렌더링만 하면 !
어찌저찌 이미지 에셋 자동화가 가능해지지 않을까요 ?
부푼 꿈을 안고 다음에 더 업그레이드된 사례글로 돌아오겠습니다 🥰