Yazarlar: @hi_im_isaac_, @learnwdaniel, @gaozenghao
not: Teknik blogun interaktif versiyonu mevcut: https://www.cerebras.ai/blog/how-we-built-our-knowledge-base
Çalışanlarımız her gün iç bilgi tabanımıza 15.000'den fazla soru soruyor. 3 ay önce kullanıma sunulduğundan beri şirkette en yaygın kullanılan iç araçlardan biri haline geldi. İnsanlar, otomasyonlar ve ajanlar tarafından kullanılıyor.
Cerebras'ta ekiplerimiz veri merkezi operasyonları, çip tasarımı, donanım, eğitim, çıkarım, bulut platformu ve daha birçok alanda çalışıyor. Her yıl yüzlerce yeni çalışanın katılmasıyla iletişim kanallarımız aynı sorularla dolup taşıyordu:
- "X'i nerede bulabilirim?"
- "Y'nin uzmanı kim?"
- "Z nedir?"

Cerebras Knowledge'i, insanları ve sistemleri faydalı bilgilere bağlamaya yardımcı olmak için geliştirdik.
Verilerin olduğu yerde buluşmak
Bir organizasyon içinde bilgi bulmak zordur. Veriler araçlara dağılmıştır ve her çeyrekte bir aynı parlak çözüm önerilir: her şeyi tek bir platformda kaydedelim ki tüm bilgiler tek bir yerde olsun. Tek bir doğru kaynak hayali, elbette, pratikte nadiren işe yarar.
Bilgi, nerede uygun ve ergonomikse orada üretilir: bir belgedeki önerilen düzenlemeler, Slack'teki iş parçacıkları, GitHub'daki kod referansları ve Jira'daki durum meta verileri. Bu platformlar, belirli alanları için özel olarak tasarlanmış, yıllarca süren ürün mühendisliği ve analitiği ile optimize edilmiştir. Bir pull request'i Google Dokümanlar'da tartışmak korkunç bir deneyim olurdu.
Bu yüzden mevcut davranışta minimum değişiklik gerektiren bir sistem tasarlamaya koyulduk. Veri toplama tarafında bu, verileri her platformdan doğrudan çıkarmak anlamına geliyordu.
Bir bilgi tabanının anatomisi
Bilgi tabanımız üç şey sunar:
- Dahili verileri toplamak ve depolamak için bir platform.
- Bu verileri sorgulamak için bir platform.
- Denetim ve analitik ile kimlik doğrulama ve yetkilendirmeyi uygulayan bir katman.
Merkezde, birçok kaynaktan gelen gömme vektörleri, ham özetleri ve meta verileri tutan tek bir Postgres tablosu bulunur. Sistem, şirket genelinden sürekli olarak veri alır ve sorgulamaya hazır bir veri deposu tutar.
Basit ama çoğu veri formuyla çalışabilen bir veri arayüzü istedik. Ayrıca Cerebras'taki diğer geliştiricilerin özel bağlayıcılar oluşturabilmesini istedik. Sonuç kasıtlı olarak basit: Slack iş parçacıklarından netlistlere kadar her kaynak aynı gömme tablosuna düşer ve bu tablodaki her şey aynı arayüz üzerinden hemen sorgulanabilir:

Her veri kaynağı, verinin ne olduğunu, ona nasıl bağlanılacağını ve ne sıklıkta getirilmesi gerektiğini tanımlar. Ortaya çıkan her gömme satırı, Slack'ten, bir kod deposundan, bir belge sisteminden veya özel bir veritabanından gelmiş olmasına bakılmaksızın aynı arayüzü izler.
Yapılandırılmamış Slack Konuşmalarını Nasıl İşliyoruz
Slack, tasarlamamız gereken en önemli veri kaynağıydı. Şirket genelinde en güncel mühendislik tartışmalarının yapıldığı yerdir.

