AI Agent Harness Engineering 开发效率工具:代码生成、调试辅助与文档自动生成

1. 标题 (Title)

  • AI Agent Harness Engineering 实战:构建下一代开发效率工具栈
  • 从代码生成到文档自动完成:AI Agent 如何重塑现代开发流程
  • 解锁开发效率新高度:基于 AI Agent 的代码生成、调试与文档自动化
  • Harness Engineering 入门指南:打造你的 AI 驱动开发工具箱

2. 引言 (Introduction)

痛点引入 (Hook)

你是否曾经陷入过这样的困境:在一个新项目开始时,花费数小时甚至数天来搭建基础架构、编写重复的样板代码?或者在调试一个棘手的 bug 时,在代码的海洋中迷失方向,试图找出问题所在?又或者在项目即将交付前,不得不放下手头的开发工作,投入大量时间来编写和更新技术文档?

作为开发者,我们的时间是最宝贵的资源。然而,大量的时间往往被这些重复性、机械性的工作所占据,而不是用在真正有创造性的工作上。根据 Stack Overflow 的一项调查,开发者平均每周要花费超过 10 小时在调试、文档编写和其他非核心开发任务上。这意味着,如果我们能将这些时间的一部分自动化,我们的生产力将获得显著提升。

文章内容概述 (What)

本文将带你深入探索 AI Agent Harness Engineering 的世界,这是一个正在重塑软件开发流程的新兴领域。我们将不仅仅停留在理论层面,而是会通过实际的代码示例,手把手教你如何构建三个核心的 AI 驱动开发效率工具:

  1. 智能代码生成器:根据需求描述自动生成高质量代码
  2. AI 调试助手:帮助快速定位和解决代码问题
  3. 文档自动生成系统:从代码中自动提取信息生成技术文档

我们将使用 Python 作为主要编程语言,结合大语言模型 API(如 OpenAI 的 GPT 系列或其他开源模型),并探索如何将这些 AI 能力无缝集成到我们的日常开发工作流中。

读者收益 (Why)

读完本文,你将不仅仅理解 AI Agent Harness Engineering 的概念,更重要的是,你将掌握一套实用的技术和方法,能够:

  • 构建自己的 AI 驱动开发工具
  • 大幅减少重复性工作,提升开发效率
  • 理解如何将大语言模型集成到开发流程中
  • 拥有三个可立即投入使用的原型工具
  • 为未来的 AI 辅助开发打下坚实基础

无论你是想提升个人工作效率的独立开发者,还是希望优化团队开发流程的技术负责人,本文都将为你提供有价值的见解和实用的技术方案。

3. 准备工作 (Prerequisites)

在开始我们的 AI Agent Harness Engineering 之旅之前,让我们确保你已经具备了必要的知识和工具。

技术栈/知识

为了能够充分理解和实践本文中的内容,你应该具备以下基础:

  1. Python 编程基础:熟悉 Python 语言(3.8+ 版本),包括函数、类、模块等基本概念
  2. 基本的 API 交互知识:了解如何使用 HTTP 请求与 API 进行交互
  3. 版本控制:熟悉 Git 的基本使用
  4. 软件开发流程理解:对代码生成、调试、文档编写等开发活动有基本的实践经验
  5. 大语言模型基础概念:对 LLM(如 GPT)有基本了解,知道它们能做什么

环境/工具

在开始之前,请确保你的开发环境已经准备好:

  1. Python 环境:Python 3.8 或更高版本
  2. 包管理工具:pip 或 conda
  3. 代码编辑器:VS Code、PyCharm 或你偏好的其他编辑器
  4. API 密钥
    • OpenAI API 密钥(用于访问 GPT 模型)
    • 或者其他 LLM 提供商的 API 密钥(如 Anthropic、Cohere 等)
  5. Git:用于版本控制(可选但推荐)

在接下来的章节中,我们将逐步安装项目依赖,所以不需要现在就安装所有包。

4. 核心内容:手把手实战 (Step-by-Step Tutorial)

步骤一:项目基础搭建与环境配置

在我们开始构建具体的 AI 驱动开发工具之前,让我们先搭建一个坚实的项目基础。这一步虽然看似简单,但对于后续的开发工作至关重要。

核心概念

在这一步中,我们将了解:

  1. 什么是 AI Agent Harness Engineering 的基本架构
  2. 如何设计一个灵活的工具框架
  3. 如何安全地管理和使用 API 密钥
问题背景

