본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 04:49

Headless Claude Code: GitHub Actions에서 실행하는 5가지 작업

요약

Claude Code의 -p 플래그를 사용하여 GitHub Actions 환경에서 헤드리스(headless) 모드로 자동화 작업을 수행하는 방법을 소개합니다. 블로그 생성, 일일 감사, PR 분류 등 반복적인 개발 업무를 cron 트리거로 자동화하여 일관성을 높이고 비용 효율적으로 운영하는 가이드를 제공합니다.

핵심 포인트

  • -p 플래그를 통해 대화형 세션 없이 CLI 도구처럼 실행 가능
  • GitHub Actions와 cron을 결합하여 24/7 자동화 워크플로우 구축
  • 실행당 약 0.10 ~ 0.60 EUR의 낮은 비용으로 운영 가능
  • 헤드리스 모드에서는 질문이 불가능하므로 정밀한 프롬프트 작성 필수
  • Claude Code -p는 터미널 없이 CI에서 headless(헤드리스)로 실행됩니다.

  • 블로그 생성, 일일 감사(daily audit), PR 분류(triage), 릴리스 노트 작성, README 동기화 모두 cron(크론)으로 실행됩니다.

  • 각 실행 비용은 컨텍스트(context) 크기에 따라 0.10 ~ 0.60 EUR가 소요됩니다.

  • CLI 버전을 고정하고 상태를 캐시(cache)하지 않으면 토큰(token)을 낭비하게 됩니다.

제 노트북에 머물러 있던 다섯 가지 작업을 GitHub Actions에서 실행하고 있습니다. 열려 있는 터미널도 없고, 제가 진행률 표시줄을 지켜보고 있지도 않습니다. Headless 모드의 Claude Code는 정해진 일정에 따라 작업을 수행하고, 보여줄 결과물이 있으면 Pull Request(PR)를 생성합니다. 무엇이 실행되는지, 비용은 얼마인지, 그리고 제대로 작동하기 전 어떤 부분들이 고장 났었는지 정확히 알려드리겠습니다.

왜 Headless Claude Code가 로컬 터미널보다 나은가

대부분의 사람들은 Claude Code를 대화형(interactively)으로 사용합니다. 터미널을 열고, 요청을 입력하고, 파일이 수정되는 것을 지켜보며, diff(차이점)를 승인합니다. 이는 일회성 작업에는 괜찮습니다. 하지만 제가 잠든 사이 매일 오전 6시에 일어나야 하는 작업에는 확장성(scale)이 없습니다.

비결은 -p 플래그에 있습니다. 이는 Claude Code를 print 모드로 실행합니다. 프롬프트(prompt)를 전달하면, 작업을 수행하고, 결과를 출력한 뒤 종료됩니다. 대화형 세션도 없고, 승인 프롬프트도 없습니다. 덕분에 일반적인 커맨드 라인 도구(command line tool)가 되며, 이는 GitHub Actions가 테스트 스위트(test suite)를 실행하는 것과 동일한 방식으로 이를 실행할 수 있음을 의미합니다.

최소한의 작업(job)은 다음과 같습니다. CLI를 설치하고, API 키를 secret(비밀값)으로 설정한 뒤, 프롬프트와 함께 호출합니다.


- run: npm install -g @anthropic-ai/claude-code
- run: claude -p "Read CHANGES.md and write release notes to RELEASE.md"
...

이것이 전체 패턴입니다. 나머지는 모두 이 패턴의 변형입니다. 작업(job)이 제 리포지토리(repo)를 클론(clone)하면, Claude가 파일을 읽고 쓰고, 이후 단계에서 변경 사항을 커밋(commit)하거나 Pull Request를 생성합니다.

이것이 중요한 이유는 일관성(consistency) 때문입니다. 작업이 제가 스크립트를 실행하는 것을 기억하는 것에 의존한다면, 일주일에 세 번 정도만 실행될 것입니다. 하지만 cron 트리거로 실행하면, 단 하루도 거르지 않고 일 년 365일 실행됩니다. 저의 일일 감사(daily audit)는 현재 90회 연속으로 실행되었습니다. 수동으로 했다면 적어도 40번은 빼먹었을 것입니다.

비용은 예상보다 낮습니다. 일반적인 헤드리스 (headless) 실행은 읽어들이는 컨텍스트 (context) 양에 따라 15,000에서 80,000 토큰 (tokens) 사이를 사용합니다. 이는 실행당 0.10에서 0.60 EUR 사이의 비용이 발생함을 의미합니다. 제가 사용하는 다섯 가지 작업의 총비용은 한 달에 12 EUR 미만입니다. 제가 사용하는 정도의 볼륨(volume)이라면 GitHub Actions 분(minutes)은 무료입니다.

