---
title: "Semble, grep보다 토큰 98% 덜 쓰는 에이전트용 코드 검색 공개"
published: 2026-05-17T15:37:07.000Z
canonical: https://jeff.news/article/3043
---
# Semble, grep보다 토큰 98% 덜 쓰는 에이전트용 코드 검색 공개

Semble은 코딩 에이전트가 자연어로 코드베이스를 검색하고 필요한 코드 조각만 받게 해주는 오픈소스 코드 검색 라이브러리다. CPU만으로 평균 저장소를 약 250ms에 인덱싱하고 쿼리는 약 1.5ms에 처리하며, grep+read 대비 토큰을 평균 98% 줄였다고 주장한다.

- Semble은 코딩 에이전트를 위한 코드 검색 라이브러리임. 핵심 주장은 꽤 직관적임: 에이전트가 `grep`으로 파일을 왕창 읽지 말고, 필요한 코드 조각만 바로 받게 하자는 것.
  - 예를 들어 에이전트가 `How is authentication handled?` 같은 자연어로 물으면 관련 코드 스니펫만 반환함.
  - `save_pretrained`, `save model to disk`처럼 심볼명과 자연어 설명을 섞어 검색할 수도 있음.
  - 로컬 경로뿐 아니라 git URL도 받을 수 있어서, 원격 저장소를 바로 클론하고 인덱싱하는 흐름도 지원함.

> [!IMPORTANT]
> Semble이 내세우는 숫자는 꽤 세다. 평균 저장소 인덱싱 약 250ms, 쿼리 약 1.5ms, grep+read 대비 토큰 사용량 약 98% 절감이 핵심임.

- 벤치마크 기준으로도 그냥 장난감 검색기는 아니라고 주장함.
  - 63개 저장소, 19개 언어, 약 1,250개 쿼리로 품질과 속도를 측정함.
  - 검색 품질은 NDCG@10 0.854로, 137M 파라미터짜리 코드 특화 CodeRankEmbed Hybrid 품질의 99% 수준이라고 함.
  - 대신 인덱싱은 218배 빠르다고 주장함. 여기서 살짝 “이거 진짜면 꽤 큰데?” 소리 나오는 지점.

- 토큰 절감 쪽 벤치마크가 특히 에이전트 사용자한테 와닿음.
  - Semble은 평균적으로 grep+read보다 토큰을 98% 덜 쓴다고 함.
  - 2k 토큰만 써도 94% recall에 도달했다고 주장함.
  - 반면 grep+read 방식은 100k 컨텍스트 윈도우를 꽉 써도 85% recall 수준이었다고 함.
  - 요즘 코딩 에이전트가 “일단 파일 다 읽고 생각해볼게” 모드로 토큰을 태우는 걸 생각하면, 이 숫자는 꽤 자극적임.

```mermaid
sequenceDiagram
    participant 에이전트
    participant Semble
    participant 코드베이스
    participant 검색랭커
    에이전트->>Semble: 자연어 또는 심볼 쿼리 전송
    Semble->>코드베이스: tree-sitter 기반 코드 청킹 및 인덱싱
    Semble->>검색랭커: 임베딩 검색과 BM25 검색 실행
    검색랭커->>검색랭커: RRF로 결과 결합 후 코드 신호로 재랭킹
    Semble-->>에이전트: 관련 코드 스니펫만 반환
```

- 내부 구조는 “가벼운 의미 검색 + 전통적인 키워드 검색 + 코드 특화 랭킹” 조합임.
  - 파일을 tree-sitter로 코드 구조에 맞게 청킹함.
  - 의미 검색에는 code-specialized `potion-code-16M` Model2Vec 임베딩을 사용함.
  - 식별자나 API 이름처럼 정확한 단어 매칭이 중요한 쿼리는 BM25가 보완함.
  - 두 검색 결과는 Reciprocal Rank Fusion(RRF)으로 합침.

- 재랭킹도 코드 검색에 맞게 꽤 세세하게 들어감.
  - `Foo::bar`, `_private`, `getUserById` 같은 심볼스러운 쿼리는 lexical weight를 더 줌.
  - 쿼리한 심볼을 “참조”하는 코드보다 직접 “정의”하는 클래스, 함수, 메서드 쪽을 위로 올림.
  - `parse config`를 검색하면 `parseConfig`, `ConfigParser`, `config_parser` 같은 식별자 변형도 잡아줌.
  - 같은 파일에서 여러 청크가 매칭되면 파일 단위 관련성을 높게 보고 부스트함.
  - 테스트, 레거시 shim, 예제 코드, `.d.ts` 선언 스텁은 canonical implementation보다 아래로 내림.

- 설치 방식은 에이전트 환경을 꽤 넓게 겨냥함.
  - MCP 서버로 Claude Code, Cursor, Codex, OpenCode, VS Code, GitHub Copilot CLI, Windsurf, Gemini CLI, Kiro, Zed 등에 붙일 수 있음.
  - `uvx --from "semble[mcp]" semble` 형태로 MCP 서버를 띄우는 설정 예시가 각 도구별로 제공됨.
  - MCP를 못 쓰는 sub-agent용으로는 Bash에서 `semble search`를 직접 호출하는 방식도 안내함.

- CLI 사용법은 단순함. 먼저 검색하고, 부족할 때만 전체 파일을 열어보라는 워크플로를 권장함.
  - `semble search "authentication flow" ./my-project`
  - `semble search "save_pretrained" ./my-project`
  - `semble search "save model to disk" ./my-project --top-k 10`
  - 이미 찾은 위치 주변의 관련 구현을 찾고 싶으면 `semble find-related src/auth.py 42 ./my-project`처럼 호출함.