当我们开始构建 AI 驱动的开发工具时,首先面临的挑战是如何组织代码结构,使其既易于扩展,又能保持各个功能模块的独立性。此外,安全地管理 API 密钥也是一个必须解决的问题,我们不希望将敏感信息硬编码在代码中。

问题解决

我们将采用模块化的项目结构,将不同功能的工具分离到独立的模块中。同时,使用环境变量来管理 API 密钥,确保安全性。

让我们开始搭建项目结构:

# 创建项目目录
mkdir ai-dev-tools
cd ai-dev-tools

# 创建虚拟环境(推荐)
python -m venv venv

# 激活虚拟环境
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate

# 创建基础项目结构
mkdir -p src/{code_generator,debug_helper,doc_generator}
mkdir -p config
mkdir -p examples
mkdir -p tests

# 创建必要的文件
touch README.md
touch requirements.txt
touch config/.env.example
touch src/__init__.py
touch src/code_generator/__init__.py
touch src/debug_helper/__init__.py
touch src/doc_generator/__init__.py

现在,让我们创建基本的配置文件和环境变量管理。首先,创建 .env.example 文件,展示需要配置的环境变量:

# config/.env.example
# OpenAI API 配置
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_MODEL=gpt-4o-mini  # 或者你偏好的模型

# 应用配置
LOG_LEVEL=INFO
MAX_TOKENS=2000
TEMPERATURE=0.7

接下来,复制这个文件为实际的 .env 文件,并填入你的 API 密钥:

cp config/.env.example config/.env

现在,让我们创建一个基础的 LLM 客户端封装,这样我们就可以在不同的工具中复用相同的 LLM 调用逻辑:

# src/llm_client.py
import os
from typing import Dict, List, Optional
from dotenv import load_dotenv
import openai

# 加载环境变量
load_dotenv(dotenv_path='config/.env')

class LLMClient:
    """
    大语言模型客户端封装
    提供统一的接口来调用不同的 LLM
    """
    
    def __init__(self):
        # 初始化 OpenAI 客户端
        self.client = openai.OpenAI(
            api_key=os.getenv("OPENAI_API_KEY")
        )
        self.model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
        self.max_tokens = int(os.getenv("MAX_TOKENS", 2000))
        self.temperature = float(os.getenv("TEMPERATURE", 0.7))
        
    def generate_response(
        self, 
        system_prompt: str, 
        user_prompt: str,
        context: Optional[List[Dict[str, str]]] = None
    ) -> str:
        """
        生成 LLM 响应
        
        Args:
            system_prompt: 系统提示词,定义 AI 的角色和行为
            user_prompt: 用户提示词,具体的请求内容
            context: 可选的上下文消息列表,用于多轮对话
            
        Returns:
            LLM 生成的响应文本
        """
        messages = [
            {"role": "system", "content": system_prompt}
        ]
        
        # 添加上下文消息
        if context:
            messages.extend(context)
            
        # 添加用户消息
        messages.append({"role": "user", "content": user_prompt})
        
        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                max_tokens=self.max_tokens,
                temperature=self.temperature
            )
            return response.choices[0].message.content.strip()
        except Exception as e:
            return f"生成响应时出错: {str(e)}"

# 创建一个全局实例,方便在其他模块中使用
llm_client = LLMClient()

现在,让我们更新 requirements.txt 文件,添加我们需要的依赖:

# requirements.txt
python-dotenv>=1.0.0
openai>=1.0.0
python>=3.8.0

安装这些依赖:

pip install -r requirements.txt
边界与外延

这个基础架构为我们提供了很大的灵活性。未来,我们可以轻松地扩展 LLMClient 类,添加对其他 LLM 提供商的支持,而不需要修改我们的工具代码。我们还可以添加缓存机制、日志记录、错误重试等高级功能。

最佳实践 Tips
  1. 环境变量管理:始终使用环境变量来管理 API 密钥和其他敏感配置
  2. 模块化设计:将 LLM 调用封装在单独的类中,便于测试和替换
  3. 错误处理:在 LLM 调用中添加适当的错误处理,提高工具的鲁棒性
  4. 版本控制:将 .env 文件添加到 .gitignore 中,避免意外提交敏感信息

现在我们已经搭建好了基础架构,接下来我们将开始构建第一个具体的工具:智能代码生成器。

步骤二:构建智能代码生成器

在这一步中,我们将创建一个强大的智能代码生成器,它能够根据我们的需求描述自动生成高质量的代码。这是提升开发效率的关键工具之一。

核心概念

代码生成器的核心思想是利用大语言模型的代码理解和生成能力,结合精心设计的提示词工程(Prompt Engineering),将自然语言描述转换为可执行的代码。我们将探索如何设计有效的提示词,如何处理不同类型的代码生成需求,以及如何验证和优化生成的代码。

