3줄 요약
- Cerebras 엔지니어링팀(Isaac Tai, Daniel Kim, Mike Gao)이 2026년 7월 16일 공개한 사내 지식베이스 구축기다. 출시 3개월 만에 사내에서 가장 널리 쓰이는 도구가 되었고, 하루 15,000건 이상의 질문을 받는다. 사람뿐 아니라 자동화와 에이전트도 사용한다.
- 핵심 설계는 “데이터가 사는 곳에서 그대로 끌어온다"다. 모든 정보를 한 플랫폼에 모으자는 단일 진실 공급원의 꿈을 명시적으로 버리고, Slack부터 넷리스트까지 전부 동일한 스키마의 Postgres 임베딩 테이블 한 개로 착지시켰다. 소스마다 커넥터 하나씩.
- 검색은 어떤 단일 스코어러도 신뢰하지 않는다. 전문 검색, 임베딩, IDF, 시간 감쇠가 각자 순위를 매기고 질의 시점에 RRF로 융합된다.
데이터가 사는 곳에서 그대로 끌어온다
글은 조직마다 분기에 한 번씩 반복되는 제안을 먼저 겨냥한다. 모든 것을 한 플랫폼에 기록하자. 저자들은 이 꿈이 실제로 작동하는 일은 드물다고 잘라 말한다.
정보는 편리하고 손에 맞는 곳이면 어디서든 생성된다. 문서의 제안된 수정, Slack의 스레드, GitHub의 코드 참조, Jira의 상태 메타데이터.
각 플랫폼은 자기 도메인에 맞춰 수년간 다듬어진 물건이다. 풀 리퀘스트를 Google Docs에서 논의하는 건 끔찍한 경험일 것이다. 그래서 이들은 기존 행동을 최소한으로만 바꾸는 시스템을 목표로 삼았고, 수집 측면에서 이는 각 플랫폼에서 데이터를 직접 추출한다는 뜻이 되었다.
지식베이스의 해부
지식베이스가 제공하는 것은 셋이다.
- 사내 데이터를 수집하고 저장하는 플랫폼
- 그 데이터를 질의하는 플랫폼
- 인증과 인가를 강제하고 감사와 분석을 붙이는 계층
중심에는 임베딩, 원본 요약, 메타데이터를 담은 Postgres 테이블 하나가 있다. 시스템은 사내 전역에서 데이터를 계속 수집하며 질의 준비가 된 데이터스토어를 유지한다.
인터페이스는 의도적으로 단순하게 두었다. Slack 스레드든 넷리스트든 모든 소스가 같은 임베딩 테이블에 착지하고, 그 테이블에 있는 것은 무엇이든 같은 인터페이스로 즉시 질의된다.

