上一篇 下一篇 分享链接 返回 返回顶部

实测 AI 写代码:从 Todo 小工具看效率、质量与源码落地

发布人:慈云数据-客服中心 发布时间:22小时前 阅读量:4

AI编程测评报告|附源码

摘要

过去一年,“AI 编程”已经从一个新鲜概念,快速变成了许多开发者日常工作流的一部分。从代码补全、单元测试生成、Bug 定位,到需求拆解、架构设计、文档编写,AI 编程工具正在不断拓展边界。本文将以一次相对完整的实测为基础,对 AI 编程在真实开发场景中的表现进行评估,并给出一个可运行的小项目源码示例,帮助读者理解 AI 在编码效率、代码质量、可维护性以及工程落地方面的实际价值。

本次测评不追求“AI 是否能够完全替代程序员”这类极端结论,而是重点关注一个更现实的问题:在当前阶段,AI 编程到底能帮开发者做到什么、做得怎么样、有哪些风险,以及如何更高效地使用它。


一、测评背景

随着大语言模型能力的提升,AI 编程工具已经不再只是简单的代码提示器。它们能够根据自然语言需求生成代码,解释已有代码逻辑,辅助重构复杂函数,甚至根据报错信息给出修复方案。

常见的 AI 编程使用方式包括:

  1. 代码补全
    根据上下文自动补齐变量、函数、类、配置项等内容。

  2. 代码生成
    根据需求描述生成接口、页面、脚本、算法、数据处理逻辑等。

  3. 代码解释
    对已有代码进行逐行解释,帮助开发者理解陌生项目。

  4. Bug 修复
    根据错误日志、异常堆栈或测试失败信息提出修复建议。

  5. 单元测试生成
    自动为函数、类或接口生成测试用例。

  6. 文档生成
    根据代码生成 README、接口说明、注释或技术文档。

  7. 重构建议
    发现重复代码、复杂逻辑、潜在异常,并提出优化方案。

从实际体验来看,AI 编程最显著的价值并不是“代替开发者写完整项目”,而是帮助开发者减少重复劳动、提升思考效率,并在一些边界清晰的问题上快速给出可用方案。


二、测评目标

本次测评主要围绕以下几个维度展开:

测评维度 说明
代码生成能力 是否能根据需求生成可运行代码
逻辑准确性 生成代码是否符合业务逻辑
可读性 命名、结构、注释是否清晰
可维护性 是否容易扩展和修改
错误处理 是否考虑异常输入和边界情况
测试能力 是否能够生成有效单元测试
工程化能力 是否具备模块化、配置化、文档化意识
开发效率 是否明显节省开发时间

为了避免测评过于空泛,本文选择一个小型但相对完整的案例:使用 Python 编写一个命令行待办事项管理工具

这个案例看似简单,但实际包含了不少常见开发要素:

  • 命令行参数解析;
  • 数据持久化;
  • 增删改查;
  • 状态变更;
  • 输入校验;
  • JSON 文件读写;
  • 基础异常处理;
  • 可扩展代码结构;
  • 单元测试思路。

三、测试需求描述

向 AI 提出的原始需求如下:

请使用 Python 编写一个命令行 Todo 工具,支持添加任务、查看任务列表、标记任务完成、删除任务。数据保存在本地 JSON 文件中。要求代码结构清晰,提供基础异常处理,并附带使用示例。

这个需求并不复杂,但也不是单个函数能够完成的任务。它要求 AI 能够将自然语言转化为合理的程序结构。


四、AI 生成代码整体表现

从结果来看,AI 通常可以较快生成一个可运行版本,核心功能基本完整。特别是在以下方面表现较好:

1. 能快速搭建基础结构

AI 往往会自动选择 argparse 作为命令行解析工具,使用 json 模块进行数据持久化,并将任务抽象成字典结构,例如:

{
    "id": 1,
    "title": "学习 AI 编程",
    "done": False
}

这种结构简单直观,对于小型工具来说足够使用。

2. 能完成主要业务功能

在添加任务、查看任务、完成任务、删除任务方面,AI 生成代码通常能够覆盖主要流程:

  • 添加任务时读取现有任务;
  • 自动生成任务 ID;
  • 将新任务写入 JSON 文件;
  • 查询时展示所有任务;
  • 根据 ID 找到对应任务;
  • 修改任务状态或删除任务。

3. 代码可读性较好