한 가지 사고방식의 전환이 필요합니다: 헤드리스 Claude는 당신에게 질문을 할 수 없습니다. 만약 혼란을 겪는다면, 스스로 추측하고 다음 단계로 넘어갑니다. 따라서 프롬프트 (prompt)는 채팅 (chat)에서 사용하는 것보다 더 정밀해야 합니다. 저는 프롬프트를 요청 (request)이 아닌 명세서 (spec)처럼 작성합니다. 이 모든 과정의 전체 설정법을 알고 싶다면, Claude Blueprint에서 기초 과정을 살펴볼 수 있습니다.

블로그 생성 및 일일 감사 (daily audit)

저의 다섯 가지 작업 중 두 가지는 이 사이트에 직접적으로 관여합니다. 첫 번째는 블로그 초안을 생성하는 것이고, 두 번째는 이미 게시된 내용을 감사하는 것입니다.

생성 작업은 일주일에 세 번 실행됩니다. 대기열 (queue) 파일에서 주제를 가져오고, 어조 (voice) 참조를 위해 기존 기사 세 개를 읽은 뒤, 구조 명세 (structure spec)에 따라 전체 초안을 작성합니다. 결과물은 풀 리퀘스트 (pull request)로 전송되며, 절대 바로 게시되지 않습니다. 저는 초안이 라이브(live)되기 전에 반드시 모든 내용을 읽습니다. 왜냐하면 헤드리스 모드는 프롬프트에 여지가 있다면 기술적으로 틀린 문단을 아주 자신 있게 만들어낼 수 있기 때문입니다.

이 작업의 프롬프트는 약 600단어 정도로 깁니다. 여기에는 목표 단어 수, 섹션 구조, 금지어, 그리고 세 가지 예시 도입부가 포함됩니다. 프롬프트에 더 많은 정보를 미리 담을수록(front-load), 나중에 수정할 일이 줄어듭니다. 처음 시작했을 때는 단 두 문장의 지침만 주었기에 각 초안을 편집하는 데 20분이 걸렸습니다. 이제는 프롬프트가 힘든 일을 다 처리해주고, 저는 4분만 사용합니다.

일일 감사는 제가 가장 자랑스럽게 생각하는 작업입니다. 매일 아침 7시에 마지막으로 게시된 10개의 기사를 읽고 규칙 목록과 대조하여 확인합니다: 깨진 내부 링크, 누락된 제휴 공시 (affiliate disclosures), 순서가 잘못된 헤딩 (headings), 범위를 벗어난 단어 수 등을 체크합니다. 작업은 마크다운 (markdown) 파일에 보고서를 작성하며, 만약 오류를 발견하면 구체적인 수정 사항을 담은 이슈 (issue)를 생성합니다.

90일 동안 이 작업은 31개의 실제 문제를 발견했습니다. 11개는 핸들(handle) 이름을 변경하고 참조를 업데이트하는 것을 잊어버려 발생한 깨진 내부 링크 (dead internal links)였습니다. 9개는 글자 수 하한선 미만으로 떨어진 문서들이었습니다. 나머지는 서식 드리프트 (formatting drift)였습니다. 이 중 그 어떤 것도 수동으로는 찾아낼 수 없었을 것입니다. 매일 아침 자신의 아카이브를 다시 읽어보는 사람은 없으니까요.

감사 (audit) 작업은 더 많은 파일을 읽기 때문에 다른 작업보다 비용이 더 많이 듭니다. 전체 실행에는 약 70,000 토큰 (tokens)이 소모되어 약 0.50 EUR가 듭니다. 한 달 동안 31번의 깨진 링크 게시를 막아준 작업의 대가로 15 EUR를 지불하는 셈입니다. 충분히 가치 있는 거래입니다.

한 가지 주의할 점 (gotcha)이 있습니다. 이전의 감사 작업은 저장소 (repo)의 모든 문서를 읽었기 때문에 토큰 사용량이 200,000을 넘었고 실행당 비용도 1.50 EUR를 초과했습니다. 저는 이를 수정 날짜 기준 최신 파일 10개로 제한했습니다. 가치는 동일하면서 비용은 5분의 1로 줄었습니다. 만약 어떤 작업의 비용이 너무 비싸게 느껴진다면, 그 답은 거의 항상 "너무 많은 컨텍스트 (context)를 제공하고 있다"는 것입니다.

