Featured Post

AI 바이브 코딩으로 GitHub Actions 짤 때, 토큰 덜 쓰고 덜 헤매는 내 방식

GitHub Actions - CI/CD 관련 이미지

요즘 개발자들 사이에서 AI 바이브 코딩 이야기 정말 많이 나오잖아요. 저도 처음엔 살짝 삐딱하게 봤어요. 20년 넘게 개발하면서 별별 도구를 다 봤는데, 또 하나의 유행어인가 싶었거든요. 그런데 막상 써보니까 생각이 좀 바뀌었습니다. 특히 GitHub Actions로 CI/CD 파이프라인 만들 때는, 혼자 문서 뒤지고 에러 로그 붙잡고 있는 것보다 AI한테 방향을 물어보는 게 훨씬 빠를 때가 많더라고요. 다만 문제는 하나 있었어요. 편하다고 막 물어보다 보면 토큰이 생각보다 많이 녹습니다. 진짜 눈 녹듯이요. 그래서 오늘은 제가 실제로 부딪히면서 정리한, GitHub Actions 작업할 때 토큰 아끼는 프롬프트 작성법이랑 설정해두면 좋은 작은 습관들을 좀 편하게 풀어보려고 해요.

GitHub Actions 질문이 생각보다 토큰을 많이 잡아먹는 이유

처음에는 저도 참 순진하게 물어봤습니다. ChatGPT나 Claude한테 그냥 이렇게 던졌어요.

GitHub Actions로 Node.js 프로젝트 CI/CD 파이프라인 만들어줘.

그랬더니 아주 성실하게 답을 주긴 하더라고요. 문제는 너무 성실했다는 겁니다. 제가 원하지도 않은 deploy 단계, 캐싱 설정, 테스트 단계, lint, build, 심지어 브랜치 전략까지 줄줄이 붙어서 나왔어요. 딱 보면 그럴듯한데, 막상 제 프로젝트에 붙이려면 손볼 데가 한두 군데가 아니었습니다.

이게 뭐랄까, 컵라면 물만 부어달라고 했는데 갑자기 코스 요리가 나온 느낌이에요. 고맙긴 한데, 지금 필요한 건 그게 아니거든요.

그때 알았습니다. AI에게 요청 범위를 넓게 주면, AI는 친절하게 과하게 답한다는 걸요. 그리고 그 과한 친절은 그대로 토큰 비용이 됩니다.

또 하나 놓치기 쉬운 게 context 관리예요. 대화가 길어질수록 이전에 주고받은 내용이 계속 같이 딸려갑니다. 예를 들어 처음에 긴 yaml 파일을 만들고, 그다음에 “방금 거에 secrets 추가해줘”라고 하면, AI 입장에서는 앞에서 만든 긴 yaml까지 같이 참고해야 하잖아요. 그러면 내가 입력한 문장은 짧아도 실제로는 꽤 많은 토큰이 소비됩니다.

제가 겪었던 패턴을 간단히 표로 정리해보면 이렇습니다.

질문 방식 토큰 소모 느낌 실제 만족도
전체 CI/CD 파이프라인을 한 번에 만들어달라고 요청 높음, 대략 3000~5000 토큰 수준 생각보다 낮음. 필요 없는 코드가 많이 섞임
test.yml에서 runs-onubuntu-latest로 바꿔달라고 요청 낮음, 대략 200~500 토큰 수준 높음. 수정 지점이 명확해서 결과도 깔끔함
긴 대화를 계속 이어가며 수정 요청 매우 높음. 누적이 무섭게 쌓임 편하긴 한데 비용 대비 애매할 때가 있음

이 경험 이후로 저는 질문을 잘게 쪼개기 시작했어요. 예전에는 “CI/CD 만들어줘”라고 했다면, 지금은 이렇게 물어봅니다.

    • pull request가 열릴 때 npm run lint만 실행하는 GitHub Actions workflow를 만들어줘.
    • 아래 yaml에서 npm cache 설정만 추가해줘. 전체 파일은 다시 쓰지 말고 변경되는 step만 보여줘.
    • 이 에러의 원인만 짧게 설명하고, 수정된 코드 5줄 이내로 보여줘.

이렇게 하면 신기하게도 답이 훨씬 좋아집니다. AI도 덜 헤매고, 저도 덜 읽고, 토큰도 덜 씁니다. 사실 개발도 그렇잖아요. 큰 문제를 잘게 쪼개면 대부분 해결이 쉬워집니다. 프롬프트도 똑같더라고요.

