WRITING · 2026-11-03

YAML 파일 하나로 포트폴리오·이력서·비공개 페이지까지 — 이 사이트를 만든 방식

내용은 한 곳에만 쓰고, 웹 페이지·PDF 이력서·노션 문서는 빌드로 만든다. 공개하면 안 되는 내용은 저장소에 평문으로 남기지 않는다.

정적 사이트PythonJinja2GitHub Actions암호화

지금 보고 계신 이 사이트는 데이터 파일 하나에서 만들어집니다. 이력서를 고칠 때마다 웹, PDF, 노션을 따로 고치다 보면 어딘가 내용이 어긋나기 마련이라, 처음부터 "내용은 한 곳에만 쓴다"를 원칙으로 잡았습니다.

구조

data/portfolio.yaml      ← 내용은 여기에만 씀 (활동, 논문, 기술, 수상)
content/posts/*.md       ← 이런 글
content/study/           ← 강의 정리 노트
        │
        ▼  scripts/build.py (Jinja2 템플릿)
docs/index.html          ← 웹 포트폴리오
docs/resume.html → PDF   ← 상세 이력서 (Playwright로 PDF 변환)
docs/resume-1page → PDF  ← 1장 이력서
docs/study/              ← 학습 공간
out/notion.md            ← 노션에 붙여 넣을 문서

git push를 하면 GitHub Actions가 빌드하고 GitHub Pages로 배포합니다.

데이터 구조를 먼저 정했다

활동 하나를 STAR(상황·과제·행동·결과) 구조로 적습니다. 같은 데이터를 쓰되, 출력물마다 다르게 보여 줍니다.

최근에는 "석사과정 / 학부 / 부트캠프"처럼 여러 프로젝트를 한 묶음으로 보여 달라는 요구가 생겨서, 활동 아래에 projects:로 하위 프로젝트를 둘 수 있게 바꿨습니다. 하위 구조를 모르는 출력물(노션 문서 등)에서도 내용이 빠지지 않도록, 빌드 단계에서 하위 프로젝트의 내용을 모아 상위 활동에도 채워 넣습니다.

빌드가 잡아 주는 것

빌드할 때 보완 체크리스트를 같이 만듭니다.

글을 쓰다 보면 "열심히 했다"로 끝나는 문장이 많아지는데, 이 체크리스트가 그걸 계속 알려 줍니다.

사진은 위치 정보를 지우고 넣는다

활동 사진은 photos/<활동 id>/에 원본을 넣으면 스크립트가 웹용 크기로 줄이고 EXIF(촬영 위치 등)를 모두 지운 뒤 갤러리에 붙입니다. 파일 이름이 그대로 사진 설명이 됩니다. 원본 사진 폴더는 저장소에 올리지 않습니다.

공개하면 안 되는 내용

연락처, 증빙 서류 목록, 자기소개서 소재, 면접 답변 연습처럼 나만 봐야 하는 내용도 같은 사이트 안에 두고 싶었습니다. 다만 공개 저장소에 평문으로 올리면 안 됩니다.

그래서 두 단계로 암호화했습니다.

  1. 저장소에 올릴 때: 평문은 로컬에만 두고(.gitignore), 공개키로 암호화한 파일만 커밋 (RSA-OAEP + AES-GCM). 개인키는 저장소가 아니라 GitHub Secrets에만 있음
  2. 배포할 때: Actions가 개인키로 복호화해 페이지를 만들고, 이번에는 비밀번호 기반 키(PBKDF2-SHA256 60만 회 + AES-GCM)로 다시 암호화해 배포

방문자 브라우저에는 암호문만 내려가고, 비밀번호를 입력하면 브라우저의 WebCrypto가 그 자리에서 복호화합니다. 서버 없이도 "로그인해야 보이는 페이지"를 만들 수 있었습니다.

만들고 나서

관련 프로젝트이 글에서 다룬 코드는 저장소에서 볼 수 있습니다.
GitHub 저장소 →포트폴리오로
다른 글겹쳐 있는 두 신호를 위상으로 가르기 — 파수 상관 필터링 석사 연구 정리중력과 자력 데이터를 같은 주파수 성분끼리 비교해, 함께 움직이는 성분과 반대로 움직이는 성분을 나눴다. 임계값을 감으로 정하지 않으려고 한 일들.점수를 지키면서 올리기 — VQA 챌린지에서 앙상블 후보를 고른 기준정확도가 조금 올라도 원래 맞히던 문제를 많이 틀리면 불안정한 개선이다. fixes와 breaks로 순기여를 따져 0.94608에서 시작한 점수를 쌓아 올린 과정.LLM이 붙인 [근거 N]을 코드로 다시 검사하기 — 국보 RAG 가이드의 인용 설계근거를 인용하라고 프롬프트에 써도 LLM은 없는 번호를 붙입니다. 근거 번호를 검색 단계에서 고정하고, 답변의 인용을 코드로 파싱해 없는 번호는 지우고 실제로 인용한 근거만 보여 주는 구조를 만든 기록.데이터를 해석하기 전에 그 데이터가 만들어진 역사를 본다 — 학부 제1저자 논문 회고해외 대규모 CO2 저장소 8곳을 판구조 형성사와 탄성파 영상으로 비교했다. 처리 결과를 '그럴듯한지' 판단하는 기준을 어디서 가져올 것인가에 대한 이야기.길찾기에서 의사결정으로 — 배틀싸피 자동 플레이 봇을 세 번 고친 기록목표까지 가는 BFS 한 줄짜리 봇이, 사거리·장애물·탄약·보급·암호 해독까지 판단하는 봇이 되기까지. 매 턴 다시 계획하는 구조로 바꾼 이유.산불 4건으로 시공간 딥러닝 학습하기데이터가 35개 시점뿐일 때 어떻게 학습시켰고, 다시 보니 무엇이 부족했는지. U-LSTM 산불 확산 예측 모델 회고.LLM 응답을 믿지 않는 파이프라인 설계LLM에는 판단만 맡기고, 결과는 코드로 검증한다. 댓글 분석 파이프라인과 AI 도서 추천을 만들며 정한 네 가지 원칙.순차 학습이 성능을 떨어뜨린 이유 — catastrophic forgetting 실험기단어 단위 → 문맥 단위로 차례로 학습하면 더 좋아질 줄 알았는데, BERTScore가 0.47에서 0.32로 떨어졌다. FLAN-T5 LoRA 학습 전략 비교.