Maison > Périphériques technologiques > IA > Construire un explorateur de base de code avec Google GEMINI-2.0

Construire un explorateur de base de code avec Google GEMINI-2.0

William Shakespeare
Libérer: 2025-03-08 11:30:15
original
889 Les gens l'ont consulté

Avez-vous déjà eu du mal à comprendre une grande base de code désordonnée? Ou vous vous êtes demandé comment les outils qui analysent et explorent le code fonctionnent réellement? Dans cet article, nous résoudrons ces problèmes en construisant un puissant outil d'exploration de base de code à partir de zéro. En utilisant l'analyse de code statique et le modèle Gemini, nous créerons un système facile à utiliser qui aide les développeurs à interroger, à comprendre et à obtenir des informations utiles à partir de leur code. Prêt à changer la façon dont vous naviguez par code? Commençons!

Objectifs d'apprentissage

  • Développement de logiciels complexes à l'aide de la programmation orientée objet.
  • Comment analyser et analyser la base de code Python à l'aide de l'AST ou de l'arbre de syntaxe abstrait.
  • Comprendre comment intégrer l'API Gemini LLM de Google à l'application Python de l'analyse du code.
  • Système de requête basé sur la ligne de commande Typer pour l'exploration de la base de code.

Cet article a été publié dans le cadre du Data Science Blogathon.

Table des matières

  • Le besoin d'exploration de code plus intelligente
  • Présentation de l'architecture
  • Implémentation du code pratique
  • Environnement du projet
  • Implémentation du code
  • Le moteur de traitement de la commande
  • Implémentation (CLI)
  • Testez l'application
  • Développement futur
  • Conclusion
  • Questions fréquemment posées
  • Le besoin d'exploration de code plus intelligente

Tout d'abord, la création d'une telle application vous donne un coup de pouce d'apprentissage dans le développement de logiciels, il vous aidera à apprendre à mettre en œuvre des logiciels complexes à l'aide du paradigme de programmation orienté objet et vous aidera également à maîtriser l'art de gérer de grands projets (bien qu'il ne soit pas si grand)

Deuxièmement, les projets logiciels d'aujourd'hui se composent de milliers de lignes de code écrites dans de nombreux fichiers et dossiers. Approches traditionnelles de l'exploration du code, telles que la fonction de recherche Grep ou IDE. Ce type de système échouera lorsque les développeurs doivent comprendre les concepts ou les relations de niveau supérieur dans la base de code. Nos outils alimentés par l'IA peuvent faire une foulée significative dans ce domaine. Notre application permet aux développeurs de poser des questions sur leur base de code en anglais simple et de recevoir des réponses contextuelles détaillées.

Aperçu de l'architecture

L'outil se compose de quatre composants principaux

  • Parser de code: C'est le fondement de notre système, qui est responsable de l'analyse des fichiers Python et de l'extraction de leur structure à l'aide du module ASTAX Tree (AST) de Python. Il identifie les classes, les méthodes, les fonctions et les importations. Il créera une carte complète de la base de code.
  • Client Gemini: un emballage autour de l'API Gemini de Google qui gère la communication avec le modèle LLM. Ces composants gèrent l'authentification de l'API et fournissent une interface propre pour envoyer des requêtes et recevoir des réponses.
  • Processeur de requête: C'est le moteur principal de l'outil qui est responsable de la mise en forme du contexte et des requêtes de base de code d'une manière que les Gémeaux peuvent comprendre et traiter efficacement. Il maintient un index persistant de la structure de base de code et gère l'interaction entre l'analyseur et le llm.
  • Interface CLI: Une interface de ligne de commande conviviale construite avec Typer, fournissant des commandes pour indexer la base de code, interroger la structure du code et analyser les traces de pile.

Démarrer le projet pratique

Cette section vous guidera à travers les étapes initiales pour construire et mettre en œuvre votre projet, assurant une expérience d'apprentissage en douceur et un apprentissage efficace.