각 데이터 소스는 세 가지를 정의한다. 데이터가 무엇인지, 어떻게 연결하는지, 얼마나 자주 가져올지. 결과로 나오는 임베딩 행은 출처가 Slack이든 코드 저장소든 문서 시스템이든 커스텀 데이터베이스든 동일한 인터페이스를 따른다. 사내 다른 개발자가 커스텀 커넥터를 직접 만들 수 있게 하려는 목적도 있었다.
Slack을 어떻게 다뤘는가
Slack은 이들이 가장 공들여 설계해야 했던 소스다. 사내에서 가장 최신의 엔지니어링 논의가 벌어지는 곳이기 때문이다.
처음에는 원문 텍스트에 임베딩만 걸어도 충분한지 시험했고, 벡터 검색만으로는 부족하다는 걸 금방 알았다. Slack 메시지에는 고유한 문제가 있다.
- 정보 밀도의 편차가 극단적이다. “hey yeah sure mike"도 메시지고 상세한 커널 설명도 메시지다.
- 길이가 제각각인데, 짧은 메시지가 길고 상세한 메시지를 코사인 유사도에서 이기는 일이 잦다.
- 메시지의 의미가 주변 대화에 달려 있는 경우가 많다.
네 가지 검색 기법이 서로의 약점을 메운다
그래서 모든 스레드가 여러 검색 기법으로 동시에 검색되도록 만들었다. 각 기법이 다른 기법의 약점을 보완한다.
| 기법 | 무엇을 잡는가 |
|---|---|
| 전문 검색 | 임베딩이 뭉개버리는 정확한 토큰. 에러 문자열, 플래그 이름, 호스트 이름. 엔지니어가 에러 메시지를 그대로 붙여넣었다면 정확한 어휘 일치가 거의 항상 최선의 증거이고, 어떤 의미적 유사도도 그걸 앞질러선 안 된다. |
| 임베딩 검색 | 바꿔 말하기. “restore hangs after manifest load"라고 묻는 사람과 “checkpoint stalls on the NFS mount"라고 답한 사람은 어휘를 하나도 공유하지 않을 수 있다. |
| 역문서빈도(IDF) | 신호와 잡음의 분리. 희귀 토큰으로 이루어진 짧은 메시지는 순위에 오를 자격이 있다. “sounds good, thanks!“는 임베딩 공간에서 많은 질의와 가깝지만 희소성을 따지면 점수가 0에 수렴한다. |
| 시간 감쇠 | Slack의 답은 만료된다. 같은 질문에 답하는 두 스레드 중 6개월 전 것은 이미 없어진 인프라를 설명할 수 있다. 나머지가 같다면 최신 스레드가 이긴다. |
어떤 단일 스코어러도 그 자체로 신뢰되지 않는다.
각 기법은 같은 코퍼스에 대해 자기만의 순위를 만들고, 그 순위들은 질의 시점에 융합된다.
Socket Mode와 스레드 통째 재작성
실시간 수집을 위해 Slack 봇을 워크스페이스에 설치하고 Socket Mode로 돌린다. Slack이 지속 WebSocket으로 모든 메시지 이벤트를 밀어주므로, Web API를 폴링하며 레이트 리밋을 태우지 않고도 실시간 갱신을 받는다. 이벤트가 도착하면 즉시 확인 응답을 보내고, 안정적인 이벤트 ID로 중복을 제거한 뒤 인제스트 소비자에게 넘긴다.
여기서 눈여겨볼 선택이 있다. 인제스트 소비자는 새 메시지를 홀로 저장하지 않는다. 메시지가 속한 스레드를 해석하고, 부모와 모든 답글을 포함한 대화 전체를 Slack API에서 다시 가져와, 스레드 전체를 한 행으로 다시 쓴다. 기존 스레드에 답글이 달리면 부모와 형제를 전부 다시 끌어오는 셈이라, 저장된 내용과 참여자 목록과 마지막 활동 시각이 항상 완전한 대화를 반영한다.
Slack 채널마다 자기 데이터 소스를 갖는다. 덕분에 신선도를 채널 단위로 조절할 수 있다. 바쁜 장애 대응 채널은 더 자주 수집하는 식이다.