PR 트리아지 (triage) 및 릴리스 노트 (release notes)

세 번째와 네 번째 작업은 저장소 자체를 유지 관리하는 지루한 부분들을 처리합니다.

PR 트리아지 (PR triage)는 풀 리퀘스트 (pull request)가 열릴 때마다 실행됩니다. 제 풀 리퀘스트의 대부분은 블로그 생성 작업에서 오지만, 가끔 수동으로 생성되는 경우도 있습니다. 트리아지 작업은 디프 (diff)를 읽고, 제 규칙에 따라 검사하며, 무엇이 변경되었는지와 이상이 있는지 여부를 요약하여 댓글 (comment)을 게시합니다. 블로그 초안의 경우 글자 수가 범위 내에 있는지와 내부 링크 (internal links)가 제대로 연결되는지 확인합니다. 코드 변경의 경우 비밀 정보 (secrets)나 게시 흐름 (publish flow)에 영향을 주는 요소를 플래그 (flag)합니다.

이것은 깊은 의미에서의 코드 리뷰 (code review)는 아닙니다. 제가 직접 하지 않아도 되도록 명백한 문제들을 잡아내는 1차 필터 (first-pass filter) 역할을 합니다. 댓글은 풀 리퀘스트가 열리고 90초 이내에 나타납니다. 제가 확인하러 갈 때쯤이면 요약 내용이 이미 작성되어 있습니다.


on:
  pull_request:
...

Release notes(릴리스 노트)는 네 번째 작업입니다. 제가 버전을 태그할 때마다, 이 작업은 마지막 태그 이후의 커밋 메시지(commit messages)를 읽어 유형별로 그룹화하고 사람이 읽기 쉬운 릴리스 노트를 작성합니다. 제 커밋 메시지는 간결하고 형편없습니다. 하지만 결과물로 나오는 릴리스 노트는 깔끔하며 "Fixes"나 "New"와 같은 헤딩(headings) 아래에 그룹화되어 나타납니다. 제가 신경 쓰지 않아도 "fix typo in audit prompt lol" 같은 메시지를 적절한 변경 로그(changelog) 항목으로 변환해 줍니다.

커밋 메시지는 짧기 때문에 비용은 실행당 약 0.10 EUR 정도로 매우 적습니다. 이 작업은 지금까지 14개의 릴리스 항목을 작성했습니다. 저는 그중 정확히 두 개만 수정했습니다. 나머지는 작성된 그대로 배포되었습니다.

두 작업 모두에서 가장 큰 주의 사항(gotcha)은 권한(permissions)입니다. GitHub Actions가 댓글을 게시하고 커밋을 하려면 명시적인 쓰기 권한(write permission)이 필요합니다. 워크플로(workflow)의 토큰 범위(token scope)가 읽기 전용(read-only)이라서, 작업은 완벽하게 실행되었지만 댓글 게시에는 조용히 실패하는 바람에 한 시간을 허비했습니다. 작업(job) 수준에서 permissions: pull-requests: writecontents: write를 추가하세요. 만약 릴리스를 바탕으로 소셜 포스트(social posts)를 예약한다면, Buffer가 웹훅(webhook)을 받아 대기열(queue)을 처리합니다.

README 동기화와 비용을 발생시킨 주의 사항들

다섯 번째 작업은 제 README를 정직하게 유지해 줍니다. 문서(documentation)는 점차 어긋나기 마련입니다. 플래그(flag)를 변경하고, 스크립트(script)를 추가하고, 폴더 이름을 바꾸다 보면 README는 조용히 거짓말을 하게 됩니다. 이 작업은 실제 프로젝트 구조와 현재 스크립트를 읽은 다음, 현실에 맞게 관련 README 섹션을 다시 작성합니다.

이 작업은 매주 실행됩니다. 변경 사항(diff)이 포함된 풀 리퀘스트(pull request)를 생성하여, 변경 사항이 반영되기 전에 제가 정확히 무엇이 바뀌었는지 확인할 수 있게 합니다. 3주 중 약 1주는 실제 변경 사항이 있습니다. 나머지 주에는 아무것도 생성하지 않는데, 이것이 올바른 동작입니다. 할 일이 없을 때 아무것도 하지 않는 작업이 좋은 작업입니다.

이제 주의 사항(gotchas)에 대해 말씀드리겠습니다. 이를 수정하기 전에는 실제로 토큰(tokens) 비용을 낭비했기 때문입니다.

