- 공유 링크 만들기
- X
- 이메일
- 기타 앱
Featured Post
작성자:
Iros
- 공유 링크 만들기
- X
- 이메일
- 기타 앱

AI 바이브 코딩 하다 보면, 이상하게 토큰이 먼저 지치더라
요즘 개발하면서 LLM 안 쓰는 분들 거의 없죠. 저도 20년 넘게 개발 밥 먹고 살았는데, 솔직히 요즘은 문서 찾는 시간보다 AI한테 물어보는 시간이 더 많을 때도 있어요. 예전 같으면 Stack Overflow 뒤지고, GitHub issue 뒤지고, 공식 문서 읽다가 커피 식고 그랬는데... 이제는 일단 물어보게 되더라고요.
근데 문제는 이거예요. AI가 똑똑하긴 한데, 아무 코드나 왕창 던져주면 꼭 내가 원하는 데서 살짝 비껴갑니다. “이 함수만 고쳐줘”라고 했는데 파일 전체 분위기를 보고 엉뚱한 구조로 바꿔버린다든지, 이미 잘 돌아가는 부분까지 친절하게 손대준다든지요. 고마운데, 안 고마운 그런 느낌 있잖아요.
게다가 AI 코딩에서 토큰은 생각보다 빨리 사라져요. 특히 큰 프로젝트에서 React 컴포넌트 하나, Python 서비스 파일 하나, Java 클래스 하나 통째로 넣다 보면 금방입니다. 처음에는 “뭐 이 정도야” 싶은데, 하루 종일 쓰다 보면 비용도 비용이고, 응답 품질도 점점 애매해져요.
그래서 제가 요즘 꽤 진지하게 보고 있는 도구가 바로 Tree-sitter예요. 처음엔 저도 그냥 “코드 파싱하는 라이브러리겠지 뭐” 하고 넘겼거든요. 그런데 막상 AI 코딩 워크플로우에 끼워 넣어보니까, 이게 은근히 판을 바꿉니다. 말 그대로 필요한 코드만 딱 잘라서 AI에게 먹일 수 있게 도와주는 도구예요.
Tree-sitter가 뭐냐면, 코드를 ‘문장’이 아니라 ‘구조’로 보는 도구예요
Tree-sitter는 코드를 문법적으로 분석해서 트리 구조로 만들어주는 파서입니다. 너무 딱딱하게 들리죠. 조금 풀어서 말하면, 코드라는 긴 글을 보고 “여긴 함수고, 여긴 클래스고, 여긴 if 문이고, 여긴 import 영역이네” 하고 구조를 나눠주는 친구예요.
사람이 코드를 볼 때도 사실 그렇게 보잖아요. 파일을 처음부터 끝까지 글자 그대로 읽는 게 아니라, “아 이 함수가 핵심이네”, “여기 useEffect가 문제구나”, “이 클래스의 public method만 보면 되겠네” 이런 식으로 구조를 잡고 보죠. Tree-sitter는 이걸 기계가 할 수 있게 해줍니다.
여기서 중요한 포인트가 나와요. AI에게 코드를 줄 때도 똑같이 구조를 잡아서 줘야 한다는 거예요. 전체 파일을 던지는 게 아니라, 지금 질문에 필요한 함수, 클래스, 블록만 골라서 전달하는 방식이 훨씬 효율적입니다. 토큰도 아끼고, AI가 헛소리할 가능성도 줄어들어요.
예를 들어 이런 상황이 있다고 해볼게요.
- 500줄짜리 React 컴포넌트에서 특정 이벤트 핸들러만 고치고 싶을 때
- Python 파일 안에 함수가 20개 있는데 그중 하나만 리팩토링하고 싶을 때
- Java 클래스에서 특정 method의 예외 처리만 점검하고 싶을 때
- TypeScript 프로젝트에서 특정 interface와 연결된 함수만 분석하고 싶을 때
이럴 때 파일 전체를 AI에게 주는 건, 뭐랄까... 친구에게 길 물어보려고 전국 지도를 펼쳐주는 느낌이에요. 필요한 건 골목 하나인데 말이죠. Tree-sitter를 쓰면 그 골목만 잘라서 보여줄 수 있습니다.
정규식으로 대충 하면 안 되냐고요? 저도 그렇게 생각했어요
개발자들 다 비슷하잖아요. 뭔가 파서를 붙여야 한다고 하면 일단 귀찮습니다. “그냥 regex로 잡으면 되지 않나?” 이 생각, 저도 정말 많이 했어요. 함수 이름 찾고, 중괄호 위치 찾고, 대충 split 하고... 초반에는 그럭저럭 되는 것처럼 보이거든요.
근데 코드가 조금만 복잡해지면 정규식은 금방 삐끗합니다. 중첩된 중괄호, 문자열 안에 들어간 괄호, 주석 안의 코드 비슷한 텍스트, decorator, anonymous function, arrow function, nested class... 이런 거 만나면 슬슬 손에 땀이 나요.
특히 JavaScript나 TypeScript 쪽은 함수 선언 방식이 워낙 다양하잖아요.
function declarationarrow functionmethod_definitionfunction expressionasync function
정규식으로 이걸 다 안정적으로 처리하려고 하면, 어느 순간 내가 AI 코딩을 하는 건지 정규식 지옥에서 수행 중인 건지 헷갈립니다. 반면 Tree-sitter는 언어 문법을 기반으로 코드를 파싱하니까 훨씬 안정적이에요. 코드에 약간의 에러가 있어도 가능한 범위 안에서 트리를 만들어주고요. 이게 실무에서는 생각보다 큰 차이를 만듭니다.
AI에게 줄 코드 양을 줄이면, 답변 품질도 같이 좋아집니다
토큰 절약 얘기를 하면 보통 비용만 떠올리는데, 저는 응답 품질 쪽이 더 중요하다고 봐요. AI에게 너무 많은 정보를 주면 오히려 집중을 못 합니다. 사람도 그렇잖아요. “이 문서 전체 읽고 문제 찾아줘”보다 “이 함수의 조건 분기만 봐줘”가 훨씬 답하기 쉽죠.
Tree-sitter를 활용한 AI 코딩의 핵심은 질문 범위를 좁히는 겁니다. AI가 봐야 할 부분과 안 봐도 되는 부분을 개발자가 먼저 정리해주는 거예요. 그러면 AI는 더 작은 문맥 안에서 더 정확한 판단을 할 수 있습니다.
제가 자주 쓰는 방식은 이런 식이에요.
- 현재 커서가 위치한 함수만 추출한다
- 함수와 관련된 type 또는 interface만 같이 붙인다
- 해당 함수가 호출하는 내부 helper 함수가 있으면 그것만 추가한다
- 파일 전체 import는 필요할 때만 최소한으로 넣는다
- AI에게 “이 범위 밖은 수정하지 말라”고 명확히 말한다
이렇게 하면 프롬프트가 훨씬 담백해져요. “여기부터 여기까지가 내가 보고 싶은 코드야. 이 안에서만 리팩토링해줘.” 이런 식으로요. 신기한 게, 이렇게 범위를 좁히면 AI도 덜 나댑니다. 표현이 좀 그렇지만 진짜 그래요. 괜히 프로젝트 구조를 바꾸거나, 없는 유틸 함수를 만들어내는 일이 줄어듭니다.
Tree-sitter로 뽑아내면 좋은 코드 조각들
처음 Tree-sitter를 붙이면 뭘 뽑아야 할지 살짝 막막할 수 있어요. 저도 처음엔 “AST 노드 이름부터 외워야 하나?” 싶었는데, 그렇게까지 부담 가질 필요는 없더라고요. 실무에서 자주 필요한 패턴은 생각보다 정해져 있습니다.
현재 커서가 들어있는 함수
가장 많이 씁니다. AI에게 질문할 때 “지금 내가 보고 있는 함수”만 넘기는 방식이에요. 예를 들어 버그가 특정 함수 안에서 발생한다면, 파일 전체보다 이 함수 하나가 훨씬 중요하죠.
이 방식은 특히 토큰 절약 효과가 큽니다. 800줄 파일에서 40줄짜리 함수 하나만 뽑아 보내면, 토큰 사용량이 확 줄어요. 비용도 줄지만, AI가 문제 지점을 더 빨리 잡습니다.
클래스 또는 컴포넌트 단위
객체지향 코드나 프론트엔드 컴포넌트에서는 함수 하나만 보면 문맥이 부족할 때가 있어요. 이럴 땐 클래스 전체나 컴포넌트 전체를 뽑는 게 낫습니다. 단, 그래도 파일 전체를 넣는 것보다는 훨씬 깔끔하죠.
React 기준으로 보면 하나의 component body, 관련 props type, 주요 hook 정도만 같이 넘기면 꽤 좋은 결과가 나옵니다. 괜히 import 전체, 스타일 객체 전체, 테스트용 mock 데이터까지 넣을 필요는 없어요. AI는 친절하지만, 너무 많이 먹이면 소화가 안 됩니다.
특정 조건문이나 반복문 블록
버그는 의외로 작은 조건문 하나에서 나오는 경우가 많습니다. if, switch, for, while 같은 블록만 뽑아서 “이 조건에서 빠지는 케이스가 있을까?”라고 물어보면 꽤 쓸 만한 답을 줘요.
이건 코드 리뷰할 때도 좋습니다. 전체 로직을 다 설명하지 말고, 의심되는 분기만 잘라서 보여주는 거죠. 뭔가 의사한테 “온몸이 아파요”라고 하는 것보다 “오른쪽 무릎이 계단 내려갈 때 아파요”라고 말하는 게 낫잖아요. 비슷합니다.
함수 시그니처와 호출 관계
AI에게 전체 구현을 주지 않아도 될 때가 있어요. 그냥 함수 이름, parameter, return type, 호출 관계 정도만 있으면 충분한 경우도 많습니다. 설계 리뷰나 리팩토링 방향을 물어볼 때는 오히려 구현 코드를 빼는 게 더 좋을 때도 있고요.
Tree-sitter로 이런 구조 정보만 뽑아내면, “이 모듈의 public API가 너무 복잡한지 봐줘” 같은 질문을 아주 가볍게 던질 수 있습니다. 토큰도 아끼고, 답변도 설계 관점으로 나오기 쉬워요.
설정 파일에 미리 박아두면 진짜 편합니다
이런 도구는 한 번만 써보는 걸로는 습관이 안 됩니다. 매번 명령어 치고, 쿼리 찾고, 결과 복사해서 AI에 붙여넣고... 그러면 결국 안 쓰게 돼요. 사람은 생각보다 귀찮음에 약합니다. 특히 야근 직전에는 더더욱요.
그래서 저는 Tree-sitter 쿼리를 개발 환경에 미리 넣어두는 걸 추천합니다. VS Code를 쓰든, Neovim을 쓰든, Cursor를 쓰든, 본인 워크플로우에 맞게 “한 번에 뽑는” 단축키를 만들어두면 좋아요.
예를 들면 이런 식입니다.
- 현재 커서의 함수 본문만 추출
- 현재 파일의 함수 목록만 추출
- 현재 클래스의 method 목록만 추출
- 선택한 코드의 상위 AST 노드 추출
- 관련 type 또는 interface만 함께 추출
이걸 매번 손으로 하려면 귀찮은데, 단축키로 만들어두면 이야기가 달라져요. 저는 개인적으로 “현재 함수 복사해서 AI 프롬프트용으로 정리”하는 스크립트를 만들어두고 쓰는데, 이게 은근히 삶의 질을 올려줍니다. 정말 별거 아닌데, 하루에 열 번만 써도 체감이 와요.
회사에서 레거시 리팩토링할 때도 이 방식이 꽤 도움이 됐습니다. 수천 줄짜리 파일을 AI에게 통째로 넣으면 답변이 산으로 가는데, Tree-sitter로 문제 함수와 관련 타입만 잘라서 넣었더니 훨씬 정확하게 봐주더라고요. 그날 오후에 옆자리 동료한테 바로 보여줬습니다. “이거 세팅해놔. 커피값보다 빨리 회수된다” 이렇게요.
언어마다 AST 노드 이름이 달라서, 이 부분은 살짝 조심해야 해요
Tree-sitter가 좋은 도구인 건 맞는데, 모든 언어가 같은 이름으로 노드를 제공하는 건 아닙니다. 이걸 모르고 시작하면 처음에 좀 헤맬 수 있어요.
예를 들어 Python에서는 함수 정의가 보통 function_definition으로 잡히는데, JavaScript에서는 function_declaration이 나옵니다. TypeScript는 또 interface나 type alias가 따로 있고요. Java, Go, Rust도 각자 문법 구조가 다르니 노드 이름도 다르게 나옵니다.
그러니까 Tree-sitter를 제대로 쓰려면, 내가 주로 쓰는 언어의 grammar 문서를 한 번은 훑어보는 게 좋아요. 처음부터 다 외울 필요는 없습니다. 자주 쓰는 노드만 익히면 됩니다.
- JavaScript:
function_declaration,method_definition,arrow_function - TypeScript:
interface_declaration,type_alias_declaration,function_declaration - Python:
function_definition,class_definition - Java:
method_declaration,class_declaration - Go:
function_declaration,method_declaration
이 정도만 알아도 시작은 충분합니다. 그리고 실제로는 AST explorer 같은 도구로 한 번 찍어보면 감이 빨리 와요. 코드 넣고 트리 구조 보면, “아 이게 이런 이름으로 잡히는구나” 하고 바로 보입니다. 개발자는 역시 눈으로 봐야 빨라요.
AI 프롬프트도 같이 바꿔야 효과가 납니다
Tree-sitter로 코드만 잘라낸다고 끝은 아니에요. AI에게 어떻게 말하느냐도 중요합니다. 프롬프트가 두루뭉술하면, 코드 조각을 잘라줘도 AI가 또 마음대로 해석합니다.
제가 자주 쓰는 표현은 이런 느낌이에요.
- “아래 코드는 전체 파일이 아니라 특정 함수만 추출한 것입니다.”
- “이 함수 외부의 구조는 변경하지 않는다고 가정해주세요.”
- “동작을 바꾸지 말고 가독성과 예외 처리만 개선해주세요.”
- “필요한 경우에만 최소한의 코드 변경을 제안해주세요.”
- “추측이 필요한 부분은 코드로 만들지 말고 질문으로 남겨주세요.”
이런 문장을 같이 넣으면 AI가 훨씬 얌전해집니다. 특히 “이 범위 밖은 건드리지 마”라는 말을 꼭 해줘야 해요. 안 그러면 가끔 너무 성실해서 프로젝트를 새로 설계하려고 합니다. 착한데 부담스러운 후배 느낌이랄까요.
그리고 저는 프롬프트에 “전체 코드를 다시 출력하지 말고 변경된 부분만 보여줘”도 자주 넣습니다. 이것도 토큰 절약에 꽤 도움이 돼요. AI가 매번 전체 코드를 다시 뿌려주면, 읽는 사람도 피곤하고 비용도 나갑니다.
실무에서 느낀 Tree-sitter의 진짜 장점
제가 느낀 Tree-sitter의 장점은 단순히 “토큰이 줄었다”에서 끝나지 않았어요. 오히려 개발 흐름이 조금 달라졌습니다. 예전에는 AI에게 물어보기 전에 내가 코드를 한참 정리해야 했거든요. 관련 없는 부분 지우고, 필요한 타입 찾아 붙이고, 설명 적고... 그 과정이 은근히 피곤했습니다.
그런데 Tree-sitter를 워크플로우에 넣으니까, 이 준비 과정이 훨씬 짧아졌어요. 현재 함수만 뽑고, 관련 type만 붙이고, 질문 하나 얹어서 바로 던지는 식이죠. 그러면 AI와 대화하는 속도가 빨라집니다. 이게 바로 요즘 말하는 AI 바이브 코딩의 현실적인 생산성 아닐까 싶어요.
물론 AI가 모든 걸 해결해주진 않습니다. 아직도 결과는 개발자가 봐야 하고, 테스트도 돌려야 하고, 가끔은 “이건 좀 아닌데?” 하고 걸러내야 합니다. 하지만 좋은 재료를 주면 좋은 답이 나올 가능성이 높아지는 건 분명해요. Tree-sitter는 그 재료를 다듬어주는 칼 같은 도구입니다.
이런 분들은 Tree-sitter를 한 번쯤 꼭 만져보면 좋습니다
모든 개발자가 당장 Tree-sitter를 깊게 파야 한다고 생각하진 않아요. 바쁜데 또 배울 게 늘어나는 건 사실 부담스럽죠. 저도 새로운 도구 볼 때마다 반가움 반, 피곤함 반입니다.
그래도 아래에 해당한다면 한 번쯤은 꼭 써보셨으면 해요.
- AI에게 큰 파일을 자주 붙여넣는 개발자
- LLM 토큰 비용이 은근히 부담되는 팀
- 레거시 코드 리팩토링을 자주 하는 개발자
- Cursor, VS Code, Neovim 등에서 AI 코딩 워크플로우를 개선하고 싶은 분
- 정규식으로 코드 구조를 뽑다가 한계를 느낀 분
- 코드 리뷰 자동화나 문서화 자동화에 관심 있는 분
특히 팀 단위로 AI를 쓰고 있다면 효과가 더 큽니다. 개인이야 조금 낭비해도 넘어갈 수 있는데, 팀 전체가 매일 대용량 코드를 LLM에 넣고 있다면 이야기가 달라져요. 비용도 쌓이고, 보안 이슈도 생기고, 품질도 흔들립니다. 필요한 코드만 최소한으로 보내는 습관은 이제 거의 기본기가 되어가는 느낌입니다.
Tree-sitter는 AI를 더 똑똑하게 만드는 게 아니라, 우리가 더 잘 쓰게 해줍니다
사실 AI 도구가 아무리 좋아져도, 결국 중요한 건 “내가 무엇을 물어볼지”예요. 질문이 흐리면 답도 흐립니다. 코드도 마찬가지고요. AI에게 줄 문맥을 잘 고르는 능력이 앞으로 개발자에게 꽤 중요한 역량이 될 거라고 봅니다.
Tree-sitter는 그 문맥을 고르는 데 아주 현실적인 도움을 줍니다. 전체 파일을 통째로 넘기는 대신, 지금 필요한 AST 노드만 뽑아 보내는 것. 이 단순한 차이가 토큰을 줄이고, 답변 품질을 올리고, 개발자의 집중력까지 지켜줍니다.
솔직히 저도 처음엔 “파서 하나 붙인다고 뭐가 그렇게 달라지겠어?” 했습니다. 그런데 써보니까 생각이 바뀌었어요. AI 코딩을 오래, 많이, 제대로 하려면 이런 작은 도구들이 꽤 큰 차이를 만듭니다.
여행 갈 때도 그렇잖아요. 좋은 신발 하나 챙기면 하루 피로가 달라집니다. Tree-sitter도 제 개발 생활에서는 그런 느낌이에요. 엄청 화려하진 않은데, 한 번 익숙해지면 안 챙기기 어려운 도구. AI 바이브 코딩을 하고 있다면, 한 번쯤은 꼭 옆에 둬볼 만합니다.
댓글
댓글 쓰기