Vectr — 코드 인텔리전스 (Code Intelligence) AI 도구
요약
AI 어시스턴트가 세션 간 작업 기억을 유지하지 못해 발생하는 개발 마찰을 해결하기 위한 로컬 코드베이스 인덱서 Vectr를 소개합니다. Vectr는 계층적 회상 능력을 통해 AI가 코드베이스의 구조와 맥락을 효율적으로 파악하도록 돕습니다.
핵심 포인트
- AI 어시스턴트의 세션 간 컨텍스트 부재 문제 지적
- 토큰 낭비와 반복적인 코드 탐색 비용 발생
- Vectr의 계층적 회상(Layered Recall) 시스템 도입
- 코드베이스 맵을 통한 효율적인 모듈 및 엔트리 포인트 파악
두 시간 동안의 조사 끝에 당신은 하루 일과를 마칩니다. 당신은 진입점(entry point)이 targeting/segment/evaluator.go 파일의 EvaluateSegments라는 것을 알고 있습니다. nil visitor_id 케이스가 처리되지 않았다는 것도 알고 있습니다. bidder/auction.go가 이 함수를 호출하며, 해당 인터페이스(interface)를 변경할 수 없다는 사실도 알고 있습니다.
다음 날 아침, Claude Code는 이 중 아무것도 알지 못합니다. 처음부터 다시 시작합니다. grep을 수행하고, 파일을 읽고, 당신이 이미 찾아낸 것들을 재발견하기 위해 8,000개의 토큰(tokens)을 소비합니다. 모든 세션은 마치 첫날인 것처럼 시작됩니다.
이것이 AI 지원 개발(AI-assisted development)에서 발생하는 실제 마찰(friction)입니다. 코드 생성의 품질 문제가 아니라, 세션 경계(session boundaries)를 가로지르는 작업 기억(working memory)의 완전한 부재가 문제입니다.
AI 어시스턴트의 컨텍스트(context) 사용 방식의 문제점
40,000개의 파일이 있는 코드베이스(codebase)에서 AI는 rg -l "authenticate"를 실행하여 200개의 결과를 얻고, 8개의 전체 파일을 읽습니다. 단 하나의 쿼리(query)에 12,000개의 토큰이 사라집니다. 그리고 다음 세션에서 AI는 다시 제로(zero)에서 시작합니다. 무엇을 찾았는지에 대한 기억도, 무엇이 여전히 누락되었는지에 대한 기록도 없습니다.
200,000-토큰 컨텍스트 윈도우(context window)는 방대하게 들리지만, 40,000개의 파일이 있는 코드베이스는 훨씬 더 거대합니다. 어시스턴트들은 grep 스타일의 검색을 실행하여 일치하는 파일을 찾고, 관련 함수를 찾기 위해 파일 전체를 읽는 방식으로 이를 보완합니다. 단일 세션 내에서는 숙련된 사용자들이 이를 관리할 수 있습니다. 진짜 문제는 세션 간의 문제입니다. 모든 대화는 빈 상태로 시작됩니다. 월요일에 수행한 조사가 목요일에 다시 반복됩니다.
인간은 이를 다르게 해결합니다. 지난주에 특정 기능(feature)을 작업했던 개발자가 모든 코드를 한 줄 한 줄 기억하지는 않지만, 타겟팅(targeting) 코드가 targeting/에 있다는 것, 세그먼트 평가(segment evaluation)에 nil visitor ID와 관련된 예외 케이스(edge case)가 있다는 것, 그리고 경매 파이프라인(auction pipeline)이 EvaluateSegments를 호출한다는 사실은 기억합니다. 그들은 다양한 수준의 정밀도(fidelity)로 기억하며, 필요할 때 몇 초 안에 세부 사항을 다시 읽을 수 있습니다. 그들은 검색(retrieval)이 빠르기 때문에 잊어버리는 것을 '감수'할 수 있습니다.
Vectr가 하는 일
Vectr는 AI 어시스턴트에게 동일한 계층적 회상(layered recall) 능력을 부여하는 로컬 코드베이스 인덱서(local codebase indexer)입니다. Vectr는 세 가지 종류의 지식과 작업 상태(working state)를 위한 메모리 시스템을 제공합니다.
Layer 1: 코드베이스 맵 (Codebase map). 시작 시, Vectr는 디렉토리 구조와 README를 대상으로 한 번의 LLM 호출을 수행하여 약 300토큰 분량의 평이한 영어로 된 패스포트(passport)를 생성합니다. 이는 모듈의 목적, 기술 스택 (tech stack), 엔트리 포인트 (entry points), 그리고 도메인 어휘를 포착합니다. 매 세션마다 AI는 파일 읽기 과정 없이 vectr_map을 통해 이를 무료로 제공받습니다.
vectr_map() →
"Go DSP 광고 서버. 주요 모듈: targeting/ (타겟팅/오디언스 매칭),
bidder/ (입찰 로직), tracker/ (이벤트 기록).
...
Layer 2: 심볼 그래프 (Symbol graph). Vectr는 tree-sitter를 사용하여 모든 함수, 클래스, 메서드를 호출 관계를 포함한 SQLite 기반의 영구적인 그래프로 추출합니다. vectr_locate는 코드 내용 자체를 반환하지 않고 심볼이 정의된 위치(파일, 줄 번호, 종류)를 찾아냅니다. vectr_trace는 호출 그래프 (call graph)를 양방향으로 추적합니다.
vectr_locate("EvaluateSegments") →
[function] EvaluateSegments targeting/segment/evaluator.go:45
...
Layer 3: 콘텐츠 검색 (Content search). AST 인식 청크(AST-aware chunks) — 로직 중간이 아닌 함수 및 클래스 경계에서 분할됨 — 는 Snowflake/snowflake-arctic-embed-m-v1.5를 사용하여 임베딩됩니다 (로컬 실행, API 키 불필요, 약 440MB 1회 다운로드). 적응형 하이브리드 검색 (Adaptive hybrid search): 벡터 유사도 (vector similarity) + BM25 키워드 방식을 사용하며, 코드베이스 지문 (fingerprint)에 따라 가중치가 조정됩니다 — 작은 저장소는 BM25에 의존하고, 큰 저장소는 의미론적 (semantics) 검색에 의존하며, 정적 타입 모노레포 (static-typed monorepos)는 그래프 순회 (graph traversal)를 우선적으로 사용합니다. VECTR_EMBED_MODEL=<hf-model-id>를 통해 sentence-transformers와 호환되는 모든 모델로 재정의할 수 있습니다.
vectr_search("nil visitor_id handling segment evaluation") →
[1] targeting/segment/evaluator.go lines 45-89 score 0.934
symbol: EvaluateSegments
...
실제로 새로운 부분: 작업 메모리 (working memory)
Vectr를 다른 모든 코드 검색 도구와 다르게 만드는 레이어는 AI와 메모리 저장소 간의 양방향 프로토콜입니다.
vectr_remember를 통해 AI는 작업 노트 (working note)를 오프로드(offload)할 수 있습니다:
vectr_remember(
"세그먼트 타겟팅 구현 중. 엔트리: evaluator.go:45의 EvaluateSegments().
61번 줄 이전에 visitor_id에 대한 nil 가드(nil guard)를 추가해야 함.
...
이제 AI는 컨텍스트 윈도우 (context window)에서 코드 청크 (code chunks)를 삭제할 수 있습니다. Vectr가 이를 보유하고 있으며 50ms 이내에 다시 반환할 것입니다.
vectr_evict_hint는 이를 명시적으로 수행합니다. AI가 한 세션 분량의 검색된 콘텐츠를 축적하면, Vectr는 무엇을 버려야 할지 선제적으로 알려줍니다:
vectr_evict_hint() →
"Vectr가 인덱싱된 6개의 청크(~3,840 토큰)를 보유하고 있으며 즉시 검색 가능합니다.
다음 내용을 컨텍스트 윈도우에서 안전하게 삭제할 수 있습니다:
...
다음 날 아침:
vectr_recall("segment targeting") →
[HIGH] [seg, wip] (14시간 전)
segment targeting 구현 중. Entry: evaluator.go:45의 EvaluateSegments().
...
세 번의 MCP 호출과 약 5초의 시간 만에, AI는 코드를 다시 읽지 않고도 컨텍스트가 완전히 로드됩니다.
실행 방법
환경에 따라 두 가지 설치 옵션이 있습니다.
옵션 A — pip (개인 개발자에게 권장):
pip install git+https://github.com/swapnanil/vectr
cd /path/to/your/project
...
옵션 B — Docker (서버 및 CI 파이프라인용):
git clone https://github.com/swapnanil/vectr
docker-compose up api
첫 실행 시, Vectr는 임베딩 모델 (embedding model, ~440MB)을 다운로드하고, 워크스페이스 (workspace)를 인덱싱하며, 심볼 그래프 (symbol graph)를 구축하고, Cursor 및 Claude Code를 위한 MCP 설정 파일을 작성합니다. 로컬 전용 사용 시 작성해야 할 설정 파일이나 필요한 환경 변수는 없습니다.
기타 CLI 명령어:
# 다른 워크스페이스에서 중지 및 재시작
vectr restart --path /path/to/other/project
...
ANTHROPIC_API_KEY (또는 OPENAI_API_KEY + LLM_MODEL)를 설정하면, Vectr는 시작 시 코드베이스 패스포트 (codebase passport)도 구축합니다. 이는 단 한 번의 LLM 호출(약 $0.005)로 이루어지며 영구적으로 캐싱됩니다.
실행되면 Claude Code와 Cursor는 수동 설정 없이도 10개의 MCP 도구(vectr_map, vectr_locate, vectr_trace, vectr_search, vectr_remember, vectr_recall, vectr_evict_hint, vectr_snapshot, vectr_snapshot_list, vectr_status)를 자동으로 사용합니다. MCP 서버는 localhost:8765/mcp에서 실행되며, 호환 가능한 모든 클라이언트는 두 줄의 JSON 설정만으로 연결할 수 있습니다.
벤치마크 결과: Camel Run 2
교차 세션 메모리 (cross-session memory)의 이점을 측정하기 위해, 이 벤치마크는 두 단계로 설계되었습니다: 1단계는 코드베이스를 탐색하고 vectr_remember를 사용하여 노트를 저장합니다. 2단계는 콜드 세션 (cold session)을 열고, vectr_recall()을 호출한 뒤 구현을 진행합니다. 일반적인 (Vanilla) 2단계는 처음부터 다시 읽기를 수행합니다.
Camel 코드베이스는 5,856개의 엔터프라이즈 Java 파일로 구성되어 있으며, 이는 모델이 유의미한 학습 커버리지 (training coverage)를 갖지 못한 유형의 코드입니다.
| 작업 (Task) | 일반적인 (Vanilla) 2단계 | Vectr 2단계 | 비용 변화 (Cost Δ) | 도구 호출 변화 (Tool calls Δ) | 출력 (Output) |
|---|---|---|---|---|---|
custom_component | $0.56 · 134s · 51 tools | $0.36 · 195s · 11 tools | −35% | −78% | 0 bytes (실패) vs 9,398 bytes (5개 파일) |
| ... |
custom_component 결과는 실패 모드를 가장 명확하게 보여줍니다: 일반적인 방식은 생소한 Java 패키지 계층 구조를 탐색하다가 컨텍스트 예산 (context budget)을 모두 소진하여 아무것도 생성하지 못했습니다. Vectr의 2단계는 1단계에서 생성된 구조화된 노트로 시작했습니다. 약 200개의 토큰이 수백 번의 재탐색 도구 호출 (re-discovery tool calls)을 대체하였고, 결과적으로 5개 파일로 구성된 완전한 구현을 제공했습니다.
route_policy는 양측 모두 성공한 효율성 사례를 보여줍니다: 3배 더 저렴하고, 2.4배 더 빠릅니다.
Vectr는 2단계에서 수행해야 했을 재탐색 (re-discovery) 작업의 양에 비례하여 도움을 줍니다. 잘 알려진 코드베이스에서의 단일 세션 작업은 이점이 미미합니다. 규모가 크고 생소한 코드베이스 및 교차 세션 연속 작업에서 가장 큰 이점을 얻을 수 있습니다.
Django 결과는 엇갈렸습니다: 복잡한 ORM 내부 구조에서는 토큰 −24%, 비용 −60%를 기록했습니다. 반면 모델이 이미 학습 커버리지를 가진 잘 알려진 API에서는 이점이 나타나지 않았습니다. 두 경우 모두 메커니즘은 동일합니다. Vectr는 재탐색 비용이 이미 낮은 곳에서는 도움이 되지 않을 뿐입니다.
풀 스택(Full Stack)과의 세션
오전 — 세션 시작 (3회 호출, 약 5초):
vectr_map() → 구조적 개요 (247 tokens)
vectr_recall() → 어제의 노트, 그대로 (verbatim)
vectr_locate("EvaluateSegments") → 파일:라인, 코드 읽기 없음
세션 진행 중:
vectr_search("visitor_id nil handling") → 3 chunks, 580 tokens
vectr_trace("EvaluateSegments", direction="callers") → 2 callers identified
세션 종료:
vectr_remember("Segment targeting done...") → note stored
vectr_evict_hint() → drops 3,840 tokens of chunks
vectr_snapshot("segment-targeting-day1") → full session saved
세 번의 호출과 5초 만에 전체 컨텍스트(Full context)를 파악했습니다. 재연결 시 파일 읽기는 발생하지 않습니다.
다음 단계
Vectr는 github.com/swapnanil/vectr에서 오픈 소스(open source)로 제공됩니다. 현재 빌드는 AST 청킹 (AST chunking) 및 심볼 추출 (symbol extraction)을 위해 Python, JavaScript, TypeScript, Go, Rust, Java를 지원합니다. 향후 계획으로는 코드베이스 지문 (codebase fingerprint)에 기반한 적응형 검색 전략 선택 (예: Java 모노레포는 그래프 탐색 (graph traversal)을 통해 이점을 얻고, 동적 Python 코드베이스는 의미론적 검색 (semantic search)에 더 잘 반응함)과 첫 접근 시 지연 생성 (lazily generated)되는 LLM 생성 심볼 설명 (symbol descriptions) 기능이 예정되어 있습니다.
대규모 코드베이스에서 작업하며 AI 어시스턴트가 매 세션의 첫 5분을 동일한 파일을 다시 읽는 데 소비하고 있다면, Vectr를 사용해 보세요. 전체 도구 페이지는 swapnanilsaha.com/tools/vectr/에서 확인할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기