问题背景

在日常开发中,我们经常需要编写大量的样板代码、实现常见的算法、创建数据模型等。这些任务虽然不难,但却消耗了我们大量的时间。一个好的代码生成器可以帮助我们自动化这些任务,让我们专注于更有创造性的工作。

问题解决

我们将创建一个灵活的代码生成器,它可以:

  1. 根据功能描述生成完整的函数或类
  2. 支持多种编程语言(我们将重点关注 Python)
  3. 生成带有注释和文档字符串
  4. 提供代码解释和使用示例

让我们开始实现代码生成器:

# src/code_generator/generator.py
import os
from typing import Optional, Dict, Any
from src.llm_client import llm_client

class CodeGenerator:
    """
    智能代码生成器
    根据需求描述生成高质量代码
    """
    
    def __init__(self):
        self.llm_client = llm_client
        self.supported_languages = {
            "python": self._generate_python_code,
            "javascript": self._generate_javascript_code,
            # 可以添加更多语言支持
        }
    
    def generate_code(
        self,
        description: str,
        language: str = "python",
        context: Optional[str] = None,
        include_examples: bool = True,
        include_tests: bool = False
    ) -> Dict[str, Any]:
        """
        根据描述生成代码
        
        Args:
            description: 代码功能描述
            language: 目标编程语言
            context: 可选的上下文信息(如相关代码、API 文档等)
            include_examples: 是否包含使用示例
            include_tests: 是否包含测试代码
            
        Returns:
            包含生成的代码、解释和其他元数据的字典
        """
        if language not in self.supported_languages:
            return {
                "success": False,
                "error": f"不支持的编程语言: {language}"
            }
        
        try:
            # 调用对应语言的生成函数
            result = self.supported_languages[language](
                description, 
                context, 
                include_examples, 
                include_tests
            )
            return result
        except Exception as e:
            return {
                "success": False,
                "error": f"生成代码时出错: {str(e)}"
            }
    
    def _generate_python_code(
        self,
        description: str,
        context: Optional[str],
        include_examples: bool,
        include_tests: bool
    ) -> Dict[str, Any]:
        """
        生成 Python 代码的具体实现
        """
        system_prompt = """你是一位专业的 Python 开发者,擅长编写高质量、可维护、符合 PEP 8 规范的 Python 代码。
你的任务是根据用户的需求描述生成完整的 Python 代码。
请遵循以下原则:
1.  代码应该简洁、高效、易读
2.  包含详细的文档字符串(docstrings)
3.  添加必要的类型提示(type hints)
4.  遵循 PEP 8 代码风格
5.  处理可能的边界情况和错误
6.  如果需要,提供使用示例
7.  尽可能使用标准库,避免不必要的依赖"""
        
        user_prompt = f"""请根据以下需求描述生成 Python 代码:

需求描述:
{description}"""
        
        if context:
            user_prompt += f"""

上下文信息:
{context}"""
        
        user_prompt += f"""

请按照以下 JSON 格式返回结果,不要包含任何其他文本:
{{
    "code": "生成的 Python 代码",
    "explanation": "代码的详细解释",
    "examples": "使用示例代码(如果有)",
    "tests": "测试代码(如果有)"
}}

注意:
- 确保返回的是有效的 JSON 格式
- 代码中的引号需要正确转义
- 如果不需要示例或测试,可以返回空字符串
"""
        
        # 调用 LLM 生成代码
        response = self.llm_client.generate_response(
            system_prompt=system_prompt,
            user_prompt=user_prompt
        )
        
        # 解析响应
        import json
        try:
            # 尝试提取 JSON 部分
            import re
            json_match = re.search(r'\{[\s\S]*\}', response)
            if json_match:
                json_str = json_match.group(0)
                result = json.loads(json_str)
            else:
                # 如果没有找到 JSON,尝试直接解析
                result = json.loads(response)
            
            # 确保返回的结果包含必要的字段
            result["success"] = True
            result["language"] = "python"
            
            # 如果不想要示例或测试,可以清空
            if not include_examples:
                result["examples"] = ""
            if not include_tests:
                result["tests"] = ""
                
            return result
        except json.JSONDecodeError:
            return {
                "success": False,
                "error": "无法解析 LLM 响应为 JSON",
                "raw_response": response
            }
    
    def _generate_javascript_code(
        self,
        description: str,
        context: Optional[str],
        include_examples: bool,
        include_tests: bool
    ) -> Dict[str, Any]:
        """
        生成 JavaScript 代码的具体实现
        (这里我们只提供框架,具体实现可以参考 Python 版本)
        """
        # 实现类似于 _generate_python_code 的逻辑
        # 为了简洁,这里我们返回一个简单的实现
        return {
            "success": True,
            "language": "javascript",
            "code": f"// JavaScript 代码生成器正在开发中\n// 需求: {description}",
            "explanation": "JavaScript 代码生成器功能即将上线",
            "examples": "",
            "tests": ""
        }
    
    def save_code_to_file(self, code: str, file_path: str) -> bool:
        """
        将生成的代码保存到文件
        
        Args:
            code: 要保存的代码
            code: 要保存的代码
            file_path: 文件路径
            
        Returns:
            是否保存成功
        """
        try:
            # 确保目录存在
            os.makedirs(os.path.dirname(file_path), exist_ok=True)
            
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(code)
            return True
        except Exception as e:
            print(f"保存文件时出错: {str(e)}")
            return False