첫째, CLI 버전을 고정(pin)하세요. 저는 버전 지정 없이 npm install -g @anthropic-ai/claude-code를 실행했는데, 어느 날 아침 새로운 릴리스가 기본 모델을 변경했고 그 결과 하룻밤 사이에 토큰(tokens) 사용량이 40% 급증했습니다. 버전을 고정하세요: @anthropic-ai/claude-code@2.0.1. 의도적으로 업그레이드해야지, 실수로 업그레이드되게 해서는 안 됩니다.

둘째, 이해하지 못하는 것은 캐싱(cache)하지 마세요. 컨텍스트 읽기(context reads)를 절약하기 위해 실행 간에 Claude의 내부 상태를 캐싱하려고 시도한 적이 있습니다. 토큰은 절약했지만, 캐시가 변경된 파일의 이전 버전을 유지하고 있었기 때문에 오래된(stale) 결과물이 생성되었습니다. 이러한 작업의 경우, 매번 새로 읽는 것이 추가적인 0.05 EUR의 가치가 있습니다. 추론(reasoning)이 아니라 npm 설치를 캐싱하세요.

셋째, 엄격한 타임아웃(timeout)을 설정하세요. 루프(loop)에 빠져 멈추지 않는 헤드리스(headless) 작업은 무언가가 멈추게 할 때까지 API를 계속 호출할 것입니다. 저는 모든 작업에 timeout-minutes: 10을 추가합니다. 타임아웃이 없었을 때는 통제 불능의 실행 한 번으로 3 EUR를 낭비한 적이 있습니다. 이제 최악의 상황도 제한됩니다.

넷째, 헤드리스 작업이 인간의 승인(human gate) 없이 배포되도록 두지 마세요. 제가 운영하는 다섯 가지 작업은 모두 풀 리퀘스트(pull request)를 생성하거나 초안(draft)을 작성합니다. 그 중 어떤 것도 프로덕션(production)에 직접 푸시(push)하지 않습니다. 헤드리스 Claude는 훌륭하지만 완벽하지는 않습니다. 잘못된 게시물이 라이브되는 비용은 제가 4분 동안 초안을 읽는 비용보다 훨씬 높습니다.

다섯째, 토큰 사용량을 기록(log)하세요. Claude Code는 실행 끝에 사용량을 출력합니다. 이를 파일로 파이프(pipe)하여 매주 확인하세요. 그렇게 해서 저는 비용을 두 배로 늘린 버전 업데이트를 잡아낼 수 있었습니다. 작업이 당신이 잠든 사이에 일어날 때는 가시성(visibility)이 전부입니다.

결론 (Bottom Line)

헤드리스 Claude Code는 제가 예전에 건너뛰곤 했던 다섯 가지 잡무를 스스로 실행되는 다섯 가지 작업으로 바꾸어 놓았습니다. 블로그 초안 작성, 일일 감사(audit), PR 분류(triage), 릴리스 노트(release notes), 그리고 README 동기화는 모두 합쳐 한 달에 12 EUR 미만이 들며, 어차피 쓰지 않았을 시간들을 절약해 줍니다. 왜냐하면 그중 절반은 제가 수동으로 아예 하지 않았던 일들이기 때문입니다.

패턴은 매번 동일합니다: CLI를 설치하고, -p 옵션으로 정밀한 프롬프트 (prompt)를 전달하며, 출력 내용을 파일에 쓰고, 풀 리퀘스트 (pull request)를 생성하고, 무언가가 배포되기 전에 반드시 인간의 검토 단계를 거치도록 합니다. 버전을 고정(Pin)하고, 타임아웃 (timeout)을 설정하며, 토큰 (tokens) 사용량을 기록하고, 각 작업 (job)에 업무 수행에 필요한 최소한의 컨텍스트 (context)만 제공하십시오.

제가 Claude를 채팅창이 아닌 인프라 (infrastructure)로서 실행하는 방식에 대한 전체적인 기반을 알고 싶다면, Claude Blueprint에 제가 설정해 둔 내용을 보관하고 있습니다. 하나의 작업부터 시작해 보세요. 일일 감사 (daily audit)는 가장 쉽게 성과를 낼 수 있는 방법이며, 독자들이 발견하기 전에 당혹스러운 실수를 잡아낼 가능성이 가장 높은 작업입니다.

이 기사에는 제휴 링크가 포함되어 있습니다. 이 링크를 통해 가입하시면, 귀하에게 추가 비용 부담 없이 저에게 소정의 수수료가 지급될 수 있습니다. (광고)

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0