포스트

CodeGraph가 grep보다 나을 때: 함수 영향 범위와 오래된 그래프를 구분하는 법

CodeGraph는 grep을 없애는 도구가 아니라, “이 함수를 바꾸면 어디까지 영향을 받는가”처럼 관계를 따라가야 하는 질문에서 검색 범위를 줄이는 보조 인덱스입니다.

문자열, 의미, 관계 검색은 답하는 질문이 다르다

grep은 정확한 이름과 문자열을 찾는 데 빠르고 결과의 출처가 분명합니다. 벡터 검색은 validate_token과 check_auth처럼 이름이 달라도 의미가 비슷한 코드를 찾는 데 유리하지만, 두 함수가 실제로 호출 관계인지 증명하지는 않습니다. 그래프 순회는 AST나 언어 도구가 만든 CALLS, INHERITS_FROM, DEPENDS_ON 같은 엣지를 따라 영향 범위를 좁힙니다.

따라서 세 방식은 대체재가 아닙니다. 이름을 알면 grep, 개념만 알면 의미 검색, 호출자와 의존성의 깊이를 알고 싶으면 그래프가 출발점입니다. CodeGraph 계열의 장점은 이 결과를 MCP로 에이전트에 전달해 관련 파일 전체가 아니라 작은 서브그래프부터 읽게 하는 데 있습니다.

“결정론적 그래프”라는 표현도 범위를 제한해야 합니다. 정적 import와 직접 호출은 비교적 명확하지만 리플렉션, 런타임 등록, 문자열 라우팅, 의존성 주입은 파서가 놓칠 수 있습니다. 그래프의 엣지는 코드 전체의 진실이 아니라 해당 인덱서가 관찰한 사실입니다.

CodeGraph는 네 층을 거쳐 만들어진다

원문은 구조를 다음처럼 설명합니다.

  1. Tree-sitter 기반 AST 파싱으로 클래스, 함수, 인터페이스, import를 노드와 엣지로 만듭니다.
  2. 심볼과 설명을 임베딩해 이름이 다른 유사 기능을 찾습니다.
  3. Neo4j, FalkorDB 또는 로컬 RocksDB에 구조와 의미 데이터를 저장합니다.
  4. MCP 인터페이스가 에이전트의 질의를 그래프 검색으로 연결합니다.

특정 함수의 상위 호출자를 세 단계까지 찾는 원문의 Cypher는 개념용 예시입니다.

1
2
3
4
MATCH (target:Function {name: "validate_token"})<-[:CALLS*1..3]-(caller:Function)
MATCH (caller)-[:BELONGS_TO]->(file:File)
RETURN caller.name, file.path, target.complexity
ORDER BY target.complexity DESC;

이 쿼리가 실행되려면 실제 그래프에 Function, File 라벨, CALLS, BELONGS_TO 관계와 complexity 속성이 같은 이름으로 존재해야 합니다. 저장소 초기화, 인덱싱, 데이터베이스 연결, MCP 설정은 포함하지 않은 핵심 조각입니다. 또한 결과가 “세 단계 안의 정적 호출자”라는 사실과 “실제 변경 영향 전체”를 혼동하면 안 됩니다.

오래된 지도는 정확한 쿼리도 틀리게 만든다

대형 모노레포의 첫 스캔은 파싱과 임베딩 비용이 큽니다. 이후 PR이 계속 합쳐지는데 그래프 갱신이 늦으면 Cypher 자체는 정확해도 어제 구조를 반환합니다. 결과에는 커밋 ID나 생성 시각이 따라야 하며, 질의 대상 브랜치와 인덱스 버전이 다르면 경고해야 합니다.

언어 지원도 확인할 부분입니다. 주류 언어의 Tree-sitter 문법이 있어도 프레임워크별 라우팅, 템플릿, 사내 DSL까지 자동으로 의미 있는 엣지가 되는 것은 아닙니다. 이름 규칙과 모듈 경계가 무너진 코드에서는 복잡한 현실을 복잡한 그래프로 옮길 뿐입니다. 커스텀 파서를 유지할 사람이 없다면 누락을 문서화하고 grep, LSP, 테스트로 보완해야 합니다.

