본문으로 건너뛰기

© 2026 Molayo

Reddit요약2026. 06. 15. 09:18

도구 선택을 위해 시맨틱 임베딩 (Semantic Embeddings) 사용을 중단하고 BM25로 돌아간 이유

요약

에이전트의 도구 선택(Tool Selection) 과정에서 시맨틱 임베딩 대신 BM25를 사용하는 것이 더 효과적임을 분석합니다. 짧고 구조화된 도구 설명의 특성상 코사인 유사도는 변별력이 떨어지며, BM25가 더 높은 정확도를 보였습니다.

핵심 포인트

  • 도구 설명은 짧고 구조적이라 시맨틱 임베딩의 변별력이 낮음
  • BM25 적용 시 Top-1 정확도가 81%로 시맨틱 임베딩(64%)보다 높음
  • 하이브리드 방식은 오히려 시맨틱 노이즈로 인해 성능이 저하될 수 있음
  • 어휘적 불일치는 쿼리 재작성(Query Rewriting)으로 해결 가능

저는 약 1년 동안 에이전트(Agents)를 구축해 왔으며, 최근 피크 타임에 약 140개의 MCP 노출 도구(MCP-exposed tools)를 실행하는 클라이언트를 위한 에이전트를 출시했습니다. 그 과정에서 저는 전형적인 실수를 저질렀습니다. 모델이 턴(turn)마다 볼 수 있는 도구를 선택하기 위해 도구 설명 임베딩 (tool description embeddings)에 대한 코사인 유사도 (cosine similarity)를 사용했습니다. 데모에서는 아주 잘 작동했습니다. 하지만 프로덕션 환경에서는 매우 위험했습니다.

문제는 이렇습니다. 기본적인 시맨틱 랭킹 (semantic-ranking) 설정에서는 사용자 쿼리를 임베딩하고, 모든 도구 설명을 한 번씩 임베딩한 다음, 런타임에 코사인 유사도로 순위를 매깁니다. 이는 청크(chunks)가 문단 길이이고, 의미적으로 풍부하며, 형식이 대략적으로 동일한 일반적인 문서 검색(document retrieval)에는 효과적입니다.

도구 설명은 그렇지 않습니다. 그것들은 짧고 (종종 50 토큰 미만), 구조적으로 유사하며 (동사-명사, 파라미터 목록), 변별력 있는 정보가 종종 단일 키워드인 경우가 많습니다. "디스크에서 파일을 읽기(Read a file from disk)"와 "채널에서 메시지 읽기(Read messages from a channel)"는 둘 다 "read" + "file/channel"에 가깝게 임베딩됩니다. 코사인 유사도는 "최신 커밋 읽기(read the latest commits)"와 같은 쿼리에 대해 이들을 서로 인접하게 배치하는데, 이는 세 단어 모두 동사 임베딩 공간을 공유하며 실제 변별 요소(명사인 "commits")가 희석되기 때문입니다.

저는 평가(eval) 과정에서 이런 일이 발생하는 것을 목격했습니다. 에이전트에게 "이 저장소의 오픈 이슈를 나열해줘(list the open issues for this repo)"라고 요청했습니다. 시맨틱 랭커는 slack_search_messages를 첫 번째로 반환했는데, 그 이유는 설명에 "list", "open", "issues"가 인접한 임베딩 이웃으로 포함되어 있었기 때문입니다. 실제 github_list_issues 도구는 4위를 기록했는데, 이는 GitHub MCP 작성자가 모든 소프트 키워드(soft keyword)에서 점수가 더 낮게 나오는 간결한 "Lists issues in a repository"라는 설명을 작성했기 때문입니다.

만약 모델이 slack_search_messages를 첫 번째로 보고 github_list_issues를 네 번째로 본다면, 모델은 잘못된 것을 선택하게 될 것입니다. 자주 말이죠.