现在,让我们创建一个简单的命令行界面来使用我们的代码生成器:

# src/code_generator/cli.py
import argparse
import os
from src.code_generator.generator import CodeGenerator

def main():
    parser = argparse.ArgumentParser(description="智能代码生成器")
    parser.add_argument(
        "description", 
        help="代码功能描述"
    )
    parser.add_argument(
        "--language", 
        "-l", 
        default="python", 
        help="目标编程语言 (默认: python)"
    )
    parser.add_argument(
        "--context", 
        "-c", 
        help="可选的上下文信息文件路径"
    )
    parser.add_argument(
        "--output", 
        "-o", 
        help="输出文件路径"
    )
    parser.add_argument(
        "--no-examples", 
        action="store_true", 
        help="不包含使用示例"
    )
    parser.add_argument(
        "--tests", 
        action="store_true", 
        help="包含测试代码"
    )
    
    args = parser.parse_args()
    
    # 读取上下文信息(如果有)
    context = None
    if args.context and os.path.exists(args.context):
        with open(args.context, 'r', encoding='utf-8') as f:
            context = f.read()
    
    # 创建代码生成器实例
    generator = CodeGenerator()
    
    # 生成代码
    print(f"正在生成 {args.language} 代码...")
    result = generator.generate_code(
        description=args.description,
        language=args.language,
        context=context,
        include_examples=not args.no_examples,
        include_tests=args.tests
    )
    
    if not result.get("success"):
        print(f"生成失败: {result.get('error', '未知错误')}")
        if 'raw_response' in result:
            print(f"原始响应: {result['raw_response']}")
        return
    
    # 输出结果
    print("\n" + "="*50)
    print("生成的代码:")
    print("="*50)
    print(result["code"])
    
    print("\n" + "="*50)
    print("代码解释:")
    print("="*50)
    print(result["explanation"])
    
    if result.get("examples"):
        print("\n" + "="*50)
        print("使用示例:")
        print("="*50)
        print(result["examples"])
    
    if result.get("tests"):
        print("\n" + "="*50)
        print("测试代码:")
        print("="*50)
        print(result["tests"])
    
    # 保存到文件(如果指定了输出路径)
    if args.output:
        # 组合完整的代码内容
        full_code = result["code"]
        if result.get("examples"):
            full_code += "\n\n# 使用示例\n" + result["examples"]
        if result.get("tests"):
            full_code += "\n\n# 测试代码\n" + result["tests"]
        
        if generator.save_code_to_file(full_code, args.output):
            print(f"\n代码已保存到: {args.output}")

if __name__ == "__main__":
    main()

现在,让我们创建一个示例来演示如何使用我们的代码生成器。首先,在项目根目录创建一个 examples 文件夹,然后创建一个简单的测试脚本:

# examples/test_code_generator.py
from src.code_generator.generator import CodeGenerator

def main():
    # 创建代码生成器实例
    generator = CodeGenerator()
    
    # 示例 1: 生成一个简单的工具函数
    print("示例 1: 生成一个计算斐波那契数列的函数")
    print("-" * 50)
    result1 = generator.generate_code(
        description="创建一个函数,计算斐波那契数列的第 n 项,使用递归和迭代两种方法实现",
        language="python",
        include_examples=True,
        include_tests=True
    )
    
    if result1.get("success"):
        print("生成的代码:")
        print(result1["code"])
        print("\n解释:")
        print(result1["explanation"])
    else:
        print(f"错误: {result1.get('error')}")
    
    print("\n" + "="*50 + "\n")
    
    # 示例 2: 生成一个简单的数据处理类
    print("示例 2: 生成一个 CSV 数据处理类")
    print("-" * 50)
    result2 = generator.generate_code(
        description="创建一个 CSV 数据处理类,支持读取 CSV 文件、过滤数据、计算统计指标",
        language="python",
        include_examples=True,
        include_tests=False
    )
    
    if result2.get("success"):
        print("生成的代码:")
        print(result2["code"])
    else:
        print(f"错误: {result2.get('error')}")