Başlangıçta, ham metin üzerinde basit gömme vektörlerinin yeterince iyi performans gösterip göstermediğini test ettik. Vektör aramasının tek başına tüm ilgili verileri eşleştirmek için yetersiz olduğunu çabucak fark ettik.
Slack mesajları birkaç zorluk sunar:
- Bilgi yoğunluğu büyük ölçüde değişir: "hey evet tabii mike" ve ayrıntılı bir kernel açıklaması, ikisi de mesajdır.
- Mesaj uzunlukları değişir ve daha kısa mesajlar, kosinüs benzerliğinde daha uzun, daha ayrıntılı mesajları sık sık yener.
- Bir mesajın anlamı genellikle çevresindeki konuşmaya bağlıdır.
Hibrit bir yaklaşıma ihtiyacımız vardı. Slack alımını, her iş parçacığının aynı anda birkaç arama tekniği aracılığıyla aranabilir olacağı şekilde oluşturduk; her teknik diğerlerinin zayıf yönlerini telafi ediyor:
- Tam metin araması, gömme vektörlerinin birbirine karıştırdığı tam belirteçleri yakalar: hata dizeleri, bayrak adları, ana bilgisayar adları. Bir mühendis gerçek bir hata mesajını yapıştırdığında, birebir sözcüksel eşleşme neredeyse her zaman en iyi kanıttır ve hiçbir anlamsal benzerlik miktarı onu geçemez.
- Gömme araması, başka sözcüklerle ifade etmeyi yakalar. "Manifest yüklemesinden sonra geri yükleme takılıyor" diye soran kişi ile "NFS bağlantısında kontrol noktası duruyor" diye yanıtlayan kişi hiçbir zaman ortak bir kelime dağarcığı paylaşmayabilir. Vektör benzerliği, bir soruyu farklı kelimelerle yazılmış bir cevaba bağlayan şeydir.(1)
- Ters belge sıklığı, sinyali dolgudan ayırır. Belirsiz bir yapılandırma bayrağı gibi nadir belirteçler etrafında inşa edilmiş kısa bir mesaj sıralanmayı hak eder. "kulağa hoş geliyor, teşekkürler!" gömme uzayında birçok sorguya yakın durur ancak terim nadirliği hesaba katıldığında sıfıra yakın puan alır.
- Yaş azalması, Slack yanıtlarının sona erdiğini kodlar. İki iş parçacığı aynı soruyu yanıtlayabilir ve altı ay önceki, artık var olmayan bir altyapıyı tanımlıyor olabilir. Alaka düzeyi aksi takdirde eşit olduğunda, daha yeni iş parçacığı kazanır.

Hiçbir tek puanlayıcı kendi başına güvenilmez. Her teknik, aynı külliyatın kendi sıralanmış görünümünü üretir ve bu görünümler sorgulama zamanında birleştirilir (yeniden sıralamaya bakın).
Socket Modu
Verileri gerçek zamanlı olarak toplamak için çalışma alanımıza bir Slack botu yükledik ve onu Socket Modunda çalıştırdık. Slack, her mesaj olayını kalıcı bir WebSocket üzerinden bize gönderir, böylece Web API'sini yoklamadan ve hız sınırlarını aşmadan gerçek zamanlı güncellemeler alırız.
Bir olay geldiğinde, onu hemen onaylarız, kararlı olay kimliğini kullanarak kopyasını ayıklarız ve mesajı alım tüketicisi için işaretleriz.
Alım tüketicisi yeni bir mesajı tek başına kaydetmez. Mesajın ait olduğu iş parçacığını çözer ve Slack API'sinden üst öğe ve her yanıt dahil olmak üzere tüm konuşmayı yeniden getirir. Ardından tüm iş parçacığını tek bir satır olarak geri yazar. Bu nedenle, mevcut bir iş parçacığına yapılan bir yanıt, üst öğeyi ve tüm kardeşleri yeniden çeker, böylece depolanan içerik, katılımcı listesi ve son etkinlik zaman damgası her zaman tam konuşmayı yansıtır.
Sistemimizdeki her Slack kanalının kendi veri kaynağı vardır. Bu, veri tazeliği için ince ayar yapılmasını sağlar. Örneğin, bir ekip yoğun bir olay kanalını daha sık almayı seçebilir.
İş parçacıkları ve mesajlar
Ham Slack metni, ham içerik üzerinde bir Postgres tam metin (GIN) indeksi tuttuğumuz için indiği anda anahtar kelime aranabilir hale gelir. Ancak, yararlı vektör aramasını etkinleştirmek için bazı ek işlemler yapıyoruz.(8)
Damıtma sırasında, bir LLM tam iş parçacığından yapılandırılmış veriler çıkarır:
- Bir mühendisin gerçekten arayacağı tek satırlık bir soru.
- Kısa bir özet.
- Çözüm.
- Bahsedilen sistemler ve kod referansları.