원본은 임베딩하지 않는다
원문 Slack 텍스트는 Postgres 전문 인덱스(GIN)를 유지하기 때문에 착지하는 즉시 키워드로 검색된다. 하지만 쓸 만한 벡터 검색을 위해서는 추가 처리를 거친다.
distillation 단계에서 LLM이 스레드 전체로부터 구조화된 데이터를 뽑는다.
- 엔지니어가 실제로 검색할 법한 한 줄짜리 질문
- 짧은 요약
- 해결책
- 언급된 시스템과 코드 참조
그리고 이 데이터포인트들을 임베딩한다. 원본 전사는 직접 임베딩하지 않는다. 스레드를 일관된 형식으로 정규화했을 때 정확도가 유의미하게 올랐다는 게 이들의 실험 결과다. 추가 메타데이터가 의미 매칭에 더 유용한 신호를 준다는 이유도 붙는다.
Bursting
여기까지 오니 Slack 검색은 괜찮아졌지만 같은 문제가 계속 나왔다. 긴 스레드 안의 중요한 메시지가 스레드 수준 요약에 늘 반영되지는 않는다는 것.
그래서 버스트를 쓴다. 버스트는 같은 작성자가 연속으로 남긴 메시지 묶음이다. 스레드 주제를 맥락으로 앞에 붙여 개별 버스트를 임베딩한다. 답이 곁가지 메시지 하나에 들어 있고 그 어휘가 스레드 요약에는 끝내 오르지 못하는 경우가 있기 때문이다. 버스트 임베딩은 그런 메시지를 독립적으로 찾아낸다.
낮은 신호가 DB에 닿지 않도록, 각 버스트는 가중 신호 조합으로 채점되어 임계값을 넘어야만 임베딩된다.
- 코퍼스 전체에서 상대적으로 희귀한 토큰을 포함할 것 (IDF 4.0 이상)
- 결합된 버스트가 200자 이상일 것
- 버스트 안의 메시지 하나 이상에 리액션이 있을 것 (사회적 가산점)
코드 저장소
코드 저장소를 임베딩할 필요가 있는지부터가 논쟁거리였다. Claude Code 같은 명령줄 도구가 부상하면서 “grep이면 충분하다"로 보이는 마당에 코드 임베딩을 만드는 게 직관에 반한다고 느꼈다는 것이다. 업계 사람들과 이야기하고 대규모 코드베이스의 시맨틱 검색에 관한 Cursor의 결과를 읽은 뒤 시도해 보기로 했다.
내부 저장소는 많고 일부는 40GB를 넘는다. 주된 고민은 이걸 어떻게 효율적으로 최신 상태로 유지하느냐였다.
CocoIndex
여러 실험 끝에 코드베이스 벡터화에 특화된 오픈소스 임베딩 프레임워크 CocoIndex로 정착했다.
저장소마다 언어별 정규식 경계로 코드를 쪼개는데, 경계는 거친 것에서 세밀한 것 순으로 정렬되어 있다. 스플리터는 클래스 같은 상위 경계를 먼저 시도한다. 결과 청크가 여전히 너무 크면 메서드 경계로, 다시 더 작은 블록으로 내려간다. 파일 하나가 파일 수준과 함수 수준처럼 서로 다른 구체성의 임베딩을 여러 개 만들어낼 수 있다.
CocoIndex는 동기화 메타데이터를 Postgres에 추적한다. 커밋마다 저장소 전체를 다시 계산하는 대신 바뀐 코드 청크만 다시 임베딩하고 다시 내보낸다. 동기화 상태와 임베딩 저장소가 같은 데이터베이스에 사는 구조라 특히 잘 맞았다고 한다.
코드베이스 수가 늘면서 저장소 온보딩은 팀이 직접 제출하는 설정 파일로 옮겼다. 파일 경로 수준의 허용 목록과 차단 목록도 여기 들어간다.
커스텀 데이터 소스
이미 자기 데이터베이스를 갖고 있고, 지식베이스에 참여하겠다고 데이터를 Slack이나 문서 시스템으로 옮기고 싶지는 않은 팀들이 있었다. 이들이 원한 건 기존 테이블 위에 얹히는 동일한 질의 표면이었다.
그래서 커스텀 소스를 플러그인 스크립트로 취급한다. 팀이 자기 시스템에서 읽어 임베딩 테이블 모양의 행을 뱉는 작은 Python 모듈과 그에 맞는 데이터 소스 항목을 풀 리퀘스트로 연다. 스크립트가 다른 모든 임베딩 행과 같은 스키마로 공용 데이터베이스에 쓰기만 하면 나머지 스택은 그대로 작동한다.
검색: 플래닝, 팬아웃, 리랭킹
모든 질의에 대해 먼저 짧은 플래닝 패스를 돌린다. LLM이 어떤 도구와 데이터 소스가 중요할지 판단한다. 주요 도구는 여섯이다.
| 도구 | 역할 |
|---|---|
subsystem_index | 파일별 LLM 요약 |
search | Slack, 위키, 코드 등을 가로지르는 통합 벡터 파이프라인. 내부에서 병합하고 리랭크 |
search_slack | Slack 직접 검색 |
search_code | 소스 저장소에 대한 ripgrep |
recent_prs | 질문에 관련된 최근 풀 리퀘스트 |
who_knows | 해당 주제에 전문성이 입증된 사람 |
플래너는 인덱싱된 것들의 압축된 서술 위에서 작동한다. 어떤 프로젝트가 있고, 각 프로젝트에 어떤 소스가 있고, 각 소스가 무엇에 잘 답하는지. 플래너가 도구 선택을 내보내면 실행기가 병렬로 팬아웃하고, 공통 증거 형식으로 정규화한 뒤, 최종 종합 LLM에 넘긴다.

