내 학습허브 — 학습 전자책
학습위키를 책으로 묶었어요. 로드맵이 서문, 주차가 챕터예요. 지금 17꼭지.
내 학습허브
AI와 함께한 한 달의 학습 기록
나의 4주 로드맵 — 검색되는 나만의 지식체계 만들기
4주 뒤 내 손에 남는 것 (카드 4개)
- 나만의 AI 학습메이트 ‘하루’ — 나를 아는 AI (✅ 이미 완성)
- 확정된 주제 + 이 로드맵 — “검색되는 나만의 지식체계(AKM·에이전트 지식관리)”
- 작동하는 MVP — 에이전트가 유지하는 LLM 위키 + 기본 RAG 검색. 즉 “내 지식에 질문하면 근거와 함께 답하는” 상태.
- 혼자서도 굴리는 AKM 운영 근육 — 자료를 넣고(ingest) → 점검하고(lint) → 질문하는(query) 루프가 몸에 붙음.
이 로드맵의 뿌리 — 나는 어디서 출발하나
- 지금 나: 데이터 분석·모델링은 자신 있는데, 내 지식을 체계로 쌓는 건 매번 흩어지고 어디서 시작할지 막막하다.
- 되고 싶은 나: 개념부터 기본기가 탄탄한 지식관리자. 도구를 빨리 쓰는 사람이 아니라, 밑바탕(본질)부터 이해하고 쌓는 사람.
이 로드맵은 그래서 “개념 먼저, 기본기 먼저” 원칙으로 짰다. 화려한 도구를 급하게 붙이지 않고, 구조(위키)를 먼저 세운 뒤 내 강점(RAG·검색)을 얹는다.
큰 그림 — 왜 이 순서인가 (실제 사례 근거)
공개된 개인 지식관리 구축 사례들이 공통으로 쓰는 2단 구조를 따른다:
- 위키 먼저 (1주차 말 ~ 2주차) — 벡터DB 없이 마크다운만으로.
raw/(원본, 불변) ↔wiki/(AI가 합성한 지식)로 나누고, 에이전트가 위키를 유지. - RAG 나중 (3주차) — 그 위에 “내 노트를 벡터로 바꿔 의미로 검색”하는 층을 얹는다. 여기가 내 DS 강점(임베딩·유사도·평가)이 빛나는 구간.
4주차는 새로 만들지 않고, 만든 것을 회고·발표로 정리하는 데 쓴다. 즉 만들기는 1주차 끝에 시작해서 3주차에 끝난다.
raw ↔ wiki 분리는 어제 배운 AKM의 Source(원본) vs Knowledge(합성 지식) 레이어와 같다. 배운 개념이 그대로 구축법이 된다.
1주차 — 기획 + MVP 첫 조각 (지금 여기)
- 할 일: 학습메이트 ‘하루’ 세팅(✅), 주제·로드맵 확정(✅), AKM 개념페이지 정리(✅), 사이트 GitHub·Vercel로 배포(✅), 커밋·버전관리 익히기(✅), “나만의 지식체계” 간단 기획서(PRD — 무엇을·왜·어떻게) 쓰기, 세부계획 + 위키 뼈대(
raw/+wiki/폴더 구조) 만들기 = MVP 첫 조각, 첫 주 회고. - 그 주 결과물: 인터넷에 배포된 학습허브 사이트 + 확정된 로드맵 + PRD 1장 + 위키 폴더 뼈대.
- 사례글 예시: “코딩 몰라도 나만의 학습메이트·사이트 만들기”(✅ 씀), “되돌릴 수 있는 안심 — 커밋과 버전관리”(✅ 씀), “내 지식체계의 뼈대(raw/wiki) 잡기”.
- 근거 사례: Karpathy식 LLM 위키 폴더 구조(raw/wiki/index/log), 마크다운 메모리 패턴.
2주차 — MVP 본격 제작 (위키 층)
- 할 일: 위키 운영 규칙(schema·CLAUDE.md) 정의(페이지 유형·링크 정책 = AKM의 Memory·Procedure 레이어), 내 자료 10개를 위키에 ingest(원본은
raw/에 보존 → AI가wiki/에 개념·엔티티 페이지로 합성 +[[위키링크]]연결), 넣고(ingest) → 점검하고(lint) → 질문하는 루프를 매주 굴려보기. - 그 주 결과물: 내 자료 10개가 정리된 위키(개념·엔티티 페이지 몇 개) +
schema.md+ 실제로 돌아가는 ingest·lint 루프. - 사례글 예시: “내 자료 10개를 AI로 위키 페이지로 합성해봤다 (raw → wiki)”.
- 근거 사례: itlackey
akm(schema·index·log·ingest 루프), Karpathy 위키의 “소스 10개로 시작”.
3주차 — MVP 완성·다듬기 (RAG 층)
- 할 일: RAG 검색 얹기 — 위키·노트를 잘게 나눠(청킹) → 벡터로 바꿔(임베딩, 우선 가벼운 MiniLM으로 프로토타입) → DuckDB 벡터 검색으로 “질문하면 답하는” 상태 구현. 이어서 품질 다듬기(임베딩을 bge-m3로,
[[위키링크]]그래프 가중) + 반복 작업 자동화(자료 넣기·lint점검 루프). - 그 주 결과물: 완성형 MVP — 작동하는 LLM 위키 + RAG(내 지식에 질문 → 근거와 함께 답변).
- 사례글 예시: “내 노트에 질문하면 답하는 RAG를 DuckDB로 붙였다”.
- 근거 사례: MotherDuck의 Obsidian×DuckDB RAG(DS 친화), Smart Connections(무코드 맛보기 먼저 → 원리 학습),
akmlint 자동화, 임베딩 품질 업그레이드·위키링크 그래프 가중.
4주차 — 회고·발표
- 할 일: 한 달 회고(before 흩어짐 → after 구조·검색), 발표자료, 전자책 마무리(그동안 쓴 위키 글 묶기). 새로 만들지 않고 정리하는 주.
- 그 주 결과물: 발표 + 전자책 초안 + 성장회고.
- 사례글 예시: “한 달 만에 흩어진 지식을 검색되는 체계로 — 회고”.
- 근거 사례: DS 강점(임베딩·유사도·평가)이 결과로 드러나는 지점 정리.
참고한 실제 사례 (근거)
- Karpathy식 LLM 위키 / second-brain — raw↔wiki 분리, 에이전트가 위키 유지 (초보 친화).
- Agentic Knowledge Management (S. Dubois) — 읽기전용 → 제안 → 자율 실행 권한 확대, Git 변경추적.
- akm (itlackey) — 결정론적 툴 + 합성은 에이전트, schema/index/log/lint (AKM 7레이어에 기능적 최근접).
- Obsidian × DuckDB RAG (MotherDuck) — 청킹·임베딩·벡터검색·위키링크 그래프 가중 (DS 친화, 포트폴리오화 가능).
- 자가호스팅 RAG 풀스택 / Smart Connections — 고급(Docker·로컬 LLM) / 무코드 진입점.
솔직 고지: 지피터스 AKM의 정확한 7레이어 명칭·근거 상태 5분류를 그대로 쓰는 공개 도구는 확인 못 함(원전 고유). 위 사례들이 기능적으로 같은 역할을 하므로 뼈대로 참고함.
1주차
개념 — AKM(에이전트 지식관리)란 무엇인가
이 개념페이지는 지피터스 원전 사례(AI가 매번 처음부터 다시 시작해서 만들었다: 에이전트 지식 운영체계 AKM, 글쓴이 DECK)를 읽고 거기 나온 개념만 뽑아 정리한 거예요. 실행 계획이 아니라 “개념 이해”가 목적이에요.
한눈에 — AKM이 뭐예요?
AKM = Agent Knowledge Management(에이전트 지식관리). AI 에이전트가 무엇을 읽고 · 어디에 저장하고 · 어떤 절차로 실행하고 · 결과를 어떻게 검증하고 · 실패를 어디로 되돌릴지를 정하는 **지식 운영 아키텍처(구조)**예요.
중요한 포인트 하나 — AKM은 특정 앱·플러그인·벡터 데이터베이스의 이름이 아니에요. “어떤 도구를 쓰느냐”가 아니라 **“정보를 어떤 규칙으로 다루느냐”**라는 설계 자체예요.
왜 필요했을까? (문제)
글쓴이가 겪은 문제는 “지식이 없어서”가 아니었어요. 오히려 반대 — 지식이 여러 곳에 너무 많이 흩어져 있어서 생긴 문제였죠.
- 자료는 옵시디언, 선호·프로젝트 정보는 에이전트 메모리, 작업 절차는 스킬… 제각각.
- 새 세션을 시작하면 중요한 맥락을 매번 다시 설명해야 했어요.
- 원본과 요약문이 섞이고, “내 취향”과 “일반 지식”의 경계가 흐릿했어요.
- 성공·실패를 다 저장하니 기록만 쌓이고, 실패에서 배우질 못했어요.
핵심 통찰: 문제는 **양이 아니라 “역할 구분”**이었어요.
핵심 개념 ① — 정보를 7개 레이어로 나눈다
AKM의 심장이에요. 정보를 **“어디에 두느냐”가 아니라 “무슨 역할이냐”**로 7개 층(레이어)으로 나눠요.
| 레이어 | 무슨 역할 | 한 줄 판별 기준 |
|---|---|---|
| Source | 수정 안 하는 원본 (문서·웹·녹취·코드) | 손대지 않는 날것 |
| Knowledge | 여러 원본을 정리한 재사용 지식 | 누구에게나 적용되면 여기 |
| Context | 특정 사용자·조직·프로젝트에서만 참인 맥락 | ”나/이 프로젝트만” 참이면 여기 |
| Operational Memory | 매 세션 전 꼭 알아야 할 짧은 포인터 | 먼저 알아야 하나 전문은 안 읽어도 되면 여기 |
| Procedure | 반복 작업의 순서·도구·실패지점·검증법 | 반복 단계 + 검증이 있으면 여기 |
| Action | 재현·인수인계용 실행 기록 | ”이렇게 했다”는 로그 |
| Evaluation | 실패 패턴·품질 기준·검증 결과 | 같은 실패가 또 날 수 있으면 여기 |
(+ 외부로 내보낼 결과물은 80-outputs, 안 쓰는 건 90-archive에서 관리)
왜 나눌까? 각 레이어가 서로 다른 방식으로 고장 나기 때문이에요. 긴 지식을 메모리에 넣으면 모든 세션이 무거워지고, 도메인 지식을 절차에 넣으면 이중 관리가 되고, 평가 레이어가 없으면 같은 실수를 반복해요. 그래서 나눠 저장하고, 링크와 메타데이터로 다시 연결해요.
핵심 개념 ② — 메모리는 “지식 창고”가 아니라 “작은 지도”
글쓴이의 AKM엔 문서가 약 8,591개 있어요. 그런데 매 세션 시작 때 먼저 읽는 메모리는 딱 4개예요.
처음엔 “중요한 걸 다 메모리에 넣어야 똑똑해진다”고 생각했지만 실제론 반대였대요. 긴 내용을 매번 읽는 것보다, “어디에 뭐가 있는지” 알려주는 짧은 포인터가 더 유용했어요.
- 세션 시작 = 전체 지식이 아니라 **INDEX(목차)**를 읽는다.
- 공통 메모리 포인터 4개를 읽는다.
- 지금 작업에 필요한 지식·맥락·절차만 추가로 찾는다.
- 중요한 주장은 원문을 직접 확인한다.
메모리는 지식 창고가 아니라, 탐색을 시작하는 작은 지도예요.
핵심 개념 ③ — 저장보다 “운영 루프”가 먼저
AKM은 저장 구조이기 전에 하나의 **흐름(루프)**이에요.
Ingest(인입) → Classify(분류) → Compile(지식화) → Contextualize(맥락 연결) → Execute(실행) → Verify(검증) → Learn Back(되먹임)
앞부분(모으고·나누고·연결하고·실행)은 직관적이에요. 진짜 핵심은 마지막 Learn Back이에요.
- 결과가 나오면 끝이 아니라 검증해요.
- 실패하면, 그 실패를 만든 레이어를 콕 집어 고쳐요:
- 매번 같은 실수 → 메모리에 예방 포인터 추가
- 절차대로 했는데 틀림 → Procedure의 검증 단계 수정
- 의도를 잘못 이해 → Context 수정
- 오래된 지식 사용 → Knowledge 신뢰도 낮추기 / 교체
지식만 쌓고 실행 안 하면 “위키”에 머물고, 실행만 하고 검증 안 하면 “자동화”에 머물러요. 실패를 다음 실행의 입력 품질로 되돌리는 것 — 그게 AKM의 정수예요.
핵심 개념 ④ — “검색 결과”와 “근거”는 다르다
문서가 많아지면 검색이 필요해지는데, 여기서 정한 원칙이 날카로워요: 검색에 떴다고 근거가 아니에요. 근거에 상태를 매겨요.
| 근거 상태 | 뜻 |
|---|---|
| Candidate | 검색엔 떴지만 아직 직접 안 읽음 (후보) |
| Direct Read | 그 위치를 실제로 읽음 |
| Claim Supported | 특정 주장을 실제로 뒷받침한다고 확인함 |
| Conflicted | 다른 근거와 충돌함 |
| Stale | 오래됐거나 대체됨 |
검색 점수가 높다고 최신·권위 있는 게 아니에요. 출처의 범위·권위를 먼저 보고, 최신성은 같은 조건 안에서 비교해요.
핵심 개념 ⑤ — 여러 에이전트를 “얇은 어댑터”로 연결
Claude Code, Codex처럼 에이전트마다 자기 기억 시스템이 있어요. 이걸 다 AKM으로 바꾸려 하면 오히려 복잡해져요. 그래서 각 에이전트의 기본 메모리는 그대로 두고, AKM으로 이어주는 얇은 어댑터만 붙여요.
어댑터는 딱 4가지만 답해요: ① AKM 루트는 어디? ② 세션 시작 때 뭘 읽어? ③ 새 정보는 어디에 저장(라우팅)? ④ 실패하면 어떤 Learn Back 절차?
→ 본문(진짜 지식)은 AKM에 한 번만 두고, 각 에이전트엔 찾아가는 포인터만 둬요.
배운 점 (원문 요약)
- 양보다 역할 분리가 먼저 — 더 좋은 검색보다, 원본·지식·맥락·절차·평가를 나누는 게 먼저였다.
- 에이전트 메모리는 작아야 한다 — 다 기억하려 말고, 필요한 걸 올바른 순서로 찾게.
- 실패는 저장만으론 부족 — 어느 레이어를 고칠지까지 연결해야 다음이 달라진다.
- 상세한 근거가 늘 좋은 컨텍스트는 아니다 — 근거를 다 넣었더니 모델에 가는 컨텍스트 중앙값이 887 → 10,172.5 토큰으로 폭증. 감사(검증)용 패킷과 모델에 주는 압축 패킷을 분리해야 했다.
개념 테이블 (한눈 정리)
| 단어 | 쉬운 뜻 | 어디서 나왔나 |
|---|---|---|
| AKM | 에이전트가 지식을 읽고·저장·실행·검증·되돌리는 운영 아키텍처 | 전체 |
| 레이어(Layer) | 정보를 역할별로 나눈 층 (7개) | 개념 ① |
| 포인터 | 내용 대신 “여기 있어”라고 가리키는 짧은 링크 | 개념 ② |
| 운영 루프 | Ingest → … → Learn Back 의 반복 흐름 | 개념 ③ |
| Learn Back | 실패를 원인 레이어로 되돌려 다음 실행을 고침 | 개념 ③ |
| 근거 상태 | Candidate / Direct Read / … 근거의 신뢰 단계 | 개념 ④ |
| 어댑터 | 두 시스템을 잇는 얇은 연결부 | 개념 ⑤ |
| 압축 패킷 | 검증용 근거는 따로, 모델엔 요약만 주는 것 | 배운 점 4 |
💡 주니에게 — 이게 왜 너한테 특별한가 (내 보충, 원문엔 없어요)
세 가지가 겹쳐서 이 사례가 너한테 특별해:
- 네 4주 목표가 바로 이거야. “AKM 구축 + 나만의 지식체계”가 목표였잖아. 이 글이 그 원전이자 롤모델이야.
- 우리가 지금 세션에서 이미 하고 있어. 오늘
MEMORY.md(목차) + 개별 메모리 파일들로 네 정보를 저장했지? 그게 정확히 개념 ②(작은 지도 = 인덱스 + 짧은 포인터) 구조야.SOUL.md/USER.md/AGENTS.md도 각각 역할이 다른 레이어고. 넌 이미 AKM의 축소판을 쓰고 있는 셈이야. - 네 “지식 구조화 3원칙”과 똑같아. 레이어로 나누는 건 모듈화, 표로 대칭 정렬한 건 대칭화, Ingest → Learn Back 순서는 순서화. AKM은 네 원칙을 에이전트 지식에 적용한 버전이라고 봐도 돼.
⚠️ 용어 확인 필요 (Agent vs AI)
원문은 AKM을 “Agent Knowledge Management”(에이전트 지식관리)로 정의해요. 우리가 지난번 USER.md에 적어둔 **“AI Knowledge Management(AI 기반 지식관리)“**와 첫 단어가 달라요(Agent vs AI). 뜻은 가깝지만 초점이 다르니, 어느 쪽으로 통일할지 정하면 USER.md·메모리를 맞춰 고칠게요.
개념 — 지식체계의 터를 잡을 때 나오는 말들
세부계획의 첫 단계는 knowledge/ 폴더 뼈대를 만드는 일이에요. 그런데 폴더를 만드는
명령 자체는 3초면 끝나요. 하루가 걸리는 쪽은 **“이 폴더를 왜 이렇게 나누는가”**를
정하는 일이고, 그 판단에 낯선 말 여섯 개가 끼어 있어요. 손만 움직이고 넘어가면
2주차에 논문을 열 편 넣을 때 “이걸 왜 이렇게 했지”가 되니까, 먼저 익혀요.
여섯 개를 세 묶음으로 나눠서 볼게요. 묶음마다 답하는 질문이 달라요.
| 묶음 | 답하는 질문 | 나오는 말 |
|---|---|---|
| ① 양식 | 노트 한 장에 어떤 칸이 들어가나 | 스키마 |
| ② 보존 | 원본을 어떻게 안 망가뜨리나 | 불변, 소스 레이어 · 지식 레이어 |
| ③ 기록 | Git에 무엇을 담고 무엇을 빼나 | .gitignore, 와일드카드, .gitkeep |
① 스키마 — 칸을 미리 정해두는 것
스키마는 “이 자료엔 어떤 칸이 들어간다”를 미리 정해둔 틀이에요. 서류 양식과 똑같아요. 병원 접수표에 이름·생년월일·증상 칸이 정해져 있는 것처럼요.
왜 미리 정해야 하냐면, 안 정하면 논문 열 편이 열 가지 모양이 되기 때문이에요. 첫 편은 결과를 자세히 쓰고 둘째 편은 방법만 쓰고 셋째 편은 인용을 빠뜨리면, 나중에 “방법이 비슷한 논문 찾아줘”라고 물어도 답이 안 나와요. 어떤 노트엔 방법 칸이 아예 없으니까요.
우리 논문 노트의 칸은 PRD에서 이미 일곱 개로 정했어요.
서지정보 · 연구문제 · 방법 · 데이터 · 결과 · 한계 · 원문 인용
이 중 한계가 특별해요. 논문 요약 도구 대부분이 결과만 뽑고 한계는 버려요. 그런데 “이 방법을 내가 진짜 쓸 수 있나”를 판단할 때 결정적인 건 한계예요. 칸을 정해두면 빠뜨리고 싶어도 빈칸이 눈에 보여서 빠뜨릴 수가 없어요. 규칙을 의지에 맡기지 않고 양식에 박아두는 거예요.
이미 익숙한 것과 이어보면 — 우리 사이트 글 맨 위의 frontmatter(title, date,
종류, 주차)도 스키마예요. config.ts가 “위키 글엔 이 칸이 들어간다”를
정해뒀고, 칸을 어기면 빌드가 실패해요. 이미 쓰고 있던 거예요.
② 원본을 지키는 두 폴더
불변 — 한번 넣으면 고치지 않는다
불변은 한번 넣으면 고치지 않는다는 뜻이에요. knowledge/raw/에 들어간 논문
원본은 불변으로 둬요.
왜 그러냐면, 고칠 수 있게 두면 나중에 “이게 원본이었나 내가 고친 건가”를 매번 의심해야 하기 때문이에요. 논문 인용문이 원문과 정말 같은지 확인할 방법이 사라지면, “원문에 없는 인용은 0건”이라는 우리 기준(S3)을 지킬 수가 없어요. 믿을 수 있는 바닥이 하나 있어야 그 위에 쌓은 것도 믿을 수 있어요.
소스 레이어와 지식 레이어 — 위치로 실수를 막는다
raw/와 wiki/를 굳이 두 폴더로 나누는 이유예요. 이건 1일차에 배운 AKM의
두 레이어와 같아요.
| 폴더 | 레이어 | 무엇이 들어가나 | 고쳐도 되나 |
|---|---|---|---|
knowledge/raw/ | Source (원본) | 논문 PDF, 옮긴 마크다운 | ❌ 안 됨 |
knowledge/wiki/ | Knowledge (지식) | 논문 노트, 개념 페이지 | ✅ 계속 고침 |
같은 폴더에 섞어두면 규칙을 기억에 의존해야 해요. 사람은 반드시 까먹어요. 폴더를 나눠두면 위치가 실수를 막아줘요 — “이건 raw 폴더 안이니까 손대면 안 되는 거구나”가 눈으로 보이니까요. 규칙을 머리에 두지 말고 구조에 박아두는 것, 이게 AKM이 레이어를 나누는 이유예요.
③ Git에 무엇을 담고 무엇을 뺄지
.gitignore — “이건 기록하지 마” 목록
.gitignore는 Git이 무시할 파일 목록을 적어두는 파일이에요. 여기 적힌 파일은 커밋에 안 들어가요.
논문 원본 PDF를 여기 넣으려고 해요. 이유가 둘이에요. 하나는 저작권 — 논문 PDF는 대개 출판사에 권리가 있어서, 저장소에 담아두면 나중에 공개 전환을 검토할 때 위험이 커져요. 하나는 용량 — PDF 열 편이면 금방 무거워지고, Git은 한번 담은 파일을 히스토리에서 지우기가 아주 번거로워요.
원본을 잃는 게 아니라는 점이 중요해요. 보존은 내 컴퓨터 폴더에서 하고, Git에는 옮긴 마크다운만 올려요. 어느 논문이었는지는 노트에 적힌 서지정보와 DOI로 언제든 되짚을 수 있어요.
우리 사이트에도 이미 .gitignore가 있어요. node_modules/(부품 폴더),
dist/(빌드 결과), .env(비밀 열쇠)가 들어 있죠. 전부 “다시 만들 수 있거나
남에게 보이면 안 되는 것”이에요. 논문 PDF도 같은 부류예요.
와일드카드 — “아무 글자나”를 뜻하는 기호
.gitignore에 논문 PDF를 적을 때 파일 이름을 하나하나 적지 않아요.
knowledge/raw/*.pdf라고 한 줄 쓰면 끝이에요.
여기서 *가 와일드카드예요. “아무 글자나”라는 뜻이라, *.pdf는
이름이 무엇이든 pdf 파일 전부를 가리켜요. 앞으로 넣을 논문까지 미리 덮어주니까
논문을 추가할 때마다 .gitignore를 고칠 필요가 없어요.
조심할 것 하나 — 패턴을 적어도 틀리면 조용히 안 먹어요. 에러가 안 나니까 모르고 지나가다 나중에 PDF가 커밋에 섞여 들어가요. 그래서 적은 뒤에 정말 무시되는지 Git한테 직접 물어봐야 해요. 그 확인용 명령이 따로 있어요.
.gitkeep — 빈 폴더를 붙잡아 두는 빈 파일
Git은 파일을 기록하고 폴더는 기록하지 않아요. 그래서 빈 폴더는 커밋해도 사라져요. 다음에 이 저장소를 다른 컴퓨터에 받으면 폴더가 없는 거예요.
그래서 관례적으로 .gitkeep이라는 빈 파일을 하나 넣어둬요. 파일이 하나 들어 있으면 폴더가 기록되니까요. 특별한 기능이 있는 이름이 아니고 “이 폴더를 유지하려고 넣은 파일”이라는 뜻으로 개발자들이 약속처럼 쓰는 이름이에요.
우리는 knowledge/wiki/papers/와 knowledge/wiki/concepts/가 처음엔 비어 있으니
여기에 넣어요. 논문이 들어오기 시작하면 굳이 지우지 않아도 돼요.
곁들여 — peerDependencies
터 잡기에 직접 쓰이진 않지만, 오늘 세부계획을 짜면서 이것 덕분에 하루를 아꼈으니 같이 익혀둬요.
peerDependencies는 “이 부품이 어떤 버전과 어울리는지” 제작자가 선언해둔 칸이에요.
검색창 부품(astro-pagefind)의 이 칸에 ^4가 적혀 있어서, 우리 사이트의
Astro 4를 올리지 않고 그대로 써도 된다는 걸 확인했어요.
초보가 제일 많이 하는 헛수고가 “새 기능 붙이려고 프레임워크부터 올리다 사이트를 깨는 것”이에요. 이 칸 한 줄을 보면 그걸 건너뛸 수 있어요. 부품을 붙일 때마다 “이거 내 버전에서 되나?”를 여기서 확인하는 습관을 들이면 좋아요.
개념 요약
| 단어 | 쉬운 뜻 |
|---|---|
| 스키마 | ”이 자료엔 어떤 칸이 들어간다”를 미리 정해둔 틀. 서류 양식 |
| 불변 | 한번 넣으면 고치지 않는다는 뜻 |
| 소스 레이어 | 손대지 않는 원본이 사는 층 (raw/) |
| 지식 레이어 | 원본에서 뽑아 정리한 것이 사는 층 (wiki/) |
| .gitignore | Git이 무시할 파일 목록을 적어두는 파일 |
| 와일드카드 | ”아무 글자나”를 뜻하는 기호(*). *.pdf는 모든 pdf |
| .gitkeep | 빈 폴더를 Git에 남기려고 넣는 빈 파일 |
| peerDependencies | 이 부품이 어떤 버전과 어울리는지 제작자가 선언해둔 칸 |
한 줄로 꿰면
여섯 개가 따로 있는 게 아니에요. 스키마로 칸을 정하고 → 불변 원본과 지식을 두 층으로 나눠 담고 → Git에는 되살릴 수 있는 것만 남긴다. 이 한 줄이 지식체계의 터예요. 나머지 열한 단계는 전부 이 터 위에서 일어나요.
세부계획 — 지식체계를 어떤 순서로 만드나
로드맵이 “동네 지도”, PRD가 “지을 집의 도면”이라면 이 문서는 공정표다.
PRD에서 정한 요구사항(R1R7)과 성공 기준(S1S5)을 어떤 순서로, 하루에 하나씩
만들어갈지만 여기서 정한다. 무엇을·왜는 다시 정하지 않는다.
짜기 전에 다시 조사한 이유
계획을 AI의 기억으로 짜면 학습 시점에 굳은 옛 방식이 나온다. 그러면 초보가 괜히 어려운 길로 간다. 그래서 순서를 짜기 전에 “지금 제일 적은 노력으로 되는 방법”을 먼저 확인했다. 결과로 PRD보다 쉬운 길이 세 군데 나왔다.
① PDF 변환 도구를 지금 깔지 않는다
PRD는 Marker·MinerU·Docling 중 하나를 2주차에 실측해 고르기로 했다. 그런데 세 도구 모두 파이썬 환경 구성과 모델 내려받기가 먼저라, 도구를 쓸 수 있게 만드는 데만 하루가 넘는다.
논문 10편 규모에서는 그 값을 못 한다. 학습메이트가 PDF를 직접 읽어 마크다운으로
옮기면 설치 없이 같은 결과가 나온다. 변환 도구는 손이 아파질 때 — 논문이 30편을
넘거나 표·수식이 자주 깨질 때 — 붙인다. 그때 Marker가 첫 후보다. 파이썬 도구
중 CPU에서 가장 가볍고, pip install marker-pdf 한 줄이며 OCR을 끈 모드가
CPU만으로 돈다.
이 판단은 미루기가 아니라 순서 바꾸기다. 도구는 문제가 생긴 뒤에 붙이면 되고, 문제가 안 생기면 안 붙여도 된다.
② 검색창 설치는 명령 한 줄이고, Astro를 올릴 필요가 없다
astro-pagefind 최신 버전(2.0.1)이 pagefind와 @pagefind/component-ui를
이미 품고 있어 npm i astro-pagefind 하나면 끝난다. 인터넷 글 대부분이 둘을 따로
설치하라고 하지만 그건 옛 버전 기준이다.
더 중요한 것은 이 패키지가 어울리는 Astro 버전을 ^2 || ^3 || ^4 || ^5 || ^6 || ^7로
선언해 두었다는 점이다. 지금 사이트의 Astro 4.16을 올리지 않아도 된다. 새 기능을
붙이려다 프레임워크부터 올려 사이트를 깨는 것이 초보가 가장 많이 하는 헛수고인데,
이 한 줄 확인으로 건너뛴다. 빌드 뒤 색인도 통합이 알아서 해서 별도 스크립트가 없다.
③ 지식베이스는 사이트 콘텐츠 폴더 밖에 둔다
src/content/ 안은 config.ts가 정한 네 종류(위키·프로젝트·저널·랜딩)만 받는다.
그 파일은 손대지 않기로 했으므로, 논문 PDF와 논문 노트를 그 안에 넣으면 규칙과 부딪친다.
프로젝트 맨 위에 knowledge/를 따로 둔다. 사이트 빌드와 완전히 분리되고,
“논문 노트를 사이트에 띄울지”를 나중에 결정할 여지가 남는다. 띄우기로 정하면
그때 사이트 폴더로 옮기면 되고, 안 띄우기로 정하면 그대로 둔다.
knowledge/
raw/ 논문 원본 PDF + 옮긴 마크다운 (한번 넣으면 고치지 않는다)
wiki/
papers/ 논문 노트 (논문 1편 = 1장)
concepts/ 개념 페이지 (여러 논문에서 뽑혀 합쳐진다)
SCHEMA.md 위 폴더의 규칙 — 어떤 항목이 들어가고 어떻게 잇는지
순서를 이렇게 잡은 이유 네 가지
검색창을 논문보다 먼저 붙인다. 검색창이 이미 돌고 있으면 논문 노트를 넣는 순간 자동으로 잡힌다. 반대로 논문을 다 넣은 뒤에 붙이면, 안 잡힐 때 원인이 논문 쪽인지 검색 쪽인지 갈라 봐야 한다. 고장 원인을 하나씩만 남기는 순서가 초보에게 훨씬 싸다.
1편을 10편보다 먼저 끝까지 통과시킨다. 논문 노트 양식이 틀린 채로 10편을 넣으면 10편을 다 고쳐야 한다. 1편으로 처음부터 끝까지 한 번 통과시켜 양식을 굳힌 뒤 늘린다.
개념 페이지는 주제가 갈린 4편이 모인 뒤에 뽑는다. 1편으로는 이을 것이 없다. 소재·바이오·AI가 섞인 3~4편이 모여야 PRD의 S2(서로 다른 주제의 논문을 잇는 개념)가 실제로 시험된다.
채점하는 자를 벡터보다 먼저 만든다. 벡터를 붙인 뒤에 평가 질문을 만들면, 자를 벡터에 유리하게 만들 위험이 있다. 질문 10개와 채점 방식을 먼저 확정하고 점수를 기록해 둔 다음 벡터를 얹는다. 결과를 부풀리지 않는다는 원칙이 여기서 순서로 나타난다.
12단계 공정표
각 단계는 하루 안에 될 크기다. 됐다는 기준을 눈으로 확인할 수 있게 적었다.
1주차 남은 것
| # | 무엇을 | 채우는 요구사항 | 됐다는 기준 |
|---|---|---|---|
| 1 | knowledge/ 폴더 뼈대와 SCHEMA.md 규칙 1장 만들기 | R1 착수 | 폴더가 생기고, 논문 노트에 어떤 항목이 들어가는지 규칙으로 적혀 있다 |
2주차 — 위키 층
| # | 무엇을 | 채우는 요구사항 | 됐다는 기준 |
|---|---|---|---|
| 2 ✅ | 논문 1편을 PDF부터 논문 노트까지 끝까지 통과시켜 양식 굳히기 | R2 | 논문 노트 1장에 서지정보·연구문제·방법·데이터·결과·한계·원문 인용이 다 있다 |
| 3 ✅ | 사이트 검색창 붙이기 (npm i astro-pagefind) + 미룬 결정 2건 확정 | R6 | 검색창에 단어를 넣으면 기존 위키 글이 목록으로 뜬다 |
| 4 ✅ | 논문 넣기를 /논문넣기 같은 정해진 명령으로 고정하고, 논문 3편 더 넣기 (총 4편) | R7, S1 진행 | 같은 명령으로 3편이 같은 양식으로 들어간다 |
| 5 ✅ | 논문 노트에서 개념 뽑아 개념 페이지 만들고 [[위키링크]]로 잇기 | R3, R4 | 개념 페이지가 생기고, 그중 하나가 주제 다른 논문 2편에 걸린다 |
| 6 ✅ | 논문 6편 더 넣기 (총 10편) | S1 | knowledge/raw/에 10편, 논문 노트 10장 |
| 7 ✅ | 점검 명령 만들기 — 끊긴 링크·빈 항목·원문에 없는 인용 잡아내기 | R7 | 명령 한 번에 문제 목록이 나온다 |
| 8 ✅ | 질문 명령 만들기 — 답 + 출처 논문 + 원문 인용을 함께 돌려주기 | R5 | 질문 하나에 세 가지가 다 나온다 |
3주차 — 검색 층과 비교
| # | 무엇을 | 채우는 요구사항 | 됐다는 기준 |
|---|---|---|---|
| 9 ✅ | 평가 질문 10개와 채점 방식 확정, 가벼운 검색으로 먼저 채점 | S3 기준선 | 10문항 점수와 “원문에 없는 인용” 건수가 기록돼 있다 |
| 10 ✅ | 벡터 검색 얹기 | R8 착수 | 같은 질문이 벡터 쪽으로도 답된다 |
| 11 ✅ | 같은 10문항으로 가벼운 검색 대 벡터 비교·측정 | R8 | 두 점수가 표로 나란히 있고, 어느 쪽이 왜 나은지 적혀 있다 |
| 12 ✅ | 논문 1편 넣는 과정 다듬어 손 가는 시간 줄이기 | S5 | /논문넣기 스킬에 21편 넣으며 겪은 사고 4건을 반영. 병렬 위임 방식(raw+노트를 한 에이전트가 같이 맡기)이 “손 가는 시간”(대기 아닌 실제 조작 시간)을 10분 내로 줄임 — 단, 전문 옮기기 자체(요약 금지)는 시간이 걸려 총 소요시간은 논문 분량에 비례 |
4주차
새로 만들지 않는다. 회고·발표자료·전자책 정리만 한다.
미리 짚어두는 것 둘
논문 원본 PDF는 저장소에 올리지 않는다. knowledge/raw/*.pdf를 .gitignore에
넣고 옮긴 마크다운만 커밋한다. 논문 PDF는 대개 출판사 저작권이 있어 저장소에 담아두면
나중에 공개 전환을 검토할 때 위험이 커지고, 용량도 는다. 원본 보존(R1)은 내 컴퓨터
폴더로 지키고, 어느 논문인지는 노트에 적힌 서지정보와 DOI로 되짚는다.
단계 3의 결정 2건, 2026-08-05에 확정했다.
① 논문 노트를 사이트에 띄운다. R5·R6(사이트 검색창에서 질문하면 답+출처+
인용이 같이 나오는 것)이 논문 노트가 사이트 밖에 있으면 애초에 성립하지 않는다.
그래서 knowledge/wiki/papers/에 있던 논문 노트를 src/content/papers/로 옮기고
전용 페이지(/papers)와 헤더 메뉴까지 연결했다. 원본 PDF와 raw 마크다운은
그대로 knowledge/raw/(사이트 빌드 밖)에 남는다 — 옮긴 건 정제된 노트뿐이다.
② 논문 10편의 주제 배분은 소재 4·바이오 3·AI 3으로 확정한다. 지향점 3갈래(데이터 사이언티스트·소재 AI 개발자·바이오헬스케어 AI 개발자)와 이미 맞물려 있고, 오늘 넣은 BNNT 논문이 소재 1편으로 바로 카운트된다. S2(서로 다른 주제 논문을 잇는 개념 페이지) 검증에도 세 갈래가 고루 섞여야 유리하다.
PRD 요구사항이 어디서 채워지나
빠뜨린 것이 없는지 거꾸로 확인한다.
| 요구사항 | 채우는 단계 |
|---|---|
| R1 원본 보존 | 1, 2 |
| R2 논문 노트 | 2 |
| R3 개념 페이지 | 5 |
| R4 위키링크 연결 | 5 |
| R5 답 + 출처 + 인용 | 8 |
| R6 사이트 검색창 | 3 |
| R7 정해진 명령 | 4, 7, 8 |
| R8 벡터 비교 (3주차) | 9, 10, 11 |
| R9 그래프 (범위 밖) | 안 함 |
성공 기준은 S1이 단계 6, S2가 단계 5, S3이 단계 9와 11, S4가 단계 3, S5가 단계 12에서 확인된다. 빠진 칸이 없다.
참고한 근거
- astro-pagefind 2.0.1 — 의존성에
pagefind·@pagefind/component-ui포함, 어울리는 Astro 버전^2 || ^3 || ^4 || ^5 || ^6 || ^7. npm 등록 정보 · 저장소 - Pagefind — 정적 사이트 전문검색. 1.5.0부터 UI를 컴포넌트로 제공. 공식 문서
- PDF 변환 도구 비교 (2026) — Marker가 CPU에서 가장 가볍고 설치가 단순. MinerU는 GPU 권장, Docling은 기업용 RAG 지향. 비교 1 · 비교 2 · Marker v2 벤치마크
- Astro 위키링크 — 기본 기능이 아니고 remark 플러그인으로 붙인다. 논문 노트를 사이트에 띄우기로 정할 때만 필요하다. remark-wiki-link · Astro 적용 사례
- 앞선 조사(Karpathy LLM 위키 패턴, 「Keyword search is all you need」)는 PRD의 근거 목록에 있다.
내 프로젝트 PRD — 검색되는 나만의 지식체계
로드맵이 “동네 지도”라면 이 문서는 “지을 집의 도면”이다. 로드맵에서 이미 정한 무엇을·왜·누구를 위해는 그대로 가져오고, 거기에 없던 **“그래서 뭐가 어떻게 생겼는지”**만 여기서 정한다.
한 줄 정의
다양한 주제의 공학 논문을 원본 그대로 보존하고, AI가 그 위에 개념 지식을 합성해, 질문하면 원문 인용과 함께 답하는 나만의 위키.
로드맵에서 그대로 가져오는 것 (다시 정하지 않음)
| 항목 | 확정 내용 |
|---|---|
| 무엇 | 검색되는 나만의 지식체계 — LLM 위키 + 검색 |
| 왜 | 지식이 매번 흩어진다. 도구를 빨리 쓰는 사람이 아니라 개념부터 탄탄한 지식관리자가 되려고 |
| 누구 | 나 자신이 첫 사용자. 다음이 포트폴리오를 보는 사람 |
| 구조 | raw/(원본, 불변) ↔ wiki/(AI가 합성한 지식) — AKM의 Source 레이어 vs Knowledge 레이어 |
| 운영 | 넣고(ingest) → 점검하고(lint) → 질문하는(query) 루프 |
무엇을 넣나 — 자료
다양한 주제의 공학 논문 10편으로 시작한다. 소재·바이오·AI를 일부러 섞는다.
한 주제만 모으면 논문 10편이 다 비슷해서 연결할 것이 없다. 주제가 갈려야 “이 소재 논문의 측정 기법이 저 바이오 논문에도 쓰이네” 같은 교차 연결이 생기고, 그 연결이 위키를 단순 요약 폴더와 갈라놓는다. 지향점 세 갈래(데이터 사이언스·소재 AI· 바이오 헬스케어 AI)를 하나로 좁히지 않는 것과도 맞다.
무엇이 되어야 하나 — 요구사항
MVP에 반드시 들어가는 것:
| 번호 | 요구사항 |
|---|---|
| R1 | raw/에 논문 원본 PDF와 변환된 마크다운을 함께 보존한다. 원본은 절대 수정하지 않는다 |
| R2 | 논문 1편을 넣으면 논문 노트 1장이 생긴다. 서지정보·연구문제·방법·데이터·결과·한계·원문 인용이 들어간다 |
| R3 | 논문 노트에서 개념이 뽑혀 개념 페이지로 새로 생기거나, 이미 있는 개념 페이지에 합쳐진다 |
| R4 | 개념 페이지와 논문 노트가 [[위키링크]]로 서로 연결된다 |
| R5 | 질문하면 답 + 출처 논문 + 원문 인용문이 함께 나온다 |
| R6 | 사이트에 검색창이 있어 단어로 위키 전체를 찾을 수 있다 |
| R7 | 넣기·점검·질문이 정해진 이름의 명령으로 실행된다 (매번 다르게 부탁하지 않는다) |
3주차 이후로 미루는 것:
| 번호 | 요구사항 |
|---|---|
| R8 | 벡터 검색을 얹고, 가벼운 검색(grep·BM25) 대비 품질을 측정해서 비교한다 |
| R9 | 개념 사이의 관계를 그래프로 본다 |
한계(limitations)를 R2에 못박은 이유: 논문 요약 도구 대부분이 결과만 뽑고 한계는 버린다.
그런데 “이 방법을 내가 진짜 쓸 수 있나”를 판단할 때 결정적인 것은 한계다.
결과를 부풀리지 않는다는 원칙을 문서 구조로 못박아 둔다.
화면에 뭐가 보여야 하나
질문하는 자리를 둘 만든다. 하나는 이미 되고, 하나는 새로 붙인다.
① 대화로 묻기 (이미 동작함) — 학습메이트에게 그냥 물어본다. 위키 파일을 읽고 답 + 원문 인용을 돌려준다. 화면이 따로 없다. 추가로 만들 것이 없다.
② 사이트 검색창 (새로 붙임) — 위키 페이지 상단에 입력창 하나. 단어를 넣으면 제목 + 본문 일부 + 일치한 단어 강조가 목록으로 뜬다. 클릭하면 그 글로 이동한다. 백엔드도 API 키도 없다.
두 자리의 역할이 다르다. 검색창은 “어디에 있었지” 를 찾고, 대화는 “그래서 뭐야” 에 답한다. 검색창이 답을 만들어주지는 않는다.
어떻게 만드나 — 2026년 기준으로 다시 조사한 결과
벡터DB는 이제 필수가 아니다
2026년 4월 Karpathy가 공개한 LLM 위키 패턴은 임베딩·벡터DB 없이 마크다운 + grep + frontmatter만으로 개인 지식베이스를 돌린다. 노트 500~1,000편 (약 10만 토큰) 이하면 AI가 목차를 통째로 들고 직접 추론하기 때문이다. AAAI 2026 논문 「Keyword search is all you need」는 같은 조건에서 벡터DB 없이 키워드 검색 + 에이전트 루프만으로 기존 RAG 성능의 90% 이상을 냈다. Claude Code 자체도 초기의 로컬 벡터DB RAG를 걷어내고 이 방식으로 옮겼다.
논문 10편은 이 한계에 한참 못 미친다. 그래서 2주차는 가벼운 검색으로 만들고, 3주차에 벡터를 얹어 둘을 비교한다. “무거운 것을 썼다”보다 “무거운 것이 진짜 필요한지 측정해서 확인했다” 가 더 정직하고, 검증의 엄밀성이라는 원칙에도 맞다.
논문 PDF를 마크다운으로 뽑는 도구 — 2주차에 실측해서 고른다
| 도구 | 강점 |
|---|---|
| Marker | 정확도·속도 둘 다 상위. MinerU보다 약 5배 빠름 |
| MinerU | 다단 편집·LaTeX 수식·밀집 표에 특히 강함 |
| Docling (IBM) | 복잡한 표, 구조화 출력 |
세 도구 모두 문서 개요(다단 제목·섹션 순서) 인식이 부정확해서 손보정이 필요하다는 같은 한계를 갖는다. 논문마다 편집이 달라 미리 하나로 정하면 틀린다. 실제 논문 2~3편으로 붙여보고 2주차에 결정한다.
사이트 검색창
Pagefind. 정적 사이트용 전문검색으로, 빌드할 때 인덱스를 만들어 사이트와 함께 배포하고 검색은 브라우저에서 돈다. 서버가 없고 무료이며, 인덱스는 큰 사이트도 100KB 미만이다. 설치는 개발 의존성 하나와 빌드 명령 한 줄.
4주에 어떻게 나누나
| 주차 | 하는 일 | 그 주 끝의 상태 |
|---|---|---|
| 1주차 (지금) | 로드맵 점검(✅), 이 PRD(✅), 세부계획, raw/+wiki/ 폴더 뼈대 | 폴더 구조가 서고, 논문 1편이 끝까지 통과 |
| 2주차 | PDF 변환 도구 실측·결정, 논문 10편 넣기, 개념 페이지 합성, 가벼운 검색, 검색창 | 논문 10편이 정리된 위키 + 검색창 |
| 3주차 | 벡터 검색 얹고 가벼운 검색과 품질 비교·평가, 넣는 과정 자동화 | 완성형 MVP + 비교 결과 |
| 4주차 | 회고, 발표자료, 전자책 마무리 | 새로 만들지 않고 정리 |
뭐가 되면 “됐다”인가 — 성공 기준
숫자로 확인할 수 있게 잡는다.
| 기준 | |
|---|---|
| S1 | 논문 10편이 raw/에 보존되고, 각각 논문 노트가 있다 |
| S2 | 개념 페이지가 5개 이상, 그중 2개 이상이 서로 다른 주제의 논문 2편 이상에 연결된다 |
| S3 | 미리 만든 질문 10개 중 8개 이상이 정확한 출처·인용과 함께 답된다. 원문에 없는 인용은 0건 |
| S4 | 사이트 검색창에서 단어를 넣으면 관련 글이 나온다 |
| S5 | 새 논문 1편을 넣는 데 내 손이 가는 시간이 10분 이내 |
S2가 이 프로젝트의 진짜 시험대다. 교차 연결이 하나도 안 생기면 위키가 아니라 요약 폴더를 만든 것이다. S3의 “원문에 없는 인용 0건”은 타협하지 않는다. 이 값이 3주차에 벡터와 가벼운 검색을 비교할 때 평가 지표가 된다.
안 하는 것 (범위 밖)
4주 안에 끝내기 위해 의도적으로 뺀다.
- 논문 자동 수집·크롤링 — 논문은 내가 골라 넣는다
- 여러 사람이 같이 쓰기, 실시간 동기화
- 지식 그래프 시각화 (R9로 미룸)
- 학습일지·사례글을 이 위키에 섞기 — 학습 기록과 논문 지식은 끝까지 분리한다
2주차 시작 전에 정할 것
논문 노트를 사이트에 띄울지 정해야 한다. 저장소는 비공개지만 배포된 사이트 주소는 누구나 열 수 있다. 논문 요약과 원문 인용이 그대로 올라가면 공개되는 것이다. 검색창(R6)이 인덱싱하는 대상은 배포된 페이지라서, 이 결정이 검색 범위를 함께 정한다.
선택지는 둘이다. ① 논문 노트를 공개: false로 두고 검색창은 학습위키만 덮는다.
② 배포 접근 보호를 걸고 논문 노트까지 검색 범위에 넣는다.
같이 정할 것: 논문 10편을 어느 주제로 몇 편씩 나눌지 (예: 소재 4 · 바이오 3 · AI 3).
참고한 근거
- LLM 위키 패턴 (Karpathy, 2026-04) — 마크다운 + grep으로 벡터DB 대체. 정리 글 · 판단 기준
- 「Keyword search is all you need」 (AAAI 2026) — 벡터DB 없이 RAG 성능 90%+. 논문
- llm-wiki-plugin — 같은 패턴의 구현체.
raw/+wiki/{sources,concepts,entities,synthesis}구조, BM25 + 벡터 + RRF 융합 (벡터를 끄는--no-embed옵션 있음). 3주차 비교의 참고 구현. 저장소 - 연구 위키 표준 스키마 — source note(요약·핵심 주장·인용·연결) + concept page 구분, 논문에서 뽑는 항목: 연구문제·방법·데이터셋·평가지표·결과·한계·향후과제. 위키 방식 연구 관리 · 논문 지식그래프 구축
- PDF 변환 도구 비교 (2026) — Marker / MinerU / Docling. 비교 1 · 비교 2 · Marker 저장소
- Pagefind — 정적 사이트 전문검색. Astro 적용 안내 · Starlight 문서
AI를 내 전용 학습메이트로 만드는 법 — 지침 파일 4개 이야기
코딩을 잘 모르는 제가 AI랑 매일 작업하면서 제일 번거로웠던 건, 새 대화를 켤 때마다 “저는 이런 사람이고, 설명은 쉽게 해주세요”를 처음부터 다시 말해야 하는 거였어요. 오늘 그걸 없앴어요. AI한테 저에 대한 설명서 4개를 만들어줬거든요.
코딩을 몰라도 AI를 “내 상황을 이미 아는 전용 도우미”로 만들고 싶은 분께 도움이 될 거예요.
왜 했나 (Before)
AI는 대화가 바뀌면 이전 대화를 기억하지 못해요. 그래서 매번 저를 소개하고, 어떤 톤으로 도와달라고 부탁하고, 제 목표를 다시 설명했어요. 짧게는 되지만 매일 반복하면 은근히 지쳐요. “이걸 한 번만 적어두고 AI가 알아서 읽게 할 수 없을까?”가 시작이었어요.
만든 것 — 파일 4개
역할을 넷으로 나눴어요.
| 파일 | 역할 | 쉽게 말하면 |
|---|---|---|
SOUL.md | 성격 | AI의 이름·말투·행동 원칙 |
USER.md | 나 | 내가 누구고 뭘 배우는지 |
AGENTS.md | 규칙 | 작업 방식·매일 하는 루틴 |
CLAUDE.md | 입구 | ”대화 전에 위 3개 먼저 읽어” |
핵심은 CLAUDE.md가 “입구” 라는 점이에요. AI는 폴더에서 대화를 켜면 이 파일을 자동으로 먼저 읽어요. 거기에 “나머지 3개도 읽고 그대로 행동해”라고 적어두면, 파일 하나가 나머지를 줄줄이 불러와요. 그래서 매번 설명하던 걸 파일이 대신하게 되죠.
어떻게 시켰나 (따라 하기)
제가 파일을 직접 쓴 게 아니라, AI한테 저를 인터뷰하게 했어요. 제가 짜내는 대신 AI가 물어보고 저는 답만 하면 되게요. 시킨 프롬프트는 이런 뼈대였어요. 그대로 복사해서 [B]만 자기 상황으로 바꾸면 됩니다.
학습메이트를 만들 거야. 파일 4개(SOUL·USER·AGENTS·CLAUDE.md)로.
진행 방법: 먼저 [A]만 하나씩 인터뷰해줘. [B]는 나한테 묻지 말고 그대로 반영해.
[A. 나한테 물어볼 것]
1. 네 이름 — 후보 몇 개 제안하고 내가 고르게
2. 말투 — 나를 어떻게 부르고 어떤 톤으로 도울지
3. 나에 대해 — 내가 누구고, 뭘 배우고 싶은지
[B. 그냥 넣을 규칙]
- (여기에 "어려운 말은 바로 쉽게 풀어줘" 같은 내 원칙들을 적어둠)
다 되면 파일 4개를 만들어서 보여줘.
이렇게 하니 AI가 이름 후보를 제안했고(저는 “하루”로 골랐어요), 말투를 정하고, 저에 대해 물어봐서 알아서 채웠어요. 5분 정도밖에 안 걸렸어요.
솔직한 삽질 하나
파일 만드는 것 자체는 안 막혔어요. 대신 웃긴 일이 있었는데, AI가 기억하던 제 정보가 옛날 버전이더라고요(“아직 전환 준비 중”으로 알고 있었어요). 그래서 제 포트폴리오 사이트 주소를 주고 “이거 읽고 업데이트해줘”라고 했더니 최신으로 싹 고쳤어요.
여기서 배운 게 있어요. AI의 기억은 낡을 수 있으니, 진짜 기준이 되는 출처(내 사이트 같은 것)를 직접 줘야 한다. 그냥 “내 정보 알지?” 하고 믿으면 안 되고요.
뭐가 바뀌었나 (After)
이제 이 폴더에서 대화를 켜면 AI가 알아서 “하루”로 인사하고, 제 상황을 이미 알고 시작해요. 소개하는 시간이 사라졌어요. 작은 변화 같지만 매일 쌓이면 꽤 커요.
가져가세요 (재사용 자산)
- 개념 한 줄 — 이런 걸 컨텍스트 엔지니어링이라고 해요. 매번 말로 설명하는 대신, 환경(파일)이 대신 설명하게 만드는 것.
- 재사용 프롬프트 — 위의 인터뷰 프롬프트를 복사해서
[B]만 여러분 상황으로 바꾸면, 여러분만의 학습메이트가 생겨요.
📸 스크린샷 자리: “AI가 이름 후보를 제안하는 대화 화면”을 여기에 넣으면 따라 하기 훨씬 쉬워요.
막연한 계획 대신, 실제 사례로 근거를 붙인 4주 로드맵 짜기
4주 계획을 세워야 하는데, AI한테 그냥 “로드맵 짜줘” 하면 그럴듯하지만 속 빈 계획이 나올 것 같았어요. 그래서 조건을 하나 걸었습니다. “막연히 짜지 말고, 내 방향에 맞는 실제 사례를 먼저 찾아서 거기에 근거해 짜줘.” 결과가 확실히 달랐어요.
4주(또는 그 이상)짜리 학습·프로젝트 계획을 세우는데 “이게 현실적인 계획일까?” 막막한 분께 도움이 될 거예요.
왜 했나 (Before)
제 목표는 “나만의 지식체계”를 만드는 거였는데, 방향은 어렴풋했어요. 이 상태에서 계획을 짜면 보통 두 가지가 나옵니다. 남들 다 하는 뻔한 계획이거나, 그럴듯하지만 중간에 무너지는 뜬구름 계획이거나. 저는 둘 다 싫었어요.
핵심 한 수 — “리서치 먼저, 계획 나중”
그냥 짜달라고 하지 않고, AI에게 먼저 실제 구축 사례를 조사시켰습니다. 제가 쓴 지시는 이런 뼈대였어요. 대괄호 [ ]만 자기 상황으로 바꾸면 그대로 쓸 수 있어요.
[내가 만들려는 것]에 맞는 실제 구축 사례·방법을 리서치해줘. 결과는 정제된 요약으로.
- 맥락: 나는 [내 상황·수준]. 목표는 [만들려는 것]을 [기간] 안에 만드는 것.
- 찾을 것: 실제 사례 4~6개. 각각 (1) 출처 URL (2) 무엇인지 (3) 구체적 단계·구조
(4) 쓰는 도구 (5) 내 기간(주차)에 어떻게 매핑되는지.
- 난이도: 최소 1개는 초보용, 최소 1개는 조금 고급.
- ★ 확인 못 한 건 지어내지 말고 "확인 못 함"이라고 표시. URL은 실제 접근한 것만.
- 마지막에 "내 계획에 쓸 핵심 시사점 3~5개"로 마무리.
AI가 찾아온 것
실제 사례 6개가 왔어요. 그런데 흥미로운 건, 하나같이 같은 패턴을 쓰고 있었다는 거예요. “위키 먼저(12주) → 검색 기능 나중(34주)”, 그리고 원본과 AI가 정리한 지식을 폴더로 나누기(raw ↔ wiki). 제 상상만으로는 못 떠올렸을 구조였어요. 계획을 여기에 그대로 얹었습니다.
솔직한 포인트 — AI 리서치도 다 믿지 않았어요
결과를 받자마자 계획에 붙이지 않았어요. 지시에 “확인 못 한 건 솔직히 표시해”를 넣었더니, 실제로 **“이 페이지는 접근 실패”, “이 명칭은 확인 못 함”**이라고 구분해서 왔어요. 덕분에 어디까지가 근거고 어디부터가 추측인지 나눌 수 있었죠. 이번에 제일 크게 배운 게 이거예요. AI 리서치는 편하지만, “확인한 것”과 “못 한 것”을 구분하게 시켜야 믿고 쓸 수 있다.
뭐가 바뀌었나 (After)
막연하던 계획이, 검증된 길 위에 얹은 단단한 로드맵이 됐어요. “3주차에 뭐 하지?”를 안 헤매게 됐고, 무엇보다 방향이 확실해졌습니다.
가져가세요 (재사용 자산)
- 위의 리서치 지시 프롬프트 — 계획 세울 때 그대로 복사해서 쓰세요.
- 배운 원칙 두 개: ① 계획은 상상이 아니라 ‘이미 성공한 실제 사례’에서 출발한다. ② AI에게 리서치를 시킬 땐 “확인 못 한 것”을 구분하게 시켜라.
📸 스크린샷 자리: “AI가 찾아온 사례 목록” 화면을 여기에 넣으면 따라 하기 좋아요.
학습 사이트를 처음 배포하며 겪은 두 가지 막힘 — 프라이버시와 GitHub 권한
로컬에서만 띄워보던 학습 사이트를 처음으로 인터넷에 올려봤어요. git init부터 실제 주소가 뜨기까지 순탄하게 갈 줄 알았는데, 중간에 두 번 막혔어요. 하나는 제가 직접 발견한 거였고, 하나는 에러 메시지로 알려준 거였어요. 둘 다 배포 직전에 잡아서 다행이었어요.
비공개로 남기고 싶은 폴더가 있는 프로젝트를, private 저장소로 처음 배포하는 분이라면 똑같은 곳에서 막힐 수 있어요.
왜 했나 (Before)
제 학습 사이트엔 journal/이라는 폴더가 있어요. 매일 쓰는 학습일지인데, 사이트 설정상 화면엔 안 뜨게 되어 있어요. 그래서 저는 “이 폴더는 비공개니까 안전하다”고 막연히 생각하고 있었어요. 배포는 그냥 git init → GitHub 저장소 만들기 → Vercel 연결, 이 세 단계면 끝날 줄 알았어요.
첫 번째 막힘 — “사이트에 안 보임”과 “저장소에 안 올라감”은 다른 얘기였다
배포 전에 뭐가 저장소에 올라가는지 .gitignore를 열어봤어요.
# build
dist/
.astro/
# deps
node_modules/
# env
.env
.env.production
# macOS / editor
.DS_Store
*.log
journal/이 어디에도 없더라고요. 사이트가 그 폴더를 페이지로 안 보여주는 것과, GitHub에 그 폴더가 올라가는 것은 완전히 다른 문제였어요. 저장소를 public으로 만들었으면, 화면엔 안 보여도 저장소 파일 목록에서는 누구나 학습일지 원문을 그대로 읽을 수 있었을 거예요.
여기서 두 가지 방법 중 골라야 했어요. journal/을 .gitignore에 추가해서 아예 안 올리거나, 저장소 자체를 private으로 만들어 전부 비공개로 두는 것. 저는 학습일지를 나중에 원본 그대로 백업해두고 싶어서 후자를 골랐어요.
gh repo create learning-hub --private --source=. --remote=origin --push
두 번째 막힘 — Vercel이 저장소를 못 물어왔다
이어서 Vercel에 연결하는데 이런 에러가 떴어요.
Error: Failed to connect 내계정/learning-hub to project.
Make sure there aren't any typos and that you have access to
the repository if it's private.
저장소 이름은 분명 맞는데 “접근 권한이 있는지 확인해라”라니, 처음엔 뭘 봐야 할지 몰랐어요. 알고 보니 이유는 명확했어요. Vercel은 GitHub에 “앱”으로 등록되어 동작하는데, 이 앱이 어떤 저장소를 볼 수 있는지는 저장소마다 따로 관리돼요. 방금 첫 번째 막힘에서 private을 선택한 대가로, 이번엔 이 앱한테 “이 저장소 봐도 돼”라고 따로 허락해줘야 하는 단계가 하나 더 생긴 거였어요. public 저장소였다면 이 단계 자체가 없었을 거예요.
해결은 이랬어요.
github.com/settings/installations로 들어가요.- 설치된 앱 목록에서 Vercel을 찾아 Configure를 눌러요.
- Repository access에서 방금 만든 저장소를 추가하거나(또는 “All repositories”로 바꾸거나) 저장해요.
권한을 열어준 다음 다시 시도하니 바로 됐어요.
vercel git connect --yes
# > Connected
vercel --prod --yes
뭐가 바뀌었나 (After)
몇 초 뒤 실제 주소가 나왔고, 접속해보니 사이트가 그대로 떠 있었어요. 학습일지 경로로 들어가 봐도 여전히 404(페이지 없음)로 잘 막혀 있는 것도 확인했어요. 이제 main에 push할 때마다 Vercel이 알아서 다시 빌드하고 배포해줘요. 배포 명령어를 매번 손으로 칠 필요가 없어졌어요.
가져가세요 (재사용 자산)
- 체크리스트: 뭔가를 배포하기 전엔 “화면에 안 보이는 것”과 “저장소에 안 올라가는 것”을 따로 확인하세요.
.gitignore파일을 직접 열어서, 비공개로 남기고 싶은 폴더 이름이 실제로 적혀 있는지 눈으로 봐야 해요. - 패턴 인식: 배포 서비스 연결 중에 “Failed to connect … access to the repository if it’s private” 비슷한 에러를 보면, 열 곳은 코드가 아니라
github.com/settings/installations예요. private 저장소 + 외부 배포 서비스 조합에서는 “저장소를 만드는 것”과 “그 앱한테 저장소를 볼 권한을 주는 것”이 별개의 단계라는 걸 기억하면 돼요.
📸 스크린샷 자리: “github.com/settings/installations에서 Vercel Configure 화면”을 여기에 넣으면 따라 하기 훨씬 쉬워요.
배포하고 나니 손을 못 대겠더라고요 — 일부러 망가뜨려보고 되돌린 이야기
며칠 전에 학습 사이트를 처음 인터넷에 올렸어요. 그런데 그 다음부터 오히려 사이트에 손을 대기가 어려웠어요. 소개글 한 줄 고치려다가도 “이거 잘못 건드려서 화면이 깨지면 어쩌지” 싶어서 멈췄어요. 그래서 오늘은 반대로 갔어요. 일부러 망가뜨려보고, 되돌아오는지 눈으로 확인했어요.
배포는 했는데 이제 뭘 고치기가 무서운 분, 되돌리는 법을 몰라서 조심조심 건드리고 있는 분이라면 도움이 될 거예요.
왜 했나 (Before)
배포 전에는 마음이 편했어요. 제 컴퓨터에서만 뜨는 사이트였으니 뭘 해도 저만 봤거든요. 그런데 진짜 주소가 생긴 다음부터는 달랐어요. 고치면 그게 바로 인터넷에 반영되니까, 실수하면 남이 보는 화면이 깨져요.
문제는 겁이 나는 게 아니라 되돌리는 법을 몰랐다는 것이었어요. 되돌릴 수 있으면 겁낼 이유가 없어요. 그래서 순서를 이렇게 잡았어요. 먼저 지금 상태를 저장해두고, 그다음 일부러 망가뜨리고, 저장한 데로 돌아오는지 본다.
1단계 — 먼저 지금 상태를 저장해둔다
되돌리기는 “돌아갈 지점”이 있어야 되는 거라서, 저장부터 했어요. 학습메이트한테 이렇게 부탁했어요.
방금까지 작업한 걸 커밋으로 저장해줘. 나는 코딩을 몰라, 커밋이 뭔지
한 줄로 쉽게 설명하면서 해줘. 그리고 "뭘 저장했는지" 알아보기 쉬운
이름(메시지)도 네가 붙여줘.
커밋(commit) 은 지금 상태에 “여기까지 저장” 도장을 찍는 거예요. 게임 세이브포인트랑 같아요. 세이브해두면 죽어도 그 지점부터 다시 시작하잖아요.
저장하고 나니 기록이 이렇게 쌓여 있었어요.
79147b6 07/30 13:50 게시글 마감 산출물 추가 (DEVLOG + 외부 게시용 사례글)
92025aa 07/26 20:35 7월 26일 학습일지 + 첫 배포 사례글 추가
61e78a6 07/26 20:25 chore: .vercel 로컬 설정 폴더 gitignore 추가
10d2156 07/26 20:18 학습허브 사이트 + AI 학습메이트 '하루' 초기 세팅
날짜와 “뭘 했는지”가 한 줄씩 남아 있어요. 이렇게 쌓인 기록 전체를 버전관리라고 불러요. 이 중 어느 지점으로든 돌아갈 수 있어요.
여기서 처음 알게 된 게 있어요. 저장 안 된 파일에 붙는 표시가 두 종류예요.
?? 260726_DEVLOG.md ← git이 이 파일의 존재 자체를 모름
M src/content/landing/landing.md ← git이 원래 모습을 알고 있고, 지금 달라짐
되돌리기는 M에만 통해요. ??는 git이 원래 모습을 모르니 돌아갈 기준이 없어요. 커리큘럼이 커밋(1단계)을 되돌리기(2단계)보다 먼저 시킨 이유가 이거였어요. 순서에 이유가 있었어요.
2단계 — 일부러 망가뜨린다
이제 망가뜨릴 차례예요. 손이 좀 떨렸는데, 방금 저장해뒀으니 괜찮다고 스스로 달랬어요.
내 랜딩 소개글 첫 문장을 아무렇게나 바꿔서 살짝 망가뜨려줘.
바뀐 걸 로컬로 보여줘. (이건 되돌리기 연습이야, 걱정 마)
홈 화면 첫 문단이 이렇게 바뀌었어요.
ㅁㄴㅇㄹ 여기 아무렇게나 망가뜨린 문장입니다 asdf 123 ㅋㅋㅋ 이건 되돌리기 연습용.
git은 이 변화를 이렇게 보고 있었어요.
M src/content/landing/landing.md
1 file changed, 1 insertion(+), 1 deletion(-)
M 표시가 붙었어요. 아까 배운 대로, 이제 되돌릴 수 있는 상태예요.
실제로 홈 화면이 이렇게 됐어요.

3단계 — 되돌린다
방금 바꾼 걸 취소하고, 마지막으로 커밋한 상태로 되돌려줘.
그리고 원래대로 돌아왔는지 로컬로 보여줘.
되돌리는 데 쓴 명령은 딱 한 줄이었어요.
git restore src/content/landing/landing.md
새로고침하니 첫 문단이 원래 문장으로 돌아와 있었어요. 파일을 열어봐도 그대로였어요. 이게 오늘의 핵심이에요. 읽어서 아는 것과, 돌아오는 걸 직접 보는 건 달라요.
위의 망가진 화면과 같은 자리예요. 첫 문단만 원래대로 돌아왔어요.

막혔던 것 — “저장할 게 없다”는 말에 당황했어요
되돌린 다음에 커밋을 한 번 더 해보려고 했어요. 그런데 이런 답이 왔어요.
nothing to commit, working tree clean
처음엔 뭘 잘못했나 싶었어요. nothing이라는 단어가 부정적으로 읽혔거든요. 알고 보니 에러가 아니었어요. “저장할 게 없다”, 즉 이미 다 저장돼 있다는 뜻이었어요. 방금 되돌려서 커밋 지점과 한 글자도 다르지 않은 상태가 됐으니 당연한 결과였어요.
git은 아무 메시지도 안 나오는 게 가장 좋은 상태예요. 이걸 working tree clean, 작업 공간이 깨끗하다고 불러요. 처음엔 좀 낯설었어요.
하나 더 — 커밋했는데 아직 인터넷엔 안 올라갔어요
커밋한 다음 상태를 보니 ahead 1이라는 표시가 있었어요. 내 컴퓨터엔 저장이 4개인데 GitHub엔 3개, 즉 하나 앞서 있다는 뜻이에요.
- Git 은 내 컴퓨터에 세이브 도장을 찍는 기능이에요.
- GitHub 은 그 기록을 올려두는 인터넷 창고예요.
- 푸시(push) 는 창고에 올리는 거예요. 올리는 순간 배포 서비스가 사이트를 다시 만들어요.
커밋만 하고 푸시를 안 하면 사이트는 그대로예요. 되돌리기 연습을 사이트에 영향 없이 마음껏 할 수 있었던 이유가 이거예요. 되돌리기는 내 컴퓨터의 커밋만 보니까요.
뭐가 바뀌었나 (After)
겁이 줄었어요. 전에는 소개글 한 줄 고치는 것도 망설였는데, 이제는 먼저 커밋해두고 편하게 고쳐요. 잘못되면 한 줄로 돌아오면 되니까요.
그리고 AI에게 일을 맡기는 것도 편해졌어요. 커밋에는 누가 언제 무엇을 바꿨는지가 남아요. AI가 작업한 것도 똑같이 남아서, 마음에 안 들면 그 지점으로 되돌릴 수 있어요. 맡기고도 안심할 수 있는 근거가 생긴 셈이에요.
가져가세요 (재사용 자산)
프롬프트 3개 — 순서대로 넣으면 그대로 따라 할 수 있어요.
1) 방금까지 작업한 걸 커밋으로 저장해줘. 커밋이 뭔지 한 줄로 쉽게
설명하면서 해줘. "뭘 저장했는지" 알아보기 쉬운 이름도 붙여줘.
2) 내 랜딩 소개글 첫 문장을 아무렇게나 바꿔서 살짝 망가뜨려줘.
바뀐 걸 로컬로 보여줘.
3) 방금 바꾼 걸 취소하고, 마지막으로 커밋한 상태로 되돌려줘.
그리고 원래대로 돌아왔는지 로컬로 보여줘.
매일 쓰는 한 줄 — 뭔가 잘 됐다 싶을 때마다 이 한 줄이면 돼요. 앞으로 저장할 일이 생기면 매번 이렇게만 말해요.
오늘 여기까지 잘 된 것 같아. 커밋으로 저장해줘.
표시 읽는 법 — ??는 git이 모르는 새 파일이라 되돌릴 수 없고, M은 커밋된 파일이 수정된 상태라 되돌릴 수 있어요. 되돌리고 싶은 게 있으면 먼저 커밋됐는지 확인하세요.
순서를 지키세요 — 저장 → 망가뜨리기 → 되돌리기. 저장을 건너뛰면 돌아갈 지점이 없어요. 되돌리기가 안 될 때는 대개 커밋을 안 해둔 경우예요.
문서를 고쳐도 되돌아가요 — AI 절차에 옛 정보가 굳어 있던 이야기
AI에게 문서를 고쳐달라고 해서 잘 고쳤는데, 며칠 뒤 같은 문서를 다시 만들면 고치기 전 상태로 돌아와 있는 경험이 있으신가요? 저는 오늘 그 직전까지 갔습니다. 다행히 발견해서 막았고, 왜 이런 일이 생기는지 알게 됐습니다.
이런 분께 도움이 됩니다. AI에게 반복 작업을 시키려고 순서를 파일로 정리해두신 분, 또는 AI가 만들어준 문서를 나중에 고쳐본 적 있는 분.
먼저, 오늘 등장하는 말 하나
스킬 — AI에게 “이 순서대로 해줘”를 미리 적어둔 파일입니다. 요리 레시피 카드와 비슷해요. 한 번 만들어두면 다음엔 이름만 부르면 그 순서대로 돕니다. 저는 4주 학습 계획을 만들 때 이 방식을 썼습니다. 로드맵 스킬을 만들어두고 “내 4주 로드맵 만들어줘”라고 부르면, AI가 인터뷰를 하고 계획서를 써주는 식이었습니다.
편해서 좋았는데, 여기에 함정이 있었습니다.
Before — 계획이 한 주씩 밀려 있었어요
오늘 학습 과정에서 이런 안내를 받았습니다.
계획이 “3주차쯤 만들기 시작”처럼 만들기를 뒤로 미뤄뒀을 수 있는데, 이 과정은 1주차부터 이미 만들기를 시작합니다.
제 계획서를 열어보니 정말 그랬습니다.
| 제 계획서 | 실제 흐름 | |
|---|---|---|
| 1주차 | 기획만 | 기획 + 만들기 시작 |
| 2주차 | 상세 계획 | 본격 제작 |
| 3주차 | 제작 시작 | 완성·다듬기 |
| 4주차 | 제작 + 회고 | 회고·발표만 |
통째로 한 주씩 밀려 있었습니다. 이대로 가면 마지막 주까지 만들기를 붙들고 있게 되는 구조였어요.
1단계 — 문서를 고쳤습니다
받은 안내문을 그대로 AI에게 넣었습니다.
내 로드맵을 다시 봐줘. 이 챌린지의 실제 주차 흐름은 이래:
- 1주차: 로드맵·PRD·세부계획 세우고 MVP 초반까지 만들기 시작
- 2주차: MVP 본격 제작
- 3주차: MVP 완성·다듬기
- 4주차: 회고·발표
내 로드맵이 만들기를 뒤(3주차 등)로 미뤄뒀으면, 이 흐름에 맞게 고쳐줘.
이미 맞게 돼 있으면 그대로 둬.
5분도 안 걸려 고쳐졌습니다. 주차 순서가 제자리를 찾았고, 화면으로 확인까지 했습니다. 여기서 끝났다고 생각했어요.
📸 여기에 고치기 전과 후의 계획서 화면 두 장을 나란히 넣으면 좋습니다.
2단계 — 다른 일을 하다 우연히 발견했어요
다음 작업으로 넘어갔습니다. 이번엔 방금 한 작업을 스킬로 남기는 일이었는데, 새 스킬을 만들려면 기존 스킬의 형식을 봐야 했습니다. 말투와 구조를 맞춰야 하니까요.
그래서 로드맵 스킬 파일을 열었습니다. 그런데 그 안에 이런 대목이 있었습니다.
- 2주차 = 상세 계획: PRD·세부계획
- 3주차 = 제작: 내 MVP 만들기
한 시간 전에 고친 그 옛 순서였습니다.
무슨 상황이었나
고친 것과 안 고친 것이 갈려 있었습니다.
| 상태 | |
|---|---|
| 계획서 (결과물) | ✅ 고쳤음 |
로드맵 스킬 (그걸 만드는 순서) | ❌ 옛 순서 그대로 |
다음에 제가 “내 4주 로드맵 만들어줘”라고 부르면, AI는 그 스킬 파일을 읽고 옛 순서로 다시 만들어줄 상태였습니다. 오늘 고친 게 소리 없이 되돌아가는 거죠.
더 곤란한 건 되돌아간 걸 제가 알아채기 어렵다는 겁니다. AI가 새로 만들어준 계획서를 보면 그럴듯하니까요. “어? 전에 고쳤는데?” 하고 의심할 이유가 없습니다.
3단계 — 절차도 같이 고쳤어요
스킬 파일의 주차 틀을 실제 흐름으로 바꿨습니다. 그리고 한 줄을 더 넣었습니다.
★ 만들기를 3주차로 미루지 않습니다. 이 챌린지는 1주차 끝에 이미 만들기를 시작합니다.
초보 로드맵이 가장 흔하게 틀리는 지점이라, 여기서 한 주씩 밀리면 뒤가 다 밀립니다.
값만 바꾸면 다음에 또 같은 실수가 나올 수 있어서, 왜 그런지까지 적어둔 겁니다. 스킬 안의 자가점검 항목에도 “만들기가 뒤로 밀리지 않았나”를 추가했습니다.
📸 여기에 스킬 파일의 고친 부분 화면을 넣으면 좋습니다.
After — 무엇이 달라졌나
| Before | After | |
|---|---|---|
| 계획서 | 한 주씩 밀림 | 실제 흐름과 맞음 |
| 다시 만들면 | 옛 순서로 되돌아감 | 같은 결과가 나옴 |
| 같은 실수 재발 | 막을 장치 없음 | 경고문 + 자가점검 항목 |
제일 크게 달라진 건 안심입니다. 스킬을 다시 불러도 오늘 판단이 유지된다는 걸 아니까요.
왜 이런 일이 생기나
AI에게 반복 작업을 맡기면 결과물이 두 겹으로 생깁니다.
- 결과물 — 계획서, 문서, 코드 같은 눈에 보이는 것
- 절차 — 그걸 만드는 순서가 적힌 파일. 스킬이나 규칙 파일 같은 것
우리가 고치는 건 보통 1번입니다. 눈앞에 있고 틀린 게 보이니까요. 2번은 평소에 열어보지 않습니다. 잘 돌아가고 있으면 존재를 잊습니다.
그런데 다음번 결과물을 만드는 건 2번입니다. 1번만 고치면 그 수정은 한 번짜리가 됩니다.
종이 문서였다면 이런 일이 없습니다. 고치면 고쳐진 채로 있으니까요. AI에게 자동화를 맡기는 순간 “다시 만들어질 수 있는 것”이 되고, 그때부터 절차가 진짜 원본이 됩니다.
가져다 쓰실 것
확인 프롬프트
문서를 고친 뒤 이걸 넣어보세요. 저는 앞으로 습관으로 만들려고 합니다.
방금 고친 내용이 스킬이나 규칙 파일에도 옛 버전으로 남아 있는지 확인해줘.
남아 있으면 같이 고치고, 왜 그렇게 정했는지 이유도 그 파일에 적어줘.
체크리스트 — 문서를 고쳤을 때 볼 3곳
- 문서 자체 — 눈앞의 그 파일
- 그 문서를 만드는 절차 — 스킬, 규칙 파일, 지침서. “이 문서를 AI가 만들어줬나?” 하고 물어보면 찾기 쉽습니다
- 왜 그렇게 정했는지 — 값만 바꾸면 다음에 또 틀립니다. 이유를 함께 남기면 판단이 재사용됩니다
마무리
오늘 배운 건 주차 순서가 아니라 고침이 한 번짜리인지 계속 가는지를 구분하는 눈이었습니다.
발견도 우연이었습니다. 다른 일을 하려고 파일을 열었다가 봤을 뿐이에요. 그래서 우연에 맡기지 않으려고 위 체크리스트를 만들었습니다.
AI에게 반복 작업을 맡겨두신 게 있다면 그 절차 파일을 한 번 열어보세요. 제 경우는 만든 지 엿새밖에 안 된 스킬이었는데도 이미 옛 판단이 굳어 있었습니다.
확인했다고 생각했는데 안 본 거였어요 — git이 폴더를 뭉쳐 보여줄 때
논문 지식체계를 만들면서 논문 원본 PDF를 git에 올리지 않도록 막았어요. 막은 뒤에 “정말 막혔나” 확인했고, 통과했다고 판단했어요.
그런데 그 확인이 아무것도 확인하지 못한 확인이었어요.
누구에게 도움이 될까요 — git으로 파일을 관리하는데 .gitignore를 써본 적 있는 분,
그리고 “확인했다”와 “봤다”가 다르다는 걸 아직 겪어보지 않은 분이요.
왜 PDF를 막으려 했나
논문 원본 PDF를 저장소에 담으면 두 가지가 걸려요.
저작권. 논문 PDF는 대개 출판사에 권리가 있어요. 지금 제 저장소는 비공개지만, 나중에 공개로 바꿀지 검토할 때 발목을 잡아요.
용량. PDF는 무거워요. 그리고 git은 한번 담은 파일을 히스토리에서 지우기가 아주 번거로워요. 잘못 담고 나서 고치는 비용이 처음에 막는 비용보다 훨씬 커요.
그래서 원본은 제 컴퓨터 폴더에 두고, git에는 그걸 옮긴 마크다운만 올리기로 했어요. 어느 논문이었는지는 노트에 적은 서지정보와 DOI로 되짚을 수 있으니 잃는 게 아니에요.
어떻게 했나
1. 학습메이트한테 이렇게 부탁했어요
knowledge/raw/ 안의 PDF 파일은 git에 올라가지 않게 .gitignore에 추가해줘.
그리고 실제로 무시되는지 확인까지 해줘.
“확인까지 해줘”를 일부러 붙였어요. .gitignore에 한 줄 적는 건 쉬운데,
패턴이 틀리면 에러 없이 조용히 안 먹어요. 아무 일도 안 일어나니까 잘 된 줄
알고 넘어가게 돼요. 그러다 나중에 PDF가 커밋에 섞여 들어가요.
2. .gitignore에 한 줄이 들어갔어요
knowledge/raw/*.pdf
여기서 *는 “아무 글자나”라는 뜻이에요. 그래서 이름이 무엇이든 pdf 파일 전부를
가리켜요. 앞으로 넣을 논문까지 미리 덮어주니까 논문을 추가할 때마다 고칠 필요가 없어요.
3. 확인했어요 — 그런데 여기가 문제였어요
가짜 PDF와 가짜 마크다운을 하나씩 만들어놓고, git이 뭘 보는지 물었어요.
git status --short knowledge/raw/
돌아온 답이 이거였어요.
?? knowledge/raw/
한 줄이에요. 저는 이걸 보고 “PDF가 안 보이니 잘 막혔네”라고 생각했어요.
아니었어요. 저 한 줄은 “이 폴더 안에 아직 기록 안 된 게 있다”는 말이지, 그 안에 무엇이 있는지는 아무것도 알려주지 않아요. PDF가 걸러졌는지, 마크다운은 통과했는지. 저 출력으로는 둘 다 알 수가 없어요.
💡 여기에
?? knowledge/raw/한 줄만 나온 터미널 화면 스크린샷을 넣으면 좋아요.
막힘 → 어떻게 뚫었나
학습메이트가 먼저 짚어줬어요. “이건 확인한 게 아니다”라고요.
git은 폴더 전체가 아직 기록 안 된 상태면 폴더 하나로 뭉쳐서 보여줘요. 안에 파일이 1개든 100개든 한 줄이에요. 목록을 짧게 유지하려는 친절인데, 확인하려는 사람에게는 오히려 눈을 가려요.
파일 단위로 보려면 옵션을 붙여야 해요.
git status --short -uall knowledge/raw/
-uall은 “기록 안 된 파일을 전부 보여줘”라는 뜻이에요. 이번엔 이렇게 나왔어요.
?? knowledge/raw/.gitkeep
?? knowledge/raw/_test.md
이제 보여요. 마크다운(_test.md)은 git에 보이고, PDF(_test.pdf)는 목록에 없어요.
막힌 게 맞아요. 같은 상태를 두 번째 명령으로 봤을 때 처음 알게 된 거예요.
한 걸음 더 — 반대 방향도 확인해야 해요
여기서 하나 더 배웠어요. “PDF가 막혔나”만 보면 반쪽이에요.
과하게 막혔을 수도 있으니까요. 패턴을 잘못 쓰면 마크다운까지 같이 막혀요. 그러면 정작 올려야 할 논문 노트가 git에 안 올라가는데, 이건 에러가 안 나서 훨씬 늦게 발견돼요. 그래서 양쪽을 다 물어봤어요.
# ① 막아야 할 것이 막혔나
git check-ignore -v knowledge/raw/some-paper.pdf
# → .gitignore:24:knowledge/raw/*.pdf knowledge/raw/some-paper.pdf
# ② 통과해야 할 것이 통과하나
git check-ignore -q knowledge/raw/some-paper.md
# → 아무것도 안 나오면 통과 (막히지 않았다는 뜻)
git check-ignore는 파일이 실제로 없어도 패턴을 확인해줘요. 그래서 앞으로 넣을
파일 이름을 미리 넣어보고 물어봐도 돼요. -v를 붙이면 .gitignore의 몇째 줄이
그 파일을 잡았는지까지 알려줘서, 여러 규칙이 섞여 있을 때 어느 게 범인인지 보여요.
결과
논문 원본 PDF는 git에서 안 보이고, 옮긴 마크다운은 올라가요. 폴더째 담아도 안전해요.
실제로 커밋할 때 git add knowledge/로 폴더를 통째로 담았는데 PDF는 들어가지
않았어요. .gitignore가 add 단계에서 먼저 걸러주기 때문이에요. 다만 그건 패턴이
맞을 때만이라, 먼저 확인한 게 이 안전의 근거였어요. 확인 안 하고 담았으면
지금 PDF가 들어가 있었을지도 몰라요.
| 확인 전 | 확인 후 | |
|---|---|---|
| 본 것 | ?? knowledge/raw/ 한 줄 | 파일 이름 목록 |
| 알 수 있던 것 | 없음 | PDF 제외 · 마크다운 통과 |
| 판단 | ”잘 막혔네” (근거 없음) | “막혔다” (근거 있음) |
가져가서 쓰세요
확인 체크리스트
.gitignore에 무언가를 추가했다면 세 가지를 확인하세요.
- 막아야 할 것이 막혔나 —
git check-ignore -v <막을파일> - 통과해야 할 것이 통과하나 —
git check-ignore -q <올릴파일>(출력 없으면 통과) - git이 파일 단위로 뭘 보나 —
git status --short -uall <폴더>
세 번째를 빼면 안 돼요. 앞의 둘은 패턴을 묻는 것이고, 세 번째는 지금 실제 상태를
묻는 거예요. 패턴이 맞아도 이미 커밋된 파일은 .gitignore가 못 막으니까 둘 다 필요해요.
붙여넣어 쓰는 프롬프트
[파일 종류]를 git에 올라가지 않게 .gitignore에 추가해줘.
추가한 다음 세 가지를 확인해줘 —
① 막아야 할 파일이 정말 막혔는지
② 올려야 할 파일이 실수로 같이 막히지 않았는지
③ git이 파일 단위로 뭘 보고 있는지 (폴더로 뭉쳐서 보여주지 말고)
③번을 빼면 소용없어요. 안 적으면 폴더로 뭉친 출력을 받고 확인했다고 착각하게 되니까요.
배운 것
“봤다”와 “확인했다”는 달라요. 저는 출력을 눈으로 봤어요. 그런데 그 출력에는 제가 알고 싶었던 정보가 담겨 있지 않았어요. 화면에 뭔가 떴다는 것이 확인의 근거가 되지 않아요.
확인하는 방법을 모르면 확인한 줄 알고 지나가요. 이게 제일 무서웠어요. 틀린 걸 봤다면 다시 봤을 거예요. 그런데 아무것도 안 보여주는 출력을 받았을 때는 문제가 없다고 읽혀요. 빈 결과와 아무것도 안 물어본 결과는 다르다는 걸 알아야 해요.
도구의 친절이 눈을 가릴 수 있어요. git이 폴더를 뭉쳐 보여주는 건 목록을 짧게 하려는 배려예요. 평소에는 고마운데, 확인하려는 순간에는 방해가 돼요. 도구가 기본으로 뭘 숨기는지 알아둘 필요가 있어요.
양방향으로 물어야 해요. 막혔나만 묻지 말고 통과하나도 물어야 해요. 과하게 막힌 실수는 에러를 내지 않아서 훨씬 늦게 발견돼요.
확인하지 않으면 틀린 채로 갑니다 — 1주차에 여섯 번 되풀이한 한 가지
일주일 전 제 손에는 남의 템플릿 하나가 있었어요. 지금은 인터넷에 올라간 제 사이트에 글 13편이 있고, 논문이 들어갈 폴더와 노트 양식까지 서 있습니다.
그런데 이 글에서 자랑하려는 건 결과물이 아니에요. 한 주를 마치고 매일 쓴 학습일지 네 편을 나란히 놓고 봤더니, 날마다 다른 걸 배운 게 아니었어요. 같은 일이 여섯 번 반복됐습니다.
확인하지 않으면 틀린 채로 갑니다.
여섯 번 다 확인해서 잡았습니다. 안 잡았으면 하나같이 나중에 훨씬 크게 터질 일이었어요. 그 여섯 장면을 순서대로 풀겠습니다.
누구에게 도움이 될까요 — AI와 뭔가를 만들기 시작했는데 “AI가 그렇다니까 그런가 보다” 하고 넘어가는 게 불안한 분이요. 코딩을 몰라도 읽을 수 있게 썼습니다.
그 전에 — 한 주 전의 저
“지식을 체계로 쌓고 싶은데 매번 흩어지고, 어디서 시작할지 막막하다.”
이게 출발점이었어요. 자료는 옵시디언에, 결정은 대화창에 흩어져 있고 새 대화를 켜면 매번 처음부터 다시 설명해야 했습니다.
장면 1 — AI가 처음에 짚어준 게 틀렸어요 (7/23)
첫날 AKM이라는 개념을 정리했어요. AI가 “AI Knowledge Management”라고 알려줬고, 저는 그럴듯하다고 생각했습니다. 그런데 원문을 찾아 읽어보니 Agent Knowledge Management(에이전트 지식관리)였어요.
한 단어 차이지만 뜻이 완전히 달라요. “AI가 지식을 관리한다”가 아니라 “AI 에이전트가 무엇을 읽고 어디 저장하고 어떻게 실행하고 실패를 어디로 되돌릴지 정하는 운영 구조” 였습니다. 이걸 틀린 채로 갔으면 개념페이지 한 장이 아니라 4주 프로젝트의 방향이 어긋났을 거예요.
그래서 학습메이트에게 규칙을 하나 박아뒀습니다.
도구 설치법·명령어·설정처럼 정확해야 하고 자주 바뀌는 것은
기억으로 지어내지 말고, 최신 공식문서를 확인해서 알려줘.
이 한 줄이 이번 주 내내 일했어요.
장면 2 — 계획을 짜기 전에 사례를 찾게 했어요 (7/24)
4주 계획을 세울 때, 그냥 “계획 짜줘”라고 하면 그럴듯한 계획이 나옵니다. 문제는 그럴듯한 것과 맞는 것이 다르다는 거죠. 그래서 이렇게 부탁했어요.
막연히 짜지 말고, 이걸 실제로 만든 사람들의 사례를 먼저 찾아줘.
그 사례들에 근거해서 계획을 세워줘.
사례 여섯 개가 나왔고, 그중 성공한 것들이 하나같이 같은 순서를 쓰고 있었어요. 위키를 먼저 만들고 검색을 나중에 얹는 순서요. 제 감으로 짰으면 반대로 갔을 겁니다. 검색이 더 재미있어 보였거든요.
장면 3 — 배포 직전에 일지가 공개될 뻔했어요 (7/26)
사이트를 인터넷에 올리려는데, 학습일지 폴더가 git이 무시하는 목록에 없었어요. 저장소를 공개로 만들었으면 제 일지 원문이 그대로 인터넷에 올라갔을 겁니다.
배포 전에 발견해서 저장소를 비공개로 정했어요. 여기서 배운 건 올리기 전에 무엇이 올라가는지 봐야 한다는 거예요. 올린 다음에 지우는 건 훨씬 어렵습니다.
💡 여기에 저장소를 private으로 만드는 화면 스크린샷을 넣으면 좋아요.
장면 4 — 순서에 이유가 있었어요 (4일차)
되돌리기를 배우는 날이었어요. 커리큘럼이 “먼저 저장(커밋)하고, 그다음 일부러 망가뜨렸다가 되돌려보라”고 했습니다. 저는 순서가 왜 그런지 몰랐어요.
해보고 알았습니다. 저장하지 않은 건 되돌릴 수 없어요. git이 아직 모르는 파일은 “되돌릴 지점”이 없으니까요. 순서를 바꿔서 망가뜨리기부터 했으면 되돌아갈 데가 없었을 겁니다.
일부러 랜딩 글을 ㅁㄴㅇㄹ asdf로 망가뜨려놓고 화면으로 확인한 다음, 명령 한 줄로
되돌렸어요. 되돌아오는 걸 눈으로 보고 나니 사이트를 건드리는 게 덜 무서워졌습니다.
장면 5 — 정석이 정석이 아니었어요 (5일차)
기획서를 쓰면서 만드는 방법을 다시 조사하게 했어요. 제가 알던 정석은 벡터DB였습니다. 전에 만든 프로젝트에서도 그렇게 했고요.
조사 결과가 뒤집혔어요. 지금은 마크다운과 기본 검색만으로 하는 쪽이 표준이고, 노트가 500~1,000편 이하면 벡터가 필요 없다는 거였어요. 제 위키는 8편이었습니다. 한참 못 미쳤죠.
여기서 그냥 가벼운 쪽으로 갈아탈 수도 있었는데, 학습메이트가 짚어줬어요. 벡터를 빼면 제가 데이터 쪽에서 보여줄 알맹이가 얇아진다고요. 그래서 가벼운 것으로 먼저 만들고, 나중에 벡터를 얹어 둘을 비교하기로 정했습니다.
“무거운 걸 썼다”보다 **“무거운 게 진짜 필요한지 재봤다”**가 더 정직하고 내세울 것도 많다고 봤어요. 이게 이번 주 제일 큰 판단이었습니다.
같은 날 하나 더 걸렸어요. 계획 문서의 순서가 한 주씩 밀려 있어서 고쳤는데, 그 문서를 만들어준 AI 절차 파일에 옛 순서가 그대로 박혀 있었어요. 안 고쳤으면 다음에 그 절차를 돌릴 때 오늘 고친 게 되돌아갔을 겁니다. 결과물만 고치고 끝낼 게 아니라 그걸 만드는 절차까지 봐야 했어요.
장면 6 — “확인했다”고 생각했는데 안 본 거였어요 (6일차)
이게 제일 아찔했어요.
논문 원본 파일을 git에 올리지 않도록 막고, 정말 막혔는지 확인했습니다. 확인 명령을 넣었더니 이렇게 나왔어요.
?? knowledge/raw/
한 줄이에요. 저는 “논문 파일이 안 보이니 잘 막혔네”라고 판단하고 넘어가려 했습니다.
아니었어요. 저 한 줄은 “이 폴더 안에 아직 기록 안 된 게 있다”는 말이지, 그 안에 무엇이 있는지는 알려주지 않아요. git은 폴더 전체가 아직 기록 안 된 상태면 폴더 하나로 뭉쳐서 보여줍니다. 안에 파일이 1개든 100개든 한 줄이에요.
파일 단위로 보려면 옵션을 붙여야 했어요.
git status --short -uall knowledge/raw/
이번엔 파일 이름이 나왔고, 그제서야 막힌 걸 확인했습니다. 같은 상태를 두 번째 명령으로 봤을 때 처음 알게 된 거예요.
여기서 한 걸음 더 갔어요. “막혔나”만 보면 반쪽이에요. 과하게 막혔을 수도 있으니까요. 정작 올려야 할 노트까지 막히면 그건 에러가 안 나서 훨씬 늦게 발견됩니다. 그래서 양쪽을 다 물었어요.
# 막아야 할 것이 막혔나
git check-ignore -v knowledge/raw/some-paper.pdf
# 올려야 할 것이 통과하나 (출력 없으면 통과)
git check-ignore -q knowledge/raw/some-paper.md
같은 날 인터넷 글도 한 번 뒤집었어요. 사이트에 검색창을 붙이려고 찾아보니 검색 결과가 전부 부품 두 개를 설치하라고 했습니다. 그런데 그 부품의 등록 정보를 직접 열어보니 하나가 다른 하나를 이미 품고 있었어요. 한 줄이면 됐습니다. 블로그는 쓰인 시점에 멈춰 있고, 등록 정보는 지금을 보여줘요.
그래서 어떻게 됐나
| 한 주 전 | 지금 | |
|---|---|---|
| 사이트 | 남의 템플릿, 내 컴퓨터에만 | 인터넷에 배포, 글 13편 |
| 계획 | ”막막하다” | 기획서 + 하루 크기 12단계 실행계획 |
| 만들 것 | 뭘 만들지 모름 | 논문 들어갈 폴더와 노트 양식 완성 |
| 되돌리기 | 못 함 | 저장 지점 13개 |
| AI와 일하는 법 | 시키고 받기 | 조사시키고 확인하기 |
커리큘럼이 마지막에 짚어준 게 인상 깊었어요. 이번 주에 만든 문서를 실무 이름으로 바꿔보면 이렇게 됩니다.
| 만든 것 | 실무에서 부르는 이름 |
|---|---|
| 로드맵 | 기획서 |
| PRD | 요구사항 정의서 |
| 세부계획 | 실행계획 |
| 튜토리얼 | 작업 절차서 |
| 매일 쓴 사례글 | 진행 기록 |
| 매일 쓴 학습일지 | 회의록 |
코딩을 배운 게 아니라 프로젝트를 굴리는 법을 배운 거예요. 저는 연구센터에서 장비 사업을 총괄할 때 이 문서들을 만들었어요. 이름만 다르고 역할이 같습니다.
가져가서 쓰세요
조사부터 시키는 프롬프트
계획을 짜기 전에 이걸 앞에 붙이면 계획이 가벼워집니다. 실제로 이번 주에 이걸로 파이썬 도구 설치를 통째로 생략했어요.
계획을 짜기 전에 먼저 조사부터 해줘 —
이걸 지금 만든다면 요즘 제일 쉽고 많이 쓰는 방법이 뭔지 최신 기준으로 찾아봐.
(옛날 방식이 아니라, 지금 초보가 제일 적은 노력으로 만들 수 있는 방법으로.)
그 최신 방법을 바탕으로 계획을 세워줘.
확인까지 시키는 프롬프트
“해줘”로 끝내면 됐는지 알 수 없어요. 뒤에 한 줄을 붙이세요.
[할 일]을 해줘.
그리고 실제로 그렇게 됐는지 확인까지 해줘.
막아야 할 게 막혔는지, 통과해야 할 게 통과하는지 양쪽 다 봐줘.
확인 3단 체크리스트
무언가를 막거나 걸렀다면 세 가지를 보세요.
- 막아야 할 것이 막혔나
- 통과해야 할 것이 통과하나 (이걸 빼면 과하게 막힌 걸 못 잡아요)
- 도구가 파일 단위로 보여주나 (폴더로 뭉쳐 보여주면 확인한 게 아니에요)
AI에게 박아둘 규칙 한 줄
정확해야 하고 자주 바뀌는 것(설치법·명령어·버전)은
기억으로 답하지 말고 공식 출처를 확인해서 알려줘.
배운 것
틀린 답보다 빈 답이 위험해요. 틀린 걸 봤다면 다시 봤을 거예요. 그런데 아무것도 안 보여주는 출력은 “문제 없음”으로 읽힙니다. 확인하는 방법을 모르면 확인한 줄 알고 지나가요.
AI는 틀릴 때 자신 있게 틀려요. 첫날 AKM 뜻도, 인터넷 글의 설치 안내도 다 자신 있는 어조였습니다. 어조로는 구별이 안 돼요. 구별되는 건 출처를 열어봤는지 여부뿐이에요.
쉬운 길이 항상 이득은 아니에요. 가벼운 방법을 알게 됐을 때 갈아타기 쉬웠는데, 그러면 제가 보여줄 게 얇아졌어요. 쉬운 길을 알고 나서 왜 어려운 길을 가는지 말할 수 있게 된 것이 이번 주 수확입니다.
개념을 먼저 잡는 게 시간 낭비가 아니었어요. 첫날 이해한 원본/지식 분리가 계획과 기획서를 거쳐 마지막 날 폴더 구조가 됐습니다. 첫날의 개념이 그대로 손에 잡히는 게 됐어요.
다음 주
논문을 늘리기 전에 미뤄둔 결정 두 개를 먼저 정하려고 해요. 이번 주에 배운 걸 순서로 옮기는 거예요. 결정을 안 하고 넣기 시작하면 나중에 넣은 걸 전부 손봐야 하니까요.
그리고 2주차에는 화면에 보이는 게 나옵니다. 이번 주에 만든 건 터라서 눈에 안 보였어요. 하루 종일 했는데 화면에 새로 뜬 게 없는 날은 좀 허전했습니다. 그래도 집을 지을 때 터는 원래 안 보이는 거니까요.
2주차
점검 도구를 만들고, 그 도구로 내 실수를 잡아낸 하루
📝 한줄 요약
지식체계(논문 10편 + 개념 페이지)가 SCHEMA 규칙을 잘 지키고 있는지 확인하는 점검 명령(npm run lint:knowledge)을 만들었어요. 만들고 나서 “잘 통과하네” 하고 끝내는 대신 코드 리뷰를 요청했더니, 제 점검 도구가 놓치고 있던 실제 버그 — 논문 3편이 개념 페이지로 링크를 걸었는데 개념 페이지에서는 그 논문들로 돌아오는 링크가 없던 것 — 가 나왔어요. 점검 항목을 하나 더 추가해서 다시 잡아내고, 데이터도 고쳤어요.
바쁘시면 이것만 읽어도 돼요:
- “링크가 안 끊겼는지”와 “링크가 규칙대로 양방향으로 걸려 있는지”는 완전히 다른 검사예요. 하나를 검사한다고 다른 하나도 저절로 확인되는 게 아니에요.
- 자동 점검 도구를 만들고 나면, 그 도구 자체가 맞게 짜였는지도 검증해야 해요 — 일부러 틀린 데이터를 넣어보는 게 제일 확실해요.
- AI에게 “이거 다 됐어?”가 아니라 “허술한 데 없어? 제일 효과 큰 거부터 짚어줘”라고 물으면, 더 구체적이고 우선순위 있는 답이 와요.
Before — 왜 점검 도구가 필요했나
논문 노트 10편과 개념 페이지 1개를 만들고 나니, SCHEMA.md에 정해둔 규칙(빈 칸 없이 7항목 채우기, 원문에 없는 문장 인용 금지, 위키링크 양방향 연결)을 매번 사람 눈으로 확인하기가 버거워졌어요. 다음에 논문을 더 넣을 때마다 이걸 매번 손으로 확인할 순 없으니, 한 번 명령으로 문제 목록이 나오는 도구가 세부계획 7단계에 이미 정해져 있었어요.
과정 — 만들고, 테스트하고, 리뷰 요청하고, 실제 버그를 찾음
1단계 — lint 명령 만들기
knowledge/lint.mjs를 만들어서 세 가지를 검사하게 했어요: 빈 항목, 끊긴 링크, 원문에 없는 인용. npm run lint:knowledge 한 줄이면 돌아가게 했고요.
2단계 — 진짜 작동하는지 가짜 오류로 테스트
만들었다고 믿지 않고, 일부러 문제 4개를 심은 가짜 논문 파일을 넣어봤어요.
npm run lint:knowledge
## 빈항목 (1건)
- 2099-test-broken.md — '## 6. 한계' 항목이 비어있음
## 끊긴링크 (1건)
- 2099-test-broken.md — /papers/no-such-paper 대상 페이지 없음
## 인용확인필요 (1건)
- 2099-test-broken.md — 원문에서 못 찾음: "이건 원문에 절대 없는 지어낸 문장이다..."
총 3건 발견.
넷 다 잡혔어요. 실제 논문 10편으로 돌리니 문제 0건 — 여기까지는 순조로웠어요.
3단계 — “허술한 데 없어?” 라고 리뷰 요청
여기서 멈추지 않고 이렇게 물었어요:
“지금까지 만든 걸 봐줘. 돌아가긴 하는데 어딘가 허술한 것 같아. 어디가 부족한지 짚어주고, 그중 지금 고치면 제일 효과 큰 것부터 알려줘.”
돌아온 답 중 1순위가 뜻밖이었어요 — **“링크가 죽었는지 확인하는 것과, 링크가 SCHEMA §7의 양방향 규칙을 지키는지 확인하는 것은 다른 검사인데, lint가 후자를 아예 안 보고 있다”**는 지적이었어요. 그리고 실제 데이터를 확인해보니 진짜로 깨져 있었어요: BNNT 벽수제어·수질정화·오소리기름 세 논문이 “TEM 관찰” 개념 페이지로 링크를 걸었는데, 그 개념 페이지의 “어느 논문에서 나왔나” 절에는 4편만 있고 이 셋이 빠져 있었던 거예요.
4단계 — 검사 항목 추가하고, 데이터도 고침
lint에 양방향 링크 검사(④ 일방통행)를 추가했더니 정확히 그 3건이 잡혔고, 개념 페이지에 빠진 역링크 3개를 채워 넣고 나서 다시 돌리니 문제 0건이 됐어요.
After — 뭐가 달라졌나
| Before | After | |
|---|---|---|
| lint 검사 항목 | 3가지 (빈항목·끊긴링크·인용) | 5가지 (+ 일방통행 링크, + 원본 frontmatter 대조) |
| 개념 페이지 역링크 | 4편만 연결 (3편 누락, 아무도 모르던 상태) | 7편 전부 양방향 연결 |
| ”점검 통과”의 의미 | ”링크가 안 끊겼다”만 보장 | ”규칙대로 쌍을 이룬다”까지 보장 |
배운 것
점검 도구가 있다는 사실 자체가 안심의 근거가 되면 안 돼요. “lint를 돌렸는데 통과했다”는 말은 “그 lint가 보는 항목에 한해서” 문제가 없다는 뜻일 뿐, 애초에 lint가 안 보는 종류의 문제는 여전히 숨어 있을 수 있어요. 제가 처음 만든 lint는 “링크가 존재하는가”만 봤지 “링크가 규칙대로 쌍을 이루는가”는 안 봤고, 그 틈에 실제 버그가 몇 시간째 숨어 있었어요.
“다 됐어?” 대신 “허술한 데 짚어줘, 효과 큰 것부터”라고 물으니 답이 달라졌어요. 그냥 검토해달라고 하면 막연한 칭찬으로 끝나기 쉬운데, 우선순위를 매겨 달라고 구체적으로 물으니 실제로 고칠 가치가 있는 지점을 순서대로 받을 수 있었어요.
재사용 자산 — 내가 만든 점검 도구를 다시 점검하는 체크리스트
- 검사 항목마다 “이게 정확히 뭘 보고, 뭘 안 보는지” 한 줄로 적어볼 수 있나요? (못 적으면 항목이 애매한 거예요)
- 일부러 틀린 데이터를 만들어서 진짜로 잡히는지 테스트했나요?
- “링크/참조가 존재하는가”와 “그 관계가 규칙대로 완전한가(양방향, 필수 항목 등)“를 따로 구분해서 검사하고 있나요?
- 만든 뒤 “허술한 데 없어?”라고 다시 검토를 요청했나요? (같은 사람/AI가 만든 그대로 “됐다”고 끝내지 않기)
- 리뷰에서 나온 지적을 실제 데이터로 확인해봤나요? (짚어준 게 진짜 버그인지, 우려일 뿐인지는 확인해야 알아요)
AI가 논문을 못 구해왔어요 — 페이월에 세 번 막히고 나서야 안 것
📝 한줄 요약
논문 지식체계에 AI 주제 논문을 넣으려고 했는데, 딱 맞는 논문(SHINE — TEM 이미지 디노이징 AI)을 찾았지만 PDF가 페이월에 막혀 있었어요. AI가 세 가지 경로로 다운로드를 시도했지만 다 실패했고, 결국 제가 직접 브라우저에서 로그인해서 받은 다음 파일 경로만 알려주니 그제야 진행됐어요.
바쁘시면 이것만 읽어도 돼요:
- AI가 학술 논문 PDF를 다운로드할 때 페이월(paywall)에 막히면, 직접 다운로드·오픈액세스 미러(PMC 등)·기관 리포지토리 세 가지 경로를 시도해봐요. 그래도 안 뚫리면 미련 없이 사람이 받아서 넘기는 게 빨라요.
- Science Advances처럼 “오픈액세스 저널”이라고 알려진 곳도, 자동화된 요청은 봇 차단(JS 챌린지)에 걸려 원문을 못 받을 수 있어요 — 브라우저로 직접 열면 되는데
curl같은 도구는 못 뚫는 경우가 있더라고요. - 막힌 걸 세 번 시도하고도 안 되면, “이거 못 하겠어요”라고 솔직히 알리는 게 계속 헛수고하는 것보다 나아요.
Before — 왜 이 논문이 필요했나
논문 지식체계 프로젝트를 10편까지 채우는 중이었는데, AI 주제 논문 하나가 비어 있었어요. 마침 그날 만든 “TEM 관찰” 개념 페이지가 소재·바이오 논문 두 주제에 이미 걸려 있어서, 여기에 AI 논문까지 하나 걸리면 세 주제가 한 개념으로 다 이어지는 그림이 나올 수 있었어요. 그래서 “TEM 이미지를 딥러닝으로 다루는 논문”을 웹 검색으로 찾았고, SHINE(Science Advances, 2025)이라는 논문을 발견했어요 — 제 실제 관심사(TEM 이미지 디노이징)와 정확히 겹치는 논문이었죠.
과정 — 세 번 막히고, 네 번째에 풀림
1차 시도 — 직접 다운로드
curl -sL -o "shine.pdf" "https://www.science.org/doi/pdf/10.1126/sciadv.ads5552"
결과: PDF가 아니라 5.4KB짜리 HTML만 받아졌어요. 페이지가 JS로 렌더링되는 방식이라 curl로는 껍데기만 오는 거였어요.
2차 시도 — PMC(오픈액세스 미러)
논문이 실린 Science Advances는 원래 오픈액세스 저널이라, PMC(PubMed Central)에 무료 사본이 있을 거라 생각했어요. 하지만 curl로 PMC를 검색했더니 빈 결과만 나왔어요.
3차 시도 — 대학 리포지토리
검색 결과에 한양대 리포지토리(ERICA) 직접 PDF 링크가 있길래 시도했어요.
curl -sL -o "shine.pdf" "https://scholarworks.bwise.kr/erica/bitstream/.../Self-supervised...pdf"
이번에도 657바이트짜리 HTML만 받아졌어요.
여기서 멈췄어요. 세 가지 경로를 다 써봤는데 안 되니, 더 파고들기보다 “이거 못 구했어요”라고 솔직히 알리는 걸 골랐어요.
4번째 — 제가 직접 받아서 넘겨주니 바로 풀림
브라우저로 직접 열어서 로그인 상태로 다운로드받고, 로컬 파일 경로(~/Downloads/sciadv.ads5552.pdf)만 알려줬어요. AI가 그 경로에서 파일을 바로 읽어 논문 노트를 완성했어요.
After — 뭐가 달라졌나
| Before | After | |
|---|---|---|
| 논문 주제 배분 | 소재4·바이오3·AI2 | 소재4·바이오3·AI3 (목표 10편 완성) |
| TEM 개념 페이지 | 소재·바이오 2개 주제 | 소재·바이오·AI 3개 주제에 다 걸림 |
| 걸린 시간 | 자동화 시도 3번(각각 1~2분) + 사람이 받아서 넘기는 데 몇 분 | — |
배운 것
“오픈액세스”라는 말이 “자동화 도구로 바로 받을 수 있다”는 뜻은 아니에요. 사람이 브라우저로 열면 문제없이 무료로 보이는 페이지도, curl 같은 자동화 요청은 봇 차단(JS 챌린지, Cloudflare 등)에 걸려 껍데기 HTML만 받는 경우가 있더라고요. 이건 논문 사이트만의 문제가 아니라 요즘 웹사이트 전반의 패턴이라, AI가 “웹에서 파일을 받아온다”고 할 때 이 한계를 미리 알아두면 좋을 것 같아요.
세 번 막히면 네 번째는 사람에게 넘기는 게 맞아요. AI가 계속 다른 우회로를 찾아 헤매는 것보다, “이 경로들을 시도했는데 다 막혔다”고 구체적으로 보고하고 사람의 손을 빌리는 게 훨씬 빨랐어요. 실제로 제가 브라우저 로그인 하나로 몇 분 안에 해결됐거든요.
재사용 자산 — AI에게 파일 다운로드를 시킬 때 체크리스트
- 직접 URL로 시도해봤나요? (
curl -sL -o 파일명 URL) - 받은 파일이 진짜 PDF인지 확인했나요? (
file 파일명— “PDF document”가 아니라 “HTML”이면 실패) - 오픈액세스 저널이면 PMC·arXiv 같은 미러도 시도해봤나요?
- 그래도 안 되면, 몇 번까지 시도하고 사람에게 넘길지 미리 정해두세요 (저는 3번이 적당했어요)
- 사람이 직접 받았다면 로컬 파일 경로 그대로 AI에게 알려주면 돼요 — AI가 그 경로에서 바로 읽을 수 있어요
내가 만든 검증 도구도 검증이 필요했습니다
1주차 회고를 이렇게 끝냈습니다. “이번 주에 만든 건 터라서 눈에 안 보였습니다. 2주차에는 화면에 보이는 게 나옵니다.”
그 말대로 됐습니다. 2주차엔 논문 10편이 실제로 사이트에 떴고, 검색창에 단어를 치면 잡히고, 명령 한 줄로 점검이 되고, 질문 한 줄로 답이 나오고, 마지막엔 인터넷 어디서나 열리는 주소까지 생겼습니다.
그런데 이 글에서 진짜 하고 싶은 이야기는 그 결과물 목록이 아닙니다. 만든 걸 만들고 끝내지 않고, 다시 검증했더니 실제 버그가 나온 순간이 이번 주를 꿰는 진짜 이야기입니다. 일곱 장면으로 나눠서, 이번엔 실제로 쓴 명령과 나온 결과를 그대로 옮겨가며 풀겠습니다.
누구에게 도움이 될까요 — AI와 뭔가를 만들고 “됐다, 통과했다”에서 멈추는 게 불안한 분입니다. 코딩을 몰라도 읽을 수 있게 썼습니다.
그 전 — 1주차 끝의 저
문서만 있었습니다. 기획서(PRD), 실행계획(세부계획 12단계), 규칙집(SCHEMA.md). 전부 “이렇게 하겠다”는 약속이었고, 실제로 작동하는 건 하나도 없었습니다.
장면 1 — 논문 1편을 먼저 끝까지 통과시켰습니다
세부계획에 “논문 10편을 한꺼번에 넣지 말고, 1편을 먼저 끝까지 통과시켜 양식을 굳힌 뒤 늘린다”고 미리 적어뒀습니다. 이유가 있었습니다 — 양식이 틀린 채로 10편을 넣으면 10편을 다 고쳐야 하니까요.
그대로 했습니다. BNNT 리뷰 논문 하나로 SCHEMA의 일곱 칸을 다 채웠는데, 그중 여섯 번째 칸이 제일 손이 많이 갔습니다.
## 6. 한계
**저자가 밝힌 한계**: 별도의 "Limitations" 절은 없지만, 결론(§3 Summary)에서
"합성법들이 BNNT의 질과 양을 크게 개선했지만, 동시에 비정질 붕소·질화붕소·
h-BN 같은 부산물이 생겨 순도를 떨어뜨리는 부작용이 있다"고 명시했다.
**읽으면서 느낀 한계**:
- 다섯 가지 합성법을 수율·순도·비용 기준으로 나란히 비교한 정량 표가 없다.
- BNNT의 TEM 관찰·특성분석 자체를 다루는 절이 없다 — 지금 제 관심사인
TEM 이미지 분석 쪽과는 직접 연결되지 않는다.
SCHEMA.md가 이 칸을 이렇게 못박아둔 이유를 그제야 이해했습니다: “논문 요약 도구 대부분이 결과만 뽑고 한계는 버린다. 그런데 이 방법을 내가 진짜 쓸 수 있나를 판단할 때 결정적인 건 한계다.” 실제로 써보니 정말 그랬습니다 — 결과만 봤으면 “좋은 논문이네”로 끝났을 텐데, 한계를 억지로 채우면서 “TEM 관찰을 안 다룬다”는, 제 관심사와 안 겹치는 지점까지 스스로 알아챘습니다.
양식을 굳힌 다음엔 사이트 검색창(astro-pagefind)을 붙였습니다. 인터넷 글은
전부 부품 두 개를 따로 설치하라고 했지만, 실제 등록 정보를 열어보니 최신
버전은 하나가 다른 하나를 이미 품고 있었습니다.
npm i astro-pagefind
이 한 줄로 끝났습니다. (1주차부터 반복된 패턴입니다 — 인터넷 글은 쓰인 시점에 멈춰 있고, 등록 정보가 지금을 보여줍니다.)
장면 2 — 논문을 늘리다가 페이월에 세 번 막혔습니다
논문을 4편, 그다음 10편까지 늘리는 중이었습니다. 마지막 AI 논문 자리에 SHINE(TEM 이미지 디노이징 논문)을 넣으려는데, PDF가 페이월에 막혀 있었습니다.
1차 — 직접 다운로드
curl -sL -o "shine.pdf" "https://www.science.org/doi/pdf/10.1126/sciadv.ads5552"
결과: PDF가 아니라 5.4KB짜리 HTML 껍데기만 왔습니다. 페이지가 JS로
렌더링되는 방식이라 curl로는 겉모습만 받아지는 것이었습니다.
2차 — PMC(오픈액세스 미러)
Science Advances는 원래 오픈액세스 저널이라 PMC에 무료 사본이 있을 거라
생각했는데, curl로 검색하니 빈 결과만 나왔습니다.
3차 — 대학 리포지토리
curl -sL -o "shine.pdf" "https://scholarworks.bwise.kr/erica/bitstream/.../....pdf"
이번에도 657바이트짜리 HTML만 받아졌습니다.
세 번 다 막히니 AI가 더 파고들지 않고 이렇게 멈췄습니다: “이 세 경로를
시도했는데 다 막혔습니다. 못 구했습니다.” 제가 브라우저로 직접 로그인해서
받은 다음, 로컬 파일 경로(~/Downloads/sciadv.ads5552.pdf)만 알려주니
AI가 그 경로에서 바로 읽어 논문 노트를 완성했습니다. 자동화 시도 3번(각
1~2분)과 사람이 직접 받아 넘긴 몇 분을 더해도, 계속 다른 우회로를 찾아
헤맸을 때보다 훨씬 빨랐습니다. (더 자세한 과정은
페이월 사례글에 있습니다.)
여기서 배운 개념: “오픈액세스”라는 말이 “자동화 도구로 바로 받을 수
있다”는 뜻은 아니라는 것입니다. 사람이 브라우저로 열면 문제없이 보이는
페이지도, curl 같은 자동화 요청은 봇 차단(JS 챌린지)에 걸려 껍데기만
받는 경우가 있었습니다.
장면 3 — 개념 페이지 하나로 소재·바이오·AI가 이어졌습니다
논문 노트를 그냥 쌓기만 하면 흩어진 자료입니다. 여기서 처음 만든 개념 페이지 “TEM(투과전자현미경) 관찰”이 그 흩어진 걸 잇는 첫 실이었습니다.
같은 도구(TEM)라도 리뷰·in-situ 관찰·품질 검증·이미지 자체의 노이즈
제거라는 네 가지 다른 역할로 쓰인다는 게, 이 개념 페이지가 논문 노트만
따로 읽어서는 안 보이던 연결을 만들어준다. 소재·바이오·AI 세 주제가
전부 이 개념 하나로 묶인다.
- BNNT 리뷰(소재): 합성법마다 “정말 나노튜브가 만들어졌는지” 사후 확인
- 페로브스카이트(소재): 가열하며 “분해되는 과정 자체”를 실시간 촬영
- 오소리기름 항균 나노섬유(바이오): “은나노입자가 잘 분산됐는지” 검증
- SHINE(AI): “TEM 이미지 자체의 노이즈를 어떻게 없앨지”가 논문의 핵심
같은 도구를 완전히 다른 목적으로 쓰는 논문 네 편이 한 페이지에 모이는 걸 보고, 세부계획에 적어뒀던 “개념 페이지는 주제 다른 논문 여러 편이 걸릴 때 값이 생긴다”는 말이 그냥 문서 속 문장이 아니라는 걸 실감했습니다. (뒤에서 나오지만, 이때는 이 넷 말고 세 편이 더 걸려 있어야 했는데 빠져 있었습니다 — 장면 5에서 이어집니다.)
장면 4 — 논문 10편을 직접 넣어보고 신기했습니다
6단계에서 남은 6편(소재2·바이오2·AI2)을 더 넣어 총 10편을 채웠습니다. 이번 주를 돌아보며 제일 기억에 남는 걸 골라보라고 했을 때, 저는 망설임 없이 **“직접 나의 자료 논문 10편을 시도해본 것”**을 꼽았습니다. 이유를 물었더니 답은 짧고 명확했습니다 — “직접 작동하는 것을 보면서 신기했다.”
계획을 문서로 짤 때보다, 내 자료가 실제로 사이트에 뜨고 검색되고 질문에 답하는 걸 눈으로 볼 때가 훨씬 크게 와닿았다는 것입니다. 이게 왜 중요하냐면, 1주차 회고에서 “개념을 먼저 잡아두는 게 시간 낭비가 아니었다”고 적었는데, 2주차는 그 반대쪽 확인이었기 때문입니다 — 개념을 아무리 잘 잡아도, 실제로 돌려봐야 진짜인지 압니다.
장면 5 — 점검 도구를 만들었는데, 그 도구 자체가 허술했습니다
여기가 이번 주의 진짜 전환점입니다.
논문 10편, 개념 페이지 1개까지 쌓이니 SCHEMA 규칙(빈 칸 없이 채우기,
원문에 없는 문장 인용 금지, 위키링크 양방향 연결)을 매번 눈으로 확인하기
버거워졌습니다. 그래서 점검 명령 knowledge/lint.mjs를 만들었습니다. 만들고
나서 그냥 믿지 않고, 일부러 문제 4개를 심은 가짜 논문 파일로 테스트했습니다.
npm run lint:knowledge
## 빈항목 (1건)
- 2099-test-broken.md — '## 6. 한계' 항목이 비어있음
## 끊긴링크 (1건)
- 2099-test-broken.md — /papers/no-such-paper 대상 페이지 없음
## 인용확인필요 (1건)
- 2099-test-broken.md — 원문에서 못 찾음: "이건 원문에 절대 없는..."
총 3건 발견.
넷 다 잡혔고, 실제 논문 10편은 문제 0건이었습니다. 여기서 끝냈으면 좋은 하루였을 겁니다. 그런데 이렇게 물어봤습니다.
지금까지 만든 걸 봐줘. 돌아가긴 하는데 어딘가 허술한 것 같아.
어디가 부족한지 짚어주고, 그중 지금 고치면 제일 효과 큰 것부터 알려줘.
1순위로 나온 답이 뜻밖이었습니다 — “링크가 죽었는지 확인하는 것”과 “링크가 SCHEMA §7의 양방향 규칙대로 걸려 있는지 확인하는 것”은 완전히 다른 검사인데, lint가 후자를 아예 안 보고 있다는 지적이었습니다. 실제 데이터를 열어봤습니다.
awk '/## 관련 개념/,0' src/content/papers/*.md | grep -c "tem-observation"
# → 7편이 tem-observation으로 링크를 걺
논문 쪽은 7편이 링크를 걸고 있었는데, 개념 페이지 “TEM 관찰” 쪽 “어느 논문에서 나왔나” 절에는 4편(BNNT 리뷰·페로브스카이트·오소리기름· SHINE)만 돌아오는 링크가 있었습니다. BNNT 이중성장·BNNT 벽수제어(겸 수질정화)·Ag-ZnO 광촉매 항균, 이 세 논문이 개념 페이지 쪽에서 안 잡혀 있었던 것입니다. 점검을 통과했다는 사실이, 정작 그 점검이 안 보는 종류의 문제까지 숨겨버린 셈이었습니다.
검사 항목을 두 개 더 추가했습니다.
## 일방통행 (3건)
- 2015-adhikari-agzno-photocatalyst.md → /concepts/tem-observation
링크는 있는데, tem-observation.md에는 이 논문으로 돌아오는 링크가 없음
- 2019-kim-bnnt-dual-growth.md → /concepts/tem-observation
링크는 있는데, tem-observation.md에는 이 논문으로 돌아오는 링크가 없음
- 2020-cho-bnnt-water-purification.md → /concepts/tem-observation
링크는 있는데, tem-observation.md에는 이 논문으로 돌아오는 링크가 없음
총 3건 발견.
정확히 예상한 3건이 잡혔습니다. 개념 페이지에 빠진 역링크 3개를 채운 뒤
다시 돌리니 문제 0건이 됐습니다. 여기에 하나 더 — 원본: frontmatter
값이 실제 파일과 일치하는지 대조하는 검사도 추가해서, 지금은 lint가
빈항목·끊긴링크·인용확인필요·일방통행·원본불일치 5가지를 봅니다.
장면 6 — 질문하면 답+출처+원문 인용이 같이 나오는 걸 확인했습니다
lint 다음은 세부계획 8단계 — 질문 명령이었습니다. 벡터 검색은 3주차
몫이라, knowledge/ask.mjs는 키워드로 먼저 만들었습니다. 실제로 물어봤습니다.
npm run ask:knowledge -- "BNNT 수율"
1. Boron nitride nanotubes: synthesis and applications (논문, 점수 61)
출처: /papers/2018-kim-bnnt-synthesis
답(2. 연구문제): "BNNT는 1995년 첫 합성 이후 CNT에 비해 수율과 품질이
낮아 실용화가 막혀 있었는데, 지금까지 어떤 합성법들이 이 문제를
얼마나 풀었고 어떤 응용까지 왔는가"를 정리하는 것이 목적이다.
원문 인용: "Since BNNT was first synthesized in 1995, developing
efficient BNNT production route has been a significant issue due
to low yield and poor quality in comparison with CNT..."
한 줄 명령에 답(발췌)·출처 논문·원문 인용 세 가지가 다 나왔습니다. “TEM 디노이징”으로도 물어봤는데, 이번엔 SHINE 논문뿐 아니라 개념 페이지(“TEM 관찰”)까지 같이 잡혔습니다 — 장면 3에서 만든 개념 페이지가 검색 결과에도 도움이 되는 걸 처음 확인한 순간이었습니다.
장면 7 — GitHub에 올리고, 배포까지 끝냈습니다
마지막으로 지금까지 만든 걸 실제로 인터넷에 올렸습니다.
git push origin main
vercel --prod --yes
Production: https://learning-m1gd46115-jun-hee-kim-s-projects.vercel.app [23s]
Aliased: https://learning-hub-virid.vercel.app [23s]
배포 로그에 주소가 두 개 뜨는 게 눈에 띄었습니다. 하나는 이번 배포
하나에만 붙는 일회용 스냅샷 주소였고, 다른 하나(learning-hub-virid. vercel.app)는 “지금 프로덕션은 이거야”라고 가리키는 고정 별칭
(alias)이었습니다. 1주차에 옛 배포 URL 7개를 찾아 지웠던 이유가 바로
이 스냅샷 주소들이 배포할 때마다 계속 새로 생기기 때문이었는데,
alias 방식 덕분에 사람들에게는 항상 같은 주소 하나만 알려주면
된다는 걸 다시 확인했습니다.
배포 뒤엔 실제로 접속해서 확인했습니다.
curl -s -o /dev/null -w "HTTP %{http_code}\n" https://learning-hub-virid.vercel.app
# HTTP 200
프로젝트 카드 페이지(/projects/my-knowledge-system)에 들어가보니
“작업 기록” 아래에 이번 주 사례글까지 자동으로 붙어 있었습니다 —
사례글 프론트매터에 프로젝트: my-knowledge-system만 적으면 알아서
연결되는 구조를 1주차에 만들어뒀는데, 그게 그대로 작동했습니다.
그래서 어떻게 됐나
| 한 주 전 | 지금 | |
|---|---|---|
| 논문 노트 | 0편 | 10편 (소재4·바이오3·AI3) |
| 개념 페이지 | 0개 | 1개 (논문 7편이 이 하나로 연결됨) |
| 점검 명령 | 없음 | lint:knowledge — 5가지 검사(빈항목·끊긴링크·인용·양방향링크·원본대조) |
| 질문 명령 | 없음 | ask:knowledge — 키워드로 답+출처+원문 인용 반환 |
| 사이트 | 검색창 없음, 배포 안 됨 | 검색창 + /papers·/concepts 페이지 + GitHub 푸시·Vercel 프로덕션 배포 |
| 커밋 | — | 22개 |
배운 것
점검 도구가 있다는 사실 자체가 안심의 근거가 되면 안 됩니다. “lint를 돌렸는데 통과했다”는 “그 lint가 보는 항목에 한해” 문제가 없다는 뜻일 뿐입니다. 애초에 안 보는 종류의 문제는 통과와 상관없이 그대로 숨어 있을 수 있습니다. 제가 처음 만든 lint는 “링크가 존재하는가”만 봤고 “링크가 규칙대로 쌍을 이루는가”는 안 봤는데, 그 틈에 실제 버그가 몇 시간째 있었습니다.
“다 됐어?”보다 “허술한 데 짚어주고, 효과 큰 것부터”가 훨씬 나은 질문이었습니다. 그냥 봐달라고 하면 막연한 확인으로 끝나기 쉬운데, 우선순위를 매겨달라고 구체적으로 물으니 실제로 고칠 가치가 있는 지점을 순서대로 받을 수 있었습니다.
AI도 세 번 막히면 넷째부터는 사람에게 넘기는 게 맞습니다. 페이월 사건에서, AI가 계속 다른 우회로를 찾는 대신 “이 세 경로를 시도했는데 다 막혔다”고 구체적으로 보고했습니다. 제가 브라우저 로그인 한 번으로 몇 분 안에 풀렸으니, 그 판단이 맞았습니다.
결과물보다 태도가 남았습니다. 논문 10편, 점검 명령, 질문 명령, 배포 주소 — 이 목록보다, “만든 걸 믿지 않고 다시 검증하는 습관”이 이번 주 진짜 수확입니다.
가져가서 쓰세요
만든 걸 다시 검증받는 프롬프트
만들고 나서 “됐다”로 끝내지 말고 이렇게 물어보세요. 우선순위가 있는 답이 옵니다.
지금까지 만든 걸 봐줘. 돌아가긴 하는데 어딘가 허술한 것 같아.
어디가 부족한지 짚어주고, 그중 지금 고치면 제일 효과 큰 것부터 알려줘.
점검 도구 자체를 점검하는 체크리스트
- 검사 항목마다 “이게 정확히 뭘 보고, 뭘 안 보는지” 한 줄로 적을 수 있습니까? (못 적으면 항목이 애매한 것입니다)
- 일부러 틀린 데이터를 만들어서 진짜로 잡히는지 테스트했습니까?
- “존재하는가”와 “관계가 규칙대로 완전한가(양방향 등)“를 따로 구분해서 검사합니까?
- 만든 뒤 다시 검토를 요청했습니까? (같은 사람/AI가 “됐다”고 끝내지 않기)
AI가 파일을 못 받아올 때 체크리스트
- 직접 URL 다운로드를 시도했습니까? (
curl -sL -o 파일명 URL) - 받은 파일이 진짜인지 확인했습니까? (
file 파일명— “HTML”이면 실패) - 오픈액세스 미러(PMC·arXiv 등)도 시도했습니까?
- 몇 번까지 시도하고 사람에게 넘길지 미리 정해뒀습니까? (저는 3번이 적당했습니다)
배포 확인 체크리스트
- 배포 로그의 “Production”과 “Aliased” 주소가 다르다면, 사람들에게는 Aliased(고정) 주소를 알려주세요.
- 배포 후
curl -s -o /dev/null -w "%{http_code}"로 실제 응답 코드를 확인하세요. - 새로 추가한 페이지가 실제로 열리는지 주소 하나는 직접 열어보세요.
다음 주
이미 세부계획에 3주차가 정해져 있습니다. 평가 질문 10개와 채점 방식을
먼저 확정하고(벡터를 붙이기 전에 채점 기준부터 정해야 결과를 부풀리지
않는다는 원칙), 지금 만든 ask.mjs(가벼운 검색)로 먼저 기준 점수를
매긴 다음, 벡터 검색을 얹어서 같은 질문으로 비교합니다.
이번 주에 제일 크게 배운 건 결과물이 아니라 태도였습니다. 만든 걸 믿지 않고 다시 검증하는 습관, 그게 다음 주에도 그대로 갑니다.
3주차
공들여 만든 벡터 검색이 키워드 검색한테 졌어요
3주차는 “벡터 검색을 얹으면 당연히 더 좋아지겠지”라는 기대로 시작했어요. 결론부터 말하면, 안 그랬어요. 이 글은 그 결과를 어떻게 받아들이고 기록했는지에 관한 이야기예요.
누구에게 도움이 될까요 — 새 기술(벡터·임베딩·RAG)을 붙이기 전에 “정말 필요한지” 재보고 싶은 분이요. 코딩을 몰라도 읽을 수 있게 썼어요.
Before — 왜 벡터 검색을 붙이려 했나
2주차까지 만든 ask.mjs는 키워드 부분일치로 검색해요. 세부계획에 처음부터 “3주차는 벡터를 얹어서 비교한다”고 적어뒀었고, “노트 500~1,000편 이하면 벡터가 필요 없다”는 원칙도 같이 적어뒀어요. 지금 논문이 21편이니, 이 원칙이 정말 맞는지 실측으로 확인해볼 참이었어요.
막힘 1 — 청킹 대상을 잘못 골랐어요
처음엔 논문 노트(SCHEMA 7칸 요약)를 청킹했어요. 만들고 나서 이렇게 물었더니
논문 원문을 청킹해서 벡터디비로 저장하는거지?
바로 걸렸어요. 노트는 이미 골라 뽑은 요약이라, 청킹해봤자 요약을 다시 요약하는 꼴이었어요. knowledge/raw/(논문 전문)를 논문 자체의 ## 절 제목 경계로 다시 청킹했어요 — 107개 청크에서 128개로 늘었어요.
막힘 2 — DuckDB가 “저장 완료”라고 거짓말했어요
임베딩까지 다 만들고 저장 스크립트를 돌렸더니:
청크 128개를 임베딩합니다...
DuckDB에 128개 청크 저장 완료
성공한 것처럼 보였어요. 그런데 실제로 질문을 던지니 “일치하는 청크를 못 찾았다”고 나왔어요. 직접 세어봤어요.
SELECT count(*) FROM chunks;
-- 결과: 0
0행이었어요. 원인을 찾아보니, DuckDB의 Node.js 드라이버가 ? 파라미터로 넘긴 JS 배열을 FLOAT[384](384차원 벡터) 타입으로 못 바꾸고 조용히 실패하는 버그였어요.
Conversion Error: Type VARCHAR with value '1,2,3' can't be cast to
the destination type FLOAT[3]...
에러 메시지조차 콜백을 안 넘기면 안 보이는 조용한 실패였어요. 벡터를 SQL 문자열 안에 직접 박아 넣는 방식([0.01, -0.02, ...]::FLOAT[384])으로 바꿔서 고쳤고, 그제야 진짜 128행이 들어갔어요.
진짜 결과 — 그리고 실망
파이프라인이 다 돌아간 뒤, 9단계에서 썼던 것과 똑같은 질문 10개로 다시 채점했어요.
| 키워드 검색(9단계) | 벡터 검색(11단계) | |
|---|---|---|
| 점수 | 21/40 (52.5%) | 9/40 (22.5%) |
기대와 반대였어요. 예를 들어 “SHINE 자기지도 학습 노이즈 제거 방식”을 물었더니, SHINE 논문은 top-3 안에도 안 들어오고 엉뚱하게 TEM 개념 페이지가 1위로 나왔어요. “CatBoost Amazon 데이터셋 성능 차이”를 물었을 때도, 전혀 관계없는 “키워드 검색 vs RAG” 논문이 1·2위를 가로챘어요.
이 결과를 보고 처음 든 느낌은 실망이었어요. 파이프라인 만드는 데 손이 많이 갔는데, 정작 점수는 더 나쁘게 나왔으니까요.
After — 그래도 그대로 기록했어요
원인을 파봤어요. 128개밖에 안 되는 작은 코퍼스에서는 1위와 3위의 유사도 차이가 0.020.05 수준일 때가 많았어요 — 이 정도는 신호라기보다 노이즈에 가까워요. 그리고 “오답”이라고 채점한 질문 중 절반은 정답 논문이 23위엔 있었어요.
| 벡터 검색 결과 | |
|---|---|
| 정답이 1위 | 3문항 |
| 정답이 2~3위(1위는 틀림) | 4문항 |
| 정답이 top-3 밖 | 3문항 |
결론: 지금 이 규모(논문 21편)에서는 벡터 검색을 쓸 이유가 없어요. 세부계획에 처음부터 적어뒀던 “500~1,000편 이하면 벡터 불필요”라는 원칙이 실측으로 확인된 거예요. ask.mjs(키워드)가 그대로 기본 검색으로 남고, 벡터 파이프라인은 나중에 논문이 훨씬 늘어나면 다시 켜서 재평가하기로 했어요.
배운 것
“성공했다”는 로그를 그대로 믿으면 안 돼요. DuckDB가 “128개 저장 완료”라고 찍었는데 실제론 0행이었어요. SELECT count(*)로 직접 세어보지 않았으면 몇 개월 동안 빈 데이터베이스로 검색하는 줄도 몰랐을 거예요.
결과가 기대와 다르게 나왔을 때, 포장하지 않고 그대로 적는 게 더 값져요. “벡터가 최신이니까 낫겠지”라는 성급한 가정을 실측으로 반증한 거예요. 실망스러운 결과지만, 이게 데이터 사이언티스트가 실제로 하는 일이에요 — 새 기법을 도입하기 전에 정말 필요한지 재보고, 필요 없으면 안 쓰는 것.
청킹 대상 하나가 전체 결과를 좌우해요. 노트(요약)를 청킹했다가 원문(raw)으로 바꾼 것처럼, 검색 품질은 “어떤 텍스트를 검색 대상으로 삼았는가”에서 이미 절반이 갈려요.
가져가서 쓰세요
”성공했다”는 로그를 의심하는 체크리스트
- 저장·삽입 스크립트가 “완료”라고 찍으면, 별도 명령으로 실제 행 수를 세어봤나요? (
SELECT count(*)같은) - 배치 삽입에 에러 콜백을 빠뜨리지 않았나요? (콜백 없으면 실패가 조용히 묻힙니다)
- 결과가 0건이거나 비어 있을 때, “데이터가 없어서”가 아니라 “저장이 실패해서”일 가능성을 먼저 의심했나요?
새 기법을 붙이기 전에 재보는 프롬프트
이 기법(예: 벡터 검색)을 붙이기 전에, 지금 있는 방식으로 먼저
기준선을 채점해줘. 같은 질문·같은 기준으로 새 기법도 채점해서
두 점수를 나란히 비교해줘. 새 기법이 이겨야 한다고 가정하지 말고.
다음 주
이미 세부계획에 정해져 있어요 — 새로 만들지 않고 회고·발표자료·전자책 정리로 마무리해요.
4주차
배포했는데 "서버가 안 되는 것 같아요" — 원인이 다른 장애 3개를 하루에 잡은 이야기
📝 한줄 요약
지식체계 사이트에 그래프뷰와 챗봇을 새로 붙이고 배포했는데, 실제로 접속해보니 안 됐어요. 원인을 하나씩 벗겨보니 서로 무관한 장애 3개가 겹쳐 있었어요 — ① 배포 자체가 조용히 실패한 것, ② 사이트 설정에 적힌 주소가 실제 배포 주소와 달랐던 것, ③ 새로 추가한 패키지가 기존 설정과 버전 충돌을 일으킨 것. 셋 다 로컬에서는 멀쩡한데 실제 배포에서만 드러나는 유형이라, “로컬 빌드 성공 = 다 됐다”가 아니라는 걸 제대로 겪었어요.
바쁘시면 이것만 읽어도 돼요:
- 배포 후 확인은
npm run build가 끝난 화면이 아니라, 실제 배포된 주소에 직접 접속해서 해야 해요. 둘은 다른 걸 보장해요. - “안 된다”는 말을 들으면 바로 코드부터 고치지 말고, 먼저 어떤 상태인지 로그로 확인하는 게 순서예요. 배포 플랫폼은 대부분
--logs같은 명령으로 실패 원인을 그대로 보여줘요. - 여러 도구·설정을 조합해 쓸 때는, 각각이 요구하는 버전 조건이 서로 맞는지 미리 봐야 해요. 하나를 고치려고 버전을 올렸다가 다른 하나가 깨지는 경우가 실제로 있어요.
Before — 배포는 됐다는데, 실제로는 안 됨
그래프뷰(/concepts 하단 인터랙티브 그래프)와 챗봇(사이트 전역 우측 하단 위젯)을 새로 만들어서 커밋·push했어요. 이 기능들이 서버에서 API를 호출해야 해서, 사이트를 완전 정적(static)에서 하이브리드(서버 함수 포함) 모드로 바꾸는 구조적 변경도 같이 들어갔어요. push하고 나서 “서버가 작동안하는것 같은데”라는 말을 들었어요.
과정 — 장애 3개를 순서대로 벗겨냄
1단계 — 배포 상태부터 확인
바로 코드를 뒤지지 않고, 먼저 실제로 무슨 일이 있었는지부터 봤어요.
vercel ls
최신 배포가 ● Error 상태였어요. 로그를 봤어요.
vercel inspect <배포주소> --logs
The following Serverless Functions contain an invalid "runtime":
- _render (nodejs18.x)
원인: 쓰고 있던 Vercel 어댑터(@astrojs/vercel@7.8.2)가 내부적으로 Node 18·20만 알고 있었어요. 그런데 Vercel의 클라우드 빌드 환경은 이미 Node 24를 기본으로 쓰고 있었고, 어댑터는 모르는 버전을 만나면 무조건 “nodejs18.x”로 폴백하도록 짜여 있었어요. 문제는 Vercel이 그 nodejs18.x 런타임 자체를 이미 완전히 없애버려서, 폴백한 값이 애초에 유효하지 않았던 거예요.
해결: 어댑터가 아는 버전(20.x)으로 강제 고정했어요.
// package.json
"engines": { "node": "20.x" }
다시 배포하니 ● Ready로 성공했어요.
2단계 — “논문 페이지도 안 된다”는 새 제보
배포는 성공했는데, 이번엔 “논문 페이지도 작동을 안하네”라는 말을 들었어요. 서버 쪽부터 다시 확인했어요.
curl -sL -o /dev/null -w "%{http_code}\n" https://my-learning-hub.vercel.app/papers
# → 200 (근데 최종 도착지를 보니 auth/login 페이지)
서버는 200을 주는데, 실제로 도착한 곳이 로그인 페이지였어요. astro.config.mjs에 적혀 있던 site: 'https://my-learning-hub.vercel.app'이 애초에 이 프로젝트의 실제 주소가 아니었던 거예요 — 다른 곳으로 리다이렉트되는 이름이었어요.
vercel project ls
# → learning-hub 프로젝트의 실제 주소: learning-hub-virid.vercel.app
실제 주소로 바꾸고 다시 확인하니 논문 페이지도 정상이었어요. (사실 이 시점엔 서버는 처음부터 멀쩡했고, 안내된 주소가 틀렸던 것뿐이었어요.)
3단계 — 챗봇 프로바이더를 바꾸다가 또 충돌
챗봇을 처음엔 Vercel AI Gateway로 Claude를 부르게 만들었는데, 이미 다른 프로젝트용으로 발급해둔 OpenAI 키를 재사용하기로 방향을 바꿨어요. @ai-sdk/openai 패키지를 설치했더니:
npm warn EBADENGINE Unsupported engine
required: { node: '20.x' }, current: { node: 'v22.23.1' }
@ai-sdk/openai는 Node 22 이상을 요구하는데, 1단계에서 어댑터 호환 때문에 20.x로 고정해둔 것과 정면으로 충돌했어요. 20.x를 22.x로 올리면 1단계 문제가 재발하고, 그대로 두면 이 패키지가 안 돌아가는 딜레마였어요.
해결: SDK 패키지 자체를 빼고, OpenAI Chat Completions API를 fetch로 직접 호출했어요. 추가 의존성 없이 표준 REST 호출 하나면 충분했어요.
const res = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
body: JSON.stringify({ model: 'gpt-4.1-mini', messages: [...] }),
});
After — 뭐가 달라졌나
| Before | After | |
|---|---|---|
| 배포 상태 | ● Error (조용히 실패) | ● Ready |
| 안내한 주소 | 남의 로그인 페이지로 리다이렉트 | 실제 프로덕션 주소로 정확히 도착 |
| 챗봇 의존성 | SDK 버전 충돌로 설치 불가 | 의존성 0개 추가, REST 직접 호출로 정상 동작 |
| 검증 방식 | npm run build 성공만 확인 | 실제 배포 주소에 curl로 직접 확인 |
배운 것
“빌드 성공”과 “실제로 된다”는 다른 말이에요. 로컬 npm run build가 끝까지 돌았다고 해서 배포 환경에서도 똑같이 동작한다는 보장은 없어요. 오늘 겪은 세 문제 모두 로컬에서는 아무 신호가 없었고, 실제 배포 주소에 접속하거나 배포 로그를 봐야만 드러났어요.
“안 된다”는 제보는 원인을 특정하지 않아요. 같은 “안 된다”는 말이 이번엔 세 번 다 다른 원인이었어요(“서버가 안 됨” → 배포 실패, “논문 페이지가 안 됨” → 주소 오안내, 이후 새로 발견 → 버전 충돌). 매번 “어디가 어떻게 안 되는지” 로그·상태부터 다시 확인하는 게, 짐작으로 코드를 고치는 것보다 빨랐어요.
여러 도구의 버전 요구사항은 서로 부딪힐 수 있어요. 어댑터 때문에 Node 20으로 고정했는데, 나중에 추가한 패키지는 Node 22를 요구했어요. 하나를 고치면 다른 하나가 깨지는 상황에서는, 둘 다 만족시키려 하기보다 아예 그 의존성을 빼는 선택지(SDK 대신 REST 직접 호출)가 더 깔끔했어요.
재사용 자산 — 배포가 “안 된다”는 말을 들었을 때 확인 순서
-
vercel ls(또는 쓰는 플랫폼의 배포 목록)로 최신 배포가 실제로 성공(Ready) 상태인지부터 본다 - 실패했다면
--logs로 원인 문구를 그대로 읽는다 — 짐작하지 않는다 - 성공했다면, 설정 파일에 적힌 주소가 아니라 플랫폼이 알려주는 실제 배포 주소로 직접 접속해서 확인한다
-
curl -sL -o /dev/null -w "%{http_code}"로 페이지가 최종적으로 어디 도착하는지(리다이렉트 포함) 확인한다 - 새 패키지를 추가하기 전에
npm install경고(EBADENGINE등)를 그냥 넘기지 않고, 기존에 고정해둔 버전 조건과 부딪히지 않는지 본다 - SDK 하나 때문에 버전 충돌이 생기면, “SDK 없이 표준 API를 직접 호출”이 더 간단한 해결일 수 있다는 걸 후보로 둔다