Grep의 동작 방식과 LLM 위키의 중복 비용

developkmj0110·2026년 7월 29일

AI

목록 보기
3/4
post-thumbnail

목차


  1. 내가 하던 방식
  2. 이상한 지점 발견
  3. 비용 분석
  4. 그래서 단순 grep이 이긴다
  5. 그래도 문서가 필요한 부분
  6. 바뀐 workflow
  7. 정리




1. 내가 하던 방식


llm wiki를 만들고 obsidian을 이용하여 보거나 수정할 수 있도록하고, 클래스의 동작, 메서드 시그니처와 역할, 다른 클래스와의 의존 관계같은 것을 기록해놓았다.

그리고 기능 개발 시작시 agent가 먼저 읽도록하고, 기능 개발이 끝나면 자동으로 업데이트 하도록하는 스킬을 만들어 사용했다.

이것이 왜 합리적으로 보였냐면, 기능 개발시 agent가 관련된 모든 클래스나 에셋을 읽는 토큰 비용을 절약하면서도 문맥을 파악할 수 있을 것이라고 생각했기 때문이다.




2. 이상한 지점 발견


기능 개발 시작 후 agent가 위키를 먼저 읽고, 이후 grep 과 read가 실행되면서 관련된 내용을 모두 읽는 것을 발견했다.

그렇다고 한다면 wiki에 코드 관련 내용을 요약해놓는 것이 실효성이 있을까를 고민하게 되었다.

왜냐하면 세션의 시작/끝에서 wiki의 내용을 읽고 쓰려면 작업의 크기에 따라 다르겠지만 토큰(<30k)을 사용하는데, 어차피 작업을 위해 코드를 전부 읽어야한다면 굳이 필요한 과정인가 싶었다.

3. 비용 분석


내 프로젝트의 CropManager라는 클래스의 내용을 살펴보는데 agent가 사고하는 방식을 살펴보면 다음과 같다.

- 위키 방식
→ 위키 파일 로드(클래스 000개 분량 중 해당 항목 + 주변)
→ 요약 읽기
→ 실제 파일 104줄 읽기
→ 작업 후 위키 갱신

- grep 방식
시그니처 8줄 + 참조 6줄 = 14줄. 갱신 단계 없음
  1. wiki를 파악/수정하는데에 토큰 뿐만 아니라 대기 시간 또한 고정비로 사용.

  2. agent가 wiki를 실수로 업데이트 하지 않는다면, 다음 기능 개발시 참고하는 쪽에서 잘못된 전재로 오판을 유발할 수 있음.

  3. 어차피 작업시에 agent가 실제 코드를 읽어야만 함.

4. 그래서 단순 grep이 이긴다


왜냐하면,

  1. 코드가 유일한 SSOT 이다.

    SSOT란' 단일 진실의 출처'라고 합니다. 이는 모든 데이터와 정보를 오직 하나의 신뢰할 수 있는 중앙 장소나 시스템에서만 관리하고 저장하는 설계 및 운영 원칙을 뜻합니다. - wikipedia

  2. 디렉토리 구조와 클래스 명이 곧 인덱스(지도)이다.

  3. agent가필요한 순간에, 필요한 부분만 가져오는 지연 로딩(lazy)을 이미 수행 중이다.

마지막으로 grep은 검색 범위가 자동으로 좁혀지기 때문에 Unity 프로젝트에서 유용하기 때문이다.

Assets/** 은 포함하고, Library/, Temp/, Logs/ 등은 빼고 확장자를 가리지 않고 검색한다.

.cs 파일 뿐 아니라 .unity .prefab .asset .meta를 검색해서 보기 때문에 이미 필요한 정보의 상당 부분을 체크한다.

5. 그래도 wiki가 필요한 부분


  1. 코드에 안적혀 있는 것을 설명해줄 때

프로젝트에서 전역적으로 사용되는 Manager들을 Independ/ Integrated/ 두 개의 폴더로 나누는데, 새로운 매니저를 어디에 넣어야하는지에 대한 기준은 코드나 주석에 없기 때문에 agent가 헷갈리지 않도록 "씬 수명과 무관해야 하면 Integrated에 넣는다" 한 줄 정도 추가하면 판별 기준이 명확해 진다.

  1. 주석처리된 코드

프로젝트를 진행하다 코드를 주석처리하는 경우, grep은 코드가 주석처리 되어있다는 사실만 알 수 있을 뿐, 이 코드를 왜 꺼놨는지, 잠시 끈 건지 폐기한건지, 되살릴 계획이 있는지를 알 수 없다.

using System.Collections.Generic;
using UnityEngine;
public class DynamicPricingSystem
{
	// 값을 조정하는 더 좋은 방법이 있을지도 모름 <- 이 코드에 남은 유일한 단서

}

95줄이 전부 주석 처리.
호출부도 마찬가지로
ShopSystem.cs(3곳)
CropPriceObject.cs
ItemInformationPanel.cs 전부 주석처리 되어있음

만약 위키에 아래와 같이 적혀 있었다고 한다면

  • "DynamicPricingSystem: 재고량에 따라 작물 판매가를 변동시킨다. ShopSystem이 참조한다."

LLM은 그 문장을 신뢰하고 "가격 변동 폭 조정해줘" 요청에 존재하지 않는 GetSellPriceModifier를 고치려 들거나, 왜 안 되는지 헤맬것이다.

  1. 프로젝트의 크기가 거대할 때

지금 프로젝트의 크기는 줄 수로 따지면 약 15만줄 이하이고, 이 모든 코드를 한 세션에서 다룬다고 해도 context에 충분히 들어간다.

하지만 프로젝트가 커져서 수백만 줄을 넘어간다면 grep으로 나온 결과물도 많아질 것이고 그 검색은 답이 아니라 다시 필터링해야하는 문제가 되어버릴지도 모른다.

그렇게 된다면 현실적으로 wiki도 답이 아닐 수 있겠지만, 하나의 고려할 수 있는 방법이 될 수도 있다.

6. 바뀐 workflow


제거 (코드로 알 수 있는 것들)

  • 클래스 역할
  • 메서드 동작
  • 참조 구조
  • 경로 설명

유지 (코드만으로는 알 수 없는 것들)

  • grep으로 도달 할 수 없는 외부 정보
  • 왜 이런 구조이고 trade-off는 무엇인지
  • 구현시 피해야하는 것

추가 (스킬)

기존 wiki에서 관리하던 프리팹/씬은, 스크립트를 클래스명이 아니라 GUID로 참조하므로, 클래스명 grep시 0건 이라고 나올 수 있음.

검증을 위해 asset-refs 스킬을 만들고, guid를 통해 어떤 프리팹/씬에서 사용중인 스크립트를 찾을 수 있도록 함.

하지만 한계점도 존재하기에 더 개선해야할 필요가 있음.

7. 정리


  • grep으로 알 수 있는 정보는 문서화하지않기.
  • 프로젝트의 크기가 커질 때, 문서화하여 누군가 '읽고' 작업하도록 바라지 말고, 스킬/훅을 이용해 '더 나은 도구'를 만들기.
  • 사실(what)은 코드에 맡기고, 이유·대안·외부 계약(why)만 남기기.
profile
유니티 개발 블로그

0개의 댓글