Bu veri noktalarını gömer ve paylaşılan gömme tablosuna yazarız. Orijinal transkript doğrudan gömülmez. Deneylerimizde, iş parçacığı tutarlı bir formata normalleştirildiğinde doğruluk önemli ölçüde arttı.(7,9) Ek meta veriler ayrıca anlamsal eşleşmeye daha kullanışlı sinyal verir.
Patlatma
Bu noktada Slack araması iyiydi, ancak aynı sorunla karşılaşmaya devam ediyorduk: uzun iş parçacıkları içindeki önemli mesajlar her zaman iş parçacığı düzeyindeki özette temsil edilmiyordu.
Bireysel mesajlardan gelen sinyali artırmak için patlatma kullanıyoruz. Bir patlama, aynı yazardan ardışık mesajlar dizisidir. Bireysel patlamaları, bağlam olarak önceden eklenmiş iş parçacığı konusu ile gömeriz(2) çünkü bazen cevap, kelime dağarcığı hiçbir zaman iş parçacığı özetine girmeyen bir konu dışı mesajda yaşar. Patlama gömme vektörleri, bu mesajı kendi başına bulunabilir kılar.
Düşük sinyalli verilerin veritabanına ulaşmasını önlemek için, her patlama bir sinyal ağırlıklı kombinasyonuna karşı puanlanır ve gömülmeden önce bir eşiği geçmelidir:
- Külliyat genelinde en az 4,0 IDF ile nispeten nadir bir belirteç içerir.
- Birleşik patlama en az 200 karakterdir.
- Patlamadaki bir veya daha fazla mesaj, sosyal bir destek sağlayan reaksiyonlar içerir.

Damıtmadan sonra, uygun patlamalar gömülür ve iş parçacığı düzeyindeki kayıtla birlikte gömme tablosunda saklanır.
Kod depoları
Başlangıçta kod depolarını gömmenin gerekli olup olmadığını tartıştık. Claude Code ve diğer komut satırı araçlarının yükselişiyle birlikte, "grep yeterli" gibi göründüğünde kod gömme vektörleri oluşturmak mantığa aykırı geldi. Sektördeki diğerleriyle konuştuktan ve Cursor'un büyük kod tabanlarında anlamsal arama ile ilgili bulgularını okuduktan sonra denemeye karar verdik.
Birçoğu 40 GB'den büyük olan birçok dahili depomuz var. Ana endişemiz, onları verimli bir şekilde güncel tutmanın nasıl olacağıydı.
Kod gömme vektörlerini korumak için @cocoindex_io kullanma
Birkaç deneyden sonra, kod tabanlarını vektörleştirmede uzmanlaşmış açık kaynaklı bir belge gömme çerçevesi olan CocoIndex'e karar verdik.
Her depo için, kodu kaba taneden ince taneye doğru sıralanmış dile özgü normal ifade sınırlarını kullanarak böldük. Ayırıcı önce sınıflar gibi daha üst düzey sınırları dener. Ortaya çıkan parça hala çok büyükse, yöntem sınırlarına ve ardından daha küçük bloklara geri döner. Ortaya çıkan parçaları gömer ve vektörleri Postgres'e yazarız. Tek bir dosya, dosya düzeyinde ve işlev düzeyinde kayıtlar gibi farklı özgüllük seviyelerinde birden çok gömme oluşturabilir.

