Maison >développement back-end >Tutoriel Python >Construire un réviseur de code d'IA local avec ClientAI et Ollama - Partie 2

Construire un réviseur de code d'IA local avec ClientAI et Ollama - Partie 2

Susan Sarandon
Susan Sarandonoriginal
2024-12-28 02:22:08158parcourir

Building a Local AI Code Reviewer with ClientAI and Ollama - Part 2

Dans la première partie, nous avons construit les outils d'analyse de base pour notre réviseur de code. Nous allons maintenant créer un assistant IA capable d'utiliser ces outils efficacement. Nous passerons en revue chaque composant étape par étape, en expliquant comment tout fonctionne ensemble.

Pour les documents de ClientAI, voir ici et pour Github Repo, ici.

Indice des séries

  • Partie 1 : Introduction, configuration, création d'outils
  • Partie 2 : Création de l'assistant et de l'interface de ligne de commande (vous êtes ici)

Enregistrement de nos outils auprès de ClientAI

Tout d’abord, nous devons mettre nos outils à la disposition du système d’IA. Voici comment nous les enregistrons :

def create_review_tools() -> List[ToolConfig]:
    """Create the tool configurations for code review."""
    return [
        ToolConfig(
            tool=analyze_python_code,
            name="code_analyzer",
            description=(
                "Analyze Python code structure and complexity. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["observe"],
        ),
        ToolConfig(
            tool=check_style_issues,
            name="style_checker",
            description=(
                "Check Python code style issues. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["observe"],
        ),
        ToolConfig(
            tool=generate_docstring,
            name="docstring_generator",
            description=(
                "Generate docstring suggestions for Python code. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["act"],
        ),
    ]

Décomposons ce qui se passe ici :

  1. Chaque outil est enveloppé dans un objet ToolConfig qui indique à ClientAI :

    • outil : La fonction réelle à appeler
    • nom : Un identifiant unique pour l'outil
    • description : Ce que fait l'outil et quels paramètres il attend
    • portées : Quand l'outil peut être utilisé ("observer" pour l'analyse, "agir" pour la génération)
  2. Nous classons nos outils en deux catégories :

    • Les outils "observer" (code_analyzer et style_checker) collectent des informations
    • Les outils "act" (docstring_generator) produisent du nouveau contenu

Construire la classe Assistant IA

Créons maintenant notre assistant IA. Nous allons le concevoir pour qu'il fonctionne par étapes, en imitant la façon de penser d'un réviseur de code humain :

class CodeReviewAssistant(Agent):
    """An agent that performs comprehensive Python code review."""

    @observe(
        name="analyze_structure",
        description="Analyze code structure and style",
        stream=True,
    )
    def analyze_structure(self, code: str) -> str:
        """Analyze the code structure, complexity, and style issues."""
        self.context.state["code_to_analyze"] = code
        return """
        Please analyze this Python code structure and style:

        The code to analyze has been provided in the context as 'code_to_analyze'.
        Use the code_analyzer and style_checker tools to evaluate:
        1. Code complexity and structure metrics
        2. Style compliance issues
        3. Function and class organization
        4. Import usage patterns
        """

Cette première méthode est cruciale :

  • Le décorateur @observe marque cela comme une étape d'observation
  • stream=True permet une sortie en temps réel
  • Nous stockons le code dans le contexte pour y accéder lors d'étapes ultérieures
  • La chaîne de retour est une invite qui guide l'IA dans l'utilisation de nos outils

Ensuite, nous ajoutons l'étape de suggestion d'amélioration :

    @think(
        name="suggest_improvements",
        description="Suggest code improvements based on analysis",
        stream=True,
    )
    def suggest_improvements(self, analysis_result: str) -> str:
        """Generate improvement suggestions based on the analysis results."""
        current_code = self.context.state.get("current_code", "")
        return f"""
        Based on the code analysis of:

        ```
{% endraw %}
python
        {current_code}
{% raw %}

        ```

        And the analysis results:
        {analysis_result}

        Please suggest specific improvements for:
        1. Reducing complexity where identified
        2. Fixing style issues
        3. Improving code organization
        4. Optimizing import usage
        5. Enhancing readability
        6. Enhancing explicitness
        """

Cette méthode :

  • Utilise @think pour indiquer qu'il s'agit d'une étape de raisonnement
  • Prend les résultats de l'analyse en entrée
  • Récupère le code original du contexte
  • Crée une invite structurée pour des suggestions d'amélioration

L'interface de ligne de commande

Créons maintenant une interface conviviale. Nous allons diviser cela en plusieurs parties :

def main():
    # 1. Set up logging
    logger = logging.getLogger(__name__)

    # 2. Configure Ollama server
    config = OllamaServerConfig(
        host="127.0.0.1",  # Local machine
        port=11434,        # Default Ollama port
        gpu_layers=35,     # Adjust based on your GPU
        cpu_threads=8,     # Adjust based on your CPU
    )

Cette première partie configure la journalisation des erreurs, configure le serveur Ollama avec des paramètres par défaut raisonnables et permet de personnaliser l'utilisation du GPU et du CPU.

Ensuite, nous créons le client et l'assistant IA :

    # Use context manager for Ollama server
    with OllamaManager(config) as manager:
        # Initialize ClientAI with Ollama
        client = ClientAI(
            "ollama", 
            host=f"http://{config.host}:{config.port}"
        )

        # Create code review assistant with tools
        assistant = CodeReviewAssistant(
            client=client,
            default_model="llama3",
            tools=create_review_tools(),
            tool_confidence=0.8,  # How confident the AI should be before using tools
            max_tools_per_step=2, # Maximum tools to use per step
        )

Points clés de cette configuration :

  • Le gestionnaire de contexte (avec) assure un bon nettoyage du serveur
  • On se connecte à l'instance Ollama locale
  • L'assistant est configuré avec :
    • Nos outils personnalisés
    • Un seuil de confiance pour l'utilisation des outils
    • Une limite d'outils par étape pour éviter une utilisation excessive

Enfin, on crée la boucle interactive :

def create_review_tools() -> List[ToolConfig]:
    """Create the tool configurations for code review."""
    return [
        ToolConfig(
            tool=analyze_python_code,
            name="code_analyzer",
            description=(
                "Analyze Python code structure and complexity. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["observe"],
        ),
        ToolConfig(
            tool=check_style_issues,
            name="style_checker",
            description=(
                "Check Python code style issues. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["observe"],
        ),
        ToolConfig(
            tool=generate_docstring,
            name="docstring_generator",
            description=(
                "Generate docstring suggestions for Python code. "
                "Expects a 'code' parameter with the Python code as a string."
            ),
            scopes=["act"],
        ),
    ]

Cette interface :

  • Collecte la saisie de code multiligne jusqu'à voir "###"
  • Gère à la fois la sortie en streaming et hors streaming
  • Fournit une gestion propre des erreurs
  • Permet une sortie facile avec "quit"

Et faisons-en un script que nous pouvons exécuter :

class CodeReviewAssistant(Agent):
    """An agent that performs comprehensive Python code review."""

    @observe(
        name="analyze_structure",
        description="Analyze code structure and style",
        stream=True,
    )
    def analyze_structure(self, code: str) -> str:
        """Analyze the code structure, complexity, and style issues."""
        self.context.state["code_to_analyze"] = code
        return """
        Please analyze this Python code structure and style:

        The code to analyze has been provided in the context as 'code_to_analyze'.
        Use the code_analyzer and style_checker tools to evaluate:
        1. Code complexity and structure metrics
        2. Style compliance issues
        3. Function and class organization
        4. Import usage patterns
        """

Utiliser l'Assistant

Voyons comment l'assistant gère le vrai code. Lançons-le :

    @think(
        name="suggest_improvements",
        description="Suggest code improvements based on analysis",
        stream=True,
    )
    def suggest_improvements(self, analysis_result: str) -> str:
        """Generate improvement suggestions based on the analysis results."""
        current_code = self.context.state.get("current_code", "")
        return f"""
        Based on the code analysis of:

        ```
{% endraw %}
python
        {current_code}
{% raw %}

        ```

        And the analysis results:
        {analysis_result}

        Please suggest specific improvements for:
        1. Reducing complexity where identified
        2. Fixing style issues
        3. Improving code organization
        4. Optimizing import usage
        5. Enhancing readability
        6. Enhancing explicitness
        """

Voici un exemple avec des problèmes à trouver :

def main():
    # 1. Set up logging
    logger = logging.getLogger(__name__)

    # 2. Configure Ollama server
    config = OllamaServerConfig(
        host="127.0.0.1",  # Local machine
        port=11434,        # Default Ollama port
        gpu_layers=35,     # Adjust based on your GPU
        cpu_threads=8,     # Adjust based on your CPU
    )

L'assistant analysera plusieurs aspects :

  • Problèmes structurels (instructions if imbriquées augmentant la complexité, indices de type manquants, pas de validation d'entrée)
  • Problèmes de style (nom de variable incohérent, espaces manquants après virgules, docstring manquant)

Idées d'extension

Voici quelques façons d'améliorer l'assistant :

  • Outils d'analyse supplémentaires
  • Vérification de style améliorée
  • Améliorations de la documentation
  • Fonctionnalités de réparation automatique

Chacun d'entre eux peut être ajouté en créant une nouvelle fonction d'outil, en l'enveloppant dans un format JSON approprié, en l'ajoutant à la fonction create_review_tools(), puis en mettant à jour les invites de l'assistant pour utiliser le nouvel outil.

Pour en savoir plus sur ClientAI, accédez à la documentation.

Connectez-vous avec moi

Si vous avez des questions, souhaitez discuter de sujets liés à la technologie ou partager vos commentaires, n'hésitez pas à me contacter sur les réseaux sociaux :

  • GitHub : igorbenav
  • X/Twitter : @igorbenav
  • LinkedIn : Igor

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:
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