파일럿은 영향 분석 누락률로 평가한다

실제 완료된 리팩터링 10건을 골라 당시 변경 파일을 정답 집합으로 둡니다. CodeGraph가 제시한 파일과 비교해 다음을 측정할 수 있습니다.

  • 첫 관련 파일까지 걸린 시간
  • 실제 변경 파일을 놓친 비율
  • 관계는 있지만 수정할 필요 없었던 파일 비율
  • 인덱스 생성 시간과 PR 뒤 갱신 지연
  • 에이전트에 전달한 토큰 수
  • 지원하지 못한 언어, DSL, 동적 연결의 수

결과가 좋으면 먼저 읽기 전용 영향 분석과 테스트 후보 추천에 사용합니다. 배포 승인이나 “안전한 변경” 판정은 그래프 하나에 맡기지 않습니다. 그래프가 놓칠 수 있는 동적 경로를 통합 테스트와 런타임 관측으로 확인해야 합니다.

CodeGraph가 주는 이점은 검색을 하지 않아도 된다는 것이 아닙니다. 관계형 질문에 맞는 인덱스를 먼저 써서 grep과 파일 열기의 순서를 더 영리하게 만드는 것입니다.

어떤 질문에서 그래프 비용이 값을 하는가

함수 이름을 이미 알고 한 파일의 정의를 찾는 일이라면 그래프 데이터베이스를 운영할 이유가 거의 없습니다. 반대로 공용 인터페이스 변경, 권한 검사 이동, 이벤트 스키마 개편처럼 호출자와 구현체가 여러 패키지에 흩어진 작업은 관계 탐색의 이점이 큽니다. 검색 질문을 먼저 분류하면 도구가 필요 이상으로 커지는 일을 막을 수 있습니다.

질문먼저 쓸 도구CodeGraph를 덧붙일 조건
특정 문자열은 어디에 있나grep, ripgrep생성 코드나 별칭 때문에 문자열만으로 부족할 때
이 심볼의 정의와 참조는 무엇인가IDE, LSP여러 언어, 저장소 경계를 함께 봐야 할 때
이 API를 바꾸면 무엇이 영향을 받나테스트 + 그래프호출, 상속, import를 여러 단계 추적해야 할 때
비슷한 책임의 코드는 어디에 있나의미 검색후보 사이의 실제 의존 관계까지 좁힐 때
운영 중 실제로 호출되는가trace, 로그정적 그래프 후보와 실행 경로를 대조할 때

그래프가 많은 파일을 반환하면 정확도가 높다는 뜻도 아닙니다. 후보가 너무 넓으면 에이전트가 읽는 토큰과 사람이 검토하는 시간이 다시 늘어납니다. 반대로 후보가 적더라도 동적 등록 지점을 놓쳤다면 위험합니다. 따라서 결과 개수가 아니라 정답 변경에서 놓친 파일과 불필요하게 펼친 파일을 동시에 봐야 합니다.

인덱스 신선도는 빌드 산출물처럼 관리한다

코드 그래프는 한 번 만들어 두는 문서가 아니라 특정 커밋에서 파생된 산출물입니다. 저장할 때 저장소 URL, 브랜치, 커밋 SHA, 파서와 임베딩 모델 버전, 생성 시각을 함께 기록해야 합니다. 질의하는 작업 공간의 커밋과 그래프의 커밋이 다르면 에이전트가 답을 내기 전에 명확히 경고하는 편이 안전합니다.

갱신 방식은 전체 재색인과 변경분 반영으로 나뉩니다. 전체 재색인은 단순하지만 큰 모노레포에서는 느립니다. 변경분 반영은 빠르지만 파일 삭제, 심볼 이름 변경, 브랜치 전환 때 낡은 노드와 엣지가 남기 쉽습니다. PR마다 변경 파일을 증분 반영하더라도 주기적으로 전체 재색인을 수행하고, 두 결과의 노드, 엣지 수와 고아 노드를 비교해야 합니다.