AI 生成的代码一般会包含合理的函数拆分,例如:

  • load_tasks()
  • save_tasks()
  • add_task()
  • list_tasks()
  • complete_task()
  • delete_task()

这类函数命名清楚,便于理解。

4. 边界处理存在不足

虽然 AI 会添加一些基础异常处理,但常常不够完善。例如:

  • JSON 文件损坏时如何处理;
  • ID 不存在时是否有明确提示;
  • 任务标题为空时是否允许添加;
  • 多次删除或完成同一任务时如何反馈;
  • 文件权限异常是否被捕获;
  • 并发写入是否可能造成数据丢失。

这些问题说明,AI 生成代码可以作为初稿,但仍然需要开发者进行审查和增强。


五、附源码:Python 命令行 Todo 工具

下面是经过整理和优化后的完整源码。该版本在 AI 生成代码基础上做了增强,包括输入校验、文件异常处理、JSON 解析异常处理,以及更清晰的命令行提示。

1. 项目结构

todo-ai-demo/
├── todo.py
└── tasks.json

其中:

  • todo.py 是主程序;
  • tasks.json 用于保存任务数据,首次运行时会自动创建。

2. 完整源码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
一个简单的命令行 Todo 工具。

功能:
1. 添加任务
2. 查看任务列表
3. 标记任务完成
4. 删除任务