제가 실제로 쓰는 프롬프트 방식

처음엔 저도 AI한테 꽤 멋있게 말했습니다. “너는 GitHub Actions 전문가야. 다음 요구사항을 만족하는 yaml 코드를 작성해줘.” 이런 식으로요. 나쁘진 않아요. 그런데 결과물이 은근히 산만했습니다. 특히 에러를 물어볼 때 그랬어요.

예를 들어 이런 에러가 났다고 해볼게요.

Error: .github/workflows/main.yml (Line: 10, Col: 3): Unexpected value

예전 같으면 그냥 “이 에러 해결해줘”라고 물었을 겁니다. 그러면 AI가 YAML 문법의 역사부터 시작할 기세로 설명을 붙여줘요. 물론 도움이 되긴 하는데, 당장 제가 필요한 건 원인과 수정 코드거든요. 그래서 요즘은 프롬프트를 조금 더 좁혀서 씁니다.

역할만 주지 말고, 답변 모양까지 같이 정해주기

요즘 제가 자주 쓰는 문장은 이런 식이에요.

    • 너는 DevOps 엔지니어야. 아래 GitHub Actions 에러를 원인, 수정 코드, 주의사항으로 나눠서 짧게 알려줘.
    • 설명은 최대 3줄로 제한하고, 전체 yaml을 다시 쓰지 말고 수정이 필요한 부분만 보여줘.
    • 가능하면 GitHub Actions 최신 major version 기준으로 작성해줘.

이렇게 말하면 답이 확 달라집니다. 불필요한 서론이 줄어요. “YAML은 들여쓰기에 민감한 데이터 직렬화 형식이며...” 이런 문장을 안 봐도 됩니다. 솔직히 그런 설명, 이미 알고 있잖아요. 모르는 날도 있긴 하지만요. 피곤한 월요일 아침에는 들여쓰기 하나도 잘 안 보입니다.

중요한 건 AI에게 어떤 역할을 할지만 말하는 게 아니라, 어떤 형태로 답할지까지 알려주는 겁니다. 이게 토큰 절약에도 꽤 크게 작용해요.

애매한 프롬프트 제가 바꿔 쓰는 프롬프트
이거 왜 안 돼? 아래 GitHub Actions 에러의 원인 1개와 수정 코드만 보여줘. 설명은 3줄 이내로 해줘.
CI/CD 최적화해줘. 아래 workflow에서 실행 시간을 줄일 수 있는 부분만 3개 골라줘. 전체 yaml은 다시 작성하지 마.
배포 파이프라인 만들어줘. main 브랜치 push 시 Docker image를 build하고 GitHub Container Registry에 push하는 workflow만 작성해줘. secrets는 하드코딩하지 마.

짧은 예시 하나가 오히려 토큰을 아껴줍니다

이건 좀 재미있는 부분인데요. 토큰을 아끼려고 프롬프트를 무조건 짧게만 쓰는 게 능사는 아니더라고요. 오히려 짧은 예시 코드 하나를 넣어주는 게 전체 토큰을 줄이는 경우가 많았습니다.

AI는 내가 원하는 스타일을 모르면 자기 나름대로 추측합니다. 그러면 답이 길어지고, 저는 다시 “아니 그게 아니라...” 하면서 추가 질문을 하게 되죠. 이게 반복되면 토큰이 더 많이 나갑니다.

그래서 저는 이런 식으로 예시를 줍니다.

다음 예시처럼 단순한 형태로 GitHub Actions workflow를 만들어줘.
전체 설명은 필요 없고 yaml만 보여줘.

예시:
```yaml
name: Lint
on: [push]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
  • uses: actions/checkout@v4
  • run: npm run lint
```

이렇게 해두면 AI가 제 스타일을 빨리 알아차립니다. 복잡한 deploy 전략을 붙이지도 않고, 괜히 matrix를 넣지도 않고, 필요한 만큼만 답해줘요. 결국 한 번에 원하는 답을 받을 확률이 올라갑니다. 이게 꽤 큽니다. 질문 한 번 줄어드는 게 생각보다 체감이 돼요.

GitHub Actions 기본 템플릿을 만들어두면 AI도 덜 헷갈립니다

