选一段代码丢进去,AI 自动给你生成清晰准确的注释。支持 Python、JavaScript、Go、Java 等多种语言,注释风格可自定义,注释质量直接拉满。
你有没有这种经历:翻出自己半年前写的代码,发现根本看不懂自己在干什么。
不是代码写得烂,而是注释太少。你觉得当时很简单,随手写了两行就过了。等回头再看,function 叫什么、参数传什么、为什么要这么写,全都搞不清楚了。
更常见的是,接手别人的代码,注释写得天花乱坠,但核心逻辑还是模糊。
今天做一个 AI 代码注释生成器。选一段代码丢进去,它自动分析逻辑,生成清晰准确的注释。全程本地跑,代码不上传,免费用。
项目背景
代码注释是开发者的老难题。写注释花 time,不写又难维护。人工写注释有几个痛点:
- 懒得写,项目赶进度时直接跳过
- 写了但不准确,反而误导读者
- 风格不统一,有的用 docstring,有的用行注释
- 改了代码忘改注释,注释和逻辑对不上
用 AI 做这件事,优势很明显:它不用你动笔,读完代码就能输出结构化注释。而且可以按你的要求调整风格——简洁版、详细版、行注释、块注释,全都行。
技术选型
| 组件 | 选型 | 理由 |
|---|---|---|
| 大模型 | Ollama + qwen2.5:7b | 中文注释理解强,本地免费 |
| 备选模型 | Ollama + llama3.2 | 英文代码效果更好 |
| 语言检测 | 根据文件扩展名判断 | 简单直接,够用 |
| 交互方式 | 终端 CLI | 零配置,直接跑 |
| 输入输出 | 原文件 + 生成注释 | 支持原地覆盖或另存 |
不需要 Web 框架,不需要数据库。纯 Python 脚本,跑在任意有 Ollama 的机器上。
实现步骤
第一步:安装 Ollama 和模型
# 安装 Ollama(如果还没装)
curl -fsSL https://ollama.com/install.sh | sh
# 拉取模型
ollama pull qwen2.5:7b
8GB 内存够用。代码注释任务不需要太大模型,7b 版本响应速度快,质量已经足够好。
第二步:安装 Python 依赖
pip install ollama
就一个包。
第三步:写注释生成器
新建 comment_generator.py:
#!/usr/bin/env python3
"""AI 代码注释生成器"""
import ollama
import sys
import os
from pathlib import Path
# 支持的语言和文件扩展名
LANGUAGE_MAP = {
".py": "Python",
".js": "JavaScript",
".ts": "TypeScript",
".jsx": "JavaScript",
".tsx": "TypeScript",
".go": "Go",
".java": "Java",
".c": "C",
".cpp": "C++",
".cs": "C#",
".rs": "Rust",
".php": "PHP",
".rb": "Ruby",
".swift": "Swift",
".kt": "Kotlin",
}
# 注释风格模板
STYLE_TEMPLATES = {
"concise": "简洁版:每个函数只写一行说明,重点写清做什么、返回什么。",
"detailed": "详细版:每个函数写完整 docstring,包含参数说明、返回值、异常说明、使用示例。",
"inline": "行注释版:在每行关键代码旁边写注释,解释为什么这么写。",
}
def detect_language(filepath: str) -> str:
"""根据文件扩展名检测编程语言"""
ext = Path(filepath).suffix.lower()
return LANGUAGE_MAP.get(ext, "Unknown")
def read_code(filepath: str) -> str:
"""读取代码文件内容"""
with open(filepath, "r", encoding="utf-8") as f:
return f.read()
def generate_comments(code: str, language: str, style: str) -> str:
"""调用 Ollama 生成注释"""
style_desc = STYLE_TEMPLATES.get(style, style)
prompt = f"""你是一个专业的代码注释生成助手。你的任务是为给定的代码生成高质量的注释。
代码语言:{language}
注释风格:{style_desc}
要求:
1. 注释必须准确反映代码的实际逻辑
2. 对于函数/方法,说明其用途、参数含义和返回值
3. 对于复杂逻辑,解释为什么这样做
4. 不要添加冗余注释,每行注释都要有价值
5. 保持原有代码结构不变,只在适当位置插入注释
6. 用中文写注释
请直接输出添加了注释的完整代码,不要解释其他内容。
代码:
```{language.lower() if language != "Unknown" else "text"}
{code}
"""
response = ollama.chat(
model="qwen2.5:7b",
messages=[{"role": "user", "content": prompt}]
)
return response["message"]["content"]
def main(): if len(sys.argv) < 2: print(“用法: python comment_generator.py <代码文件路径> [风格]”) print("") print(“风格选项:”) print(" concise - 简洁版(默认)") print(" detailed - 详细版") print(" inline - 行注释版") print("") print(“示例:”) print(" python comment_generator.py my_script.py") print(" python comment_generator.py my_script.py detailed") print(" python comment_generator.py src/main.go inline") sys.exit(1)
filepath = sys.argv[1]
style = sys.argv[2] if len(sys.argv) > 2 else "concise"
# 检查文件
if not os.path.exists(filepath):
print(f"❌ 文件不存在: {filepath}")
sys.exit(1)
# 检测语言
language = detect_language(filepath)
if language == "Unknown":
print(f"⚠️ 未识别的文件类型: {filepath},将作为通用代码处理")
language = "通用代码"
print(f"📄 文件: {filepath}")
print(f"🔤 语言: {language}")
print(f"📝 风格: {style}")
print(f"🤖 正在分析代码,生成注释...")
# 读取代码
code = read_code(filepath)
# 生成注释
try:
commented_code = generate_comments(code, language, style)
except Exception as e:
print(f"❌ 生成失败: {e}")
print("请确认 Ollama 正在运行: ollama list")
sys.exit(1)
# 保存结果
original_path = Path(filepath)
style_suffix = f"_{style}" if style != "concise" else ""
output_path = original_path.parent / f"{original_path.stem}{style_suffix}_commented{original_path.suffix}"
with open(output_path, "w", encoding="utf-8") as f:
f.write(commented_code)
print(f"✅ 注释已生成,保存到: {output_path}")
print(f"💡 对比方法:diff {filepath} {output_path}")
if name == “main”: main()
### 第四步:准备待注释的代码
随便写一段代码,保存为 `example.py`:
```python
def find_max_min(arr):
if not arr:
return None, None
max_val = arr[0]
min_val = arr[0]
for i in range(1, len(arr)):
if arr[i] > max_val:
max_val = arr[i]
elif arr[i] < min_val:
min_val = arr[i]
return max_val, min_val
def merge_sorted_arrays(a, b):
result = []
i = j = 0
while i < len(a) and j < len(b):
if a[i] <= b[j]:
result.append(a[i])
i += 1
else:
result.append(b[j])
j += 1
result.extend(a[i:])
result.extend(b[j:])
return result
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
if self.is_empty():
return None
return self.items.pop()
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
第五步:运行注释生成器
# 简洁版(默认)
python comment_generator.py example.py
# 详细版
python comment_generator.py example.py detailed
# 行注释版
python comment_generator.py example.py inline
运行后会自动生成 example_converted_commented.py 等文件。
第六步:对比效果
# 用 diff 对比原文件和注释后的文件
diff example.py example_converted_commented.py
# 或者用 meld 做可视化对比
meld example.py example_converted_commented.py
运行效果
以 example.py 为例,运行后生成的注释代码效果如下:
# 简洁版输出示例:
def find_max_min(arr):
"""返回数组中的最大值和最小值,使用一次遍历,时间复杂度 O(n)"""
if not arr:
return None, None
max_val = arr[0]
min_val = arr[0]
for i in range(1, len(arr)):
if arr[i] > max_val:
max_val = arr[i]
elif arr[i] < min_val:
min_val = arr[i]
return max_val, min_val
def merge_sorted_arrays(a, b):
"""合并两个已排序数组,保持有序性,时间复杂度 O(len(a) + len(b))"""
result = []
i = j = 0
while i < len(a) and j < len(b):
if a[i] <= b[j]:
result.append(a[i])
i += 1
else:
result.append(b[j])
j += 1
result.extend(a[i:])
result.extend(b[j:])
return result
class Stack:
"""基于列表实现的栈数据结构"""
def __init__(self):
"""初始化空栈"""
self.items = []
def push(self, item):
"""将元素压入栈顶"""
self.items.append(item)
def pop(self):
"""弹出并返回栈顶元素,栈为空时返回 None"""
if self.is_empty():
return None
return self.items.pop()
def is_empty(self):
"""判断栈是否为空"""
return len(self.items) == 0
def size(self):
"""返回栈中元素个数"""
return len(self.items)
详细版会在每个函数前生成包含参数说明、返回值、异常说明的完整 docstring。
优化方向
脚本跑通之后,还可以继续扩展:
批量处理:扫描整个项目目录,对所有代码文件批量生成注释,适合重构老项目。
增量更新:记录上次生成注释的时间,只处理新增或修改过的函数,节省 API 调用。
风格记忆:把人工修改过的注释存下来,下次生成时参考,让 AI 逐渐学习你的注释习惯。
多模型对比:同时用 qwen2.5 和 llama3.2 生成,对比两个版本,选注释质量更好的。
集成到 IDE:写成 VS Code 插件,选中代码按快捷键就能生成注释,开发流程无缝衔接。
质量评分:生成注释后,让 AI 对自己的注释打分,低于阈值的自动重新生成。
核心思路很简单:好的注释不是写出来的,是理解代码后自然生成的。AI 擅长理解代码,你只需要告诉它想要什么风格的注释。
你的项目里有没有注释太少、想补又懒得补的代码?把它丢进去跑一圈看看效果。
这篇文章对你有帮助吗?