Structure du dossier du projet

La structure du dossier du projet sera similaire à celles

|--codebase_explorer/
|src/
├──| __init__.py
├──| indexer/
│   ├── __init__.py
│   └── code_parser.py
├──| query_engine/
│   ├── __init__.py
│   ├── query_processor.py
│   └── gemini_client.py
|
├── main.py
└── .env
Copier après la connexion
Copier après la connexion
Copier après la connexion

Configuration de l'environnement du projet

Configurer l'environnement du projet à l'étape suivante:

#create a new conda env
conda create -n cb_explorer python=3.11
conda activate cb_explorer
Copier après la connexion
Copier après la connexion
Copier après la connexion

Installez toutes les bibliothèques nécessaires:

pip install google-generativeai google-ai-generativelanguage
pip install python-dotenv typer llama-index
Copier après la connexion
Copier après la connexion
Copier après la connexion

Implémentation du code

Nous allons commencer par comprendre et implémenter le système d'analyse de base de code. Il a deux fonctions importantes

  • parse_codebase ()
  • extract_definitions ()

Extraction des définitions de l'arbre de syntaxe abstrait:

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
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il s'agit d'une fonction d'assistance pour parse_codebase (). Il faudra un arbre de syntaxe abstrait (AST) d'un fichier python. La fonction initie un dictionnaire avec des listes vides pour les classes, les fonctions et les importations. Maintenant, Ast.Walk () itère à travers tous les nœuds de l'arborescence AST. Le module AST identifiera toutes les classes, fonctions, importations et numéros de ligne. Puis ajoutez toutes les définitions au dictionnaire des définitions.

analyser la base de code

Cette fonction scanne un répertoire pour les fichiers Python, lit leur contenu et extrait leur structure.

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
Copier après la connexion
Copier après la connexion

Les fonctions lancent avec le chemin du répertoire en tant que chaîne. Il publie un dictionnaire des structures du code. Le dictionnaire stocke les données extraites pour chaque fichier python.

Il traverse toutes les sous-répertoires et les fichiers du répertoire donné. os.walk () a fourni un moyen récursif d'explorer l'ensemble de l'arborescence du répertoire. Il traitera les fichiers mettant en fin des extensions .py.

en utilisant le module Python AST pour analyser le contenu du fichier dans une arborescence de syntaxe abstraite (AST), qui représente la structure du fichier. L'arbre extrait est ensuite transmis aux Extract_Definitions (arbre) . Si l'analyse échoue, il imprime un message d'erreur mais continue de traiter d'autres fichiers.

Moteur de traitement des requêtes

Dans le répertoire du moteur de requête, créez deux fichiers nommés gemini_client.py et query_processor.py

Client Gemini

Ce fichier utilisera & lt; google_api_key & gt; pour authentifier l'API du modèle Gemini de Google. Dans la racine du projet, créez un fichier .env et y mettez votre clé API Gemini. Obtenez votre api_keyhere.

|--codebase_explorer/
|src/
├──| __init__.py
├──| indexer/
│   ├── __init__.py
│   └── code_parser.py
├──| query_engine/
│   ├── __init__.py
│   ├── query_processor.py
│   └── gemini_client.py
|
├── main.py
└── .env
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ici, nous définissons une classe geminiclient pour interagir avec le modèle Gemini AI de Google. Il authentifiera le modèle à l'aide de google_api_key à partir de votre fichier .env. Après avoir configuré l'API du modèle, il fournit une méthode de requête pour générer une réponse sur une invite donnée.

Système de gestion des requêtes

Dans cette section, nous implémenterons la classe QueryProcessor pour gérer le contexte de base de code et permettre la question avec les gemini.

#create a new conda env
conda create -n cb_explorer python=3.11
conda activate cb_explorer
Copier après la connexion
Copier après la connexion
Copier après la connexion