제가 여러 번 써보면서 느낀 건데, AI에게 매번 처음부터 만들게 하면 결과가 들쭉날쭉합니다. 어떤 날은 actions/setup-node@v4를 쓰고, 어떤 날은 예전 버전을 섞기도 해요. 물론 모델이나 시점에 따라 다르겠지만, 개발자 입장에서는 이런 작은 흔들림이 은근히 귀찮습니다.

그래서 저는 프로젝트마다 기본 GitHub Actions 템플릿을 하나 만들어둡니다. 아주 대단한 건 아니고요. 우리 팀이 선호하는 버전, Node version, cache 방식, branch 조건 정도만 정해둔 파일입니다.

Node.js 프로젝트에서 제가 자주 쓰는 기본 CI 템플릿

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
  • uses: actions/checkout@v4
  • name: Setup Node.js
uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
  • run: npm ci
  • run: npm test

이걸 기준으로 AI에게 요청하면 훨씬 편합니다.

위 템플릿에서 npm run lint 단계를 npm test 전에 추가해줘. 전체 파일을 다시 쓰지 말고 추가할 step만 보여줘.

이렇게요. 그러면 AI가 새 workflow를 통째로 다시 만들지 않고, 필요한 부분만 딱 줍니다. 읽는 시간도 줄고, 복붙 실수도 줄고, 토큰도 덜 씁니다.

사실 저는 이걸 여행 가방 싸는 거랑 비슷하게 봅니다. 매번 여행 갈 때마다 칫솔, 충전기, 여권을 처음부터 고민하면 피곤하잖아요. 기본 파우치를 만들어두면 목적지만 바뀌어도 훨씬 가볍게 떠날 수 있습니다. GitHub Actions도 비슷해요. 기본 템플릿 하나 있으면 AI랑 대화가 훨씬 짧아집니다.

Matrix build는 처음부터 요청하는 게 좋습니다

예전에 Node 18, 20, 22에서 테스트를 돌려야 하는 일이 있었어요. 아무 생각 없이 AI한테 이렇게 말했습니다.

Node 18, 20, 22에서 각각 테스트 돌리는 GitHub Actions 만들어줘.

그랬더니 job을 세 개로 나눠서 만들어주더라고요. 물론 틀린 건 아닙니다. 돌아가긴 돌아가요. 그런데 yaml이 길어지고, 나중에 step 하나 바꾸려면 세 군데를 고쳐야 합니다. 그건 좀 아니잖아요.

그래서 다시 이렇게 물었죠.

matrix strategy를 사용해서 Node 18, 20, 22에서 테스트하도록 수정해줘.

그제야 코드가 확 줄었습니다.

strategy:
  matrix:
    node-version: [18, 20, 22]

steps:
  • uses: actions/checkout@v4
  • uses: actions/setup-node@v4
with: node-version: ${{ matrix.node-version }} cache: 'npm'
  • run: npm ci
  • run: npm test

이후로 저는 여러 버전, 여러 OS, 여러 환경을 다뤄야 할 때는 프롬프트에 아예 matrix strategy를 사용해줘라고 적습니다. AI가 알아서 해주겠지, 하고 맡기면 가끔 너무 정직하게 반복 코드를 만들어냅니다. AI도 결국 내가 방향을 잘 잡아줘야 잘 움직입니다.

secrets와 환경 변수는 프롬프트에 꼭 못 박아두세요

이건 정말 조심해야 합니다. AI가 만들어준 예제 코드에 가끔 민감한 값이 하드코딩된 형태로 들어갈 때가 있어요.

env:
  API_KEY: my-secret-key

예제니까 그렇겠지 하고 넘길 수도 있는데, 정신없는 날에는 이런 게 그대로 커밋될 수 있습니다. 특히 야근하다가 머리 멍할 때는 사람도 기계처럼 움직이거든요. 저는 그래서 아예 프롬프트에 매번 적습니다.

    • 모든 민감한 값은 GitHub Secrets에서 가져오도록 작성해줘.
    • API key, token, password는 절대 yaml에 하드코딩하지 마.
    • 필요한 secrets 이름은 예시로만 보여주고, 실제 값은 넣지 마.

예를 들면 이런 식으로 나와야 마음이 편합니다.

env:
  API_KEY: ${{ secrets.API_KEY }}
  DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

그리고 GITHUB_TOKEN 같은 기본 제공 토큰을 쓸 수 있는 상황이라면, 굳이 별도 secret을 만들 필요가 없는 경우도 있습니다. 이 부분도 AI가 항상 최선으로 판단해주진 않아요. 그래서 저는 이렇게 덧붙입니다.

가능하면 GitHub 기본 GITHUB_TOKEN을 우선 사용하고, 별도 secret이 필요한 경우에만 secrets 이름을 제안해줘.

별거 아닌 문장 같지만, 이거 하나로 결과물의 안전성이 꽤 올라갑니다. 보안은 사고 나고 나서 챙기면 너무 늦거든요. 개발 오래 하다 보면 결국 이런 작은 습관이 사람을 살립니다.

AI가 만들어준 코드를 그대로 믿었다가 삽질한 이야기

솔직히 저도 몇 번 당했습니다. AI를 안 믿는 건 아닌데, 너무 믿으면 꼭 한 번씩 발등을 찍힙니다.

한 번은 artifact 업로드가 필요한 workflow를 만들고 있었어요. AI가 actions/upload-artifact@v3를 추천해줬습니다. 그 자체가 무조건 틀린 건 아니었는데, 제 저장소에 있던 다른 action 버전들과 섞이면서 이상하게 실패가 났어요. 로그를 보면 대충 이런 분위기였습니다.

Error: Unable to resolve action `actions/upload-artifact@v3`
Workflow failed during artifact upload step

처음엔 제가 뭘 잘못했나 싶어서 yaml 들여쓰기부터 다시 봤습니다. 그러다 보니 시간이 훅 지나가더라고요. 한 30분은 그냥 사라졌습니다. 그때 좀 허탈했어요. AI가 만든 코드라고 해서 검증을 건너뛰면 안 되는구나, 다시 느꼈습니다.

그 뒤로 저는 AI가 만들어준 workflow를 바로 main에 넣지 않습니다. 가능하면 별도 branch에서 돌려보고, 필요하면 act 같은 도구로 로컬 검증도 해봅니다. 물론 act가 GitHub Actions 환경을 100% 똑같이 재현하진 못합니다. 그래도 단순 문법 오류나 step 흐름 확인에는 꽤 쓸 만해요.

병렬 job 최적화도 조심해야 합니다

또 한 번은 “파이프라인 실행 시간을 줄여줘”라고 요청한 적이 있어요. AI가 나름 똑똑하게 job을 병렬로 나눠줬습니다. 문제는 needs: 조건이 꼬였다는 거예요. job 이름은 바뀌었는데, 의존성에는 예전 이름이 남아 있었습니다.

이런 식이죠.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
  • run: npm test
deploy: needs: build runs-on: ubuntu-latest steps:
  • run: npm run deploy

여기서 build라는 job은 없는데 deploybuild를 기다리고 있는 상황입니다. 딱 보면 금방 찾을 것 같지만, 실제 파일이 길어지면 이런 게 은근히 안 보입니다. 특히 workflow가 여러 개로 쪼개져 있으면 더 그렇고요.

그 이후로는 병렬화나 최적화를 요청할 때 이렇게 말합니다.

    • job 이름과 needs 관계가 서로 맞는지 검증해서 작성해줘.
    • 각 job 위에 어떤 역할인지 짧은 주석을 달아줘.
    • 존재하지 않는 job을 needs에 넣지 않도록 확인해줘.

조금 귀찮아 보여도 이런 문장을 넣어두면 나중에 디버깅할 일이 줄어듭니다. 토큰 몇 줄 더 쓰고 30분을 아끼는 거죠. 저는 이쪽이 훨씬 남는 장사라고 봅니다.

상황 AI 답변에서 생긴 문제 그 뒤로 바꾼 습관
artifact 업로드 단계 추가 action 버전이 기존 workflow와 어색하게 섞임 현재 사용 중인 action 버전을 프롬프트에 함께 적음
job 병렬화 요청 needs에 존재하지 않는 job 이름이 들어감 job 이름과 의존 관계를 함께 검증해달라고 요청함
secrets 포함 배포 workflow 생성 예제 값이 하드코딩된 형태로 들어감 민감한 값은 반드시 GitHub Secrets로 처리하라고 명시함

토큰을 아끼고 싶을 때 제가 쓰는 체크리스트

