目 录CONTENT

文章目录

AI能编写Python代码,但维护工作仍是你的职责

Administrator
2026-01-21 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://www.kdnuggets.com/ai-writes-python-code-but-maintaining-it-is-still-your-job

原文作者:Bala Priya C


AI Writes Python Code But Maintaining It Is Still Your Job
Image by Author

 

# 引言

 
人工智能编码工具在编写可运行的Python代码方面正变得非常出色。它们可以在几分钟内构建完整的应用程序和实现复杂的算法。然而,AI生成的代码在维护时往往会带来麻烦。

如果您正在使用Claude CodeGitHub CopilotCursor的智能体模式等工具,您很可能体验过这种情况。AI帮助您快速交付可运行的代码,但代价会在稍后体现。您很可能在代码生成几周后,为了理解一个臃肿的函数是如何工作的而对其进行重构。

问题不在于AI编写了糟糕的代码——尽管有时确实如此——而在于AI优化的是“当下就能运行”并完成您提示中的要求,而您需要的是长期可读、可维护的代码。本文将着重于Python特定的策略,向您展示如何弥合这一差距。

 

# 避免“空白画布”陷阱

 
开发人员犯的最大错误是让AI从零开始。AI智能体在有明确的约束和指导方针时效果最佳。

在编写第一个提示之前,请自己设置好项目的基本要素。这意味着要确定您的项目结构——安装核心库并实现几个工作示例——以定下基调。这看起来可能适得其反,但它有助于AI编写出更符合您应用程序需求的 যথার্থ代码。

首先手动构建少数功能。如果您正在构建一个API,请自己实现一个完整的端点,包含您想要的所有模式:依赖注入、适当的错误处理、数据库访问和验证。这将成为参考实现。

假设您手动编写了第一个端点:

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

router = APIRouter()

