강의 노트, 시스템 스케치 또는 화이트보드 사진이 폐쇄된 API가 노트를 전혀 볼 필요 없이 다이어그램으로 변환되어야 합니다.
내가 만든 것 (What I Built)
Inkline은 노트를 다이어그램으로 바꿔주는 책상입니다.
강의 노트를 붙여넣으면 마인드맵(mind map)이 생성됩니다. "클라이언트가 한 가지를 더 요청했어요"라고 입력하면 의사결정 흐름도(flowchart)가 나옵니다. 링크 단축기, 인보이스, 론칭 주간 또는 곧 구축할 서비스에 대해 설명하면 아키텍처 다이어그램, 시퀀스 다이어그램 또는 타임라인이 생성됩니다. 화이트보드 사진이나 손글씨 노트 페이지를 올리면 Gemma가 이미지를 읽어줍니다. 그림 아래의 "변경하기(Change it...)" 기능은 "API와 DB 사이에 Redis 캐시를 추가하세요" 같은 문장을 받아들여, 되돌리기(undo), 다시 실행(redo) 및 짧은 기록과 함께 다이어그램을 제자리에 업데이트합니다. 단순함(Simpler), 균형 잡힘(Balanced), 상세함(Detailed) 옵션으로 노트가 페이지에 얼마나 많이 반영될지 조절할 수 있습니다. 오픈 웨이트 모델인 Gemma 4를 Ollama를 통해 사용하며, 이 모델이 Mermaid 코드를 작성합니다. 페이지가 이를 그려줍니다. 소스 코드를 복사하거나 Notion, Obsidian 또는 GitHub용 마크다운 블록을 복사하고, SVG, PNG 또는 벡터 PDF로 내보내거나 동일한 다이어그램을 여는 단축 링크를 공유할 수 있습니다.
상단 스위치에서는 해당 모델이 실행되는 위치를 선택합니다. 자물쇠가 있는 Private은 로컬호스트(localhost) Ollama를 의미하며, 노트는 기기에 보관됩니다. Cloud는 Ollama Cloud를 의미합니다. 서버는 요청으로부터 제공업체를 선택하므로, 동일한 책상으로 두 가지 모두 작업을 수행할 수 있습니다. Private을 선택했고 Ollama가 실행되고 있지 않다면, 페이지는 조용히 실패하는 대신 ollama serve를 시작하고 gemma4를 풀(pull)하도록 안내합니다.
누가 비용을 지불할까요. 이미 손으로 이 작업을 하고 있는 사람들입니다:
- 시험 전날에 한 장의 내용을 상자 형태로 다시 쓰는 학생들.
- 시스템을 설명해야 하는데, Mermaid 문법과 씨름하는 반 시간을 보내고 싶지 않은 개발자들.
- 제안서, README 또는 변경 주문서에 다이어그램을 넣어야 하는 프리랜서 및 소규모 팀들.
직접 사용하면 무료입니다. 이것이 오픈 모델의 핵심입니다: 노트가 노트북을 벗어날 필요가 없고, 다이어그램당 비용도 없습니다. 테마, 사진 입력, 편집, 기록, 내보내기는 이 무료 데스크에 포함되어 있습니다. 제가 유료로 책정할 부분은 호스팅된 데스크인데, 브라우저에서 사용하고 Ollama를 설치하고 싶지 않은 사람들을 위한 것입니다. Cloud Gemma는 월 199 루피 또는 $5이며, 더 높은 제한, 사진-다이어그램 변환(picture-to-diagram), 그리고 그리기 기록 기능을 제공합니다. 팀 플랜은 연구실이나 소규모 그룹을 위한 공유 클라우드 예산입니다. 앱의 가격 페이지에 이 세 가지 플랜이 표시됩니다. 카드가 필요하지 않습니다. Pro와 Team 플랜은 할인이 적용되지 않습니다.
지루한 부분은 아이디어가 아닙니다. 실제로 파싱되는 Mermaid를 모델이 출력하게 만드는 것입니다. 소규모 오픈 모델들은 시스템의 형태는 잘 잡지만 구두점(punctuation)에는 약합니다. Inkline의 핵심 트릭은 복구 루프(repair loop)입니다. 만약 Mermaid가 초안을 거부하면, 파서 오류가 Gemma로 돌아가고 최대 세 번까지 다시 시도합니다. 거부된 것들을 포함하여 초안들이 페이지에 남아 있어 무엇이 잘못되었는지 볼 수 있습니다.
데모 (Demo)
실시간 데스크: https://inkline-lzyf.onrender.com
Gemma가 실제 노트로 만든 여섯 개의 다이어그램이 갤러리에 있습니다. 각 링크를 클릭하면 해당 다이어그램이 데스크에서 열립니다.
코드 (Code)
저장소(Repo): InKline
복구 루프는 src/lib/repair.ts에 있으며, 데스크는 하나의 Next.js 페이지로 구성되어 있습니다.
구축 방법 (How I Built It)
Gemma 4가 유일한 모델입니다. 폐쇄형 모델(closed-model) 대체재는 없습니다.
로컬 환경에서는 Next.js 서버가 http://127.0.0.1:11434의 Ollama에, 모델은 gemma4를 사용하여 통신합니다. 클라우드 요청은 OLLAMA_API_KEY와 함께 https://ollama.com으로 전송되며, 보통 gemma4:31b를 사용합니다. 데스크는 그리기(draw)마다 provider: "private" 또는 provider: "cloud"를 보내고, 서버는 이를 기본 URL로 해석합니다. private 요청은 클라우드 키를 절대 첨부하지 않으며, 이 키는 클라이언트 번들이나 상태 확인(health check)에서도 확인할 수 없습니다. 동일한 클라이언트는 Ollama의 OpenAI 호환 /v1/chat/completions 엔드포인트를 사용하며, 해당 경로가 누락된 경우 Ollama 자체의 /api/chat로 폴백합니다. Gemma 4는 멀티모달(multimodal)이기 때문에 사진은 /api/chat의 images 필드를 사용합니다. 만약 이 호출이 거부되면, Inkline은 Gemma에게 사진을 말로 설명하도록 요청한 다음, 그 설명에 대해 일반적인 복구 루프를 실행하고 페이지에는 그러한 일이 발생했다고 표시됩니다.
사진 한 장은 단 한 번만 읽힙니다. Gemma는 박스와 화살표들을 나열하고, 데스크는 이 목록을 “제가 본 것은 다음과 같습니다(Here's what I saw)”로 보여줍니다. 각 화살표마다 from, to, 그리고 레이블이 있는 행으로 표시됩니다. 사용자는 하나의 행을 수정하거나, 추가하거나, 제거할 수 있으며, 그 후 Draw를 누릅니다. 다이어그램은 사진을 다시 보는 것이 아니라 이 행들로부터 만들어지므로, 잘못된 화살촉(arrowhead)은 다이어그램이 되기 전에 볼 수 있고 수정할 수 있습니다. 그런 다음 복구 루프는 사용자가 확인한 행과 일치하지 않는 초안을 거부합니다. 채팅 편집은 현재의 Mermaid 코드, 원본 노트, 그리고 지침을 동일한 루프를 통해 전송합니다. 상세(Detail)는 프롬프트 내의 한 조항입니다: Simpler는 약 8개의 노드 이하로 유지되고, Detailed는 보조 사실들을 유지하며 24개 노드 이하로 유지되며, 어느 쪽도 노트에 없는 사실을 지어낼 수 없습니다. 사진으로부터의 첫 번째 그리기는 항상 Balanced를 유지하므로, 화살표 확인이 상세 편집과 충돌하지 않습니다. OLLAMA_REASONING_EFFORT=none은 추론 모델이 전체 응답을 사고 과정(thought trace)에 소비하고 다이어그램을 반환하지 않는 것을 방지합니다.
Mermaid 다이어그램 파싱 및 상태 관리 시스템의 기술적 구현
프롬프트는 하나의 Mermaid 펜스(fence)와 특정 다이어그램 모양을 요청합니다. 답변이 그렇게 깨끗한 경우는 드물기 때문에, 추출 과정은 산문, 일반 코드 블록, 그리고 Gemma의 사고 처리(thinking wrappers)에서 펜스를 분리하고 곡선 따옴표를 직선으로 변환합니다.
그런 다음 서버에서 Mermaid가 이를 파싱합니다. 파서가 DOM을 기대하기 때문에 happy-dom이 사용됩니다. 파싱에 오류가 발생하면, 그 오류 문자열(줄 번호, 원하는 토큰, 받은 토큰)은 손상된 소스 옆의 다음 사용자 메시지가 됩니다. 루프는 세 개의 초안에서 멈추거나, 하나라도 성공적으로 파싱되면 더 빨리 멈춥니다. API는 각 초안이 도착할 때마다 스트리밍하므로, Gemma가 이미 초안 2에 있을 때 페이지에는 "초안 1이 거부됨"을 표시할 수 있습니다. 브라우저의 Mermaid가 여전히 서버와 의견이 다르면, 남아 있는 모든 시도를 사용하여 해당 렌더링 오류도 되돌려 보냅니다. 세 개의 초안 모두 실패한 실행은 이전 그림을 페이지에 남겨둡니다. 거부된 초안들은 열어볼 수 있도록 레일(rail)에 남아 있습니다.
이 페이지는 Next.js, TypeScript, 그리고 Tailwind로 구축되었습니다. 다이어그램 유형은 auto, 마인드맵(mind map), 플로우차트(flowchart), 시퀀스(sequence), 아키텍처(architecture), 및 타임라인(timeline)입니다. architecture-beta보다 이 구문이 작은 모델에서 더 잘 유지되기 때문에, 아키텍처는 서브그래프가 있는 플로우차트로 그려집니다. 공유 링크는 유형, Mermaid 내용, 편집 기록의 압축 해시값(lz-string)이며, 메모를 추가하면 링크가 더 짧아지기도 합니다.
PDF 내보내기는 svg2pdf를 사용하여 SVG를 추적하므로, 파일은 페이지에 채워 넣는 JPEG가 아니라 벡터(vectors)입니다. Paper 테마의 샘플 그림은 베이크된 SVG이므로, 첫 번째 렌더링 시 Mermaid를 로드하지 않습니다.
테스트는 모델을 목업(mock)합니다. 이들은 추출 기능, 후속 프롬프트에 실제로 파서 오류가 존재하는지 여부, 루프가 세 번에서 멈추는지 여부, 그리고 연결이 끊어져도 이미 만들어진 초안들이 유지되는지를 확인합니다. Playwright는 동일한 목업을 대상으로 데스크톱 너비와 375px에서 두 번 작업대를 거칩니다: 생성(generate), 편집 및 되돌리기(undo), 키보드 사용, 내보내기(export), 그림 검토, 그리고 빈 책상입니다.
한계점들, 명확하게 말하자면.
- 공개 데모는 IP 주소당 분당 10회, 일일 50회의 드로우(draw)를 허용하며, 전체 서비스에 대해서는 Cloud에서 하루 200회의 드로우가 가능합니다 (
DAILY_CLOUD_LIMIT). 비공개 드로우는 이 클라우드 한도에 포함되지 않습니다. Upstash가 없다면, 이러한 카운터는 서버 메모리에 존재하며 프로세스가 종료될 때 초기화됩니다.
- 노트는 최대 20,000자로 제한됩니다. 편집은 500자입니다. 사진은 PNG, JPEG, WebP 또는 GIF 형식으로 최대 4MB까지 가능합니다. 모델의 응답은 약 2,500 토큰으로 제한됩니다.
- 드로 API 앞에는 숨겨진 회사 필드와 동일 출처 검사(same-origin check)가 위치합니다. 이것들은 로그인 장벽이 아니라 속도 제어 장치입니다.
- Detailed는 언급하지 않은 서비스를 추가할 수 없습니다. Simpler는 원했던 브랜치를 누락시킬 수 있습니다.
- PDF는 한 페이지로 구성됩니다. 매우 넓은 지도는 분리되지 않고 전체에 맞게 축소되어 표시됩니다.
- Pro와 Team은 표시 전용입니다. 가격 책정 페이지의 어떤 것도 카드를 청구하지 않습니다.
- 갤러리 미리보기는 브라우저에서 드로우됩니다. 만약 Mermaid가 여기서 실패하더라도, 데스크로 연결되는 링크는 여전히 작동합니다.
- 사진은 사용자가 확인하는 화살표 목록만큼만 정확합니다. Draw는 그 행(row)들을 사용하며, 사진을 다시 검토하지 않습니다.
정확성 참고 사항. 샘플 화이트보드는 박스 사이에 간격과 큰 화살촉이 추가되어 다시 그려졌습니다. 잉크 경로는 브라우저 → CDN (HTTPS), CDN → API, API → Redis (캐시), 그리고 API → Postgres (SQL)입니다. 2026년 10월 17일, gemma4:31b를 사용한 세 번의 읽기 작업(read)에서 이 네 가지 방향과 레이블이 반환되었습니다. 이는 3회 중 3회 성공을 의미합니다. 확인 과정은 페이지에 남아있습니다: Draw는 사용자가 확인하는 행들을 사용하며, 잘못된 행이 그려지게 됩니다.
Render가 호스팅 데스크를 제공합니다. render.yaml 파일은 Render에 로컬 GPU가 없기 때문에 서비스를 Ollama Cloud로 지정합니다. GET /api/health가 상태 검사(health check)입니다. IP별 및 일일 제한 속도(rate limit)는 공개 URL이 Ollama 키를 소진하는 것을 방지하며, 이 키는 서버를 벗어나지 않습니다.
Open Innovation은 왜 중요한가요?
모든 노트를 폐쇄적인 API로 전송하는 다이어그램 도구는 이 도구를 사용할 사람들에게 좋지 않은 거래입니다.
챕터를 정리하는 학생은 그 챕터가 다른 사람의 계정에 저장되는 것을 원하지 않습니다. 클라이언트 시스템을 스케치하는 프리랜서는 다른 사람의 아키텍처를 다루고 있습니다. 기본값은 비공개이며, 스위치에 자물쇠가 걸려 있습니다: localhost Ollama, 그리고 프롬프트는 기기에 머무릅니다. 클라우드는 Ollama를 설치하지 않은 사람이 동일한 오픈 모델을 사용하여 의도적으로 선택하는 두 번째 위치입니다. 화이트보드 사진과 손으로 쓴 페이지는 같은 경로를 거칩니다. 이 사진은 또 다른 종류의 메모이며, 폐쇄형 비전 API를 호출할 이유가 되지 않습니다.
비용이 나머지 절반을 차지합니다. 호스팅된 가격은 추론(inference) 비용이 거의 무료일 때만 작동합니다. Gemma는 오픈 웨이트(open weight) 모델이기 때문에, 다이어그램 한 달 분량이 폐쇄형 모델의 토큰 가격 상승에 의존하지 않습니다. OLLAMA_MODEL을 변경함으로써 노트북에서 gemma4:e2b를 클라우드의 gemma4:31b로 교체하거나, Mermaid를 목표로 하는 나중의 파인튜닝(fine-tune) 모델로 바꿀 수 있습니다. 수정 루프는 어느 쪽이든 동일합니다. 폐쇄형 API는 실패한 초안에도 비용을 청구할 것이고, 계속 같은 괄호 오류를 범하는 경우 모델을 조정할 수 있도록 허용하지 않을 것입니다.
오픈(Open)이라는 점이 사이드 허슬(side hustle)을 가능하게 합니다: 기본적으로 비공개이며, 실행하기에 충분히 저렴하고, 특정 공급업체의 모델에 갇히지 않습니다.
수상 부문 (Prize Categories)
- Gemma의 최고 활용 사례. Gemma 4는 Ollama를 통해 마인드맵(mind maps), 순서도(flowcharts), 시퀀스 다이어그램, 타임라인, 아키텍처 등 사진 경로를 포함한 모든 다이어그램을 작성합니다. 로컬 태그(
gemma4, gemma4:e2b, gemma4:e4b)와 Ollama Cloud (gemma4:31b)는 동일한 클라이언트입니다. 폐쇄형 모델은 호출되지 않습니다.
- Render의 최고 활용 사례.
render.yaml을 사용하여 Next.js 데스크를 배포합니다. 호스팅 서비스는 Render에 로컬 GPU가 없기 때문에 Ollama Cloud를 사용합니다. GET /api/health가 상태 확인(health check)입니다.
.tech 도메인의 최고 활용 사례. 라이브 데스크는 Render 서비스로 연결된 [ADD .TECH LINK]에서 실행됩니다. <!-- delete this bullet if no .tech domain -->