Après avoir chargé les bibliothèques nécessaires, load_dotenv () charge les variables d'environnement du fichier. Env qui contient notre google_api_key pour le gemini api clé.

  • La classe GEMINIEMBEDDING initialise les modèles Embedding-001 du serveur Google.
  • La classe QuerryProcessor est conçue pour gérer le contexte de base de code et interagir avec le geminiclient.loading_contextMethod charge les informations de base à partir d'un fichier json il existe.
  • thesaving_contextMethod enregistre le contexte actuel de base de code dans le fichier JSON pour persistance.save_contextMethod met à jour le contexte de base de code et l'enregistre immédiatement usingsave_context et theformat_contextMethod convertit les données de base de code en un format de chaîne lié à l'human
  • Interroger Geminiis La méthode la plus importante qui construira une invite en utilisant le contexte de base de code et la requête de l'utilisateur. Il envoie cette invite au modèle Gemini via la geminiclient et récupére la réponse.
Implémentation de l'application de ligne de commande (CLI)

Créez un fichier main.py dans le dossier SRC du projet et suivez les étapes

Étape 1: Importer les bibliothèques

pip install google-generativeai google-ai-generativelanguage
pip install python-dotenv typer llama-index
Copier après la connexion
Copier après la connexion
Copier après la connexion
Étape 2: Initialisez Typer et Processeur de requête

Créons un objet de processeur

typer et de requête à partir des classes.

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
Copier après la connexion
Copier après la connexion
Copier après la connexion
Étape 3: Indexation du répertoire du projet Python

Ici, la méthode

index sera utilisée comme commande dans le terminal, et la fonction indexera la base de code Python dans le répertoire spécifié pour la future requête et analyse.

|--codebase_explorer/
|src/
├──| __init__.py
├──| indexer/
│   ├── __init__.py
│   └── code_parser.py
├──| query_engine/
│   ├── __init__.py
│   ├── query_processor.py
│   └── gemini_client.py
|
├── main.py
└── .env
Copier après la connexion
Copier après la connexion
Copier après la connexion

Il vérifiera d'abord si le répertoire existe, puis utilise la fonction parse_codebase pour extraire la structure des fichiers python dans le répertoire.

Après l'analyse, il enregistrera la structure de base de code analysée dans query_processor . Tous les processus sont en essai et à l'exception du bloc afin que les exceptions puissent être gérées avec soin pendant l'analyse. Il préparera la base de code pour une interrogation efficace en utilisant le modèle Gemini.

Étape 4: Interroger la base de code

Après l'indexation, nous pouvons interroger la base de code pour comprendre ou obtenir des informations sur toutes les fonctions dans la base de code.

#create a new conda env
conda create -n cb_explorer python=3.11
conda activate cb_explorer
Copier après la connexion
Copier après la connexion
Copier après la connexion

Tout d'abord, vérifiez si le query_processor a chargé un contexte de base de code ou non et d'essayer de charger le contexte à partir du disque dur de l'ordinateur. puis utilise la méthode de requête query_processor pour traiter la requête.

Et le dernier, il imprimera la réponse du LLM au terminal en utilisant typer.echo () Méthode.

Étape 5: Exécutez l'application

pip install google-generativeai google-ai-generativelanguage
pip install python-dotenv typer llama-index
Copier après la connexion
Copier après la connexion
Copier après la connexion

Testez l'application

Pour tester votre travail acharné, suivez les étapes ci-dessous:

  • Créer un nom de dossier Index dans la racine de votre projet où nous allons mettre tous nos fichiers d'index.
  • Créez un codeBase_index.json et mettez-le dans le dossier créé précédemment (index).
  • Créez ensuite un dossier project_test dans la racine où nous stockons nos fichiers Python pour les tests
  • Créez un fichier find_palidrome.py dans le dossier project_test et mettez le code ci-dessous dans le fichier.

Implémentation du code

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
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ce fichier trouvera le palindrome à partir d'une chaîne donnée. Nous indexerons cette requête de fichier à partir du terminal à l'aide de l'application CLI.

