paint-brush
Dëshironi që AI ta kuptojë realisht kodin tuaj? Ky mjet thotë se mund të ndihmojënga@badmonster0
Histori e re

Dëshironi që AI ta kuptojë realisht kodin tuaj? Ky mjet thotë se mund të ndihmojë

nga LJ8m2025/03/21
Read on Terminal Reader

Shume gjate; Te lexosh

Udhëzues hap pas hapi për bazën e kodeve të indeksit për RAG me CocoIndex dhe Tree-sitter: copëzimi, ngulitja, kërkimi semantik dhe ndërtimi i indeksit të vektorit për rikthim efikas.
featured image - Dëshironi që AI ta kuptojë realisht kodin tuaj? Ky mjet thotë se mund të ndihmojë
LJ HackerNoon profile picture
0-item

Në këtë blog, ne do t'ju tregojmë se si të indeksoni bazën e kodeve për RAG me CocoIndex. CocoIndex është një mjet për t'ju ndihmuar të indeksoni dhe kërkoni të dhënat tuaja. Është projektuar për t'u përdorur si një kornizë për të ndërtuar tubacionin tuaj të të dhënave. CocoIndex ofron mbështetje të integruar për copëzimin e bazës së kodit, me mbështetjen e brendshme të Tree-sitter.

Mbajtës pemësh

Tree-sitter është një mjet gjenerues analizues dhe një bibliotekë analizuese në rritje, është e disponueshme në Rust 🦀 - GitHub . CocoIndex ka integrimin e integruar Rust me Tree-sitter për të analizuar në mënyrë efikase kodin dhe nxjerrjen e pemëve sintaksore për gjuhë të ndryshme programimi.


Copëtimi i bazës së kodit është procesi i zbërthimit të një baze kodi në copa më të vogla, kuptimplote semantike. CocoIndex shfrytëzon aftësitë e kujdestarit të pemëve për të copëtuar në mënyrë inteligjente kodin bazuar në strukturën aktuale të sintaksës dhe jo në prishjet arbitrare të rreshtave. Këto pjesë semantike koherente përdoren më pas për të ndërtuar një indeks më efektiv për sistemet RAG, duke mundësuar rikthim më të saktë të kodit dhe ruajtjen më të mirë të kontekstit.


Fast pass 🚀 - kodin e plotë mund ta gjeni këtu . Vetëm ~ 50 rreshta kodi Python për tubacionin RAG, shikoni 🤗!

Ju lutemi jepni CocoIndex në Github një yll për të na mbështetur nëse ju pëlqen puna jonë. Faleminderit shumë me një përqafim të ngrohtë kokosi 🥥🤗.

Parakushtet

Nëse nuk keni të instaluar Postgres, ju lutemi referojuni udhëzuesit të instalimit . CocoIndex përdor Postgres për të menaxhuar indeksin e të dhënave, ne e kemi atë në udhërrëfyesin tonë për të mbështetur bazat e të dhënave të tjera, duke përfshirë ato në zhvillim. Nëse jeni të interesuar për baza të tjera të dhënash, ju lutemi na njoftoni duke krijuar një problem GitHub ose Discord .

Përcaktoni rrjedhën e cocoIndex

Le të përcaktojmë rrjedhën e cocoIndex për të lexuar nga një bazë kodi dhe ta indeksojmë atë për RAG.

Rrjedha e CocoIndex për futjen e kodit


Diagrami i rrjedhës së mësipërme ilustron se si do të përpunojmë bazën tonë të kodit:

  1. Lexoni skedarët e kodit nga sistemi i skedarëve lokal
  2. Ekstraktoni shtesat e skedarëve
  3. Ndani kodin në copa semantike duke përdorur Tree-sitter
  4. Gjeneroni ngulitje për secilën pjesë
  5. Ruani në një bazë të dhënash vektoriale për rikthim


Le ta zbatojmë këtë rrjedhë hap pas hapi.

1. Shtoni bazën e kodeve si burim

 @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()