RRF — 합의가 강한 한 표를 이긴다
문서는 질의와 어휘를 공유한다는 이유만으로 상위에 오를 수 있다. 정작 답하는 질문은 다른데도. 리랭킹 전에 서로 호환되지 않는 검색기들의 결과 목록을 RRF(reciprocal rank fusion) 로 결합한다.
모든 문서에 대해, 그 문서가 등장한 목록마다 다음을 더한다.
$$\text{score}(d) = \sum_{l} \frac{w}{60 + \text{rank}_l(d)}$$기본 가중치는 1.0, 평활 상수는 60이다. 이 상수가 하는 일이 핵심이다.
평활 상수는 단일한 강한 한 표보다 합의가 더 중요하게 만든다. 여러 검색기에서 두루 상위에 나타나는 문서가, 그중 하나에서만 1위인 문서를 이길 수 있다.
이후 중복 청크를 원본 하나로 병합하고, 파일 하나가 기여할 수 있는 결과 수에 상한을 두어, 더 다양한 상위 20건을 얻는다. 원래 질의와 그 후보들을 작은 리랭커 모델에 보내면 문서마다 0에서 10점을 매기고, 상위 10건을 남긴다.
순위가 확정되면 승자들에게 맥락을 되돌려준다. 위키 섹션이 매치되었다면 인접한 두 섹션을 끌어와 청킹이 갈라놓은 제목과 전제 조건과 단서를 잃지 않게 한다. 맥락이 빠진 외로운 문단 대신 완결된 스니펫을 주려는 것이다.
MCP는 얇게, 웹 UI는 두껍게
MCP 통합에서는 검색 구성 요소를 “이 질문에 답하라"는 단일 엔드포인트 뒤에 숨기지 않고 직접 도구로 노출한다. 도구는 의도적으로 단순하고 가능한 한 LLM을 쓰지 않게 만들어, 클라이언트가 빠르고 싸게 질의할 수 있게 했다.
MCP 도구 하나는 밑단의 검색 프리미티브 하나에 대응한다. 입출력은 좁고 구조화되어 있고 안정적이다. 오케스트레이션 로직을 도구 안에 심지 않았기 때문에 어떤 클라이언트나 에이전트에서도 부르기 쉽다.
Claude Code나 MCP 호환 에이전트가 오케스트레이션 엔진이 된다. 어떤 도구를 어떤 순서로 부를지, 결과를 어떻게 최종 답이나 코드 편집으로 조립할지는 그쪽이 결정한다. 검색 계층 자체는 요청을 처리하는 데 그 LLM 결정에 의존하지 않는다.
반면 웹 UI에는 같은 도구들이 완전한 질의 파이프라인에 연결되어 있고, UI 에이전트가 플래너와 실행기 단계를 소유한다. 플래너가 질의와 활성 프로젝트를 보고 도구를 고르고, 실행기가 병렬로 팬아웃해 점수와 최신성과 출처 힌트를 담은 공용 증거 스키마로 정규화하고, 종합 패스가 인용과 단서와 교차 출처 종합을 담은 답을 만든다.

