공개 저장소 Agent Skill Garden에 블로그 글을 다루는 스킬을 추가했다. PR #4로 병합했다.
내게는 이미 잘 쓰고 있는 블로그 스킬이 있었다. 메모를 초안으로 만들고, 오탈자와 어색한 표현을 다듬고, 발행 전에 메타데이터와 링크를 확인하고, 승인을 받으면 실제 블로그에 올린다. 이 블로그의 글이 꾸준히 쌓일 수 있었던 데에는 그 워크플로의 도움이 컸다.
그러니 공개 저장소에 파일을 복사하는 것만으로도 기능은 추가할 수 있었다.
하지만 그렇게 하면 내 블로그를 대신 운영하는 스킬은 될 수 있어도, 다른 사람이 자기 블로그를 운영하는 스킬은 되지 않는다.
이번 PR에서 해결하고 싶었던 문제는 이것이었다.
내 설정과 문체를 공개하지 않고도, 다른 사람이 자기 글쓰기 경험을 에이전트에 이어갈 수 있을까?
내 블로그 설정은 재사용 가능한 기능이 아니다
개인 블로그 스킬에는 생각보다 많은 개인 설정과 선호가 들어간다.
- 초안을 저장하는 로컬 경로
- 게시물을 옮길 저장소와 디렉터리
- 파일명과 날짜를 정하는 방식
- 자주 사용하는 태그와 글의 구성
- 선호하는 문장 길이와 결론 방식
- 발행 명령과 공개 URL 확인 절차
이 값을 예시 문자열로 치환해 공개할 수도 있다. 그러나 경로와 URL만 가린다고 범용 스킬이 되는 것은 아니다. 내 블로그의 형식과 문체를 전제로 한 절차를 받는 사람은 결국 파일을 열어 자기 상황에 맞게 다시 고쳐야 한다.
공개 저장소에 넣고 싶었던 것은 완성된 내 설정이 아니었다.
내 블로그 설정을 복사한다
X
각자의 블로그에서 설정을 만들어내는 절차를 제공한다
O
그래서 공개 스킬과 개인 프로필을 분리했다.
public skill
-> 사용자의 블로그를 제한된 범위에서 분석
-> local inventory 생성
-> local blog profile 생성 및 사용자 확인
-> draft / polish / publish-check / publish
공개 저장소에는 초기화와 검증 방법만 둔다. 분석 결과인 .agent-blog/blog-inventory.json과 .agent-blog/blog-profile.md는 기본적으로 사용자 로컬에 남는다.
문체를 복사하지 않고 계약으로 만든다
blog-writing-workflow는 다섯 가지 모드를 가진다.
initialize: 기존 블로그에서 운영 방식과 문체 경향을 초기화한다.draft: 확인된 프로필에 맞춰 초안을 쓴다.polish: 주장과 확신 정도는 유지한 채 표현과 구조를 다듬는다.publish-check: 내용, 메타데이터, 개인정보, 발행 조건을 점검한다.publish: 사용자가 현재 대화에서 명시적으로 요청했을 때만 발행한다.
가장 중요하게 본 것은 initialize였다. 기존 글 하나를 읽고 그 문체를 흉내 내게 하면 빠르지만, 한 편의 글이 작성자의 전체 문체를 대표하지는 않는다. 최근 글만 보면 최근 주제에 치우치고, 긴 회고 글만 보면 모든 글을 길게 쓰려 할 수 있다.
초기화는 먼저 Markdown 전체의 구조를 집계한 뒤 최근 글과 형식이 다른 글을 제한된 수만큼 고른다. 이때 inventory에는 글 본문이나 frontmatter 값이 들어가지 않는다. 글 수, 제목과 본문 길이 분포, 헤딩과 코드 블록 사용량, 상대 경로로 된 표본 목록처럼 구조를 파악하는 정보만 남긴다.
그다음 에이전트가 표본을 읽고 프로필을 만든다. 프로필의 근거는 세 종류로 나눴다.
measured: 파일과 문서 구조에서 직접 잰 것inferred: 여러 글에서 반복된 경향을 해석한 것author-confirmed: 작성자가 직접 확인하거나 고친 것
문장 밀도나 제목 경향은 추론할 수 있다. 반면 어떤 감정을 어느 정도 드러낼지, 어떤 회사 정보를 외부에 쓰지 않을지, 발행 전에 무엇을 반드시 확인할지는 작성자가 결정해야 한다. 에이전트가 관찰한 문체를 영구적인 성격처럼 확정하지 않고, 수정 가능한 글쓰기 계약으로 만든 이유다.
또한 기존 글의 독특한 표현을 가져오지 않도록 했다. 보존하려는 것은 문구가 아니라 문장 밀도, 섹션의 리듬, 예시의 깊이, 결론을 맺는 방식 같은 안정적인 경향이다.
초안을 부탁했다고 발행까지 맡긴 것은 아니다
개인용 자동화에서는 “초안 작성”, “다듬기”, “발행 전 점검”, “발행”이 익숙한 연속 작업처럼 보인다. 하지만 외부에 공개하는 워크플로에서는 각각의 권한이 다르다.
그래서 스킬 첫 부분에 다음 원칙을 적었다.
하나의 모드만 선택하고, 다음 모드로 조용히 넘어가지 않는다.
초안을 써 달라는 요청은 파일을 공개하라는 요청이 아니다. 발행 전 점검에서 READY가 나왔다고 발행 권한까지 생기지도 않는다. publish는 현재 대화에서 명시적인 요청이 있어야 하고, 실행 전에는 대상 파일과 저장소 상태를 다시 읽는다.
발행 뒤에도 끝이 아니다. 커밋이나 명령이 성공한 것과 독자가 공개 페이지를 읽을 수 있는 것은 다르다. 가능한 경우 공개 URL을 다시 확인하고, 확인되기 전까지 원본 초안을 지우지 않게 했다. 실패하더라도 돌아갈 지점을 남기기 위해서다.
이 경계는 블로그에만 필요한 것은 아니다. 초안과 발행, 계획과 실행, 검토와 외부 시스템 변경을 구분하는 것은 에이전트 워크플로 전반에 필요한 권한 모델이다.
스킬 하나를 늘렸더니 CI가 깨졌다
기능을 넣고 검증을 돌리자 예상하지 못한 곳에서 CI가 실패했다.
프로젝트 설치 스모크 테스트가 설치된 스킬 수를 14개로 고정하고 있었다.
test "$(find project/.agents/skills -type l | wc -l)" -eq 14
이번 PR로 스킬이 15개가 됐으니 실패 자체는 정상이다. 처음에는 14를 15로 바꾸면 되는 문제처럼 보였다. 하지만 그렇게 고치면 다음 스킬을 추가할 때 15를 16으로 바꿔야 한다.
테스트가 확인해야 할 것은 “현재 스킬이 15개인가”가 아니었다.
코어에 존재하는 모든 스킬이 각 어댑터 경로에 설치됐는가?
그래서 기대값을 현재 코어 디렉터리에서 계산하도록 바꿨다.
expected_skill_count="$(find core/skills -mindepth 1 -maxdepth 1 -type d | wc -l)"
test "$(find project/.agents/skills -type l | wc -l)" \
-eq "$expected_skill_count"
숫자 하나를 고치는 대신 현재 상태가 아니라 지켜야 할 불변식을 테스트하게 됐다. 스킬을 늘릴 수 있는 저장소인데 스모크 테스트가 현재 개수를 규칙으로 만들고 있었던 셈이다.
작은 수정이지만 이번 PR의 방향과도 닮아 있다. 특정 사용자의 현재 설정을 정답으로 두는 대신, 새로운 사용자가 들어와도 유지되어야 할 관계를 계약으로 만든다.
이번 PR에 넣은 것
최종적으로 PR에는 다음을 넣었다.
- 블로그 초기화·초안·다듬기·발행 점검·명시적 발행을 다루는
blog-writing-workflow - 글 본문과 frontmatter 값을 복사하지 않는 Markdown inventory 스크립트
- 측정·추론·작성자 확인을 구분하는 로컬 프로필 계약
- 개인정보와 내부 식별자, 메타데이터, 링크, 발행 권한을 확인하는 점검표
- 각 사용자가 자기 블로그에서 시작할 수 있는 한국어·영어 가이드
- 자연어 요청이 스킬로 연결되는지 확인하는 라우팅 사례와 단위 테스트
- 코어 스킬 수를 기준으로 동작하는 Claude Code 및 Codex·Cursor 설치 스모크 테스트
검증에서는 15개 스킬, 19개 라우팅 사례, 9개 단위 테스트, 컨텍스트 크기 검사와 공개 안전성 검사를 통과했다. 임시 프로젝트에 설치해 각 어댑터가 같은 코어 스킬을 올바른 경로에 연결하는 것도 확인했다.
경험을 공개한다는 것
my-cursor에서 Agent Skill Garden으로 옮겨올 때부터 계속 같은 질문을 하고 있다.
도구와 환경이 바뀌어도 무엇을 가져갈 것인가?
이번에는 답이 더 구체적이었다.
내 글을 가져가는 것이 아니다. 내 문체를 정답으로 배포하는 것도 아니다. 글을 만들고 다듬고 공개하는 동안 반복해서 유효했던 판단 순서와 안전 경계를 가져간다. 그리고 새 환경에서는 그곳의 글과 작성자가 다시 프로필을 결정한다.
배운 것
1. 공개할 것은 개인화된 결과가 아니라 개인화하는 방법이다. 내 경로와 문체를 잘 가려서 복사하는 것보다, 각 사용자가 자기 환경에서 프로필을 만들게 하는 편이 더 안전하고 쓸모 있다.
2. 문체는 복제 대상이 아니라 검토 가능한 계약이다. 측정한 사실과 에이전트의 추론, 작성자가 확인한 선호를 섞지 않아야 나중에 무엇을 고칠지 알 수 있다.
3. 초안과 발행은 다른 권한이다. 작업이 자연스럽게 이어져 보여도 외부에 영향을 주는 단계는 자동으로 넘어가면 안 된다.
4. 테스트에는 현재 숫자보다 불변식을 적는다. 스킬 수를 14에서 15로 바꾸는 수정은 다음 실패를 예약한다. 코어에 있는 것과 설치된 것이 같아야 한다는 관계가 진짜 요구사항이었다.
5. 공개 저장소는 설정 파일 보관함이 아니다. 내가 여러 도구와 환경에서 반복해 얻은 경험을, 다른 사람도 자기 조건에 맞게 실행하고 검증할 수 있는 형태로 옮기는 곳이다.
앞선 브랜치 정리 스킬은 잃을 작업을 구분하는 판단을 옮겼고, E2E 스킬은 설계와 실행의 경계를 옮겼다. 사용 통계 수정에서는 무엇을 채점하지 말아야 하는지 정리했다.
PR #4에서는 내가 쓰던 글이나 문체가 아니라, 각자의 글을 계속 써 나갈 수 있게 하는 방법을 옮겼다.