Maintenant, ouvrez votre terminal, collez le code et voyez la magie.

Indexation du projet

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
Copier après la connexion
Copier après la connexion

Sortie:

Construire un explorateur de base de code avec Google GEMINI-2.0

Vous pouvez afficher avec succès 1 fichier Python indexé. Et les données JSON ressemblent à

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
Copier après la connexion

Interroger le projet

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)
Copier après la connexion

Sortie:

Construire un explorateur de base de code avec Google GEMINI-2.0

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
Copier après la connexion

Sortie:

Construire un explorateur de base de code avec Google GEMINI-2.0

Si tout est fait correctement, vous obtiendrez ces sorties dans votre terminal. Vous pouvez l'essayer avec vos fichiers de code Python et me dire dans la section des commentaires quelle est votre sortie. Merci de rester avec moi.

Développement futur

Il s'agit d'un prototype du système de fondation qui peut être étendu avec de nombreuses fonctionnalités intéressantes, telles que

  • Vous pouvez vous intégrer aux plugins IDE pour l'exploration de code sans couture.
  • Système de débogage automatisé dirigé par AI (je travaille là-dessus).
  • Ajout de la prise en charge de nombreuses langues populaires telles que JavaScript, Java, TypeScripts, Rust.
  • Analyse de code en temps réel et suggestions d'amélioration de LLM.
  • Documentation automatisée à l'aide de Gemini ou Llama3.
  • Intégration LLM locale pour l'exploration de code sur les appareils, ajout de caractéristiques.

Conclusion

L'explorateur de base de code vous aide à comprendre l'application pratique de l'IA dans les outils de développement de logiciels. En combinant une analyse statique traditionnelle avec des capacités d'IA modernes, nous avons créé un outil qui rend l'exploration de base de code plus intuitive et efficace. Cette approche montre comment l'IA peut augmenter les flux de travail des développeurs sans remplacer les outils existants, fournissant une nouvelle couche de compréhension et d'accessibilité aux bases de code complexes.

Tout le code utilisé dans cet article est ici.

Les plats clés

  • Structure L'analyse de code est la technique la plus imortante pour l'analyse du code.
  • Explorateur de base de code simplifie la navigation de code, permettant aux développeurs de comprendre et de gérer rapidement les structures de code complexes.
  • Explorateur de base de code améliore l'efficacité du débogage, offrant des outils pour analyser les dépendances et identifier les problèmes plus rapidement.
  • Les Gémeaux peuvent améliorer considérablement la compréhension du code lorsqu'ils sont combinés avec une analyse statique traditionnelle.
  • Les outils CLI peuvent fournir une interface puissante pour l'exploration du code assisté LLM.

Les questions fréquemment posées

q 1. Comment l'outil gère-t-il la grande base de code?

a. L'outil utilise un système d'indexation persistant qui analyse et stocke la structure de base de code, permettant des requêtes efficaces sans nedding pour réanalyser le code à chaque fois. L'index est mis à jour uniquement lorsque la base de code change.

q 2. L'outil peut-il fonctionner hors ligne?

a. L'analyse du code et la gestion de l'index peuvent fonctionner hors ligne, mais la question de la base de code à l'aide de l'API Gemini a besoin d'une connexion Internet pour communiquer avec les serveurs externes. Nous pouvons intégrer Olllama avec les outils qui seront possibles d'utiliser le modèle LLM ou SLM sur les appareils tels que LLAMA3 ou PHI-3 pour interroger la base de code.

Q 3. Dans quelle mesure les réponses générées par LLM sont-elles précises?

a. La précision dépend à la fois de la qualité du contexte du code analysé et des capacités du modèle Gemini. Les outils fournissent des informations de code structurées au modèle d'IA, avec une aide à améliorer la précision de la réponse, mais les utilisateurs doivent toujours vérifier les informations critiques par des moyens traditionnels.

Le média présenté dans cet article ne appartient pas à l'analyse vidhya et est utilisé à la discrétion de l'auteur.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal