
요즘 주변 개발자들이랑 이야기하다 보면 AI 바이브 코딩 얘기가 정말 자주 나와요. 저도 처음엔 좀 삐딱하게 봤습니다. 20년 넘게 개발하면서 별별 자동화 도구를 다 봤잖아요. 그래서 “AI가 코드를 대신 짜준다고? 그래도 결국 뒷수습은 사람이 하는 거 아닌가?” 싶었죠. 그런데 막상 ChatGPT나 GitHub Copilot을 일에 붙여보니까, 이게 생각보다 꽤 쓸 만하더라고요. 아니, 솔직히 말하면 이제는 안 쓰면 손해 보는 느낌까지 듭니다.
다만 여기서 중요한 게 하나 있어요. AI가 코드를 잘 만들어주긴 하는데, 그 코드가 늘 믿음직한 건 아니라는 거예요. import는 중복되어 있고, 변수명은 들쭉날쭉하고, 안 쓰는 모듈이 남아 있고, 가끔은 “얘가 어디서 10년 전 예제를 보고 왔나?” 싶은 코드도 섞여 있습니다. 그래서 저는 요즘 AI가 만들어준 파이썬 코드를 바로 믿기보다는, 꼭 Ruff를 한 번 통과시켜요. 뭐랄까, AI가 초안을 써주면 Ruff가 옆에서 옷매무새를 정리해주는 느낌입니다.
AI 바이브 코딩은 편한데, 코드 정리는 또 다른 문제더라고요
사실 저는 요즘 작은 스크립트든, 사이드 프로젝트든, 업무용 API 샘플이든 일단 AI한테 초안을 던져봅니다. “이런 구조로 만들어줘”, “FastAPI 엔드포인트 하나 짜줘”, “pytest 테스트까지 붙여줘” 이런 식으로요. 그러면 생각보다 빠르게 뼈대가 나와요. 예전 같으면 폴더 만들고, 파일 나누고, 기본 함수 쓰고, 테스트 틀 잡는 데만 30분은 훌쩍 갔는데 이제는 그 시간이 확 줄었습니다.
그런데 문제는 그다음이에요. AI가 만들어준 코드를 열어보면 은근히 손볼 게 많습니다. 사람이 쓴 코드처럼 보이긴 하는데, 자세히 보면 살짝 정신없는 경우가 많아요.
- 사용하지 않는 import가 그대로 남아 있음
- import 순서가 프로젝트 스타일과 안 맞음
- 예전 파이썬 문법이 섞여 있음
- 함수명이나 변수명이 묘하게 어색함
- 테스트 코드는 만들었는데 실제로 돌리면 깨지는 경우도 있음
- print 디버깅 코드가 아무렇지 않게 들어가 있음
예전에는 이런 걸 Flake8, isort, Black, pylint 조합으로 처리했어요. 각각 좋은 도구들이고 지금도 많이 씁니다. 그런데 도구가 여러 개면 설정도 여러 군데 나뉘고, CI에서 맞추는 것도 은근히 귀찮아요. 개발자는 결국 귀찮은 걸 줄이려고 자동화를 하는 사람들 아니겠어요. 그러다 Ruff를 본격적으로 써봤는데, 아 이건 좀 다르더라고요.
가장 크게 와닿은 건 속도였습니다. 프로젝트 전체를 검사하는데 체감상 “어? 벌써 끝났어?” 싶어요. AI가 만든 코드를 붙여 넣고 저장한 다음 Ruff를 돌리면, 중복 import나 사용하지 않는 변수 같은 건 거의 바로 정리됩니다. 저는 이 느낌이 좋아요. AI한테 “일단 만들어봐” 하고 맡긴 다음, Ruff한테 “자, 이제 네가 좀 정리해줘” 하는 흐름이죠.
AI가 만든 로그인 코드, Ruff에 넣어보면 차이가 바로 보입니다
최근에 작은 인증 예제를 만들 일이 있었어요. 진짜 서비스에 넣을 코드는 아니고, 내부 테스트용으로 로그인 흐름을 빠르게 확인하려던 상황이었죠. AI한테 “사용자 로그인 로직 하나 만들어줘”라고 했더니 대충 이런 코드가 나왔습니다.
from datetime import datetime
import os
import sys
def login(username,password):
if username == "admin":
print("Welcome admin")
return True
else:
return False
import json
from datetime import datetime # 중복 import!
처음 보면 뭐, 돌아가긴 돌아갈 것 같죠. 그런데 개발자 눈에는 거슬리는 게 바로 보입니다. datetime은 두 번 import 되어 있고, os, sys, json은 쓰지도 않아요. 함수 인자 사이 공백도 어색하고, else도 굳이 필요 없어 보입니다. 이런 사소한 것들이 쌓이면 코드 리뷰 때 괜히 말이 길어져요. 진짜 중요한 로직 얘기는 못 하고 “import 정리해주세요” 같은 댓글만 달게 됩니다. 그거 은근히 피곤하거든요.
이럴 때 저는 그냥 터미널에서 이렇게 칩니다.
ruff check --fix .
ruff format .
정말 별거 아닌 명령어인데, 체감 효과는 꽤 큽니다. 제가 자주 쓰는 명령어를 표로 정리하면 이런 느낌이에요.
| 명령어 | 제가 쓰는 상황 | 체감 속도 |
|---|---|---|
ruff check . |
문제만 먼저 보고 싶을 때 | 거의 바로 끝남 |
ruff check --fix . |
사용하지 않는 import나 간단한 린트 문제를 자동 정리할 때 | 기다린다는 느낌이 거의 없음 |
ruff format . |
코드 포매팅을 한 번에 맞출 때 | Black보다 훨씬 가볍게 느껴짐 |
Ruff를 돌린 뒤에는 코드가 이런 식으로 정리됩니다.
def login(username, password):
if username == "admin":
print("Welcome admin")
return True
return False
사용하지 않는 import가 사라지고, 함수 인자 사이 공백도 정리되고, 불필요한 else도 없어졌습니다. 물론 Ruff가 모든 걸 다 고쳐주는 건 아니에요. 예를 들어 타입 힌트를 무조건 자동으로 붙여준다거나, 비즈니스 로직을 이해해서 더 좋은 구조로 바꿔주는 건 아닙니다. 그건 여전히 사람이 봐야 해요. 저는 오히려 그 선이 마음에 듭니다. Ruff는 청소를 해주고, 설계 판단은 개발자가 하는 거죠.
가끔 --unsafe-fixes 옵션도 쓰긴 합니다. 다만 이건 이름 그대로 조심해야 해요. 자동 수정 범위가 넓어지기 때문에, 저는 개인 브랜치에서만 먼저 돌려보고 diff를 꼼꼼히 확인합니다. 특히 AI가 만든 코드에는 의도가 애매한 부분이 많아서, 너무 과감한 자동 수정은 오히려 일을 키울 때가 있더라고요.
제가 실제로 쓰는 프로젝트 구조와 Ruff 설정
요즘 제가 사이드 프로젝트에서 자주 쓰는 구조는 대충 이런 모양입니다. 거창한 건 아니고, AI랑 같이 작업하기 편하게 일부러 단순하게 잡아둔 구조예요.
project/
├── .ruff.toml
├── src/
│ ├── main.py
│ ├── auth.py
│ └── utils.py
├── tests/
│ └── test_auth.py
└── pyproject.toml
여기서 제가 제일 먼저 챙기는 파일이 .ruff.toml입니다. AI 바이브 코딩을 하다 보면 코드가 빠르게 쌓이는데, 스타일이 흔들리기 시작하면 나중에 정리하기가 귀찮아져요. 그래서 처음부터 Ruff 설정을 박아두는 편입니다. 약간 여행 갈 때 숙소 위치 먼저 잡아두는 느낌이랄까요. 숙소가 애매하면 하루 동선이 다 꼬이잖아요. 프로젝트도 비슷합니다. 기준점이 있어야 덜 헤매요.
제가 자주 쓰는 설정은 이런 정도예요.
# .ruff.toml
target-version = "py311"
line-length = 100
[lint]
select = ["E", "F", "I", "N", "W", "UP", "YTT"]
ignore = ["E501"]
[format]
quote-style = "double"
indent-style = "space"
여기서 I는 import 정렬 쪽이라 꼭 넣는 편입니다. AI가 import 순서를 생각보다 신경 안 씁니다. 위에 표준 라이브러리, 그다음 서드파티, 그다음 로컬 모듈 이런 흐름이 자연스러운데, AI가 급하게 만든 코드는 이게 뒤섞여 있는 경우가 많아요. Ruff가 이 부분을 자동으로 잡아주니까 코드가 훨씬 보기 좋아집니다.
UP도 꽤 유용합니다. 오래된 파이썬 문법을 최신 스타일로 바꿔주는 규칙인데, AI가 가끔 예전 예제에서 본 듯한 코드를 만들어낼 때가 있거든요. 예를 들면 class Foo(object): 같은 코드요. 파이썬 3 기준에서는 그냥 class Foo:라고 쓰면 되는데 말이죠. 이런 자잘한 부분을 사람이 계속 잡고 있으면 은근히 피로합니다.
E501은 줄 길이 관련 규칙인데, 저는 보통 line-length = 100으로 두고도 E501은 상황에 따라 무시합니다. AI가 생성한 긴 설명 문자열이나 테스트 데이터 때문에 줄 길이 경고가 너무 많이 뜰 때가 있거든요. 물론 팀 프로젝트라면 팀 컨벤션을 따라야 합니다. 혼자 하는 프로젝트에서는 너무 빡빡하게 잡지 않는 편이에요. 도구 때문에 개발 리듬이 끊기면 그건 또 그것대로 별로라서요.
VS Code에 붙여두면 진짜 편합니다
터미널에서 명령어를 직접 치는 것도 좋지만, 매번 그러면 또 귀찮아집니다. 저는 VS Code에 Ruff extension을 설치해두고, 저장할 때 자동으로 정리되게 해놨어요. AI가 코드를 만들어주면 붙여 넣고, 제가 살짝 보고, 저장 한 번 누르면 기본적인 정리가 끝납니다. 이게 별것 아닌데 작업 흐름이 꽤 부드러워져요.
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
},
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
설정값은 VS Code 버전에 따라 조금씩 다르게 동작할 수 있어서, 처음에는 저장할 때 자동으로 잘 도는지 확인해보는 게 좋습니다. 저는 팀원들한테도 항상 이렇게 말해요. “도구 믿어도 되는데, 처음 한 번은 눈으로 봐라.” 자동화는 편하지만, 자동화가 뭘 바꾸는지 모르면 나중에 디버깅할 때 당황합니다.
AI 코드에 Ruff를 붙일 때 제가 자주 보는 체크포인트
AI 바이브 코딩을 하다 보면 속도가 빨라지는 만큼, 검증 루틴이 더 중요해집니다. 저는 AI가 만든 파이썬 코드를 받을 때 대충 이런 순서로 봐요. 너무 거창한 프로세스는 아니고, 그냥 오래 일하면서 몸에 밴 습관에 가깝습니다.
- import가 깨끗한지 봅니다. 안 쓰는 import, 중복 import, 순서가 이상한 import는 Ruff가 잘 잡아줍니다.
- 자동 수정 전후 diff를 확인합니다. 특히
--fix를 돌린 뒤에는 Git diff를 한 번 보는 편이에요. - 포매팅은 저장할 때 자동으로 맞춥니다. 손으로 공백 맞추는 건 이제 좀 아깝잖아요.
- 테스트는 반드시 직접 돌립니다. AI가 테스트를 만들어줘도, 그 테스트가 진짜 의미 있는지는 사람이 봐야 합니다.
- 경고를 무시할 땐 이유를 남깁니다.
noqa는 편하지만, 남발하면 나중에 아무도 손 못 대는 코드가 됩니다.
특히 ruff check --add-noqa .는 조심해서 쓰는 편입니다. 이 명령어는 현재 위반 사항에 대해 noqa 주석을 자동으로 붙여주거든요. 레거시 코드가 너무 많아서 일단 CI를 통과시켜야 할 때는 도움이 됩니다. 그런데 AI가 방금 만든 새 코드에 무작정 붙이는 건 추천하지 않아요. 새 코드는 고치는 게 맞습니다. 덮어두면 언젠가 다시 돌아옵니다. 이상하게 버그는 꼭 바쁠 때 돌아오더라고요.
CI/CD에 Ruff를 넣으면 코드 리뷰가 훨씬 가벼워집니다
혼자 개발할 때도 Ruff는 좋지만, 팀에서 쓸 때 효과가 더 큽니다. 코드 리뷰를 하다 보면 진짜 중요한 얘기를 해야 하잖아요. 이 함수 책임이 너무 많다든지, 예외 처리가 부족하다든지, API 응답 구조가 애매하다든지. 그런데 리뷰 댓글이 “사용하지 않는 import 제거해주세요”, “줄 길이 맞춰주세요”, “import 순서 정리해주세요”로 채워지면 서로 힘이 빠집니다.
그래서 저는 GitHub Actions 같은 CI에 Ruff를 넣는 걸 좋아합니다. PR 올릴 때 자동으로 검사하게 해두면, 사람은 사람다운 리뷰에 집중할 수 있어요.
name: Python Lint
on:
pull_request:
push:
branches: [main]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Ruff
run: pip install ruff
- name: Run Ruff check
run: ruff check .
- name: Run Ruff format check
run: ruff format --check .
이 정도만 넣어도 기본적인 품질선은 꽤 잘 지켜집니다. AI가 만든 코드든 사람이 만든 코드든, 최소한 프로젝트의 기본 규칙은 통과해야 머지되는 거죠. 저는 이게 좋습니다. AI를 쓰는 건 자유지만, main 브랜치에 들어오는 코드는 기준을 통과해야 한다는 선이 생기니까요.
| 상황 | Ruff 없이 작업했을 때 | Ruff를 붙인 뒤 |
|---|---|---|
| AI 코드 초안 정리 | 사람이 import와 포맷을 직접 확인 | 저장 또는 명령어 한 번으로 대부분 정리 |
| 코드 리뷰 | 스타일 지적이 댓글을 차지함 | 리뷰어가 로직과 구조에 집중 |
| 팀 컨벤션 유지 | 사람마다 스타일이 조금씩 달라짐 | 설정 파일 기준으로 일관성 유지 |
Ruff 규칙은 욕심내지 말고, 프로젝트에 맞게 켜는 게 좋습니다
처음 Ruff를 쓰면 이것저것 다 켜보고 싶어집니다. 저도 그랬어요. “이왕 하는 거 엄격하게 가자” 싶어서 규칙을 잔뜩 켰다가, 경고가 너무 많이 떠서 오히려 개발 흐름이 끊긴 적도 있습니다. 특히 레거시 프로젝트에 갑자기 강한 규칙을 적용하면 팀원들이 싫어합니다. 말은 안 해도 표정에서 보여요.
그래서 저는 보통 이렇게 갑니다. 새 프로젝트는 조금 엄격하게, 오래된 프로젝트는 천천히. AI가 만든 코드가 많은 프로젝트라면 기본 린트와 import 정렬, 포매팅부터 잡고, 그다음에 필요할 때 docstring이나 네이밍 규칙을 추가합니다.
- 새 프로젝트라면 처음부터
E,F,I,UP정도는 켜둡니다. - 레거시 프로젝트라면 자동 수정 가능한 규칙부터 적용합니다.
- 팀 프로젝트라면 규칙을 늘리기 전에 팀원들과 기준을 맞춥니다.
- AI 생성 코드가 많다면 import 정리와 포매팅 자동화만 해도 효과가 큽니다.
docstring을 강제하고 싶다면 D 계열 규칙도 고려할 수 있습니다. 다만 이건 취향과 팀 문화가 많이 갈려요. 모든 함수에 docstring이 있는 게 좋은 프로젝트도 있고, 짧고 명확한 내부 함수에는 오히려 과하다고 느끼는 팀도 있습니다. 저는 공개 API나 복잡한 도메인 로직에는 docstring을 요구하고, 단순 유틸 함수에는 너무 집착하지 않는 쪽을 좋아합니다.
제가 느낀 AI 바이브 코딩과 Ruff의 좋은 거리감
AI 바이브 코딩을 하면서 제일 많이 바뀐 건 “처음부터 완벽하게 짜야 한다”는 부담이 줄었다는 거예요. 예전에는 빈 파일을 열고 첫 줄을 쓰기까지 은근히 시간이 걸렸습니다. 지금은 AI한테 먼저 초안을 맡기고, 저는 그걸 읽고 고치고 판단하는 쪽에 에너지를 씁니다. 개발자의 일이 사라지는 게 아니라, 조금 다른 위치로 옮겨간 느낌이에요.
그런데 이 방식이 잘 굴러가려면 최소한의 안전장치가 필요합니다. 저는 그중 하나가 Ruff라고 봅니다. AI가 빠르게 만든 코드는 속도라는 장점이 있지만, 일관성은 약할 수 있어요. Ruff는 그 빈틈을 꽤 잘 메워줍니다. 그렇다고 Ruff가 설계를 대신해주진 않습니다. 이 둘의 거리감이 딱 좋아요. AI는 초안, Ruff는 정리, 최종 판단은 사람. 저는 이 구도가 제일 건강하다고 봅니다.
여행 다닐 때도 비슷하잖아요. 지도 앱이 길은 알려주지만, 어디서 멈춰서 커피 한 잔 할지는 내가 정하는 거니까요. 개발도 그런 것 같습니다. AI가 길을 안내해주고, Ruff가 길 위의 작은 돌멩이들을 치워주면, 우리는 좀 더 멀리 볼 수 있습니다.
이런 분들은 Ruff를 꼭 한 번 붙여보세요
제가 써보니 AI 바이브 코딩을 이미 하고 있거나, 파이썬 프로젝트에서 린트와 포매팅 때문에 은근히 스트레스를 받는 분들에게 Ruff는 꽤 현실적인 선택입니다. 특히 이런 분들께 잘 맞을 것 같아요.
- ChatGPT나 GitHub Copilot으로 파이썬 코드를 자주 만드는 개발자라면, AI 초안을 정리하는 도구로 Ruff가 정말 편합니다.
- Flake8, isort, Black 설정을 따로 관리하는 게 귀찮았던 분이라면, Ruff 하나로 상당 부분을 단순화할 수 있습니다.
- 코드 리뷰에서 스타일 지적을 줄이고 싶은 팀 리더라면, CI에 Ruff를 넣는 것만으로도 리뷰 분위기가 꽤 달라집니다.
- 레거시 파이썬 코드를 조금씩 현대화하고 싶은 시니어 개발자라면, 자동 수정 가능한 규칙부터 천천히 적용해보면 좋습니다.
저는 이제 AI가 만들어준 파이썬 코드를 보면 거의 반사적으로 Ruff부터 돌립니다. 무작정 믿지는 않지만, 무작정 의심만 하지도 않아요. AI에게 초안을 맡기고, Ruff로 기본기를 다지고, 사람 눈으로 맥락을 보는 것. 지금 제 기준에서는 이 조합이 꽤 괜찮습니다.
혹시 요즘 AI 바이브 코딩을 시작했는데 “코드는 빨리 나오는데 왜 이렇게 정리가 안 되지?” 하는 느낌이 들었다면, Ruff를 한 번 붙여보세요. 처음엔 그냥 린트 도구 하나 추가한 정도로 느껴질 수 있는데, 며칠 써보면 작업 리듬이 달라지는 게 느껴질 겁니다. 저는 그 작은 차이가 꽤 크더라고요.
댓글
댓글 쓰기