把手写复杂代码丢给本地 LLM,自动翻译成大白话+逐行注释+画流程图。代码看不懂?本地 AI 替你拆解。
项目背景
你是不是也经历过这种场景:接手一段前人写的代码,功能逻辑复杂,注释几乎没有,看半天看不懂在干嘛。
上网搜解决方法?把代码贴给 ChatGPT 吧,敏感业务逻辑全上传到人家服务器;用本地模型吧,又不会搭。
其实用 Ollama 搭一个本地代码解释器很简单——代码不离开本地,翻译、注释、画流程图一步到位。
这个项目的目标:输入一段代码,输出大白话解释 + 逐行中文注释 + 调用流程图,全在本地跑。
技术选型
| 组件 | 选择 | 理由 |
|---|---|---|
| 语言 | Python 3.10+ | 生态成熟 |
| LLM | Ollama + Qwen2.5-Coder | 代码理解能力强,本地免费 |
| 代码解析 | tree-sitter | 抽象语法树,精准定位代码结构 |
| 流程图 | Graphviz (digraph) | 轻量,Python 直接调用 |
| 输出格式 | Markdown | 兼容性好,可直接嵌入文档 |
不需要数据库,不需要后端服务。一个脚本,一段代码,出来就是解释结果。
实现步骤
第一步:安装依赖
pip install ollama tree-sitter tree-sitter-python graphviz
brew install graphviz # macOS
# 或 sudo apt install graphviz # Ubuntu
启动 Ollama 并拉取代码专用模型:
ollama pull qwen2.5-coder:7b
ollama serve
第二步:项目结构
code_explainer/
├── explainer.py # 主脚本
├── prompts.py # 提示词模板
├── parser.py # 代码结构解析
├── visualizer.py # 流程图生成
├── config.yaml # 配置文件
└── samples/ # 示例代码
└── example.py
第三步:编写主脚本
explainer.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import json
import ollama
import yaml
from pathlib import Path
from parser import parse_code_structure
from visualizer import generate_flowchart
from prompts import (
EXPLAIN_PROMPT,
COMMENT_PROMPT,
FLOW_PROMPT
)
def load_config(config_path: str = "config.yaml") -> dict:
"""加载配置文件"""
with open(config_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
def explain_code(code: str, model: str = "qwen2.5-coder:7b", config: dict = None) -> dict:
"""调用 Ollama 解释代码"""
cfg = config or load_config()
# 1. 大白话解释
explain_resp = ollama.chat(
model=model,
messages=[{
"role": "user",
"content": EXPLAIN_PROMPT.format(code=code, language=cfg.get("language", "python"))
}]
)
plain_explain = explain_resp["message"]["content"].strip()
# 2. 逐行注释
comment_resp = ollama.chat(
model=model,
messages=[{
"role": "user",
"content": COMMENT_PROMPT.format(code=code, language=cfg.get("language", "python"))
}]
)
commented_code = comment_resp["message"]["content"].strip()
# 3. 流程图描述(给 visualizer 用)
flow_resp = ollama.chat(
model=model,
messages=[{
"role": "user",
"content": FLOW_PROMPT.format(code=code)
}]
)
flow_desc = flow_resp["message"]["content"].strip()
return {
"plain_explain": plain_explain,
"commented_code": commented_code,
"flow_desc": flow_desc
}
def process_file(file_path: str, output_dir: str = "output"):
"""处理单个代码文件"""
code = Path(file_path).read_text(encoding="utf-8")
model = load_config().get("model", "qwen2.5-coder:7b")
print(f"📄 正在分析: {file_path}")
print(f"🤖 使用模型: {model}")
print("-" * 50)
result = explain_code(code, model=model)
# 生成输出目录
out = Path(output_dir)
out.mkdir(exist_ok=True)
base_name = Path(file_path).stem
# 保存大白话解释
explain_file = out / f"{base_name}_explain.md"
explain_file.write_text(f"# {base_name} 代码解释\n\n{result['plain_explain']}\n", encoding="utf-8")
print(f"✅ 解释已保存: {explain_file}")
# 保存带注释的代码
comment_file = out / f"{base_name}_commented.py"
comment_file.write_text(result["commented_code"], encoding="utf-8")
print(f"✅ 注释代码已保存: {comment_file}")
# 生成流程图
flow_file = out / f"{base_name}_flowchart.dot"
flow_file.write_text(result["flow_desc"], encoding="utf-8")
print(f"✅ 流程图描述已保存: {flow_file}")
# 尝试渲染流程图
try:
import graphviz as gv
dot = gv.Source(result["flow_desc"])
dot.render(out / f"{base_name}_flowchart", format="png", cleanup=True)
print(f"✅ 流程图已渲染: {out / f'{base_name}_flowchart.png'}")
except Exception as e:
print(f"⚠️ 流程图渲染失败: {e}")
# 打印到终端
print("\n" + "=" * 50)
print("📖 大白话解释:")
print("=" * 50)
print(result["plain_explain"])
print("\n" + "=" * 50)
print("💬 终端输出完成,结果已保存到 output/ 目录")
def main():
if len(sys.argv) < 2:
print("用法: python explainer.py <代码文件路径> [输出目录]")
print("示例: python explainer.py samples/example.py ./output")
sys.exit(1)
code_file = sys.argv[1]
output_dir = sys.argv[2] if len(sys.argv) > 2 else "output"
if not Path(code_file).exists():
print(f"❌ 文件不存在: {code_file}")
sys.exit(1)
process_file(code_file, output_dir)
if __name__ == "__main__":
main()
第四步:编写提示词模板
prompts.py:
# 大白话解释提示词
EXPLAIN_PROMPT = """你是一位经验丰富的程序员,擅长把复杂代码翻译成普通人能听懂的话。
请用中文解释以下 {language} 代码的功能和逻辑:
```{language}
{code}
```
要求:
1. 用一段话概括这段代码的核心功能(不超过100字)
2. 列出代码的输入、输出和关键步骤
3. 指出代码中可能存在的性能问题或潜在 bug
4. 给出改进建议(不超过3条)
只输出解释内容,不要重复代码。"""
# 逐行注释提示词
COMMENT_PROMPT = """你是代码注释专家。请为以下 {language} 代码添加详细的中文注释。
```{language}
{code}
```
要求:
1. 文件头注释说明文件用途
2. 每个函数/方法添加 docstring
3. 关键逻辑行添加行内注释
4. 复杂算法添加步骤说明
直接输出带注释的完整代码,不要添加额外解释。"""
# 流程图提示词
FLOW_PROMPT = """请分析以下代码的逻辑流程,输出 DOT 格式的有向图描述。
```python
{code}
```
要求:
1. 用节点表示关键步骤(函数调用、条件判断、循环等)
2. 用箭头表示执行顺序
3. 条件分支标注 true/false
4. 使用标准的 DOT 语法
只输出 DOT 代码,格式如下:
digraph {
rankdir=TB;
node [shape=box];
...
}"""
第五步:运行
# 先准备一段示例代码
python explainer.py samples/example.py ./output
运行后你会得到三个文件:
example_explain.md— 大白话解释example_commented.py— 带中文注释的代码example_flowchart.png— 流程图
终端输出示例:
📄 正在分析: samples/example.py
🤖 使用模型: qwen2.5-coder:7b
--------------------------------------------------
✅ 解释已保存: output/example_explain.md
✅ 注释代码已保存: output/example_commented.py
✅ 流程图描述已保存: output/example_flowchart.dot
✅ 流程图已渲染: output/example_flowchart.png
==================================================
📖 大白话解释:
==================================================
这段代码实现了一个简单的缓存装饰器...
运行效果
以这段经典的快速排序为例:
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
AI 生成的解释:
核心功能:对列表进行升序排序,使用分治策略,每次选中间元素作为基准点,将数组分为小于、等于、大于三部分,递归排序后合并。
输入:任意可比较元素的列表 输出:排序后的新列表(不修改原列表)
潜在问题:
- 每次递归都创建三个新列表,内存开销大
- 最坏情况 O(n²),虽然概率低
改进建议:
- 改为原地排序,减少内存分配
- 使用三数取中法选择 pivot
流程图会自动画出递归调用结构,一眼看清数据流向。
优化方向
支持多语言:当前只解析 Python,加上 JavaScript、Go 等语言的 tree-sitter parser,输入不同语言自动切换。
批量处理:加个
--dir参数,一次性处理整个目录的代码文件,适合给新项目做整体解读。增量解释:只解释修改过的部分,不重复分析未改动代码。结合 git diff 实现。
交互式问答:加个 REPL 模式,解释完之后可以继续追问"这个函数为什么这么写?““有没有更简单的写法?”
集成 IDE:做成 VSCode 插件,选中代码右键就能看解释,写代码时实时提示。
模型切换:短代码用
llama3.2:1b秒出结果,复杂算法切到qwen2.5-coder:14b提升准确率。导出 PDF:把解释、注释代码、流程图打包成一份 PDF 报告,发给同事直接看。
核心思路就一句:代码看不懂的时候,本地 AI 替你拆。不用联网,不用担心泄露,模型选对解释质量就够了。
你手头有没有一段看不懂的老代码?直接喂进去试试,看 AI 能不能给你讲清楚。
这篇文章对你有帮助吗?