if __name__ == "__main__":
    main()
概念结构与核心要素组成

我们的代码生成器由以下几个核心部分组成:

  1. LLM 客户端:负责与大语言模型进行交互
  2. 代码生成器核心:管理不同语言的生成逻辑
  3. 提示词模板:定义如何向 LLM 描述我们的需求
  4. 输出解析器:将 LLM 的响应转换为结构化数据
  5. 用户界面:提供命令行或其他接口供用户使用

这些组件之间的关系可以用以下 Mermaid 架构图表示:

用户界面 CLI

代码生成器核心

提示词模板

LLM 客户端

大语言模型 API

输出解析器

文件保存器

实际场景应用

这个代码生成器可以应用于多种实际场景:

  1. 快速原型开发:根据需求快速生成原型代码
  2. 学习新技术:生成示例代码来学习新的编程概念
  3. 代码重构:生成更高效或更易读的代码版本
  4. 测试用例生成:自动为现有代码生成测试用例
  5. API 封装:根据 API 文档生成调用代码
最佳实践 Tips
  1. 描述要清晰具体:提供尽可能详细的需求描述,包括输入输出、边界条件等
  2. 提供上下文信息:如果有相关的代码或文档,一并提供给生成器
  3. 验证生成的代码:始终检查和测试生成的代码,不要直接在生产环境中使用
  4. 迭代优化:如果第一次生成的代码不理想,可以根据结果调整描述再次尝试
  5. 保持简洁:一次只让生成器完成一个明确的任务,避免过于复杂的需求

现在我们已经构建了一个功能强大的代码生成器,接下来我们将继续构建第二个工具:AI 调试助手。

步骤三:构建 AI 调试助手

在这一步中,我们将创建一个 AI 驱动的调试助手,它能够帮助我们快速定位和解决代码中的问题。调试是开发过程中最耗时的活动之一,一个好的调试助手可以大幅提升我们的效率。

核心概念

AI 调试助手的核心思想是利用大语言模型的代码分析能力,结合错误信息、代码上下文和运行时数据,帮助开发者理解和解决代码问题。我们将探索如何设计有效的调试提示词,如何分析错误信息,以及如何提供有针对性的修复建议。

问题背景

每个开发者都经历过这样的情况:花费数小时甚至数天来调试一个看似简单的问题。错误信息可能不明确,问题可能隐藏在复杂的代码逻辑中,或者问题只在特定条件下才会出现。AI 调试助手可以帮助我们更快地找到问题的根源,并提供可能的解决方案。

问题解决

我们将创建一个灵活的调试助手,它可以:

  1. 分析错误信息和堆栈跟踪
  2. 检查相关代码,找出潜在问题
  3. 提供具体的修复建议
  4. 生成测试用例来验证修复

让我们开始实现调试助手:

# src/debug_helper/debugger.py
import os
import traceback
from typing import Optional, Dict, Any, List
from src.llm_client import llm_client