CocoIndex, Postgres'te senkronizasyon meta verilerini izler. Her işlemede, tüm depoyu yeniden hesaplamak yerine yalnızca değişen kod parçalarını yeniden gömer ve yeniden dışa aktarır. Bu bizim için özellikle iyi çalıştı çünkü senkronizasyon durumu ve gömme deposu aynı veritabanında yaşıyor.
Kod tabanlarının sayısı arttıkça, depo ekleme işlemini ekiplerin kendilerinin gönderebileceği, dosya yolu düzeyinde izin listeleri ve engelleme listeleri içeren yapılandırma dosyalarına taşıdık.
Özel veri kaynakları
Bazı ekiplerin zaten kendi veritabanları vardı ve bilgi tabanına katılmak için verileri Slack'e veya bir belge sistemine taşımak istemediler. Mevcut tabloları üzerinde aynı sorgu yüzeyini istediler.
Bunu desteklemek için, özel kaynakları eklenti betikleri olarak ele alıyoruz. Bir ekip, kendi sisteminden nasıl okunacağını bilen ve gömme tablomuz şeklinde satırlar yayan küçük bir Python modülü ve eşleşen bir veri kaynağı girişi içeren bir pull request açar.
Betik, diğer her gömme satırıyla aynı şemayı kullanarak paylaşılan veritabanına yazdığı sürece, yığının geri kalanı değişmeden çalışır. Veriler, sistemin başka hiçbir yerinde özel bir işlem gerektirmeden Slack, kod ve belgelerin yanında sorgulanabilir hale gelir.
Planlama ve araç yayılımı
Her sorgu için, önce bir LLM'nin hangi araçların ve veri kaynaklarının önemli olacağına karar verdiği kısa bir planlama geçişi yaparız. Ana araçlar:
- subsystem_index: dosya başına LLM özetleri.
- search: Slack, wiki, kod ve diğer indekslenmiş kaynaklar arasında birleşik vektör hattı, dahili olarak birleştirilir ve yeniden sıralanır.
- search_slack: doğrudan Slack alma.
- search_code: kaynak depoları üzerinde ripgrep.
- recent_prs: soruyla ilgili son pull request'ler.
- who_knows: bir konuda kanıtlanmış uzmanlığa sahip kişiler.
Planlayıcı, neyi indekslediğimizin kompakt bir açıklaması üzerinde çalışır: hangi projelerin var olduğu, her projede hangi kaynakların mevcut olduğu ve her kaynağın neyi yanıtlamada iyi olduğu. Kullanıcının sorgusu ve etkin kapsamı verildiğinde, yürütücünün paralel olarak yaydığı, ortak bir kanıt formatında normalleştirdiği ve son bir sentez LLM'sine ilettiği araç seçimlerini yayar.(4)

Yeniden sıralama
Bir belge, farklı bir soruyu yanıtlarken sorguyla kelime dağarcığını paylaştığı için en üste yakın bir yerde görünebilir. Yeniden sıralamadan önce, alıcıların uyumsuz sonuç listelerini karşılıklı sıra birleştirme veya RRF ile birleştiririz. Her belge için, göründüğü her liste için ağırlık / (60 + sıra) ekleriz, varsayılan ağırlık 1.0 ve düzeltme sabiti 60'tır.

Düzeltme sabiti, fikir birliğini tek bir güçlü oydan daha önemli kılar: birden çok alıcıda üste yakın görünen bir belge, yalnızca birinde birinci sırada olanı geçebilir. Ardından yinelenen parçaları tek bir kaynağa geri birleştiririz, her dosyanın kaç sonuç katkıda bulunabileceğini sınırlarız ve daha çeşitli bir ilk yirmi ile sonuçlanırız.
Orijinal sorguyu ve bu adayları küçük bir yeniden sıralama modeline göndeririz. Her belgeye sıfırdan ona kadar bir puan verir ve ilk onu tutarız.(6)
Sıralama nihai olduğunda, kazananlara bağlamı geri ekleriz. Örneğin, bir wiki bölümünü eşleştirirsek, parçalamanın ayırdığı başlık, ön koşullar ve uyarıların kaybolmaması için iki komşu bölümü de çekeriz. Bu, okuyuculara önemli bağlamı eksik olan yalnız bir paragraf yerine eksiksiz bir parçacık verir.
Dolayısıyla aramanın çıktısı zengin bir kanıt paketidir: farklı alıcılardan birleştirilmiş, kaynak düzeyinde kopyaları ayıklanmış, gerçek soruya karşı yeniden sıralanmış ve ancak o zaman çevreleyen bağlamla genişletilmiş sonuçlar.
MCP
MCP entegrasyonunda, alma yapı taşlarını tek bir "bu soruyu yanıtla" uç noktasının arkasına saklamak yerine doğrudan araçlar olarak kullanıma sunarız. Bu araçlar kasıtlı olarak basit ve mümkün olduğunca LLM'sizdir, böylece istemciler bunları hızlı ve ucuz bir şekilde sorgulayabilir.(5)
Her MCP aracı, search_slack, search_code, search veya who_knows gibi temel bir alma ilkeline karşılık gelir. Araç girdileri ve çıktıları dar, yapılandırılmış ve kararlıdır; bu da aracın içine ek orkestrasyon mantığı yerleştirmeden herhangi bir istemciden veya ajandan çağrılmalarını kolaylaştırır.
Çoğu araç, vektör araması, sözcüksel arama veya ripgrep gibi bir sorgu hattı çalıştırır, hafif puanlama buluşsal yöntemleri uygular ve ham kanıt satırlarını döndürür.
Claude Code veya MCP uyumlu herhangi bir ajan, orkestrasyon motoru haline gelir. Hangi araçları hangi sırayla çağıracağına ve sonuçları nihai bir cevap veya kod düzenlemesinde nasıl birleştireceğine karar verir. Alma katmanının kendisi, istekleri yerine getirmek için bu LLM kararlarına bağlı değildir.
Web Kullanıcı Arayüzü
Web kullanıcı arayüzünde aynı araçlar mevcuttur, ancak her kullanıcı sorusu için uçtan uca çalışan eksiksiz bir sorgu hattına bağlıdırlar. UI ajanı, planlayıcı ve yürütücü adımlarına sahiptir.
- Planlayıcı: Hafif bir LLM geçişi, sorguyu ve etkin projeyi inceler, ardından search, search_slack ve subsystem_index gibi hangi alma araçlarının çağrılacağını seçer.
- Yürütücü: Sistem bu araç çağrılarını paralel olarak yayar, sonuçları toplar ve bunları puanlar, güncellik ve kaynak ipuçları içeren paylaşılan bir kanıt şemasında normalleştirir.
- Sentez: Son bir LLM geçişi, yazılan kanıt paketini ve orijinal soruyu alır ve alıntılar, uyarılar ve kaynaklar arası sentez dahil olmak üzere kullanıcı arayüzünde gösterilen cevabı üretir.
Kullanıcının bakış açısından, web kullanıcı arayüzü basitçe "bir soru sor ve bir cevap al" dır. Perde arkasında, MCP istemcilerinin açıkça yeniden oluşturabileceği aynı planlayıcı → yürütücü → sentezleyici modelini çalıştırır.