그래서 저는 세 가지 검색 전략을 구축하고 200개의 쿼리→정답 도구 쌍으로 구성된 고정된 코퍼스(corpus)에서 테스트했습니다.

시맨틱 임베딩 (Semantic embeddings, text-embedding-3-small): Top-1 정확도 64%. 교묘한 실패 모드: 틀렸을 때는 매우 확신에 차서 틀렸으며, 종종 완전히 관련 없는 도구가 첫 번째로 순위에 올랐습니다.

  • 도구 이름 + 설명 + 스키마 워크(schema walk)의 평면 텍스트 투영(flat-text projection)에 대한 BM25 적용: Top-1 정확도 81%. 실패 사례는 거의 항상 어휘적(lexical)인 문제였습니다(예: 도구는 "fetch"를 사용하지만 사용자는 "get"이라고 말함). 이는 가벼운 쿼리 재작성(query rewriting)으로 복구 가능한 수준이었습니다.
  • 하이브리드 (0.7 시맨틱 + 0.3 BM25 정규화): 78%. BM25 단독 사용보다 결과가 좋지 않았습니다. 시맨틱 노이즈(semantic noise)가 BM25의 깨끗한 신호를 저하시켰습니다.

저는 이 결과를 한동안 곱씹어 보았습니다. "당연한" 정답은 하이브리드입니다. 2023년 이후의 모든 RAG 논문들은 하이브리드 방식이 승리한다고 말합니다. 하지만 도구 선택(tool selection)에 있어서는 하이브리드가 패배했습니다. 그 이유는 도구가 문서보다 더 작고 구조화된 공간에 존재하기 때문입니다. 변별력 있는 신호(discriminative signal)는 키워드 형태를 띱니다. BM25는 바로 그 용도에 맞춰 설계되었습니다.

또 하나 배운 점은 스키마 필드(schema fields)를 인덱싱하는 것이 중요하다는 것입니다. BM25의 깔끔한 승리는 이름 + 설명 + input_schema 및 output_schema에 대한 워크(walk)를 투영함으로써 얻어졌습니다 (시맨틱 토큰만 사용하고 JSON Schema 구조는 제거함). repo_id나 branch와 같은 속성 이름(Property names)은 "open issues를 나열해줘"라는 요청을 Slack이 아닌 GitHub에 대한 히트로 전환하는 결정적인 변별 요소입니다. 만약 이름과 설명만 인덱싱한다면, 신호의 절반을 버리는 셈입니다.

결국 저는 Ratel의 인덱싱 방식을 채택했습니다 (그들의 ADR-0004 문서에 정확한 투영 방식이 기록되어 있습니다). 직접 다시 만드는 것은 중복 작업이었기 때문입니다. 오픈 소스이며, 프로세스 내(in-process) Rust 기반이고, TS SDK에 NAPI-RS로 바인딩되어 있으며, 별도의 인프라가 필요 없습니다. 시맨틱 + 재순위화(re-ranking) 기능은 그들의 로드맵에 있지만, 현재로서는 BM25 전용 기본 설정이 제가 원하는 방식입니다. 혹시 시도해보고 싶은 분이 있다면 댓글로 공유해 드리겠습니다.

도구 선택(tool selection)이나 에이전트 게이트웨이(agent gateways)를 구축하는 분들을 위한 교훈: 문서 기반 RAG의 기본 설정이 그대로 전이될 것이라고 가정하지 마십시오. 도구는 데이터의 형태가 다릅니다. BM25는 지루한 대체 수단이 아닙니다. 이 문제에 있어서는 BM25가 적절한 기본(primary) 방식이며, 시맨틱 방식은 선택적인 추가 요소입니다. 임베딩(embeddings)을 사용하기 전에 여러분의 특정 코퍼스(corpus)를 먼저 테스트하십시오.

/u/AbjectBug5885 님이 r/MachineLearning 에 제출함

[link] [comments]

AI 자동 생성 콘텐츠

본 콘텐츠는 r/OpenAI Codex (search)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0