class DebugHelper:
    """
    AI 调试助手
    帮助分析和解决代码问题
    """
    
    def __init__(self):
        self.llm_client = llm_client
    
    def analyze_error(
        self,
        error_message: str,
        code: Optional[str] = None,
        stack_trace: Optional[str] = None,
        context: Optional[str] = None,
        language: str = "python"
    ) -> Dict[str, Any]:
        """
        分析错误并提供修复建议
        
        Args:
            error_message: 错误信息
            code: 相关代码(可选)
            stack_trace: 堆栈跟踪(可选)
            context: 其他上下文信息(可选)
            language: 编程语言
            
        Returns:
            包含错误分析和修复建议的字典
        """
        system_prompt = """你是一位专业的软件调试专家,擅长分析和解决各种编程问题。
你的任务是帮助开发者理解和修复代码错误。
请遵循以下原则:
1.  仔细分析错误信息和堆栈跟踪
2.  检查相关代码,找出潜在问题
3.  提供清晰、具体的修复建议
4.  如果可能,提供修复后的代码示例
5.  解释问题的根本原因
6.  提供预防类似问题的建议"""
        
        user_prompt = f"""请分析以下错误并提供修复建议:

错误信息:
{error_message}"""
        
        if code:
            user_prompt += f"""

相关代码:
{code}"""
        
        if stack_trace:
            user_prompt += f"""

堆栈跟踪:
{stack_trace}"""
        
        if context:
            user_prompt += f"""

其他上下文信息:
{context}"""
        
        user_prompt += f"""

编程语言:{language}

请按照以下 JSON 格式返回结果,不要包含任何其他文本:
{{
    "error_analysis": "错误的详细分析",
    "root_cause": "问题的根本原因",
    "fix_suggestions": "修复建议列表(数组格式)",
    "fixed_code": "修复后的代码示例(如果有)",
    "prevention_tips": "预防类似问题的建议"
}}

注意:
- 确保返回的是有效的 JSON 格式
- 如果没有修复后的代码,可以返回空字符串
- fix_suggestions 应该是一个字符串数组
"""
        
        # 调用 LLM 分析错误
        response = self.llm_client.generate_response(
            system_prompt=system_prompt,
            user_prompt=user_prompt
        )
        
        # 解析响应
        import json
        try:
            # 尝试提取 JSON 部分
            import re
            json_match = re.search(r'\{[\s\S]*\}', response)
            if json_match:
                json_str = json_match.group(0)
                result = json.loads(json_str)
            else:
                # 如果没有找到 JSON,尝试直接解析
                result = json.loads(response)
            
            # 确保返回的结果包含必要的字段
            result["success"] = True
            
            # 确保 fix_suggestions 是数组
            if not isinstance(result.get("fix_suggestions", []), list):
                result["fix_suggestions"] = [result["fix_suggestions"]]
                
            return result
        except json.JSONDecodeError:
            return {
                "success": False,
                "error": "无法解析 LLM 响应为 JSON",
                "raw_response": response
            }
    
    def analyze_code(
        self,
        code: str,
        issue_description: Optional[str] = None,
        language: str = "python"
    ) -> Dict[str, Any]:
        """
        分析代码,找出潜在问题
        
        Args:
            code: 要分析的代码
            issue_description: 问题描述(可选)
            language: 编程语言
            
        Returns:
            包含代码分析结果的字典
        """
        system_prompt = """你是一位专业的代码审查专家,擅长发现代码中的潜在问题。
你的任务是分析代码,找出可能的 bug、性能问题、安全隐患和代码质量问题。
请遵循以下原则:
1.  仔细检查代码逻辑
2.  识别潜在的 bug 和错误
3.  发现性能优化机会
4.  指出安全隐患
5.  提供代码质量改进建议
6.  优先考虑最严重的问题"""
        
        user_prompt = f"""请分析以下代码,找出潜在问题:

代码:
{code}"""
        
        if issue_description:
            user_prompt += f"""

问题描述:
{issue_description}"""
        
        user_prompt += f"""

编程语言:{language}

请按照以下 JSON 格式返回结果,不要包含任何其他文本:
{{
    "critical_issues": [
        {{
            "type": "问题类型",
            "description": "问题描述",
            "location": "问题位置(如果可以确定)",
            "severity": "严重程度",
            "suggestion": "修复建议"
        }}
    ],
    "minor_issues": [
        {{
            "type": "问题类型",
            "description": "问题描述",
            "location": "问题位置(如果可以确定)",
            "severity": "严重程度",
            "suggestion": "改进建议"
        }}
    ],
    "performance_issues": [
        {{
            "description": "性能问题描述",
            "suggestion": "优化建议"
        }}
    ],
    "security_issues": [
        {{
            "description": "安全问题描述",
            "suggestion": "安全建议"
        }}
    ],
    "overall_quality": "代码整体质量评估",
    "improvement_suggestions": "整体改进建议"
}}

注意:
- 确保返回的是有效的 JSON 格式
- 如果没有某类问题,可以返回空数组
- 问题严重程度可以是:高、中、低
"""
        
        # 调用 LLM 分析代码
        response = self.llm_client.generate_response(
            system_prompt=system_prompt,
            user_prompt=user_prompt
        )
        
        # 解析响应
        import json
        try:
            # 尝试提取 JSON 部分
            import re
            json_match = re.search(r'\{[\s\S]*\}', response)
            if json_match:
                json_str = json_match.group(0)
                result = json.loads(json_str)
            else:
                # 如果没有找到 JSON,尝试直接解析
                result = json.loads(response)
            
            # 确保返回的结果包含必要的字段
            result["success"] = True
            
            # 确保所有问题列表都是数组
            for key in ["critical_issues", "minor_issues", "performance_issues", "security_issues"]:
                if not isinstance(result.get(key, []), list):
                    result[key] = [result[key]]
                
            return result
        except json.JSONDecodeError:
            return {
                "success": False,
                "error": "无法解析 LLM 响应为 JSON",
                "raw_response": response
            }
    
    def debug_function(
        self,
        func,
        *args,
        **kwargs
    ) -> Dict[str, Any]:
        """
        调试一个函数,捕获并分析其异常
        
        Args:
            func: 要调试的函数
            *args: 函数参数
            **kwargs: 函数关键字参数
            
        Returns:
            包含调试结果的字典
        """
        try:
            # 尝试执行函数
            result = func(*args, **kwargs)
            return {
                "success": True,
                "execution_successful": True,
                "result": result,
                "message": "函数执行成功,没有错误"
            }
        except Exception as e:
            # 捕获异常
            error_type = type(e).__name__
            error_message = str(e)
            stack_trace = traceback.format_exc()
            
            # 获取函数源代码
            import inspect
            try:
                source_code = inspect.getsource(func)
            except (TypeError, OSError):
                source_code = None
            
            # 分析错误
            analysis_result = self.analyze_error(
                error_message=error_message,
                code=source_code,
                stack_trace=stack_trace,
                context=f"函数名: {func.__name__}\n参数: args={args}, kwargs={kwargs}",
                language="python"
            )
            
            return {
                "success": True,
                "execution_successful": False,
                "error_type": error_type,
                "error_message": error_message,
                "stack_trace": stack_trace,
                "analysis": analysis_result
            }