# 假设 get_db 和 User 模型已在别处定义
async def get_user(user_id: int, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

 

当AI看到这种模式时,它就会理解我们如何处理依赖项、如何查询数据库以及如何处理缺失的记录。

这同样适用于您的项目结构。创建目录、设置导入并配置测试框架。AI不应该做这些架构决策。

 

# 让Python的类型系统承担重任

 
Python的动态类型很灵活,但这种灵活性在AI编写代码时会成为一个负担。将类型提示作为应用程序代码中必不可少的护栏,而不是可有可无的选项。

严格的类型检查可以在AI错误进入生产环境之前将其捕获。当您要求每个函数签名都带有类型提示,并以严格模式运行mypy时,AI就不能投机取巧。它不能返回模糊的类型,也不能接受可能是字符串也可能是列表的参数。

更重要的是,严格的类型会强制更好的设计。例如,一个AI智能体尝试编写一个接受 data: dict 的函数可能会对该字典的内容做出许多假设。然而,一个接受 data: UserCreateRequest(其中 UserCreateRequest 是一个Pydantic模型)的函数的AI智能体只有一个确切的解释。

# 这会约束AI编写正确的代码
from pydantic import BaseModel, EmailStr

class UserCreateRequest(BaseModel):
    name: str
    email: EmailStr
    age: int

class UserResponse(BaseModel):
    id: int
    name: str
    email: EmailStr

def process_user(data: UserCreateRequest) -> UserResponse:
    pass

# 而不是这样
# def process_user(data: dict) -> dict:
#     pass

 

使用强制契约的库:使用支持类型检查的模型(如SQLAlchemy 2.0)和使用响应模型的FastAPI是绝佳的选择。这些不仅仅是好的实践;它们是约束AI保持正轨的屏障。

将mypy设置为严格模式,并使通过类型检查成为不可协商的条件。当AI生成的代码无法通过类型检查时,它会迭代直到通过。这种自动反馈循环产生的代码质量优于任何提示工程。

 

# 创建文档来指导AI

 
大多数项目都有被开发人员忽略的文档。对于AI智能体,您需要它们实际使用的文档——比如一份带有指导方针的README.md文件。这意味着一个包含清晰、具体规则的单个文件。

在项目根目录下创建一个CLAUDE.mdAGENTS.md文件。不要写得太长。重点关注项目独有的内容,而不是通用的Python最佳实践。

您的AI指南应明确规定:

  • 项目结构及不同类型代码的存放位置
  • 哪些库用于常见任务
  • 需要遵循的具体模式(指向示例文件)
  • 明确禁止的模式
  • 测试要求

这里是一个AGENTS.md文件的示例:

# 项目指南

## 结构
/src/api - FastAPI 路由器
/src/services - 业务逻辑
/src/models - SQLAlchemy 模型
/src/schemas - Pydantic 模型

## 模式
- 所有服务都继承自 BaseService (参见 src/services/base.py)
- 所有数据库访问都通过仓库模式 (参见 src/repositories/)
- 对所有外部依赖使用依赖注入

## 标准
- 所有函数都包含类型提示
- 使用 Google 风格的文档字符串
- 函数长度限制在 50 行以内
- 提交前运行 `mypy --strict` 和 `ruff check`

## 禁止
- 禁止裸露的 except 子句
- 禁止使用 type: ignore 注释
- 禁止可变默认参数
- 禁止全局状态

 

关键在于具体。不要只说“遵循最佳实践”。要指出确切演示该模式的文件。不要只说“正确处理错误”;要展示您想要的错误处理模式。

 

# 编写指向示例的提示词

 
泛泛的提示词产生泛泛的代码。引用您现有代码库的特定提示词会产生更具可维护性的代码。

不要只要求AI“添加身份验证”,而是通过引用您的模式引导它完成实现。这是一个指向示例的提示词示例:

src/services/auth_service.py 中实现 JWT 身份验证。遵循 src/services/user_service.pyUserService 的相同结构。使用 bcrypt 进行密码哈希(已在 requirements.txt 中)。
src/api/dependencies.py 中添加身份验证依赖项,遵循 get_db 的模式。
src/schemas/auth.py 中创建 Pydantic 模式,类似于 user.py
tests/test_auth_service.py 中添加 pytest 测试,使用 conftest.py 中的 fixture。

 

请注意,每个指令都指向一个现有的文件或模式。您不是要求AI构建架构;您是要求它将所需内容应用于新功能。

当AI生成代码时,对照您的模式进行审查。它是否使用了相同的依赖注入方法?它是否遵循相同的错误处理?它是否以相同的方式组织导入?如果不是,请指出差异并要求它与现有模式保持一致。

 

# 在实现前进行规划

 
AI智能体移动速度很快,这有时会降低其用处,如果速度是以牺牲结构为代价的。在编写任何代码之前,请使用计划模式或要求提供实施计划。

规划步骤会迫使AI思考依赖关系和结构。它还为您提供了一个在实现之前捕获架构问题(如循环依赖或冗余服务)的机会。

要求一个明确的计划,具体说明:

  • 将创建或修改哪些文件
  • 组件之间存在哪些依赖关系
  • 将遵循哪些现有模式
  • 需要哪些测试

像审查设计文档一样审查此计划。确认AI理解您的项目结构。验证它是否正在使用正确的库,并确认它没有重复已经存在的功能。

如果计划看起来不错,就让AI执行。如果不是,请在编写任何代码之前纠正计划。修复一个糟糕的计划比修复糟糕的代码要容易得多。

 

# 编写真正进行测试的测试用例

 
AI非常擅长快速编写测试。然而,除非您明确了“有用”的含义,否则AI在编写有用的测试方面效率不高。

默认的AI测试行为是只测试“快乐路径”(即一切顺利的情况),而别无其他。您会得到验证代码在一切顺利时能正常运行的测试,而这恰恰是您最不需要测试的时候。

明确指定您的测试要求。对于每个功能,要求包含:

  • 快乐路径测试
  • 验证错误测试,以检查无效输入时会发生什么
  • 边缘情况测试,包括空值、None、边界条件等
  • 错误处理测试,例如数据库失败、外部服务失败等

将AI指向您现有的测试文件作为示例。如果您已经有了良好的测试模式,AI也会编写有用的测试。如果您还没有好的测试,请先自己编写几个。

 

# 系统地验证输出

 
AI生成代码后,不要只检查它是否能运行。要通过一份清单对其进行运行检查。

您的验证清单应包括以下问题:

  • 它是否通过了mypy严格模式检查
  • 它是否遵循了现有代码的模式
  • 所有函数是否都在 50 行以内
  • 测试是否涵盖了边缘情况和错误
  • 所有函数是否都有类型提示
  • 它是否正确使用了指定的库

尽可能将检查自动化。设置pre-commit钩子来运行mypy、Ruff和pytest。如果AI生成的代码未能通过这些检查,则不允许提交。

对于无法自动化的部分,在审查了足够多的AI代码后,您会发现常见的反模式——例如功能过多、吞噬异常的错误处理,或者业务逻辑与验证逻辑混合在一起。

 

# 实施实用的工作流程

 
现在让我们把到目前为止讨论的所有内容整合起来。

您启动一个新项目。您花时间设置结构、选择和安装库,并编写少数示例功能。您创建CLAUDE.md文件,其中包含您的指南,并编写了具体的Pydantic模型。

现在您要求AI实现一个新功能。您编写了一个详细的提示词,其中引用了您的示例。AI生成一个计划。您审查并批准它。AI编写代码。您运行类型检查和测试。一切都通过了。您根据您的模式审查了代码。它匹配了。您提交。

一个功能从提示到提交的总时间可能只有大约15分钟,而手动编写可能需要一个小时。但更重要的是,您获得的 যাইতেছে代码更容易维护——它遵循了您建立的模式。

下一个功能会更快,因为AI有更多的示例可以学习。随着时间的推移,代码会变得更加一致,因为每个新功能都会强化现有的模式。

 

# 总结

 
随着AI编码工具被证明非常有用,您作为开发人员或数据专业人员的工作正在发生变化。您现在花费在编写代码上的时间更少了,而花在以下方面的时间更多了:

  • 设计系统和选择架构
  • 创建模式的参考实现
  • 编写约束和指南
  • 审查AI输出并保持质量标准

最重要的技能不是写代码的速度。而是设计能够约束AI以编写可维护代码的系统。是知道哪些实践可以扩展,哪些会产生技术债务。我希望这篇文章对您有所帮助,即使您选择的编程语言不是Python。让我们知道您认为我们还能做些什么来保持AI生成的Python代码的可维护性。请继续探索!
 
 

Bala Priya C 是来自印度的开发者和技术作家。她喜欢在数学、编程、数据科学和内容创作的交叉点上工作。她的兴趣和专长领域包括DevOps、数据科学和自然语言处理。她喜欢阅读、写作、编码和咖啡!目前,她正致力于通过撰写教程、操作指南、观点文章等方式来学习并与开发者社区分享她的知识。Bala还创建引人入胜的资源概述和编码教程。




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区