AI 워크플로우
이 프로젝트는 Claude Code로 만들어졌습니다. 대부분의 “AI로 만들었습니다”라는 주장은 라벨에서 멈춥니다. 여기에 전체 그림이 있습니다: AI가 무엇을 알고 있는지, 세션이 어떻게 작동하는지, 프롬프팅이 실제로 어떤 모습인지, 그리고 사람이 어디에서 선을 긋는지. AI로 직접 무언가를 만들고 있거나, 실제로 어떤 모습인지 궁금하다면, 이 문서가 도움이 될 것입니다.
AI가 알고 있는 것
섹션 제목: “AI가 알고 있는 것”Claude Code는 세션 간에 맥락을 유지하는 영구 메모리 파일을 가지고 있습니다. 매 대화마다 코드베이스를 다시 탐색하는 대신, 마지막으로 멈춘 곳에서 이어서 시작합니다. 다음은 그 안에 포함된 내용입니다(민감 정보 제거됨):
프로젝트 정체성
섹션 제목: “프로젝트 정체성”- 앱 이름, 소스 위치, 라이선스, 앱 식별자
- 포크 관계: 업스트림은 Francisco Salgueiro의 En Croissant이며, 우리는 독립적으로 자체 포크를 유지합니다
- 포크가 존재하는 이유: 업스트림 메인테이너가 TTS 기능을 거절했으며, 이는 타당합니다 — 같은 프로젝트에 대한 다른 비전
빌드 규칙
섹션 제목: “빌드 규칙”- pnpm만 사용 — npm은 vanillaExtract를 깨뜨립니다(런타임에 흰 화면, 에러 없음, 아무것도 표시되지 않음)
- Node.js 22+ 필수 (Vite 7에
crypto.hash필요) - 커밋 전 항상
pnpm format && pnpm lint:fix실행 - 바이너리를 덮어쓰기 전에 앱을 닫을 것 (“Text file busy”)
- 소스 디렉토리 이동 후
cargo clean으로 오래된 경로 참조 정리
아키텍처 지식
섹션 제목: “아키텍처 지식”- 어떤 파일이 어떤 기능을 담당하는지 (
atoms.ts의 atom들,tree.ts의 트리 네비게이션,tts.ts의 TTS 엔진) - 모든 TTS atom에
getOnInit: true가 필요한 이유 (React가 구독하기 전에store.get()을 통한 명령형 읽기) - 오디오 캐시 작동 방식 (
provider:voiceId:lang:text키) - chessground 좌표 수정은 CSS 측에서 이루어지며, 라이브러리 포크가 아님
- 데이터 레이아웃: 무엇이 어디에 있고, 무엇이 심볼릭 링크이며, 무엇이 앱 재시작 후에도 유지되는지
AI가 모르는 것
섹션 제목: “AI가 모르는 것”메모리에는 API 키, 비밀번호 또는 자격 증명이 포함되어 있지 않습니다. 저장 위치(localStorage atom 이름)를 참조하지만 실제 값은 절대 포함하지 않습니다. AI는 설정에서 키를 읽는 코드를 생성하며, 실제 시크릿을 보거나 처리하지 않습니다.
AI에게 지시된 것
섹션 제목: “AI에게 지시된 것”메모리 파일 외에도, Claude Code는 시스템에 내장된 규칙을 따릅니다:
- 과도하게 설계하지 말 것. 직접 요청된 변경만 수행합니다. 버그 수정에는 주변 코드 정리가 필요하지 않습니다. 세 줄의 유사한 코드가 성급한 추상화보다 낫습니다.
- URL을 추측하지 말 것. 링크나 엔드포인트를 절대 만들어내지 않습니다.
- 편집 전에 읽을 것. 읽지 않은 코드에 대한 변경을 제안하지 않습니다.
- 생성보다 편집을 선호할 것. 절대적으로 필요한 경우가 아니면 새 파일을 만들지 않습니다.
- 보안 취약점 없을 것. 인젝션, XSS, OWASP 상위 10개 이슈를 주의합니다.
- 불확실할 때 질문할 것. 지시가 모호하면 추측하지 말고 질문합니다.
- 두 번 재고, 한 번 실행할 것. 파괴적인 작업(force push, reset —hard, 파일 삭제)은 명시적인 사람의 승인이 필요합니다.
좋은 프롬프트 작성하기
섹션 제목: “좋은 프롬프트 작성하기”유용한 AI 상호작용과 답답한 상호작용의 차이는 거의 항상 프롬프트에 있습니다.
원하는 것을 구체적으로 말하십시오. “버그를 고쳐”가 아니라 “TTS 캐시 키에 프로바이더 이름이 포함되지 않아서, ElevenLabs에서 Google로 전환하면 새 오디오를 생성하는 대신 캐시된 ElevenLabs 오디오가 재생됩니다”라고 말해야 합니다.
AI가 모르는 맥락을 포함하십시오. AI는 코드를 읽을 수 있지만, 당신의 마음을 읽을 수는 없습니다. “사용자가 보드의 좌표가 거꾸로라고 보고했습니다”보다 “chessgroundBaseOverride.css의 CSS에서 랭크와 파일이 뒤바뀌어 있습니다 — Francisco의 원본에서 거꾸로 되어 있었습니다”가 더 유용합니다.
제약 조건을 명시하십시오. “새 파일을 만들지 마세요” 또는 “기존 atom 패턴을 사용하세요” 또는 “API 키 없이 작동해야 합니다”는 AI에게 가드레일이 어디에 있는지 알려줍니다.
원하지 않는 것을 말하십시오. “발생할 수 없는 경우에 대한 에러 처리를 추가하지 마세요” 또는 “주변 코드를 리팩토링하지 마세요”는 가장 흔한 AI 실패 모드인 과도한 설계를 방지합니다.
패턴은 다음과 같습니다: 의도 + 맥락 + 제약 조건. 이것을 숙달하면 AI가 극적으로 더 유용해집니다.
계획 모드: 하나의 Claude로 다른 Claude에게 프롬프트하기
섹션 제목: “계획 모드: 하나의 Claude로 다른 Claude에게 프롬프트하기”Claude Code에는 사고와 실행을 분리하는 “계획 모드”가 있습니다. 계획 모드에서 AI는 파일을 읽고, 코드베이스를 탐색하고, 계획을 작성하지만 — 코드는 작성하지 않습니다. 계획을 검토하고 조정한 다음, AI가 실행하는 구현 모드로 전환합니다.
왜 이것이 효과적일까요? 모든 코딩 작업에서 가장 어려운 부분은 코드를 작성하는 것이 아니기 때문입니다. 어떤 코드를 작성할지 — 어떤 파일을 변경할지, 어떤 패턴을 따를지, 어떤 엣지 케이스가 존재하는지 — 파악하는 것이 더 어렵습니다. 계획 모드는 단 한 줄의 코드가 작성되기 전에 그 질문에 온전한 주의를 기울입니다.
이 프로젝트에서의 예시: 언어 선택기를 추가하기 위해 도움말 메뉴를 재구성할 때, 계획 모드 대화에서 Tauri 메뉴가 어떻게 작동하는지, 어떤 atom이 이미 존재하는지, 문서 뷰어가 리소스 경로를 어떻게 해석하는지, 확인 대화상자 API가 어떤 모습인지를 탐색했습니다. 구현 모드로 전환할 때쯤에는 AI가 변경 사항의 완전한 맵을 가지고 있었습니다. 헛된 시작이 없었습니다.
본질적으로 AI의 한 인스턴스를 시니어 아키텍트로, 다른 인스턴스를 개발자로 사용하는 것입니다. 같은 모델, 다른 역할입니다.
세션 작동 방식
섹션 제목: “세션 작동 방식”일반적인 세션은 다음과 같습니다:
-
사람이 의도를 말합니다. “KittenTTS 섹션에 캐싱 참고사항을 추가해.” “PostHog 텔레메트리를 제거해.” “품질 등급이 잘못되었어, 이렇게 되어야 해.”
-
AI가 관련 파일을 읽습니다. 파일에 무엇이 있는지 추측하지 않습니다. 읽고, 현재 상태를 이해한 다음, 변경을 제안합니다. 독립적인 파일은 병렬로 읽힙니다.
-
AI가 변경을 수행합니다. 기존 파일에 대한 타겟 편집입니다. 전체 재작성이 아닌 — 주변의 모든 것을 보존하는 수술적 수정입니다.
-
사람이 검토합니다. 모든 편집은 디스크에 기록되기 전에 표시됩니다. 사람이 승인, 거부 또는 방향을 재지정합니다. “아니, 그건 너무 부드러워 — 진짜로 별로라고 말해.” “그 단락을 위로 올려.” “내가 의도한 게 아니야.”
-
지시받으면 커밋합니다. AI는 자발적으로 절대 커밋하지 않습니다. 사람이 “커밋해” 또는 “커밋하고 푸시해”라고 말합니다. 커밋에는
Co-Authored-By: Claude Opus 4.6이 포함됩니다 — 항상 기여를 명시하며, 절대 숨기지 않습니다.
컨텍스트 윈도우와 세이브 스테이트
섹션 제목: “컨텍스트 윈도우와 세이브 스테이트”모든 AI 대화에는 컨텍스트 윈도우가 있습니다 — 한 번에 메모리에 담을 수 있는 총 텍스트 양입니다. 대화가 충분히 길어지면, 새로운 공간을 만들기 위해 오래된 메시지가 압축됩니다.
두 가지 전략이 있습니다: 대화를 집중적으로 유지하기(대화당 하나의 작업), 그리고 세이브 스테이트 사용하기(Claude Code는 전체 컨텍스트가 복원된 상태에서 다시 시작할 수 있는 JSONL 파일로 대화록을 저장합니다). 메모리 파일은 다른 목적을 가집니다 — 모든 대화에 걸쳐 지속되는 영구 지식 베이스입니다.
AI가 제안한 것 vs. 실제로 배포되는 것
섹션 제목: “AI가 제안한 것 vs. 실제로 배포되는 것”AI의 첫 번째 제안이 최종 버전인 경우는 드뭅니다. 일반적인 교환:
- AI가 합리적인 초안을 작성합니다
- 사람이 “너무 기업적이야” 또는 “더 직접적으로” 또는 “그건 틀렸어, 이유는 이거야”라고 말합니다
- AI가 조정합니다
- 사람이 승인합니다
취향, 톤, 최종 결정은 항상 사람의 몫입니다. AI는 속도를 담당합니다 — 파일을 읽고, 맥락을 이해하고, 메모리에 담을 수 있는 코드베이스 전반에 걸쳐 정밀한 편집을 수행합니다. 사람은 판단을 담당합니다 — 무엇을 만들지, 어떤 느낌이어야 하는지, 언제 멈출지.
스킬과 슬래시 명령
섹션 제목: “스킬과 슬래시 명령”Claude Code는 “스킬”을 지원합니다 — .claude/commands/ 디렉토리에 마크다운 파일로 저장된 재사용 가능한 프롬프트입니다. /translate-docs와 같은 슬래시 명령으로 호출합니다.
이 프로젝트는 문서를 여러 언어로 번역하는 것을 자동화하는 /translate-docs 스킬을 사용합니다. 스킬 파일에는 전체 지시사항이 포함되어 있습니다: 어떤 파일을 번역할지, 어떤 형식을 사용할지, 코드 블록과 링크를 어떻게 처리할지, 어떤 톤을 유지할지. 매번 이 모든 것을 설명하는 대신, /translate-docs만 입력하면 AI가 정확히 무엇을 해야 하는지 알고 있습니다.
스킬은 정보뿐만 아니라 프로세스를 인코딩합니다. 테스트 실행, 배포, PR 리뷰, 변경 로그 업데이트 등 반복되는 모든 워크플로우에 대해 스킬을 만들 수 있습니다.
코딩 원칙
섹션 제목: “코딩 원칙”전체 원칙 문서는 레포지토리의 .claude/01_UNIVERSAL_PRINCIPLES.md에 있습니다. Robert C. Martin의 Clean Code(2008)에 AI 시대를 위한 추가 사항을 더한 것으로 시작했습니다. 그런 다음 여전히 유효한 것과 그렇지 않은 것에 대해 솔직한 대화를 나눴습니다.
시대를 초월하는 것
섹션 제목: “시대를 초월하는 것”- 의도를 드러내는 이름. 항상. 영원히.
- 함수는 하나의 일만 한다. 진정한 원칙은 크기가 아닌 일관성입니다.
- 부작용 없음. 여전히 대부분의 버그의 원인입니다.
- 주석은 무엇이 아닌 왜를 설명한다.
- 단일 책임. 모듈은 변경되어야 할 이유가 하나여야 합니다.
- 구현이 아닌 인터페이스에 대해 프로그래밍한다.
- 에러를 삼키지 않는다. 모든 에러는 정보입니다.
- 창발적 설계: 모든 테스트 통과, 중복 없음, 의도 표현, 복잡성 최소화. 이 순서대로.
맥락에 따른 것
섹션 제목: “맥락에 따른 것”이 원칙들은 건전하지만, 구체적인 규칙은 AI 이전 또는 특정 언어의 세계를 반영합니다. 우리는 글자가 아닌 정신을 적용합니다:
- DRY. 서로 달라지는 중복은 위험합니다. 하지만 반복되는 모든 패턴을 추상화로 추출하면 더 나쁠 수 있는 간접 참조가 생깁니다. 때로는 바로 여기의 세 줄의 읽기 쉬운 코드가 다른 파일의 성급한 추상화보다 낫습니다.
- 엄격한 TDD 의식. 원칙 — 테스트된 코드를 배포하고, 작동하는지 확인하는 것 — 은 타협할 수 없습니다. 의식 — 코드 전에 테스트가 존재해야 한다 — 은 사람이 천천히 타이핑하는 워크플로우를 위해 설계된 것입니다. 테스트를 작성하십시오. 통과하는지 확인하십시오. 테스트가 먼저인지 코드가 먼저인지보다 둘 다 존재하는지가 더 중요합니다.
- 보이스카우트 규칙. “캠프장을 더 깨끗하게 떠나라” — 네. 하지만 보이스카우트는 캠프장을 청소했지, 숲 전체를 청소하지 않았습니다. 건드린 것만 고치십시오. 한 줄을 변경했다고 파일의 전체 구조를 리팩토링하지 마십시오.
AI 시대 추가 사항
섹션 제목: “AI 시대 추가 사항”- 원칙 기반 가이드는 규칙보다 더 잘 확장됩니다. 원칙은 판단을 허용하고, 규칙은 취약합니다.
- 에이전트가 만들었다면, 에이전트가 유지보수할 수 있어야 합니다. 대화 컨텍스트와 아티팩트를 보관하십시오. 결과뿐만 아니라 빌드 프로세스를 문서화하십시오.
- 영리함보다 명확함. 이것을 만든 시스템이 추론을 재구성하고 올바르게 수정할 수 있어야 합니다. 명시적 구조가 작고 영리한 추상화를 이깁니다.
- 이것이 인프라가 될 수 있을까? 도구는 당신의 문제를 해결합니다. 인프라는 다른 사람들이 그 위에 무언가를 만들 수 있게 합니다. 그에 맞게 설계하십시오.
사람이 선을 긋는 곳
섹션 제목: “사람이 선을 긋는 곳”AI는 도구입니다. 놀라울 정도로 뛰어난 도구입니다. 하지만 AI가 하지 않는 것들이 있습니다:
- 제품 결정. 어떤 기능을 만들지, 무엇을 제거할지, 앱이 어떤 느낌이어야 하는지. “시스템 TTS 품질 등급은 ‘그럭저럭’이라고 해야 해, 진짜로 별로니까” — 이것은 실제로 들어본 것에 기반한 사람의 판단입니다.
- 취향. AI는 깔끔한 문장을 쓸 수 있지만, 프로젝트의 목소리, 품질에 대해 솔직하기로 한 결정, Francisco를 눈에 띄게 크레딧하기로 한 선택 — 이것들은 사람의 선택입니다.
- 윤리. PostHog를 제거한 것은 리팩토링 작업이 아니었습니다. “설정 페이지에서는 텔레메트리를 수집하지 않는다고 하는데, 코드에 활성 PostHog API 키가 있어. 이건 거짓말이야. 고쳐.”였습니다. AI가 실행했습니다. 사람이 문제를 식별하고 신경을 썼습니다.
- 체스. 보드는 당신의 도구에 관심이 없습니다.
이것을 공유하는 이유
섹션 제목: “이것을 공유하는 이유”“AI로 만들었습니다”가 의미 없는 말이 되었기 때문입니다. 모든 사람이 말합니다. 아무도 보여주지 않습니다. 흥미로운 질문은 AI가 관여했는지 여부가 아니라 — 어떻게 관여했는지, 그리고 사람이 실제로 무엇을 기여했는지입니다.
이것이 그 답입니다. 사람은 비전, 취향, 판단, 그리고 책임을 가져옵니다. AI는 속도, 기억력, 그리고 새벽 2시에 Rust 에러 메시지를 읽는 지칠 줄 모르는 의지를 가져옵니다.
어느 쪽도 혼자서는 이것을 만들 수 없습니다. 둘 다 크레딧을 받습니다. 그것이 약속입니다.
En Parlant~은 Francisco Salgueiro의 En Croissant 포크이며, Anthropic의 Claude Code로 만들어졌습니다.