数据保存在本地 tasks.json 文件中。
"""

import argparse
import json
import os
from typing import List, Dict, Any


TASK_FILE = "tasks.json"


def load_tasks() -> List[Dict[str, Any]]:
    """
    从 JSON 文件中加载任务列表。

    如果文件不存在,则返回空列表。
    如果文件内容损坏,则提示用户并返回空列表。
    """
    if not os.path.exists(TASK_FILE):
        return []

    try:
        with open(TASK_FILE, "r", encoding="utf-8") as file:
            data = json.load(file)

            if not isinstance(data, list):
                print("警告:任务文件格式不正确,已使用空任务列表。")
                return []

            return data

    except json.JSONDecodeError:
        print("警告:tasks.json 内容不是合法 JSON,已使用空任务列表。")
        return []
    except OSError as error:
        print(f"读取任务文件失败:{error}")
        return []


def save_tasks(tasks: List[Dict[str, Any]]) -> None:
    """
    将任务列表保存到 JSON 文件中。
    """
    try:
        with open(TASK_FILE, "w", encoding="utf-8") as file:
            json.dump(tasks, file, ensure_ascii=False, indent=2)
    except OSError as error:
        print(f"保存任务文件失败:{error}")


def get_next_id(tasks: List[Dict[str, Any]]) -> int:
    """
    获取下一个任务 ID。
    """
    if not tasks:
        return 1

    return max(task.get("id", 0) for task in tasks) + 1


def add_task(title: str) -> None:
    """
    添加新任务。
    """
    title = title.strip()

    if not title:
        print("错误:任务标题不能为空。")
        return

    tasks = load_tasks()

    new_task = {
        "id": get_next_id(tasks),
        "title": title,
        "done": False
    }

    tasks.append(new_task)
    save_tasks(tasks)

    print(f"已添加任务:[{new_task['id']}] {new_task['title']}")


def list_tasks(show_all: bool = True) -> None:
    """
    查看任务列表。

    show_all 为 True 时展示全部任务。
    """
    tasks = load_tasks()

    if not tasks:
        print("暂无任务。")
        return

    print("\n任务列表:")
    print("-" * 40)

    for task in tasks:
        if not show_all and task.get("done"):
            continue

        status = "✓" if task.get("done") else " "
        task_id = task.get("id", "?")
        title = task.get("title", "")
        print(f"[{status}] {task_id}. {title}")

    print("-" * 40)


def complete_task(task_id: int) -> None:
    """
    标记任务为完成。
    """
    tasks = load_tasks()

    for task in tasks:
        if task.get("id") == task_id:
            if task.get("done"):
                print(f"任务 [{task_id}] 已经是完成状态。")
                return

            task["done"] = True
            save_tasks(tasks)
            print(f"已完成任务:[{task_id}] {task.get('title')}")
            return

    print(f"未找到 ID 为 {task_id} 的任务。")


def delete_task(task_id: int) -> None:
    """
    删除指定任务。
    """
    tasks = load_tasks()
    new_tasks = [task for task in tasks if task.get("id") != task_id]

    if len(new_tasks) == len(tasks):
        print(f"未找到 ID 为 {task_id} 的任务。")
        return

    save_tasks(new_tasks)
    print(f"已删除任务:[{task_id}]")


def build_parser() -> argparse.ArgumentParser:
    """
    构建命令行参数解析器。
    """
    parser = argparse.ArgumentParser(
        description="一个简单的命令行 Todo 管理工具"
    )

    subparsers = parser.add_subparsers(
        dest="command",
        help="可用命令"
    )

    add_parser = subparsers.add_parser(
        "add",
        help="添加任务"
    )
    add_parser.add_argument(
        "title",
        type=str,
        help="任务标题"
    )

    list_parser = subparsers.add_parser(
        "list",
        help="查看任务列表"
    )
    list_parser.add_argument(
        "--todo",
        action="store_true",
        help="只查看未完成任务"
    )

    complete_parser = subparsers.add_parser(
        "done",
        help="标记任务完成"
    )
    complete_parser.add_argument(
        "id",
        type=int,
        help="任务 ID"
    )

    delete_parser = subparsers.add_parser(
        "delete",
        help="删除任务"
    )
    delete_parser.add_argument(
        "id",
        type=int,
        help="任务 ID"
    )

    return parser


def main() -> None:
    """
    程序入口。
    """
    parser = build_parser()
    args = parser.parse_args()

    if args.command == "add":
        add_task(args.title)
    elif args.command == "list":
        list_tasks(show_all=not args.todo)
    elif args.command == "done":
        complete_task(args.id)
    elif args.command == "delete":
        delete_task(args.id)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()

六、使用示例

1. 添加任务

python todo.py add "学习 AI 编程"
python todo.py add "完成项目文档"
python todo.py add "阅读 Python 官方文档"

输出示例:

已添加任务:[1] 学习 AI 编程
已添加任务:[2] 完成项目文档
已添加任务:[3] 阅读 Python 官方文档

2. 查看全部任务

python todo.py list

输出示例:

任务列表:
----------------------------------------
[ ] 1. 学习 AI 编程
[ ] 2. 完成项目文档
[ ] 3. 阅读 Python 官方文档
----------------------------------------

3. 标记任务完成

python todo.py done 1

输出示例:

已完成任务:[1] 学习 AI 编程

再次查看:

python todo.py list

输出示例:

任务列表:
----------------------------------------
[✓] 1. 学习 AI 编程
[ ] 2. 完成项目文档
[ ] 3. 阅读 Python 官方文档
----------------------------------------

4. 只查看未完成任务

python todo.py list --todo

输出示例:

任务列表:
----------------------------------------
[ ] 2. 完成项目文档
[ ] 3. 阅读 Python 官方文档
----------------------------------------

5. 删除任务

python todo.py delete 2

输出示例:

已删除任务:[2]

七、源码评估

1. 功能完整性

该代码实现了 Todo 工具的核心功能,能够满足基础使用场景:

  • 添加任务;
  • 查看任务;
  • 标记完成;
  • 删除任务;
  • 持久化保存。

对于一个命令行小工具而言,功能闭环已经成立。

评分:8/10

不足之处在于还没有支持任务编辑、优先级、截止日期、分类标签等扩展功能。


2. 代码可读性

代码结构较清晰,函数职责比较单一。例如 load_tasks() 只负责读取任务,save_tasks() 只负责保存任务,业务函数分别处理不同命令。

命名也比较直观,基本符合 Python 的编码习惯。

评分:8.5/10

如果继续优化,可以将任务抽象为 Task 类,或者使用 dataclass 提升结构化程度。


3. 异常处理能力

该版本已经处理了以下异常:

  • 文件不存在;
  • JSON 格式错误;
  • 文件读取失败;
  • 文件保存失败;
  • 任务标题为空;
  • 任务 ID 不存在;
  • 重复完成任务。

评分:7.5/10

不过仍然存在一些可以增强的点,例如:

  • 写文件时可以先写临时文件,再原子替换,避免写入中断导致文件损坏;
  • 可以增加文件锁,减少并发执行时的数据竞争;
  • 可以将错误输出到标准错误流;
  • 可以增加日志记录。

4. 可维护性

目前代码集中在一个文件里,适合演示和小规模使用。如果项目继续增长,可以拆分为:

todo-ai-demo/
├── main.py
├── storage.py
├── service.py
├── cli.py
├── models.py
└── tests/

其中:

  • models.py 存放任务数据结构;
  • storage.py 负责数据读写;
  • service.py 负责业务逻辑;
  • cli.py 负责命令行解析;
  • tests/ 存放测试代码。

评分:7/10

当前版本适合入门,但还不算完整工程化项目。


八、AI 编程的实际优点

通过这个案例,可以明显看到 AI 编程工具在以下方面有较大价值。

1. 降低启动成本

对于很多开发任务来说,最耗费精力的并不一定是核心算法,而是“从零开始搭架子”。AI 可以快速生成初始项目结构,让开发者不必反复编写模板代码。

例如命令行工具中的参数解析、JSON 文件读写、基础函数拆分,这些都属于重复性较高的工作。AI 在这类任务上的表现通常比较稳定。


2. 提高编码速度

如果由人工从零编写上述 Todo 工具,可能需要 20 到 40 分钟,视熟练程度而定。使用 AI 生成初稿后,再进行人工审查和修改,整体时间可能缩短到 5 到 15 分钟。

当然,这并不意味着所有任务都能节省同样比例的时间。越是常规、边界清晰、资料丰富的任务,AI 越容易发挥作用。


3. 辅助学习新技术

当开发者不熟悉某个库、框架或语言特性时,AI 可以给出入门示例。例如开发者不熟悉 argparse,AI 不仅可以生成代码,还能解释每个参数的含义。

这对于学习阶段的开发者非常有帮助。相比单纯查文档,AI 可以根据上下文给出更贴近当前需求的示例。


4. 帮助发现思路盲区

AI 在生成代码时,常常会主动补充一些开发者没有明确提出的内容,例如:

  • 参数校验;
  • 文件不存在处理;
  • 操作成功提示;
  • 帮助文档;
  • 函数注释。

虽然这些补充不一定完美,但可以提醒开发者考虑更完整的使用场景。


九、AI 编程的主要问题

AI 编程虽然有价值,但也存在明显限制,不能盲目信任。

1. 容易生成“看起来正确”的代码

AI 生成的代码通常语法规范、结构整齐,但这并不代表逻辑一定正确。尤其是在复杂业务中,代码可能表面合理,实际遗漏关键规则。

例如在订单系统、权限系统、财务系统中,一个看似微小的条件判断错误,可能造成严重后果。


2. 对隐含需求理解不足

真实业务需求中有大量隐含规则,而 AI 只能根据开发者提供的信息进行推断。如果需求描述不完整,AI 可能会自行补全假设。

例如 Todo 工具中,如果没有说明任务 ID 是否允许重复、删除后 ID 是否复用、是否需要排序,AI 可能选择一种默认方案,但未必符合实际需求。


3. 工程质量依赖提示词质量

同样的 AI 工具,输入不同提示词,输出质量差异很大。如果只是说“写一个 Todo 工具”,得到的代码可能比较粗糙;如果明确说明语言、结构、异常处理、测试要求,结果会好很多。

因此,AI 编程并不是简单地“让 AI 写代码”,而是需要开发者具备清晰表达需求和审查结果的能力。


4. 安全风险不可忽视

AI 可能生成存在安全隐患的代码,例如:

  • SQL 拼接导致注入;
  • 不安全的文件路径处理;
  • 明文存储敏感信息;
  • 缺少鉴权;
  • 依赖过旧或存在漏洞;
  • 错误地暴露环境变量。

因此,在生产环境中使用 AI 生成代码,必须经过代码审查、安全扫描和测试验证。


十、如何更高效地使用 AI 编程

1. 给出清晰的上下文

不要只说“帮我写一个接口”,而应该说明:

  • 使用什么语言;
  • 使用什么框架;
  • 输入参数是什么;
  • 输出格式是什么;
  • 错误如何处理;
  • 是否需要测试;
  • 是否有性能要求;
  • 是否有安全限制。

示例提示词:

请使用 Python 3.11 编写一个命令行 Todo 工具。
要求:
1. 使用 argparse 解析命令;
2. 数据保存到本地 JSON 文件;
3. 支持 add、list、done、delete 四个命令;
4. 对空标题、非法 ID、JSON 文件损坏进行处理;
5. 代码需要函数拆分清晰;
6. 请附带使用示例和简单测试思路。

这样的提示词明显比“写个 Todo 工具”更容易得到高质量结果。


2. 让 AI 先设计再编码

对于稍复杂的需求,不建议直接让 AI 写代码。更好的方式是先让 AI 输出设计方案:

请先不要写代码,先帮我设计模块结构、数据结构、主要函数和异常处理方案。

确认设计合理后,再让 AI 分模块生成代码。这种方式可以减少返工。


3. 要求 AI 解释关键代码

生成代码后,可以继续追问:

请解释 complete_task 函数的执行流程,并指出可能的边界问题。

通过解释,可以发现 AI 是否真的覆盖了关键逻辑,也方便开发者进行代码审查。


4. 使用测试约束 AI 输出

可以要求 AI 同时生成测试用例:

请使用 pytest 为 add_task、complete_task、delete_task 编写单元测试。

测试不一定完全正确,但可以帮助开发者发现遗漏场景。


5. 不要跳过人工审查

AI 生成代码必须经过人工确认,尤其是以下场景:

  • 涉及用户隐私;
  • 涉及支付、资金、订单;
  • 涉及权限和安全;
  • 涉及数据库写入;
  • 涉及生产环境部署;
  • 涉及复杂并发逻辑。

AI 可以提高效率,但责任仍然属于开发者和团队。


十一、可选扩展:单元测试示例

如果希望进一步提升项目质量,可以为核心逻辑添加测试。下面给出一个简单的测试思路示例。为了方便测试,实际项目中最好将 TASK_FILE 改造成可配置参数,避免测试污染真实数据。

示例测试代码:

import os
import json
import tempfile
import unittest
from unittest.mock import patch

import todo


class TestTodoApp(unittest.TestCase):

    def setUp(self):
        self.temp_dir = tempfile.TemporaryDirectory()
        self.task_file = os.path.join(self.temp_dir.name, "tasks.json")

    def tearDown(self):
        self.temp_dir.cleanup()

    def test_add_task(self):
        with patch.object(todo, "TASK_FILE", self.task_file):
            todo.add_task("测试任务")
            tasks = todo.load_tasks()

            self.assertEqual(len(tasks), 1)
            self.assertEqual(tasks[0]["title"], "测试任务")
            self.assertFalse(tasks[0]["done"])

    def test_complete_task(self):
        with patch.object(todo, "TASK_FILE", self.task_file):
            todo.add_task("测试完成任务")
            todo.complete_task(1)

            tasks = todo.load_tasks()
            self.assertTrue(tasks[0]["done"])

    def test_delete_task(self):
        with patch.object(todo, "TASK_FILE", self.task_file):
            todo.add_task("测试删除任务")
            todo.delete_task(1)

            tasks = todo.load_tasks()
            self.assertEqual(len(tasks), 0)


if __name__ == "__main__":
    unittest.main()

运行测试:

python -m unittest test_todo.py

这段测试代码主要验证三个核心功能:

  • 添加任务后文件中是否存在数据;
  • 标记完成后状态是否变为 True
  • 删除任务后任务列表是否为空。

十二、综合评分

结合本次测评,可以给 AI 编程在该类任务中的表现一个综合评分:

指标 评分
需求理解 8/10
代码生成速度 9/10
基础功能实现 8/10
代码可读性 8.5/10
异常处理 7/10
工程化能力 7/10
安全意识 6.5/10
测试生成能力 7/10
综合表现 7.8/10

总体来看,AI 在小型工具、脚本、通用业务逻辑和模板代码方面表现良好,已经可以作为开发者的高效助手。但在复杂业务、严肃工程、安全场景中,它仍然需要人工把关。


十三、结论

AI 编程不是魔法,也不是噱头。它的真实价值在于:帮助开发者更快进入问题核心,减少重复劳动,提高迭代速度。

在本次 Todo 命令行工具测评中,AI 可以较好地完成基础代码生成,并提供清晰的程序结构。经过人工优化后,代码具备了较好的可读性和可用性。对于个人项目、原型验证、学习练习、内部工具开发,AI 编程已经具有很高的实用价值。

但与此同时,AI 生成代码仍然存在边界处理不足、隐含需求理解有限、安全意识不稳定等问题。开发者不能将 AI 输出直接视为最终答案,而应将其作为“高质量初稿”或“编程协作伙伴”。

更合理的使用方式是:

  1. 人类负责定义目标、约束和业务规则;
  2. AI 负责快速生成初稿、补全代码和提出建议;
  3. 人类负责审查、测试、优化和最终决策。

未来的开发模式很可能不是“AI 替代程序员”,而是“会使用 AI 的程序员替代不会使用 AI 的程序员”。对于开发者来说,掌握 AI 编程工具的使用方法,已经逐渐成为一项新的基础能力。

目录结构
全文