AI랑 개발하다 보면 묘하게 대화가 길어질 때가 있습니다. 처음엔 간단한 질문이었는데, 어느새 workflow 전체를 다시 붙여넣고 있고, 에러 로그도 길게 넣고 있고, AI는 또 장문의 설명을 하고 있고요. 그러다 보면 “아, 이럴 거면 그냥 내가 할걸” 싶은 순간이 옵니다.

그럴 때 저는 아래 체크리스트를 한 번 봅니다. 실제로 제 메모 앱에 적어둔 내용과 거의 비슷해요.

    • 전체 파일을 다시 작성하지 말라고 했나?
    • 수정할 범위를 파일명, job 이름, step 이름 기준으로 좁혔나?
    • 원하는 출력 형식을 지정했나? 예: 코드만, 표로, 3줄 설명
    • 현재 사용하는 action version을 알려줬나?
    • secrets 하드코딩 금지를 명시했나?
    • 에러 로그는 핵심 부분만 잘라서 넣었나?
    • 이전 대화를 계속 끌고 가는 대신 새 질문으로 정리할 타이밍인가?

특히 마지막 항목이 중요합니다. 대화가 너무 길어지면 차라리 새 채팅을 열고, 현재 상황을 짧게 정리해서 다시 묻는 게 낫습니다.

예를 들면 이렇게요.

상황:
  • Node.js 20 프로젝트
  • GitHub Actions에서 pull_request 시 npm test 실행
  • actions/checkout@v4, actions/setup-node@v4 사용
  • npm ci 단계는 성공
  • npm test 단계에서 아래 에러 발생
요청:
  • 원인 1개와 수정 방법만 알려줘
  • 전체 workflow는 다시 쓰지 말고 수정할 부분만 보여줘

이렇게 정리해서 물어보면 AI도 훨씬 정확하게 답합니다. 사람한테 질문할 때도 마찬가지잖아요. “이거 왜 안 돼요?”보다 “여기까지는 됐고, 여기서 이 에러가 납니다”가 훨씬 좋습니다. AI도 별반 다르지 않더라고요.

이런 분들에게 특히 도움이 될 이야기입니다

제가 오늘 풀어놓은 이야기는 거창한 이론이라기보다, 현장에서 몇 번 넘어지면서 생긴 습관에 가깝습니다. AI 바이브 코딩이 편한 건 맞습니다. 특히 GitHub Actions처럼 문법은 단순해 보이는데 막상 실수하기 쉬운 영역에서는 꽤 든든한 조수예요.

다만 AI에게 모든 걸 맡기면 안 됩니다. 저는 요즘 AI를 후배 개발자처럼 대합니다. 빠르고 성실하고 아이디어도 잘 내지만, 코드 리뷰는 꼭 해줘야 하는 후배요. 그렇게 생각하면 마음이 편합니다. 화낼 일도 줄고, 기대치도 적당해집니다.

이 글은 특히 이런 분들에게 잘 맞을 것 같아요.

    • 혼자 또는 작은 팀에서 GitHub Actions CI/CD를 관리하는 개발자
    • ChatGPT, Claude 같은 LLM으로 workflow를 만들지만 답변이 너무 길어 부담스러운 분
    • AI 코드를 그대로 붙였다가 에러를 몇 번 겪어본 분
    • 토큰 비용은 줄이고, 결과물 품질은 높이고 싶은 분
    • AI 바이브 코딩을 업무에 제대로 녹여보고 싶은 실무 개발자

솔직히 20년차 개발자인 저도 처음엔 AI가 좀 불편했습니다. 내 일을 빼앗는 느낌도 살짝 있었고요. 그런데 지금은 생각이 달라졌어요. AI가 일을 빼앗는다기보다, 반복되는 잡일을 덜어주고 제가 더 중요한 판단에 시간을 쓰게 해준다고 느낍니다.

물론 그 도구를 어떻게 쓰느냐는 여전히 사람 몫입니다. 프롬프트를 작게 나누고, 기본 템플릿을 갖춰두고, secrets 같은 보안 포인트를 미리 못 박아두고, 결과물은 꼭 검증하기. 이 정도만 습관으로 만들어도 GitHub Actions에서 AI를 쓰는 경험이 꽤 달라질 거예요.

토큰도 아끼고, 삽질도 줄고, 퇴근도 조금은 빨라질 수 있습니다. 저는 그 정도면 충분히 좋은 변화라고 봅니다. 개발이 늘 즐거울 순 없지만, 덜 피곤하게 만들 방법은 계속 찾아볼 만하니까요.

댓글