现在,让我们创建一个命令行界面来使用我们的调试助手:

# src/debug_helper/cli.py
import argparse
import os
import sys
from src.debug_helper.debugger import DebugHelper

def main():
    parser = argparse.ArgumentParser(description="AI 调试助手")
    
    # 创建子解析器
    subparsers = parser.add_subparsers(title="命令", dest="command", help="可用命令")
    
    # 分析错误命令
    error_parser = subparsers.add_parser("error", help="分析错误")
    error_parser.add_argument(
        "--message", 
        "-m", 
        required=True,
        help="错误信息"
    )
    error_parser.add_argument(
        "--code", 
        "-c", 
        help="相关代码文件路径"
    )
    error_parser.add_argument(
        "--stack-trace", 
        "-s", 
        help="堆栈跟踪文件路径"
    )
    error_parser.add_argument(
        "--context", 
        "-x", 
        help="其他上下文信息文件路径"
    )
    error_parser.add_argument(
        "--language", 
        "-l", 
        default="python", 
        help="编程语言 (默认: python)"
    )
    
    # 分析代码命令
    code_parser = subparsers.add_parser("code", help="分析代码")
    code_parser.add_argument(
        "file", 
        help="要分析的代码文件路径"
    )
    code_parser.add_argument(
        "--issue", 
        "-i", 
        help="问题描述"
    )
    code_parser.add_argument(
        "--language", 
        "-l", 
        default="python", 
        help="编程语言 (默认: python)"
    )
    
    args = parser.parse_args()
    
    # 创建调试助手实例
    debugger = DebugHelper()
    
    if args.command == "error":
        # 读取文件内容(如果有)
        code = None
        if args.code and os.path.exists(args.code):
            with open(args.code, 'r', encoding='utf-8') as f:
                code = f.read()
        
        stack_trace = None
        if args.stack_trace and os.path.exists(args.stack_trace):
            with open(args.stack_trace, 'r', encoding='utf-8') as f:
                stack_trace = f.read()
        
        context = None
        if args.context and os.path.exists(args.context):
            with open(args.context, 'r', encoding='utf-8') as f:
            context = f.read()
        
        # 分析错误
        print("正在分析错误...")
        result = debugger.analyze_error(
            error_message=args.message,
            code=code,
            stack_trace=stack_trace,
            context=context,
            language=args.language
        )
        
        if not result.get("success"):
            print(f"分析失败: {result.get('error', '未知错误')}")
            if 'raw_response' in result:
                print(f"原始响应: {result['raw_response']}")
            return
        
        # 输出结果
        print("\n" + "="*50)
        print("错误分析:")
        print("="*50)
        print(result["error_analysis"])
        
        print("\n" + "="*50)
        print("根本原因:")
        print("="*50)
        print(result["root_cause"])
        
        print("\n" + "="*50)
        print("修复建议:")
        print("="*50)
        for i, suggestion in enumerate(result.get("fix_suggestions", []), 1):
            print(f"{i}. {suggestion}")
        
        if result.get("fixed_code"):
            print("\n" + "="*50)
            print("修复后的代码:")
            print("="*50)
            print(result["fixed_code"])
        
        print("\n" + "="*50)
        print("预防建议:")
        print("="*50)
        print(result["prevention_tips"])
    
    elif args.command == "code":
        # 读取代码文件
        if not os.path.exists(args.file):
            print(f"错误: 文件不存在: {args.file}")
            return
        
        with open(args.file, 'r', encoding='utf-8') as f:
            code = f.read()
        
        # 分析代码
        print("正在分析代码...")
        result = debugger.analyze_code(
            code=code,
            issue_description=args.issue,
            language=args.language
        )
        
        if not result.get("success"):
            print(f"分析失败: {result.get('error', '未知错误')}")
            if 'raw_response' in result:
                print(f"原始响应: {result['raw_response']}")
            return
        
        # 输出结果
        print("\n" + "="*50)
        print("代码整体质量:")
        print("="*50)
        print(result["overall_quality"])
        
        if result.get("critical_issues"):
            print("\n" + "="*50)
            print("严重问题:")
            print("="*50)
            for i, issue in enumerate(result["critical_issues"], 1):
                print(f"\n{i}. [{issue.get('type', '未知类型')} - 严重程度: {issue.get('severity', '未知')}")
                print(f"   描述: {issue.get('description', '无描述')}")
                if issue.get('location'):
                    print(f"   位置: {issue['location']}")
                print(f"   建议: {issue.get('suggestion', '无建议')}")
        
        if result.get("minor_issues"):
            print("\n" + "="*50)
            print("次要问题:")
            print("="*50)
            for i, issue in enumerate(result["minor_issues"], 1):
                print(f"\n{i}. [{issue.get('type', '未知类型')} - 严重程度: {issue.get('severity', '未知')}")
                print(f"   描述: {issue.get('description', '无描述')}")
                if issue.get('location'):
                    print(f"   位置: {issue['location']}")
                print(f"   建议: {issue.get('suggestion', '无建议')}")
        
        if result.get("performance_issues"):
            print("\n" + "="*50)
            print("性能问题:")
            print("="*50)
            for i, issue in enumerate(result["performance_issues"], 1):
                print(f"\n{i}. {issue.get('description', '无描述')}")
                print(f"   建议: {issue.get('suggestion', '无建议')}")
        
        if result.get("security_issues"):
            print("\n" + "="*50)
            print("安全问题:")
            print("="*50)
            for i, issue in enumerate(result["security_issues"], 1):
                print(f"\n{i}. {issue.get('description', '无描述')}")
                print(f"   建议: {issue.get('suggestion', '无建议')}")
        
        print("\n" + "="*50)
        print("整体改进建议:")
        print("="*50)
        print(result["improvement_suggestions"])