사용자 입장에서 웹 UI는 그냥 “질문하면 답이 나오는” 물건이다. 그 밑에서는 MCP 클라이언트가 명시적으로 재현할 수 있는 planner → executor → synthesizer 패턴이 똑같이 돌아간다.
프로젝트 — 기본 스코프
코퍼스가 커지자 “전부를 어디서나 검색"은 빠르게 쓸모없어졌다. 컴파일러 팀 엔지니어는 결과에 인프라 런북이 섞이는 걸 원하지 않았고, 반대도 마찬가지였다.
프로젝트는 질의가 도는 작업 공간을 조직하는 일차 수단이다. 특정 Slack 채널, 코드 저장소, 내부 데이터베이스, 문서 공간을 팀이나 이니셔티브 단위로 묶은 이름 붙은 번들이다. 프로젝트는 의도적으로 가볍다. 공용 장애 채널이나 중앙 플랫폼 저장소 같은 동일한 데이터 소스는 복제되지 않고 여러 프로젝트에서 참조될 수 있다.

온보딩 때 사용자는 자기 일에 맞는 기본 프로젝트를 고르거나 만들도록 안내받는다. ML 학습 인프라, 컴파일러, 데이터센터 운영 같은 것들. 그 기본값은 사용자 프로필에 저장되어 질의 범위를 자동으로 좁힌다. 새로 온 엔지니어가 어떤 Slack 채널과 저장소와 문서 공간이 중요한지 먼저 배우지 않고도 신호가 높은 답을 받는다.
가장 흥미로운 지점
내가 가장 눈여겨본 것은 RRF의 평활 상수 60이다. 이건 튜닝 파라미터로 보이지만 실은 정책 선언에 가깝다. 상수를 60까지 키우면 1위와 5위의 점수 차가 압축되고, 그 결과 여러 검색기에서 두루 상위권인 문서가 한 검색기에서만 1위인 문서를 이긴다. 어떤 단일 스코어러도 신뢰하지 않겠다는 문장이 수식 안에 숫자 하나로 들어가 있는 셈이다. 아키텍처 다이어그램보다 이 상수 하나가 이들의 태도를 더 정확히 말한다.
그런데 바로 그 지점에서 이 글의 빈칸도 눈에 띈다. 정량 평가가 하나도 없다. distillation이 정확도를 “유의미하게 올렸다"고 하지만 무엇을 얼마나 올렸는지는 없고, 벤치마크도, 임베딩 모델도 리랭커 모델도 종합 LLM도 이름이 밝혀지지 않는다. 하루 15,000건이라는 채택 지표는 인상적이지만 그건 사용량이지 품질이 아니다. 이 글은 검증된 결과 보고가 아니라 설계 서사로 읽는 게 맞다. 그렇게 읽으면 값지다. 특히 “grep이면 충분하다"는 통념을 검토한 끝에 코드 임베딩을 결국 도입했다는 대목은, 같은 저울질을 하고 있는 팀에게 결론 자체보다 저울질의 항목이 유용하다.
출처
Isaac Tai, Daniel Kim, Mike Gao (Cerebras), How Cerebras Built Its Enterprise Knowledge Base, 2026년 7월 16일.
원문: https://www.cerebras.ai/blog/how-we-built-our-knowledge-base X 게시물: https://x.com/cerebras/status/2077822555159945507
본문 도해는 원문에 인라인 SVG로 실린 다이어그램을 렌더링하여 인용했다. 원문이 인용한 참고문헌은 다음과 같다.
- Malkov and Yashunin, Efficient and Robust Approximate Nearest Neighbor Search Using Hierarchical Navigable Small World Graphs, arXiv:1603.09320 / IEEE TPAMI 2018.
- Anthropic, Introducing Contextual Retrieval, 2024.
- Cormack, Clarke, and Büttcher, Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods, SIGIR 2009.
- Li et al., Search-o1: Agentic Search-Enhanced Large Reasoning Models, arXiv:2501.05366, 2025.
- Anthropic, Code Execution with MCP, 2025.
- Liu et al., Lost in the Middle: How Language Models Use Long Contexts, arXiv:2307.03172, 2023.
- Anthropic, Use XML Tags.
- Salesforce/Slack Engineering, How Slack AI Processes Billions of Messages.
- Improving Agents, Best Nested Data Format.