Organizasyon
Külliyat büyüdükçe, "her yerde her şeyi ara" hızla kullanışsız hale geldi. Derleyici ekiplerindeki mühendisler sonuçlarında altyapı runbook'larını istemiyordu ve bunun tersi de geçerliydi. Projeler, aramayı varsayılan olarak alakalı kılma şeklimizdir.
Projeler ve kapsamlı arama
Projeleri, bir sorgunun üzerinde çalıştığı çalışma alanını düzenlemenin birincil yolu olarak tanıttık. Bir proje, belirli Slack kanalları, kod depoları, dahili veritabanları ve bir ekip veya girişimle ilgili belge alanları gibi adlandırılmış bir veri kaynakları demetidir.
Projeler kasıtlı olarak hafiftir. Paylaşılan bir olaylar kanalı veya merkezi platform deposu gibi aynı veri kaynağı, kopyalanmak yerine birden çok proje tarafından referans alınabilir.

Ekleme ve varsayılanlar
Ekleme sırasında, kullanıcılardan ML eğitim altyapısı, Derleyici veya Veri Merkezi Operasyonları gibi çalışma şekillerine uygun bir varsayılan proje seçmeleri veya oluşturmaları istenir.
Bu varsayılan proje, kullanıcı profilinde saklanır ve sorguları otomatik olarak kapsamlandırır. Yeni bir mühendis, hangi Slack kanallarının, depoların veya belge alanlarının önemli olduğunu öğrenmek zorunda kalmadan yüksek sinyalli cevaplar alır.
Son Düşünceler
Sonuç olarak, bilgi tabanı işe yarıyor çünkü insanlarla bilginin zaten yaşadığı yerde buluşuyor, her şeyi tek bir katı sisteme zorlamak yerine. Çeşitli arama tekniklerini birleştirerek kanıtları hızlı bir şekilde yüzeye çıkarabiliyoruz. Sonuç, gerçek şirket verileri için yeterince esnek kalan, ancak Cerebras büyümeye devam ederken kullanışlı kalacak kadar yapılandırılmış bir arama deneyimidir.
Buraya kadar okuduysanız ve bu ilginizi çekiyorsa, ai/growth ekibi işe alım yapıyor. İlgileniyorsanız @learnwdaniel ile iletişime geçin.
Referanslar
- Malkov ve Yashunin, Hiyerarşik Gezinebilir Küçük Dünya Grafikleri Kullanarak Verimli ve Sağlam Yaklaşık En Yakın Komşu Arama, arXiv:1603.09320 / IEEE TPAMI 2018.
- Anthropic, Bağlamsal Alımı Tanıtıyoruz, 2024.
- Cormack, Clarke ve Büttcher, Karşılıklı Sıra Füzyonu Condorcet ve Bireysel Sıra Öğrenme Yöntemlerinden Daha İyi Performans Gösteriyor, SIGIR 2009.
- Li ve ark.,