CI에서 그래프 생성 실패를 무시한 채 이전 인덱스를 계속 제공하는 것도 피해야 합니다. 읽기 전용 코드 탐색이라면 ‘오래됨’ 배지를 붙여 제한적으로 사용할 수 있지만, 자동 리팩터링이나 보안 영향 분석에서는 해당 커밋의 인덱스가 준비되지 않으면 작업을 중단하는 정책이 낫습니다. 빠른 오답보다 느리더라도 검증 가능한 후보가 더 유용하기 때문입니다.

동적 호출은 별도의 증거 층으로 보완한다

정적 AST가 잘 잡는 것은 명시적인 함수 호출, import, 상속과 타입 참조입니다. 플러그인 레지스트리, 문자열로 지정한 라우트, 리플렉션, 의존성 주입 컨테이너와 메시지 토픽은 실행 시점에 연결될 수 있습니다. 이런 관계를 억지로 확정 엣지로 만들기보다 ‘추정’ 또는 ‘런타임 관측’이라는 출처를 붙이는 편이 정확합니다.

예를 들어 payment.completed라는 토픽을 발행하는 코드와 소비하는 코드를 문자열 검색으로 연결할 수는 있지만, 동일한 이름이 테스트 fixture에만 있을 수도 있습니다. 실행 trace에서 실제 호출이 확인되면 더 높은 신뢰도를 주고, 문서나 이름 유사도만으로 연결한 엣지는 낮은 신뢰도로 표시할 수 있습니다. 에이전트에게는 경로뿐 아니라 엣지의 근거와 마지막 관측 시점을 함께 전달해야 합니다.

정적 그래프와 런타임 trace가 다를 때 어느 쪽을 무조건 정답으로 삼아서는 안 됩니다. trace는 관측 기간에 실행되지 않은 경로를 놓치고, 정적 그래프는 도달 불가능한 코드를 포함합니다. 두 집합의 교집합은 우선 검토하고, 한쪽에만 있는 경로는 테스트나 코드 리뷰로 확인하는 방식이 실무적으로 안전합니다.

에이전트에 연결할 때 권한과 출력 범위를 제한한다

MCP 도구가 전체 그래프 질의를 허용하면 편리하지만, 임의 Cypher와 대량 결과가 컨텍스트를 오염시키거나 저장소 구조를 불필요하게 노출할 수 있습니다. 처음에는 정의 찾기, 호출자 찾기, 제한 깊이 의존성 탐색처럼 읽기 전용 질의를 허용 목록으로 두는 편이 좋습니다. 깊이, 반환 노드 수, 실행 시간에도 상한을 둡니다.

결과는 파일 전체보다 심볼 이름, 관계, 파일 경로, 근거가 되는 줄 범위를 먼저 반환하고 필요할 때만 원문을 읽게 합니다. 그래프 답을 근거로 코드를 고치더라도 테스트 선택과 변경 승인은 별도 단계로 남깁니다. 인덱스가 보안 경계를 넘는다면 비밀값, 생성 파일, 외부 vendor 코드를 제외하는 규칙과 접근 로그도 필요합니다.

원문과 버전 확인

함께 읽으면 이해가 이어지는 글

자주 묻는 질문

CodeGraph를 쓰면 grep이나 IDE 검색은 필요 없나요?

아닙니다. 정확한 문자열과 정의 찾기는 grep, LSP가 더 단순하며, CodeGraph는 여러 파일의 호출, 상속, 의존 관계를 따라가야 하는 질문을 보완합니다.

그래프에 나온 영향 파일은 모두 수정해야 하나요?

아닙니다. 그래프는 조사 후보를 좁혀 줄 뿐이며, 실제 변경 필요성은 코드 검토, 테스트, 런타임 추적으로 확인해야 합니다.

CodeGraph 파일럿에서 가장 먼저 볼 지표는 무엇인가요?

완료된 변경을 정답으로 삼아 관련 파일 누락률, 불필요한 후보 비율, 인덱스 갱신 지연과 조사 시간을 함께 비교하는 것이 좋습니다.

THE END / OPSOAI

여기까지 읽었습니다

핵심 장면을 한 번 더 떠올려 보세요. 이해가 남았다면 이 책은 제 역할을 다했습니다.

다른 책 고르기
표지 1 —

←→ 키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.

CONTENTS

이 책의 목차

    12개 장 19 분읽는 시간