让 AI 写出「三个月后还能看懂」的代码:一套可落地的 Prompt 工程实战
让 AI 写出「三个月后还能看懂」的代码:一套可落地的 Prompt 工程实战
很多人用 AI 写代码的方式是这样的:粘贴需求,拿到代码,跑通,提交,完事。
三个月后打开那个文件,完全不知道某个函数在干嘛,注释要么没有,要么写着 # 处理数据。
这不是 AI 的问题,是你没告诉它你要什么。AI 的默认目标是「能跑」,你的目标应该是「能维护」。这两件事差距很大。
问题出在哪?
AI 生成的代码有几个典型毛病:
1. 变量名是 data、result、temp — 没有业务含义
2. 函数没有说明「为什么这么做」 — 只有「做了什么」
3. 边界情况被静默忽略 — except: pass 满天飞
4. 没有类型注解 — 一个月后你不知道这个参数传什么
解决方案不是写更复杂的 Prompt,而是给 AI 一个结构化的代码生成约束模板,每次调用时自动注入。
实战:用 API 构建一个「可维护代码生成器」
下面这段代码会调用 Claude,但加了一层系统级约束,强迫它输出符合可维护标准的代码。
from openai import OpenAI
client = OpenAI(
api_key="your_api_key",
base_url="https://api2everything.xyz/v1" # 国内直连,无需代理
)
MAINTAINABLE_CODE_SYSTEM_PROMPT = """
你是一位资深工程师,专注于写「六个月后的自己还能看懂」的代码。
每次生成代码,你必须遵守以下规则:
【命名规范】
- 变量名必须体现业务含义,禁止使用 data/result/temp/item 等泛化名词
- 函数名用动词短语,清晰表达行为(如 fetch_user_orders_by_date)
【注释规范】
- 每个函数必须有 docstring,包含:功能描述、参数说明、返回值、可能抛出的异常
- 非显而易见的逻辑必须有行内注释,注释写「为什么」而不是「做了什么」
【类型注解】
- 所有函数参数和返回值必须有类型注解
- 复杂数据结构使用 TypedDict 或 dataclass 定义
【错误处理】
- 禁止裸 except,必须捕获具体异常类型
- 错误信息必须包含足够的上下文,方便 debug
【结构规范】
- 单个函数不超过 30 行
- 如果逻辑复杂,拆分成多个小函数,每个函数只做一件事
输出格式:先给代码,然后附一段「维护说明」,解释三个月后接手这段代码的人需要知道什么。
"""
def generate_maintainable_code(requirement: str, language: str = "Python") -> str:
"""
根据需求生成符合可维护标准的代码。
Args:
requirement: 用自然语言描述的功能需求
language: 目标编程语言,默认 Python
Returns:
包含代码和维护说明的字符串
Raises:
ValueError: 当 requirement 为空时
APIError: 当 API 调用失败时
"""
if not requirement.strip():
raise ValueError("需求描述不能为空")
user_message = f"语言:{language}\n需求:{requirement}"
response = client.chat.completions.create(
model="claude-sonnet-4-5", # 或换成 gpt-4o、deepseek-v3 等
messages=[
{"role": "system", "content": MAINTAINABLE_CODE_SYSTEM_PROMPT},
{"role": "user", "content": user_message}
],
temperature=0.3 # 代码生成用低温,减少随机性
)
return response.choices[0].message.content
def main():
# 示例需求
requirement = """
从 PostgreSQL 数据库中查询某用户最近 30 天的订单,
按金额降序排列,返回前 10 条,
需要处理数据库连接失败的情况
"""
print("正在生成可维护代码...\n")
result = generate_maintainable_code(requirement)
print(result)
if __name__ == "__main__":
main()
效果对比
没有约束时,AI 可能给你这个:
def get_orders(user_id):
result = db.query(f"SELECT * FROM orders WHERE user_id={user_id}")
data = sorted(result, key=lambda x: x[3], reverse=True)
return data[:10]
三个月后你不知道 x[3] 是什么字段,SQL 注入风险,无错误处理。
加了约束之后,你会得到:
from typing import Optional
from dataclasses import dataclass
from psycopg2 import OperationalError, ProgrammingError
import logging
logger = logging.getLogger(__name__)
@dataclass
class OrderSummary:
order_id: str
amount: float
created_at: str
status: str
def fetch_recent_top_orders_by_amount(
user_id: str,
days_back: int = 30,
limit: int = 10
) -> list[OrderSummary]:
"""
查询用户最近一段时间内金额最高的订单。
使用参数化查询防止 SQL 注入。
按 amount 降序排列是因为业务方需要优先展示高价值订单(见 PRD v2.3)。
Args:
user_id: 用户唯一标识符
days_back: 向前追溯的天数
limit: 返回的最大条数
Returns:
按金额降序排列的订单列表
Raises:
OperationalError: 数据库连接失败
ProgrammingError: SQL 语法错误(通常是 schema 变更导致)
"""
# ...
差距一目了然。
进一步:批量审查存量代码
如果你有一个老项目想批量改善可读性,可以在上面脚本基础上加一个文件扫描:
import ast
from pathlib import Path
def review_python_file(file_path: str) -> str:
"""读取 Python 文件并让 AI 给出可维护性改进建议"""
source_code = Path(file_path).read_text(encoding="utf-8")
review_prompt = f"""
请审查以下代码的可维护性,指出具体问题并给出改进版本:
```python
{source_code}
```
重点关注:命名、注释、类型注解、错误处理。
输出格式:问题列表 → 改进后的完整代码。
"""
response = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": review_prompt}],
temperature=0.2
)
return response.choices[0].message.content
关于 API 费用
上面的代码用的是 Claude Sonnet,官方价格不便宜。我最近在用无量Api(api2everything.xyz),同样的接口格式,只需要改一行 base_url,价格比官方便宜 60% 以上,支持 Claude、GPT-4o、DeepSeek、Gemini 300 多个模型,国内直连不需要代理。注册还送 ¥1 体验额度,余额永久不过期。
对于这种批量代码审查的场景,token 消耗量不小,省这部分钱还是很实际的。
总结
让 AI 写出可维护代码的核心不是换更好的模型,而是:
- 系统 Prompt 做约束,把你的团队规范注入进去
- 低温度生成,代码不需要创意,需要稳定
- 要求输出维护说明,强迫 AI 交代上下文
这套模板可以直接复制进你的工具链,不用每次手动提醒 AI「记得写注释」。
有问题欢迎评论区交流,如果对你有帮助点个赞,后续会继续写 Prompt 工程实战系列。