당신의 AI 에이전트가 당신의 코드를 쓰레기통 뒤지듯 탐색한다,,,
I’m happy to translate the article for you, but I’ll need the text of the article itself. Could you please paste the content you’d like translated (excluding the source link you already provided)? Once I have the full text, I’ll keep the source line unchanged and translate the rest into Korean while preserving all formatting, markdown, and technical terms.
Introduction
…그리고 우리는 이를 막기 위해 무언가를 만들었습니다.
AI 에이전트를 사용하는 모든 개발자가 결국 눈치채는 패턴이 있습니다. 인증이 어디서 처리되는지 에이전트에게 묻습니다. 에이전트는 파일을 열고, 2,000줄을 훑어보고, 또 다른 파일을 열고, 그 파일을 훑어보고, 세 번째 파일을 엽니다. 답을 내놓을 때쯤이면 40 000 토큰을 소모했으며—대부분은 무관한 내용—실제 작업이 시작되기 전에 컨텍스트 창이 절반이나 사라져 버립니다.
우리는 이를 dumpster diving이라고 부릅니다. 에이전트가 전략적으로 읽는 것이 아니라, 먹을 수 있는 무언가를 찾으려 모든 것을 파헤치는 것입니다.
우리는 **jCodeMunch**와 **jDocMunch**를 통해 수백만 세션에서 이 현상을 관찰해 왔습니다. 그리고 이를 해결하기 위해 jMRI — jMunch Retrieval Interface를 만들었습니다.
오늘 우리는 사양, 벤치마크, 그리고 오픈‑소스 SDK를 공개합니다. 모두 Apache 2.0 라이선스입니다.
The Numbers
우리는 두 개의 실제 코드베이스인 FastAPI와 Flask에 대해 벤치마크를 실행했습니다. 세 가지 방법을 비교했습니다: 단순 파일 읽기, 청크 RAG, 그리고 jCodeMunch를 통한 jMRI 검색. 각 저장소당 10개의 쿼리를 수행했습니다. 결과는 다음과 같습니다.
FastAPI (~950 K 소스 토큰)
| Method | Avg Tokens | Cost/Query | Precision |
|---|---|---|---|
| Naive (read all files) | 949,904 | $2.85 | 100 % |
| Chunk RAG | 330,372 | $0.99 | 74 % |
| jMRI | 480 | $0.0014 | 96 % |
Flask (~148 K 소스 토큰)
| Method | Avg Tokens | Cost/Query | Precision |
|---|---|---|---|
| Naive (read all files) | 147,854 | $0.44 | 100 % |
| Chunk RAG | 55,251 | $0.17 | 80 % |
| jMRI | 480 | $0.0014 | 96 % |
jMRI는 FastAPI에서 naive 방식보다 1,979 배 적은 토큰을 사용합니다. 또한 청크 RAG보다 높은 정밀도를 보이며 — 96 % 대 74 % 입니다.
마지막 요점이 중요합니다. 일반적인 가정은 정밀도가 효율성을 위한 트레이드‑오프라는 것입니다. 청크 RAG는 naive보다 비용이 저렴하지만 더 많이 놓칩니다. jMRI는 두 방법 모두보다 저렴하면서 놓치는 비율도 적습니다. 이는 우연이 아니라 텍스트 유사성 대신 구조를 활용했기 때문입니다.
5 분 이내에 직접 재현해 보기
git clone https://github.com/jgravelle/mcp-retrieval-spec
cd mcp-retrieval-spec/benchmark
python benchmark.py --all
Why Chunk RAG Loses on Precision
Chunk RAG는 파일을 겹치는 텍스트 윈도우로 나누고 키워드 겹침이나 임베딩 유사도로 순위를 매깁니다. 청크 경계가 함수 중간에 놓일 수 있습니다. 가장 높은 순위의 청크는 올바른 단어는 포함하지만 올바른 코드는 포함하지 않을 수 있습니다. 검색은 설계상 근사치입니다.
jMRI 검색은 구조적으로 정확합니다. jCodeMunch는 소스 파일을 AST‑파생 인덱스로 파싱합니다: 모든 함수, 클래스, 메서드는 이름이 지정된 주소 가능한 심볼이며 안정적인 ID를 가집니다. "OAuth2 password bearer authentication"을 검색하면 fastapi/security/oauth2.py::OAuth2PasswordBearer#class와 같은 ID를 반환합니다. 해당 ID를 가져오면 정확히 그 클래스만 얻습니다 — 더 많지도, 적지도 않죠. 경계 사고가 없고, 절반만 있는 함수도 없습니다.
96 % 정확도 수치는 최상위 검색 결과가 쿼리에 대한 올바른 심볼이었던 경우를 반영합니다. 4 %가 그렇지 않았던 경우는 실제로 모호한 쿼리였으며, 인간이라 해도 정답을 두고 논쟁할 수 있는 상황이었습니다.
jMRI란 무엇인가?
jMRI (jMunch Retrieval Interface)는 검색을 올바르게 수행하는 MCP 서버를 위한 공개 사양입니다.
네 가지 작업, 하나의 응답 래퍼, 두 가지 준수 수준:
Agent
├─ discover() → 어떤 지식 소스가 사용 가능한가?
├─ search(query) → 어떤 심볼/섹션이 관련 있는가? (ID와 요약만)
├─ retrieve(id) → 이 ID에 대한 정확한 소스를 알려줘.
└─ metadata(id?) → 순수하게 읽는 데 어느 정도 비용이 들었을까?
모든 응답에는 _meta 블록이 포함됩니다:
{
"source": "def get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n",
"_meta": {
"tokens_saved": 42318,
"total_tokens_saved": 1284950,
"cost_avoided": { "claude-sonnet-4-6": 0.127 },
"timing_ms": 12
}
}
에이전트는 효율적인지 추측할 필요가 없습니다. 매 호출마다 이를 알고 있습니다.
이 사양은 의도적으로 최소화되었습니다. 우리는 플랫폼을 구축하려는 것이 아니라, 이미 대규모로 작동하는 패턴에 이름을 붙이고 다른 사람들이 구현하기 쉽게 만드는 것이 목표입니다.
구현
사양은 공개되어 있습니다. 최고의 구현은 상용입니다.
| 구현 | 도메인 | 별점 | 설치 |
|---|---|---|---|
| jCodeMunch | 코드 (30개 이상 언어) | 900+ | uvx jcodemunch-mcp |
| jDocMunch | 문서 (MD, RST, HTML, 노트북) | 45+ | uvx jdocmunch-mcp |
두 구현 모두 jMRI‑Full을 구현합니다 — 배치 검색, 해시 기반 드리프트 감지, 바이트 오프셋 주소 지정, 그리고 전체 _meta 래퍼를 포함한 완전한 사양입니다.
두 서버는 2026년 3월 첫 주에 사용자 세션 전체에서 180억 토큰 이상을 절감했습니다. 이 수치는 실제 세션 텔레메트리를 기반으로 디바이스에서 계산된 것으로, 모든 참여 응답이 os.stat을 통해 tokens_saved를 보고하므로 추정이 없습니다.
시작하기
Claude 코드
~/.claude.json에 추가:
{
"mcpServers": {
"jcodemunch-mcp": {
"command": "uvx",
"args": ["jcodemunch-mcp"]
},
"jdocmunch-mcp": {
"command": "uvx",
"args": ["jdocmunch-mcp"]
}
}
}
Python SDK
pip install jmri-sdk
from jmri.client import MRIClient
client = MRIClient()
# 무엇이 인덱싱 되었나요?
sources = client.discover()
# 찾아보기
results = client.search(
"database session dependency injection",
repo="fastapi/fastapi"
)
# 정확히 그 결과 가져오기
symbol = client.retrieve(results[0]["id"], repo="fastapi/fastapi")
print(symbol["source"])
print(f"Tokens saved this call: {symbol['_meta']['tokens_saved']:,}")
TypeScript SDK
npm install @jmri/sdk
import { MRIClient } from "@jmri/sdk";
const client = new MRIClient();
// 사용 가능한 소스 탐색
const sources = await client.discover();
// 심볼 검색
const results = await client.search(
"database session dependency injection",
{ repo: "fastapi/fastapi" }
);
// 정확한 소스 가져오기
const symbol = await client.retrieve(results[0].id, { repo: "fastapi/fastapi" });
console.log(symbol.source);
console.log(`Tokens saved this call: ${symbol._meta.tokens_saved.toLocaleString()}`);
예시 사용법 (TypeScript)
import "mri-client";
const client = new MRIClient();
const results = await client.search("OAuth2 bearer auth", "fastapi/fastapi");
const symbol = await client.retrieve(results[0].id, "fastapi/fastapi");
오픈 스펙
모든 내용은 github.com/jgravelle/mcp-retrieval-spec 에서 호스팅됩니다.
SPEC.md– 전체 jMRI v1.0 사양 (Apache 2.0)sdk/python/– Python 클라이언트 헬퍼sdk/typescript/– TypeScript 클라이언트reference/server.py– 최소 jMRI‑준수 MCP 서버examples/– Claude Code, Cursor, 그리고 일반 에이전트 통합 예시
이 스펙은 의도적으로 최소화되었습니다. 예시를 개선하거나 언어 SDK를 추가하는 PR은 환영합니다. 핵심 인터페이스를 확장하는 PR은 강력한 근거가 필요합니다.
검색형 MCP 서버를 구축한다면 jMRI‑Core를 구현하세요. 사용자의 에이전트가 감사할 것입니다.
— J. Gravelle, 2026년 3월
벤치마크 소스:
github.com/jgravelle/mcp-retrieval-spec/benchmark
SDK 설치:
pip install jmri-sdk # Python
npm install mri-client # TypeScript / JavaScript