Në këtë shembull, ne do të indeksojmë bazën e kodit të cocoindex nga direktoria rrënjësore. Ju mund të ndryshoni shtegun për në bazën e kodeve që dëshironi të indeksoni. Ne do të indeksojmë të gjithë skedarët me shtesat e .py , .rs , .toml , .md , .mdx dhe do të kapërcejmë direktoritë duke filluar me ., target (në rrënjë) dhe node_modules (nën çdo direktori).

flow_builder.add_source do të krijojë një tabelë me nënfushat e mëposhtme, shikoni dokumentacionin këtu.

  • filename (çelësi, lloji: str ): emri i skedarit, p.sh. dir1/file1.md
  • content (lloji: str nëse binary është False , përndryshe bytes ): përmbajtja e skedarit

2. Përpunoni çdo skedar dhe mblidhni informacionin

2.1 Ekstraktoni zgjerimin e emrit tëskedarit

Së pari, le të përcaktojmë një funksion për të nxjerrë zgjerimin e emrit të skedarit gjatë përpunimit të secilit skedar. Dokumentacionin për funksionin personal mund ta gjeni këtu .

 @cocoindex.op.function() def extract_extension(filename: str) -> str: """Extract the extension of a filename.""" return os.path.splitext(filename)[1]


Pastaj ne do të përpunojmë çdo skedar dhe do të mbledhim informacionin.

 # ... with data_scope["files"].row() as file: file["extension"] = file["filename"].transform(extract_extension)


Këtu nxjerrim shtesën e emrit të skedarit dhe e ruajmë atë në fushën extension . për shembull, nëse emri i skedarit është spec.rs , fusha extension do të jetë .rs .

2.2 Ndani skedarin në copa

Më pas, ne do ta ndajmë skedarin në copa. Ne përdorim funksionin SplitRecursively për të ndarë skedarin në copa. Dokumentacionin për funksionin mund ta gjeni këtu .


CocoIndex ofron mbështetje të integruar për Tree-sitter, kështu që ju mund të kaloni në gjuhën në parametrin e language . Për të parë të gjithë emrat dhe shtesat e gjuhëve të mbështetura, shihni dokumentacionin këtu . Mbështeten të gjitha gjuhët kryesore, p.sh. Python, Rust, JavaScript, TypeScript, Java, C++, etj. Nëse është e paspecifikuar ose gjuha e specifikuar nuk mbështetet, do të trajtohet si tekst i thjeshtë.


 with data_scope["files"].row() as file: # ... file["chunks"] = file["content"].transform( cocoindex.functions.SplitRecursively(), language=file["extension"], chunk_size=1000, chunk_overlap=300)

2.3 Vendosni pjesët

Ne do të përdorim funksionin SentenceTransformerEmbed për të futur pjesët. Dokumentacionin për funksionin mund ta gjeni këtu . Janë 12 mijë modele të mbështetura nga 🤗 Hugging Face . Ju thjesht mund të zgjidhni modelin tuaj të preferuar.

 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"))


Më pas për secilën pjesë, ne do ta ngulitim duke përdorur funksionin code_to_embedding . dhe mblidhni embeddings në koleksionist code_embeddings .


Ne e nxjerrim këtë funksion code_to_embedding në vend që të thërrasim drejtpërdrejt transform(cocoindex.functions.SentenceTransformerEmbed(...)) në vend.


Kjo është për shkak se ne duam ta bëjmë këtë të përbashkët midis ndërtimit të rrjedhës së indeksimit dhe përkufizimit të mbajtësit të pyetjeve. Përndryshe, për ta bërë më të thjeshtë. Është gjithashtu në rregull të shmangni këtë funksion shtesë dhe t'i bëni gjërat drejtpërdrejt në vend - nuk është e rëndësishme të kopjoni pak ngjitjen, ne e bëmë këtë për projektin e fillimit të shpejtë .


 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"])

2.4 Mblidhni ngulitje

Së fundi, le të eksportojmë ngulitje në një tabelë.

 code_embeddings.export( "code_embeddings", cocoindex.storages.Postgres(), primary_key_fields=["filename", "location"], vector_index=[("embedding", cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY)])

3. Konfiguroni mbajtësin e pyetjeve për indeksin tuaj

Ne do të përdorim SimpleSemanticsQueryHandler për të kërkuar indeksin. Vini re se ne duhet të kalojmë në funksionin code_to_embedding në parametrin query_transform_flow . Kjo është për shkak se trajtuesi i pyetjeve do të përdorë të njëjtin model ngulitjeje si ai i përdorur në rrjedhën.

 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)


Përcaktoni një funksion kryesor për të ekzekutuar trajtuesin e pyetjeve.

 @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()


Dekoratori @cocoindex.main_fn() inicializon bibliotekën me cilësimet e ngarkuara nga variablat e mjedisit. Shikoni dokumentacionin për inicializimin për më shumë detaje.

Ekzekutoni konfigurimin dhe përditësimin e indeksit

🎉 Tani jeni gati!

Ekzekutoni komandat e mëposhtme për të konfiguruar dhe përditësuar indeksin.

 python main.py cocoindex setup python main.py cocoindex update


Do të shihni gjendjen e përditësimeve të indeksit në terminal

Terminali që tregon procesin e përditësimit të indeksit


Testoni pyetjen


Në këtë pikë, mund të nisni serverin cocoindex dhe të zhvilloni kohën tuaj të funksionimit RAG kundrejt të dhënave.


Për të testuar indeksin tuaj, ekzistojnë dy opsione:

Opsioni 1: Ekzekutoni serverin e indeksit në terminal

 python main.py


Kur të shihni kërkesën, mund të shkruani pyetjen tuaj të kërkimit. për shembull: spec.

 Enter search query (or Enter to quit): spec


Rezultatet e kërkimit mund t'i gjeni në terminal

Rezultatet e kërkimit në terminal


Rezultatet e kthyera - çdo hyrje përmban pikë (ngjashmëria e kosinusit), emri i skedarit dhe copëza e kodit që përputhen. Në cocoindex, ne përdorim cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY për të matur ngjashmërinë midis pyetjes dhe të dhënave të indeksuara. Mund të kaloni edhe në metrika të tjera dhe ta provoni shpejt.


Për të mësuar më shumë rreth Ngjashmërisë Consine, shihni Wiki .


Opsioni 2: Drejtoni CocoInsight për të kuptuar tubacionin tuaj të të dhënave dhe indeksin e të dhënave


CocoInsight është një mjet për t'ju ndihmuar të kuptoni tubacionin tuaj të të dhënave dhe indeksin e të dhënave. Ai lidhet me serverin tuaj lokal CocoIndex me mbajtje zero të të dhënave.


CocoInsight është në akses të hershëm tani (falas) 😊 Na gjetët! Një video tutorial i shpejtë 3-minutësh rreth CocoInsight: Shikoni në YouTube .

Drejtoni serverin CocoIndex

 python main.py cocoindex server -c https://cocoindex.io


Pasi serveri të funksionojë, hapni CocoInsight në shfletuesin tuaj. Ju do të jeni në gjendje të lidheni me serverin tuaj lokal CocoIndex dhe të eksploroni tubacionin dhe indeksin tuaj të të dhënave.

Ndërfaqja e përdoruesit të CocoInsight që tregon eksplorimin e të dhënave


Në anën e djathtë, ju mund të shihni rrjedhën e të dhënave që përcaktuam.


Në anën e majtë, mund të shihni indeksin e të dhënave në pamjen paraprake të të dhënave.

Pamja paraprake e të dhënave të CocoInsight që tregon pjesë të kodit të indeksuar

Ju mund të klikoni në çdo rresht për të parë detajet e asaj hyrjeje të të dhënave, duke përfshirë përmbajtjen e plotë të copave të kodit dhe futjet e tyre.

Komuniteti

Na pëlqen të dëgjojmë nga komuniteti! Mund të na gjeni në Github dhe Discord .


Nëse ju pëlqen ky postim dhe puna jonë, ju lutemi mbështesni CocoIndex në Github me një yll ⭐. Faleminderit me një përqafim të ngrohtë kokosi 🥥🤗.