if __name__ == "__main__":
    main()

现在,让我们创建一个示例来演示如何使用我们的调试助手:

# examples/test_debug_helper.py
from src.debug_helper.debugger import DebugHelper

# 一个有问题的函数,用于测试
def problematic_function(n):
    """
    一个有问题的函数,用于测试调试功能
    """
    result = 0
    for i in range(n):
        result += 1 / (i - 5)  # 这里会在 i=5 时导致除零错误
    return result

def another_problematic_function(data):
    """
    另一个有问题的函数
    """
    total = 0
    for item in data:
        total += item['value']  # 这里会在没有 'value' 键时导致 KeyError
    return total

def main():
    # 创建调试助手实例
    debugger = DebugHelper()
    
    # 示例 1: 调试有问题的函数
    print("示例 1: 调试有问题的函数")
    print("-" * 50)
    result1 = debugger.debug_function(problematic_function, 10)
    
    if result1.get("success"):
        if result1.get("execution_successful"):
            print(f"函数执行成功,结果: {result1['result']}")
        else:
            print(f"函数执行失败: {result1['error_type']}: {result1['error_message']}")
            print("\n错误分析:")
            analysis = result1.get('analysis', {})
            if analysis.get('success'):
                print(f"根本原因: {analysis.get('root_cause', '未知')}")
                print("\n修复建议:")
                for i, suggestion in enumerate(analysis.get('fix_suggestions', []), 1):
                    print(f"{i}. {suggestion}")
    
    print("\n" + "="*50 + "\n")
    
    # 示例 2: 分析一段有潜在问题的代码
    print("示例 2: 分析一段有潜在问题的代码")
    print("-" * 50)
    code_to_analyze = """
def process_data(data):
    result = []
    for i in range(len(data)):
        if data[i] > 0:
            result.append(data[i] * 2)
        else:
Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