Pernahkah anda mendapati sukar untuk memahami asas kod yang besar dan berantakan? Atau tertanya -tanya bagaimana alat yang menganalisis dan meneroka kod sebenarnya berfungsi? Dalam artikel ini, kami akan menyelesaikan masalah ini dengan membina alat penerokaan codebase yang kuat dari awal. Menggunakan analisis kod statik dan model Gemini, kami akan membuat sistem yang mudah digunakan yang membantu pemaju pertanyaan, memahami, dan mendapatkan pandangan berguna dari kod mereka. Bersedia untuk menukar cara anda menavigasi kod? Mari kita mulakan!
Jadual Kandungan Keperluan untuk Eksplorasi Kod Smarter
Gambaran keseluruhan seni binaBahagian ini akan membimbing anda melalui langkah -langkah awal untuk membina dan melaksanakan projek anda, memastikan pengalaman pembelajaran permulaan dan berkesan yang lancar.
Struktur folder projek akan sama dengan
ini|--codebase_explorer/ |src/ ├──| __init__.py ├──| indexer/ │ ├── __init__.py │ └── code_parser.py ├──| query_engine/ │ ├── __init__.py │ ├── query_processor.py │ └── gemini_client.py | ├── main.py └── .env
Persekitaran Projek Persediaan Dalam langkah berikut:
#create a new conda env conda create -n cb_explorer python=3.11 conda activate cb_explorer
Pasang semua perpustakaan yang diperlukan:
pip install google-generativeai google-ai-generativelanguage pip install python-dotenv typer llama-index
kita akan bermula dengan memahami dan melaksanakan sistem parsing codebase. Ia mempunyai dua fungsi penting
Mengekstrak definisi dari pokok sintaks abstrak:
import ast import os from typing import Dict, Any def extract_definitions(tree: ast.AST) -> Dict[str, list]: """Extract class and function definitions from AST.""" definitions = { "classes": [], "functions": [], "imports": [] } for node in ast.walk(tree): if isinstance(node, ast.ClassDef): definitions["classes"].append({ "name": node.name, "lineno": node.lineno }) elif isinstance(node, ast.FunctionDef): definitions["functions"].append({ "name": node.name, "lineno": node.lineno }) elif isinstance(node, ast.Import): for name in node.names: definitions["imports"].append(name.name) return definitions
Ini adalah fungsi penolong untuk parse_codebase (). Ia akan mengambil pokok sintaks abstrak (AST) dari fail python. Fungsi ini memulakan kamus dengan senarai kosong untuk kelas, fungsi, dan import. Sekarang, ast.walk () melangkah melalui semua nod di pokok AST. Modul AST akan mengenal pasti semua kelas, fungsi, import, dan nombor garis. Kemudian masukkan semua definisi ke kamus definisi.
Fungsi ini mengimbas direktori untuk fail python, membaca kandungan mereka, dan mengekstrak struktur mereka.
import ast import os from typing import Dict, Any def parse_codebase(directory: str) -> Dict[str, Any]: """Parse Python files in the directory and extract code structure.""" code_structure = {} for root, _, files in os.walk(directory): for file in files: if file.endswith(".py"): file_path = os.path.join(root, file) with open(file_path, "r", encoding="utf-8") as f: try: content = f.read() tree = ast.parse(content) code_structure[file_path] = { "definitions": extract_definitions(tree), "content": content } except Exception as e: print(f"Error parsing {file_path}: {e}") return code_structure
Fungsi memulakan dengan laluan direktori sebagai rentetan. Ia mengeluarkan kamus struktur kod. Kamus menyimpan data yang diekstrak untuk setiap fail python.
Ia melepasi semua subdirektori dan fail dalam direktori yang diberikan. os.walk () menyediakan cara rekursif untuk meneroka seluruh pokok direktori. Ia akan memproses fail yang mengakhiri sambungan .py.
menggunakan modul Python Ast untuk menghuraikan kandungan fail ke dalam pokok sintaks abstrak (AST), yang mewakili struktur fail. Pokok yang diekstrak kemudian diluluskan ke extract_definitions (pokok) . Jika parsing gagal, ia mencetak mesej ralat tetapi terus memproses fail lain.
dalam direktori enjin pertanyaan buat dua fail bernama Gemini_Client.PY dan query_processor.py
Fail ini akan menggunakan & lt; Google_API_KEY & gt; untuk mengesahkan API Model Gemini dari Google. Dalam akar projek, buat fail .env dan letakkan kunci API Gemini anda di dalamnya. Dapatkan API_Keyhere anda.
|--codebase_explorer/ |src/ ├──| __init__.py ├──| indexer/ │ ├── __init__.py │ └── code_parser.py ├──| query_engine/ │ ├── __init__.py │ ├── query_processor.py │ └── gemini_client.py | ├── main.py └── .env
di sini, kami menentukan kelas Geminiclient untuk berinteraksi dengan model Gemini AI Google. Ia akan mengesahkan model menggunakan Google_API_KEY dari fail .env anda. Selepas mengkonfigurasi API Model, ia menyediakan kaedah pertanyaan untuk menghasilkan respons pada prompt yang diberikan.
Di bahagian ini, kami akan melaksanakan kelas QueryProcessor untuk menguruskan konteks codebase dan membolehkan pertanyaan dengan Gemini.
#create a new conda env conda create -n cb_explorer python=3.11 conda activate cb_explorer
selepas memuatkan perpustakaan yang diperlukan, load_dotenv () memuatkan pembolehubah persekitaran dari. Kelas Geminiembedding memulakan model embedding-001 dari pelayan Google. Kelas QueryProcessor direka untuk mengendalikan konteks codebase dan berinteraksi dengan geminiclient.loading_contextmethod memuatkan maklumat codebase dari fail JSON yang ada. Thesaving_contextMethod menyimpan konteks codebase semasa ke dalam fail json untuk ketekunan. Meminta Geminiis Kaedah yang paling penting yang akan membina prompt menggunakan konteks codebase dan pertanyaan pengguna. Ia menghantar petunjuk ini kepada model Gemini melalui Geminiclient dan mendapat sambutan semula.
dan objek pemproses pertanyaan dari kelas.
pip install google-generativeai google-ai-generativelanguage pip install python-dotenv typer llama-index
akan digunakan sebagai arahan di terminal, dan fungsi akan mengindeks codebase python dalam direktori yang ditentukan untuk pertanyaan dan analisis masa depan. |--codebase_explorer/
|src/
├──| __init__.py
├──| indexer/
│ ├── __init__.py
│ └── code_parser.py
├──| query_engine/
│ ├── __init__.py
│ ├── query_processor.py
│ └── gemini_client.py
|
├── main.py
└── .env
Ia akan mula -mula memeriksa sama ada direktori dan kemudian gunakan fungsi parse_codebase untuk mengekstrak struktur fail python dalam direktori.
selepas parsing ia akan menyelamatkan struktur codebase parsed dalam query_processor . Semua proses dalam percubaan dan kecuali blok supaya pengecualian dapat ditangani dengan berhati -hati semasa parsing. Ia akan menyediakan asas kod untuk pertanyaan yang cekap menggunakan model Gemini.
selepas pengindeksan kita dapat menanyakan asas kod untuk memahami atau mendapatkan maklumat mengenai sebarang fungsi dalam pangkalan kod.
#create a new conda env conda create -n cb_explorer python=3.11 conda activate cb_explorer
Pertama, periksa sama ada query_processor telah memuatkan konteks codebase atau tidak dan cuba memuatkan konteks dari cakera keras komputer. dan kemudian menggunakan kaedah pertanyaan query_processor untuk memproses pertanyaan.
dan yang terakhir, ia akan mencetak respons dari LLM ke terminal menggunakan typer.echo () kaedah.
pip install google-generativeai google-ai-generativelanguage pip install python-dotenv typer llama-index
untuk menguji kerja keras anda ikuti langkah -langkah di bawah:
import ast import os from typing import Dict, Any def extract_definitions(tree: ast.AST) -> Dict[str, list]: """Extract class and function definitions from AST.""" definitions = { "classes": [], "functions": [], "imports": [] } for node in ast.walk(tree): if isinstance(node, ast.ClassDef): definitions["classes"].append({ "name": node.name, "lineno": node.lineno }) elif isinstance(node, ast.FunctionDef): definitions["functions"].append({ "name": node.name, "lineno": node.lineno }) elif isinstance(node, ast.Import): for name in node.names: definitions["imports"].append(name.name) return definitions
Fail ini akan menemui palindrome dari rentetan yang diberikan. Kami akan mengindeks pertanyaan fail ini dari terminal menggunakan aplikasi CLI.
Sekarang, buka terminal anda, tampal kod dan lihat sihir.
Mengindeks Projek
import ast import os from typing import Dict, Any def parse_codebase(directory: str) -> Dict[str, Any]: """Parse Python files in the directory and extract code structure.""" code_structure = {} for root, _, files in os.walk(directory): for file in files: if file.endswith(".py"): file_path = os.path.join(root, file) with open(file_path, "r", encoding="utf-8") as f: try: content = f.read() tree = ast.parse(content) code_structure[file_path] = { "definitions": extract_definitions(tree), "content": content } except Exception as e: print(f"Error parsing {file_path}: {e}") return code_structure
output:
import os from typing import Optional from google import generativeai as genai from dotenv import load_dotenv load_dotenv() class GeminiClient: def __init__(self): self.api_key = os.getenv("GOOGLE_API_KEY") if not self.api_key: raise ValueError("GOOGLE_API_KEY environment variable is not set") genai.configure(api_key=self.api_key) self.model = genai.GenerativeModel("gemini-1.5-flash") def query(self, prompt: str) -> Optional[str]: """Query Gemini with the given prompt.""" try: response = self.model.generate_content(prompt) return response.text except Exception as e: print(f"Error querying Gemini: {e}") return None
menanyakan projek
import os import json from llama_index.embeddings.gemini import GeminiEmbedding from dotenv import load_dotenv from typing import Dict, Any, Optional from .gemini_client import GeminiClient load_dotenv() gemini_api_key = os.getenv("GOOGLE_API_KEY") model_name = "models/embeddings-001" embed_model = GeminiEmbedding(model_name=model_name, api_key=gemini_api_key) class QueryProcessor: def __init__(self): self.gemini_client = GeminiClient() self.codebase_context: Optional[Dict[str, Any]] = None self.index_file = "./indexes/codebase_index.json" def load_context(self): """Load the codebase context from disk if it exists.""" if os.path.exists(self.index_file): try: with open(self.index_file, "r", encoding="utf-8") as f: self.codebase_context = json.load(f) except Exception as e: print(f"Error loading index: {e}") self.codebase_context = None def save_context(self): """Save the codebase context to disk.""" if self.codebase_context: try: with open(self.index_file, "w", encoding="utf-8") as f: json.dump(self.codebase_context, f, indent=2) except Exception as e: print(f"Error saving index: {e}") def set_context(self, context: Dict[str, Any]): """Set the codebase context for queries.""" self.codebase_context = context self.save_context() def format_context(self) -> str: """Format the codebase context for Gemini.""" if not self.codebase_context: return "" context_parts = [] for file_path, details in self.codebase_context.items(): defs = details["definitions"] context_parts.append( f"File: {file_path}\n" f"Classes: {[c['name'] for c in defs['classes']]}\n" f"Functions: {[f['name'] for f in defs['functions']]}\n" f"Imports: {defs['imports']}\n" ) return "\n\n".join(context_parts) def query(self, query: str) -> Optional[str]: """Process a query about the codebase.""" if not self.codebase_context: return ( "Error: No codebase context available. Please index the codebase first." ) prompt = f""" Given the following codebase structure: {self.format_context()} Query: {query} Please provide a detailed and accurate answer based on the codebase structure above. """ return self.gemini_client.query(prompt)
import os import json import typer from pathlib import Path from typing import Optional from indexer.code_parser import parse_codebase from query_engine.query_processor import QueryProcessor
Jika semuanya dilakukan dengan betul, anda akan mendapat output ini di terminal anda. Anda boleh mencubanya dengan fail kod python anda dan beritahu saya di bahagian komen apakah output anda. Terima kasih kerana tinggal bersama saya.
Ini adalah prototaip sistem asas yang boleh diperluaskan dengan banyak ciri menarik, seperti
CodeBase Explorer membantu anda memahami aplikasi praktikal AI dalam alat pembangunan perisian. Dengan menggabungkan analisis statik tradisional dengan keupayaan AI moden, kami telah mencipta alat yang menjadikan eksplorasi codebase lebih intuitif dan cekap. Pendekatan ini menunjukkan bagaimana AI boleh menambah aliran kerja pemaju tanpa menggantikan alat yang sedia ada, menyediakan lapisan pemahaman dan akses yang baru kepada kod kompleks.
Semua kod yang digunakan dalam artikel ini ada di sini.
Media yang ditunjukkan dalam artikel ini tidak dimiliki oleh Analytics Vidhya dan digunakan pada budi bicara penulis.
Atas ialah kandungan terperinci Membina Explorer CodeBase dengan Google ' s Gemini-2.0. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!