Bu blogda, RAG için kod tabanını CocoIndex ile nasıl dizinleyeceğinizi göstereceğiz. CocoIndex, verilerinizi dizinlemenize ve sorgulamanıza yardımcı olan bir araçtır. Kendi veri hattınızı oluşturmak için bir çerçeve olarak kullanılmak üzere tasarlanmıştır. CocoIndex, yerel Tree-sitter desteğiyle kod tabanı parçalama için yerleşik destek sağlar.
Tree-sitter , Rust 🦀 - GitHub'da bulunan bir ayrıştırıcı oluşturma aracı ve artımlı bir ayrıştırma kütüphanesidir. CocoIndex, çeşitli programlama dilleri için kodu verimli bir şekilde ayrıştırmak ve sözdizimi ağaçlarını çıkarmak için Tree-sitter ile yerleşik Rust entegrasyonuna sahiptir.
Kod tabanı parçalama, bir kod tabanını daha küçük, anlamsal olarak anlamlı parçalara ayırma sürecidir. CocoIndex, Tree-sitter'ın kod parçalama yeteneklerini, keyfi satır sonları yerine gerçek sözdizimi yapısına göre akıllıca parçalara ayırma yeteneğinden yararlanır. Bu anlamsal olarak tutarlı parçalar daha sonra RAG sistemleri için daha etkili bir dizin oluşturmak için kullanılır ve daha kesin kod alma ve daha iyi bağlam koruması sağlar.
Hızlı geçiş 🚀 - tam kodu burada bulabilirsiniz. RAG boru hattı için sadece ~ 50 satır Python kodu, kontrol edin 🤗!
Çalışmalarımızı beğendiyseniz lütfen Github'da CocoIndex'e bir yıldız vererek bizi destekleyin. Sıcak bir hindistan cevizi sarılmasıyla çok teşekkür ederim 🥥🤗.
Postgres yüklü değilse lütfen kurulum kılavuzuna bakın. CocoIndex, veri dizinini yönetmek için Postgres kullanır, devam edenler de dahil olmak üzere diğer veritabanlarını desteklemek için yol haritamızda yer almaktadır. Diğer veritabanlarıyla ilgileniyorsanız lütfen bir GitHub sorunu veya Discord oluşturarak bize bildirin.
Bir kod tabanından okunacak cocoIndex akışını tanımlayalım ve bunu RAG için indeksleyelim.
Yukarıdaki akış şeması kod tabanımızı nasıl işleyeceğimizi göstermektedir:
Bu akışı adım adım uygulayalım.
@cocoindex.flow_def(name="CodeEmbedding") def code_embedding_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope): """ Define an example flow that embeds files into a vector database. """ data_scope["files"] = flow_builder.add_source( cocoindex.sources.LocalFile(path="../..", included_patterns=["*.py", "*.rs", "*.toml", "*.md", "*.mdx"], excluded_patterns=[".*", "target", "**/node_modules"])) code_embeddings = data_scope.add_collector()
Bu örnekte, cocoindex kod tabanını kök dizinden dizine ekleyeceğiz. Dizine eklemek istediğiniz kod tabanına giden yolu değiştirebilirsiniz. .py
, .rs
, .toml
, .md
, .mdx
uzantılı tüm dosyaları dizine ekleyeceğiz ve ., target (kökte) ve node_modules (herhangi bir dizin altında) ile başlayan dizinleri atlayacağız.
flow_builder.add_source
aşağıdaki alt alanlara sahip bir tablo oluşturacaktır; buradaki belgelere bakın.
filename
(anahtar, tür: str
): dosyanın adı, örneğin dir1/file1.md
content
(tür: binary
False
ise str
, aksi takdirde bytes
): dosyanın içeriğiÖncelikle her dosyayı işlerken bir dosya adının uzantısını çıkarmak için bir fonksiyon tanımlayalım. Özel fonksiyon için dokümantasyonu burada bulabilirsiniz.
@cocoindex.op.function() def extract_extension(filename: str) -> str: """Extract the extension of a filename.""" return os.path.splitext(filename)[1]
Daha sonra her dosyayı işleyip, bilgilerini toplayacağız.
# ... with data_scope["files"].row() as file: file["extension"] = file["filename"].transform(extract_extension)
Burada dosya adının uzantısını çıkarıp extension
alanına kaydediyoruz. Örneğin, dosya adı spec.rs
ise extension
alanı .rs
olacaktır.
Sonra, dosyayı parçalara böleceğiz. Dosyayı parçalara bölmek için SplitRecursively
işlevini kullanırız. İşlevin belgelerini burada bulabilirsiniz.
CocoIndex, Tree-sitter için yerleşik destek sağlar, böylece dili language
parametresine geçirebilirsiniz. Desteklenen tüm dil adlarını ve uzantılarını görmek için buradaki belgelere bakın. Tüm önemli diller desteklenir, örneğin Python, Rust, JavaScript, TypeScript, Java, C++, vb. Belirtilmemişse veya belirtilen dil desteklenmiyorsa, düz metin olarak ele alınacaktır.
with data_scope["files"].row() as file: # ... file["chunks"] = file["content"].transform( cocoindex.functions.SplitRecursively(), language=file["extension"], chunk_size=1000, chunk_overlap=300)
Parçaları yerleştirmek için SentenceTransformerEmbed
işlevini kullanacağız. İşlevin belgelerini burada bulabilirsiniz. 🤗 Hugging Face tarafından desteklenen 12 bin model var. Sadece favori modelinizi seçebilirsiniz.
def code_to_embedding(text: cocoindex.DataSlice) -> cocoindex.DataSlice: """ Embed the text using a SentenceTransformer model. """ return text.transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2"))
Daha sonra her bir parçayı code_to_embedding
fonksiyonunu kullanarak gömeceğiz ve gömdüklerimizi code_embeddings
toplayıcısına toplayacağız.
Doğrudan transform(cocoindex.functions.SentenceTransformerEmbed(...))'i yerinde çağırmak yerine bu code_to_embedding fonksiyonunu çıkarıyoruz.
Bunun nedeni, bunu dizinleme akışı oluşturma ve sorgu işleyicisi tanımı arasında paylaşmak istememizdir. Alternatif olarak, daha basit hale getirmek için. Bu ekstra işlevi atlamak ve işleri doğrudan yerinde yapmak da sorun değil - biraz kopyalayıp yapıştırmak büyük bir sorun değil, bunu hızlı başlangıç projesi için yaptık.
with data_scope["files"].row() as file: # ... with file["chunks"].row() as chunk: chunk["embedding"] = chunk["text"].call(code_to_embedding) code_embeddings.collect(filename=file["filename"], location=chunk["location"], code=chunk["text"], embedding=chunk["embedding"])
Son olarak gömülü verileri bir tabloya aktaralım.
code_embeddings.export( "code_embeddings", cocoindex.storages.Postgres(), primary_key_fields=["filename", "location"], vector_index=[("embedding", cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY)])
Dizin sorgulamak için SimpleSemanticsQueryHandler
kullanacağız. query_transform_flow
parametresine code_to_embedding
işlevini geçirmemiz gerektiğini unutmayın. Bunun nedeni, sorgu işleyicisinin akışta kullanılanla aynı yerleştirme modelini kullanacak olmasıdır.
query_handler = cocoindex.query.SimpleSemanticsQueryHandler( name="SemanticsSearch", flow=code_embedding_flow, target_name="code_embeddings", query_transform_flow=code_to_embedding, default_similarity_metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY)
Sorgu işleyicisini çalıştırmak için bir ana fonksiyon tanımlayın.
@cocoindex.main_fn() def _run(): # Run queries in a loop to demonstrate the query capabilities. while True: try: query = input("Enter search query (or Enter to quit): ") if query == '': break results, _ = query_handler.search(query, 10) print("\nSearch results:") for result in results: print(f"[{result.score:.3f}] {result.data['filename']}") print(f" {result.data['code']}") print("---") print() except KeyboardInterrupt: break if __name__ == "__main__": load_dotenv(override=True) _run()
@cocoindex.main_fn() dekoratörü, ortam değişkenlerinden yüklenen ayarlarla kitaplığı başlatır. Daha fazla ayrıntı için başlatma belgelerine bakın.
🎉 Artık hazırsınız!
Dizin kurulumu ve güncellemesi için aşağıdaki komutları çalıştırın.
python main.py cocoindex setup python main.py cocoindex update
Terminalde dizin güncelleme durumunu göreceksiniz
Sorguyu test edin
Bu noktada cocoindex sunucusunu başlatabilir ve verilere karşı RAG çalışma zamanınızı geliştirebilirsiniz.
Endeksinizi test etmek için iki seçeneğiniz var:
python main.py
İstemi gördüğünüzde arama sorgunuzu girebilirsiniz. Örneğin: spec.
Enter search query (or Enter to quit): spec
Arama sonuçlarını terminalde bulabilirsiniz
Döndürülen sonuçlar - her giriş, puan (Kosinüs Benzerliği), dosya adı ve eşleşen kod parçacığını içerir. cocoindex'te, sorgu ile dizinlenmiş veriler arasındaki benzerliği ölçmek için cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY
kullanırız. Siz de diğer metriklere geçebilir ve hızlıca test edebilirsiniz.
Konsinüs Benzerliği hakkında daha fazla bilgi edinmek için Wiki'ye bakın.
Seçenek 2: Veri hattınızı ve veri dizininizi anlamak için CocoInsight'ı çalıştırın
CocoInsight, veri hattınızı ve veri dizininizi anlamanıza yardımcı olan bir araçtır. Yerel CocoIndex sunucunuza sıfır veri saklama ile bağlanır.
CocoInsight artık Erken Erişimde (Ücretsiz) 😊 Bizi buldunuz! CocoInsight hakkında kısa 3 dakikalık bir video eğitimi: YouTube'da izleyin .
python main.py cocoindex server -c https://cocoindex.io
Sunucu çalışmaya başladıktan sonra tarayıcınızda CocoInsight'ı açın. Yerel CocoIndex sunucunuza bağlanıp veri hattınızı ve dizininizi keşfedebileceksiniz.
Sağ tarafta tanımladığımız veri akışını görebilirsiniz.
Sol tarafta veri önizlemesindeki veri indeksini görebilirsiniz.
Kod parçalarının tam içeriği ve bunların gömülmüş halleri de dahil olmak üzere, söz konusu veri girişinin ayrıntılarını görmek için herhangi bir satıra tıklayabilirsiniz.
Topluluktan haber almayı seviyoruz! Bizi Github ve Discord'da bulabilirsiniz.
Bu yazıyı ve çalışmalarımızı beğendiyseniz lütfen CocoIndex'i Github'da bir yıldızla destekleyin ⭐. Sıcak bir hindistan cevizi sarılmasıyla teşekkür ederim 🥥🤗.