> [!TIP]
> Semble 쪽이 권장하는 사용법은 grep을 버리라는 게 아니라, 첫 탐색은 Semble로 하고 정확한 문자열 확인이나 exhaustive match가 필요할 때 grep을 쓰라는 쪽에 가까움.

- Python 라이브러리로도 쓸 수 있어서, 자체 도구에 코드 검색을 붙이는 용도로도 열려 있음.
  - `SembleIndex.from_path("./my-project")`로 로컬 저장소를 인덱싱할 수 있음.
  - `SembleIndex.from_git("https://github.com/MinishLab/model2vec")`처럼 원격 git 저장소도 인덱싱 가능함.
  - 검색 결과에는 파일 경로, 시작 줄, 끝 줄, 실제 코드 청크 내용이 들어 있음.

- 로컬 실행을 전제로 한 점도 개발자 입장에선 꽤 중요함.
  - API 키, GPU, 외부 서비스가 필요 없다고 함.
  - CPU만으로 동작하고, 정적 임베딩 모델이라 쿼리 시점에 트랜스포머 forward pass가 없음.
  - 로컬 경로는 파일 변경을 감지해 자동으로 다시 인덱싱한다고 설명함.

- 토큰 절감량을 보여주는 `semble savings` 기능도 있음. 약간 “내가 오늘 얼마나 컨텍스트를 아꼈나” 대시보드 느낌임.
  - 예시 출력에서는 오늘 42회 호출로 약 58.4k 토큰, 최근 7일 287회 호출로 약 312.4k 토큰, 전체 1.4k회 호출로 약 1.2M 토큰 절감을 보여줌.
  - 계산 방식은 반환된 청크가 포함된 전체 파일 문자 수와 실제 반환 스니펫 문자 수 차이를 4로 나눠 토큰으로 추정하는 방식임.
  - 저장 위치는 `~/.semble/savings.jsonl`이라고 함.

- 결론적으로 Semble은 “코딩 에이전트 시대의 ripgrep 대체재”라기보다는 “에이전트한테 먼저 물려볼 의미 기반 코드 인덱스”에 가까움.
  - 정확한 문자열 찾기에는 grep이 여전히 빠르고 명확함.
  - 반대로 “인증 흐름 어디 있어?”, “모델 저장 로직 어디야?”처럼 사람도 파일명을 모르는 질문은 Semble 쪽이 훨씬 자연스러운 인터페이스임.
  - 대형 레포에서 에이전트가 삽질하며 컨텍스트를 태우는 문제가 자주 있었다면, 한 번 붙여볼 만한 타입의 도구임.

---

## 기술 맥락

- Semble이 고른 방향은 “더 큰 모델로 코드 검색을 잘하자”가 아니라 “가벼운 인덱스와 랭킹으로 에이전트가 읽을 양을 줄이자”에 가까워요. 코딩 에이전트는 답을 몰라서 실패하기도 하지만, 엉뚱한 파일을 너무 많이 읽다가 컨텍스트를 낭비해서 품질이 떨어지는 경우도 많거든요.

- tree-sitter로 코드를 청킹하는 이유는 코드가 일반 문서랑 다르기 때문이에요. 함수나 클래스 경계를 무시하고 텍스트를 자르면 검색 결과가 애매해지고, 에이전트가 결국 전체 파일을 다시 읽게 돼요. 구조를 알고 자르면 반환 스니펫 자체가 바로 작업 가능한 단위에 가까워져요.

- 임베딩 검색과 BM25를 같이 쓰는 것도 현실적인 선택이에요. 자연어로 “인증 흐름”을 찾을 때는 의미 검색이 유리하지만, `getUserById` 같은 심볼을 찾을 때는 전통적인 키워드 검색이 더 정확할 수 있어요. Semble은 둘 중 하나를 고집하지 않고 RRF로 섞은 뒤 코드 특화 신호로 다시 정렬해요.

- MCP와 CLI를 둘 다 제공하는 점은 에이전트 생태계의 현재 제약을 잘 본 선택이에요. 상위 에이전트는 MCP 도구를 직접 호출할 수 있지만, sub-agent는 MCP 접근이 막힌 환경이 있으니 Bash 호출도 필요하거든요. 그래서 AGENTS.md에 사용법을 심어두는 방식까지 같이 제안하는 거예요.

- 이 도구의 실전 가치는 벤치마크 숫자보다 워크플로 변화에서 나와요. 첫 탐색에서 관련 청크만 보고, 부족할 때만 전체 파일을 열면 리뷰, 버그 수정, 리팩터링에서 에이전트가 훨씬 덜 헤매게 돼요. 특히 모노레포나 오래된 서비스 코드처럼 파일 수가 많은 환경에서 차이가 커질 수 있어요.

## 핵심 포인트

- 자연어 쿼리로 관련 코드 조각만 반환해 에이전트의 컨텍스트 낭비를 줄임
- 평균 저장소 인덱싱 약 250ms, 쿼리 약 1.5ms, 외부 API나 GPU 없이 CPU에서 동작
- tree-sitter 청킹, Model2Vec 임베딩, BM25, Reciprocal Rank Fusion을 섞어 검색 품질과 속도를 맞춤
- MCP 서버, CLI, Python 라이브러리로 Claude Code, Cursor, Codex, OpenCode 등 여러 에이전트 환경에 붙일 수 있음

## 인사이트

코딩 에이전트의 병목이 모델 성능만이 아니라 ‘무슨 파일을 읽게 할 것인가’라는 점을 정면으로 찌른 도구다. 숫자가 벤치마크처럼 나온다면, 대형 코드베이스에서 grep으로 컨텍스트를 태우던 워크플로를 꽤 현실적으로 바꿀 수 있다.
