Colophon · 살아있는 제작기
고객에게 하는 일을
여기에 먼저 했습니다.
이 웹사이트는 그린파이 방법론의 1호 공개 프로젝트입니다. 무엇으로, 얼마 만에, 어떤 실패를 거쳐 지어졌는지 — 성공담만 골라 적지 않았습니다.
무엇으로 지어졌나
- 프레임워크
- Next.js 16 (App Router) + React 19 + TypeScript
- 스타일
- Tailwind CSS 4 — 디자인 토큰은 CSS 변수
- 타이포
- Noto Serif KR(디스플레이) · Wanted Sans(본문) · JetBrains Mono(수치)
- 히어로
- 자체 제작 L-시스템 SVG — 시드 고정 결정론적 생성, 라이브러리 0개
- AI
- Vercel AI SDK v7 · kinfri.ai(자사 게이트웨이) + Vercel AI Gateway 이중화
- 판별 엔진
- Claude Sonnet 5 (Vercel AI Gateway 직결, kinfri 폴백) · 스트리밍 · 거절 기준 4종 내장
- 유리 상자
- 검색→근거 게이트→생성(gemini-3.5-flash)→인용 검증 4단 파이프라인
첫 화면의 식물은 이미지가 아닙니다. 시드가 고정된 알고리즘이 매번 같은 개체를 길러내는 결정론적 생성입니다 — 저희가 고객 시스템에서 환각을 다루는 방식과 같은 원칙입니다. 이 사이트의 AI가 자사 게이트웨이(kinfri.ai)로 구동되는 것도 같은 이유입니다. 저희는 저희가 파는 것을 저희에게 먼저 씁니다.
빌드 일지
Day 1 — 조사에서 살아있는 사이트까지
- 01회사 방향 토론: 순수 구축 전문사 / 가격 비노출 / 그린파이 하우스 브랜드 / 제조·파트너 채널 이원 타깃 확정
- 02리서치 에이전트 3기 병렬 가동 — 2026 디자인 트렌드, 3D·모션 기술 스택, AI-네이티브 컨셉 사례 조사
- 03비주얼 3안을 이미지 생성 파이프라인(자체 CLI + AI 게이트웨이)으로 시안화 → 'A 계측된 정원 + B 제너레이티브 아트' 하이브리드 채택
- 04살아있는 식물 히어로 프로토타입: L-시스템 재귀 + 바람 스웨이. 1차는 단일 기관 반복이라 밋밋 → 말단 기관 5종(술·깃털잎·코일·레이스잎·꼬투리)으로 재설계
- 05Next.js 16 + Tailwind 4 스캐폴드, 디자인 토큰·타이포 3종 체계, PlantHero 포팅, 정적 페이지 9종 구현
- 06판별 엔진 + 유리 상자 구현, kinfri 게이트웨이 실연동
- 07히어로 성장 인트로(씨앗→만개 2.6초, 라이브러리 없이 rAF 단일 루프), sitemap·robots·OG 메타 정비
- 08프로덕션 빌드 — 콘텐츠 페이지 전부 정적 프리렌더. Vercel 배포(빌드 32초) + greenpi.kr 도메인 연결
* 일지는 사이트가 자랄 때마다 이어집니다.
실패의 기록
투명성은 유리한 지표만 골라 보여주는 것이 아닙니다. 이 사이트를 만들며 실제로 겪은 실패와 그 수정입니다.
✕유리 상자의 근거 검색이 한국어 조사를 처리하지 못함 — '안건을'이 '안건'과 매칭되지 않아 정답이 있는데도 '모른다'고 답함
→토큰 앞부분 절단 매칭(최대 2자, 최소 2자)으로 수정. 근거 게이트 덕에 오답 대신 무응답으로 실패한 것 자체가 아키텍처가 작동한 증거
✕판별 엔진에 claude-sonnet-4-6을 배정했으나 게이트웨이에서 401 — 게이트웨이 서버에 해당 프로바이더 키가 미설정
→실호출 테스트 라우트(/api/kinfri-health?test=모델)를 만들어 가용 모델을 실측 → gemini-3.1-pro로 전환. 모델 교체는 환경변수 한 줄
✕게이트웨이 자격증명을 다른 프로젝트에서 자동 복사하려던 스크립트가 보안 분류기에 차단됨
→우회하지 않고 수동 절차로 전환 — 자동화가 항상 정답은 아니다
✕배포 직후 사이트가 Vercel 팀 기본 설정의 배포 보호(SSO)에 가려 외부에서 보이지 않음
→프로젝트 설정에서 보호 범위를 프리뷰 전용으로 조정 — 공개 사이트의 공개는 사람이 결정
✕프로덕션에서 AI 라우트만 500 — CLI 파이프로 등록한 환경변수 끝에 보이지 않는 개행(CRLF)이 붙어 'gemini-3.1-pro\r\n'이라는 존재하지 않는 모델을 호출하고 있었음. URL은 브라우저 규칙이 개행을 지워줘서 헬스체크는 통과 — 그래서 더 늦게 발견
→env 값을 코드에서 항상 trim + 개행 없는 재등록. 진단 라우트(실호출 테스트)가 없었다면 더 오래 헤맸을 것