12 节 / 共 14

4.2 代码生成与调试

📌 本节目标

学完本节后,你将能够编写精准的提示词,让 AI 为你生成可运行的 Python 函数;同时,当 AI 生成的代码出现 Bug 时,你也能通过有效的调试提示让 AI 自我修正。你将掌握“一次生成”和“迭代调试”两种核心工作流,大幅提升编码效率。

1. 核心概念讲解

概念一:面向代码的提示设计

让 AI 写代码,就像向一位经验丰富的程序员描述需求。你不能只说“给我写个排序”,而要说“给我写一个 Python 函数,用快速排序算法对整数列表进行升序排序”。清晰、具体、包含约束条件,是代码提示的核心。

  • 比如: 模糊提示:写一个函数处理数据。 精准提示:写一个 Python 函数,接受一个包含字典的列表作为输入,每个字典有 'name' 和 'score' 两个键,返回按 score 降序排序后的新列表。

概念二:角色与格式设定

你可以通过设定 AI 的“角色”和“输出格式”来规范代码质量。告诉 AI 它是一位“资深 Python 工程师”,并要求它输出“包含详细注释的代码”或“同时给出单元测试”。

  • 比如:
    # 提示词示例
    你是一位资深 Python 开发者。请为我编写一个函数,功能是:
    1. 从字符串中提取所有 URL。
    2. 使用正则表达式实现。
    3. 请包含完整的函数注释(docstring)和类型注解。
    
    输出格式:
    ```python
    # 你的代码
    

概念三:调试提示(Debug Prompt)

AI 生成的代码不一定一次就能跑通。调试提示的核心是 “提供上下文 + 描述错误”。不要只说“代码有 Bug”,而要把错误信息、输入输出样例、甚至是你怀疑出问题的地方告诉 AI。

  • 比如:
    你之前生成的函数 `calculate_average` 运行时报错如下:
    TypeError: unsupported operand type(s) for /: 'str' and 'int'
    
    输入是:["90", "80", "70"]
    期望输出是:80.0
    请帮我修复这个 Bug,并解释原因。
    

2. 深入理解

为什么代码提示需要如此精确?

大型语言模型(LLM)本质上是一个“高级模式匹配器”。它根据你给出的提示,在它学习过的海量代码中寻找最相似的“模式”进行输出。提示词越模糊,它匹配到的模式就越泛化,结果越不可控。 比如,你说“写个函数处理数据”,它可能给你一个 CSV 读取函数,也可能给你一个数据清洗函数,完全取决于它“猜”你的意图。

初学者常见的误区

| 误区 | 表现 | 正确做法 | | :--- | :--- | :--- | | 需求模糊 | “写个爬虫” | “写一个 Python 爬虫,使用 requestsBeautifulSoup 库,抓取指定新闻网站首页的标题列表。” | | 忽略上下文 | 只贴错误信息,不贴代码 | 将相关代码片段完整错误信息一起贴给 AI。 | | 不指定语言/库 | 生成 Java 代码但你用 Python | 明确指定:“请使用 Python 3.10+,仅依赖标准库,不要使用第三方库。” | | 一次期望完美 | AI 第一次输出有 Bug 就放弃 | 学会用迭代提示:“代码运行结果不对,输入是 [1,2,3],期望输出 6,实际输出 3,请检查逻辑。” |

背后的原理:自注意力与代码结构

LLM 在处理代码时,会利用“自注意力机制”捕捉代码中变量、函数、类之间的长距离依赖关系。例如,当它生成一个函数调用时,会“注意”到之前定义的函数签名。因此,在提示中保持代码风格和命名规范的一致性,能帮助 AI 生成结构更合理、更少 Bug 的代码。

3. 实战演示

案例:让 AI 生成一个计算文件行数的函数

目标: 生成一个 Python 函数,接受文件路径作为参数,返回该文件的行数(忽略空行)。

步骤 1:编写初始提示

你是一位 Python 专家。请写一个函数 `count_lines`。

要求:
- 接受一个参数:文件路径 `file_path` (字符串)。
- 返回该文件的行数(整数)。
- 需要忽略空行(即只包含空白字符的行不算)。
- 包含完整的 docstring 和类型注解。
- 使用 `with` 语句安全地打开文件。
- 处理文件不存在的异常,返回 -1。

请只输出代码,不需要解释。

AI 可能会生成如下代码:

def count_lines(file_path: str) -> int:
    """
    计算文件的有效行数(忽略空行)。

    Args:
        file_path: 文件路径。

    Returns:
        文件的有效行数。如果文件不存在,返回 -1。
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            count = 0
            for line in f:
                if line.strip():  # 检查去除空白后是否为空
                    count += 1
            return count
    except FileNotFoundError:
        return -1

步骤 2:测试并调试

假设我们用一个包含以下内容的文件 test.txt 测试:

第一行

第三行

第五行

(实际有 5 行,但第 2、4 行是空行)

我们运行代码,发现返回结果是 3,这是正确的。但如果我们想让它也统计总行数(包括空行),我们需要修改需求。

步骤 3:迭代提示(需求变更)

感谢你生成的代码。现在我需要一个新功能:
请在 `count_lines` 函数的基础上,增加一个可选参数 `ignore_blank`,默认为 `True`。
- 当 `ignore_blank=True` 时,行为与之前一致(忽略空行)。
- 当 `ignore_blank=False` 时,统计文件的总行数(包括空行)。
请输出更新后的完整函数。

AI 会生成更新后的代码:

def count_lines(file_path: str, ignore_blank: bool = True) -> int:
    """
    计算文件的行数。

    Args:
        file_path: 文件路径。
        ignore_blank: 是否忽略空行,默认为 True。

    Returns:
        文件的行数。如果文件不存在,返回 -1。
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            if ignore_blank:
                count = 0
                for line in f:
                    if line.strip():
                        count += 1
                return count
            else:
                # 统计所有行
                return sum(1 for _ in f)
    except FileNotFoundError:
        return -1

整个过程演示了一个完整的工作流:

  1. 明确需求 -> 2. 生成代码 -> 3. 测试验证 -> 4. 迭代优化

4. 关键要点

  • 具体是金:提示词中务必包含输入、输出、边界条件和使用的库。模糊是代码 Bug 的温床。
  • 提供上下文:调试时,把错误信息、输入样例、期望输出、实际输出一并提供给 AI,不要只扔一句“有 Bug”。
  • 善用迭代:不要指望一次生成完美代码。通过“增加功能”、“修复 Bug”、“优化性能”等指令逐步逼近目标。
  • 设定角色与格式:告诉 AI“你是专家”并指定输出格式(如“只输出代码”或“包含注释”),能显著提升结果质量。
  • 保持代码规范:在提示中使用有意义的变量名和清晰的逻辑,AI 会模仿你的风格,生成更可读的代码。

✏️ 练习任务

练习 1:生成并调试一个数据清洗函数

任务描述: 让 AI 生成一个 Python 函数 clean_sales_data,用于清洗销售数据列表。

具体要求:

  1. 函数接受一个列表 raw_data,列表元素是字符串,格式为 "日期,销售额",例如 "2023-01-01, 150.5"
  2. 函数需要执行以下清洗操作:
    • 跳过格式不正确的行(如缺少逗号、销售额不是数字)。
    • 将日期转换为 datetime.date 对象(假设日期格式为 YYYY-MM-DD)。
    • 将销售额转换为浮点数。
    • 返回一个由元组 (date, sales) 组成的新列表。
  3. AI 首次生成的代码可能有一个小 Bug:如果销售额是整数(如 "100"),转换会失败。请通过调试提示让 AI 修复这个问题。
  4. 期望输出示例:
    input_data = ["2023-01-01, 150.5", "2023-01-02, 200", "invalid line", "2023-01-03, abc"]
    result = clean_sales_data(input_data)
    # result 应该为 [(datetime.date(2023, 1, 1), 150.5), (datetime.date(2023, 1, 2), 200.0)]
    # 注意:'invalid line' 和 '2023-01-03, abc' 应被跳过
    

调试提示示例(当遇到 Bug 时使用):

你生成的函数 clean_sales_data 在处理输入 ["2023-01-02, 200"] 时报错:
ValueError: could not convert string to float: '200 '
请修复这个 Bug,确保能处理销售额为整数的情况。

练习 2(选做):生成一个简单的单元测试

任务描述: 让 AI 为上面生成的 clean_sales_data 函数生成一组 pytest 单元测试。

具体要求:

  1. 测试用例需要覆盖:正常数据、空列表、包含无效行的数据、销售额为整数的情况。
  2. 使用 pytest 框架。
  3. 提示 AI 输出可直接运行的测试代码。

💡 下一节我们将学习“4.3 文档与报告生成”,你将掌握如何利用提示工程自动撰写技术文档和项目报告,让 AI 成为你的写作助手。


本节由 StudyAI8 AI 课程团队生成并审核。