我如何使用 AST 解析和多供应商 LLM 自动化 Python 文档
I’m happy to translate the article for you, but I don’t have the article’s content in your message. Could you please paste the text you’d like translated (excluding the source line you’ve already provided)? Once I have the content, I’ll translate it into Simplified Chinese while preserving all formatting, markdown, and code blocks.
Introduction
我们都有过这样的经历。你刚刚花了三天时间,精心打造了一个高度优化、结构优美的新功能。代码优雅,测试通过,代码检查器也安静得一塌糊涂。你推送了分支,打开了 Pull Request,随后现实像卡车一样砸向你:
“哦,对了,我得更新文档。”
说实话:编写文档是开发者又爱又恨的活儿。理想情况下,文档会随代码一起演进。实际情况却是,文档停留在 2023 年,而你的应用代码已经冲向 2025 年。
长期以来,解决方案要么是苦工(手动完成),要么是使用脆弱的、基于正则的解析器——一旦你引入稍微复杂一点的 Python 装饰器或嵌套的异步函数,这些解析器就会崩溃。
我决定不再使用这两种方式。于是,我在过去几周里构建了 AutoDocGen(在 PyPI 上的名称为 pypiautodocgen)。
AutoDocGen 并不是像强化版 grep 那样搜索字符串,而是将你的 Python 代码解析成 抽象语法树(AST)。它知道什么是类,什么是私有方法,以及你的模块之间是如何本质上相互关联的。它把这张蓝图交给你选择的大型语言模型,生成可读性强、格式完美的 Markdown 文档。
下面就是我构建它的过程、遇到的技术难点,以及为什么我相信 AST 解析结合 AI 是代码文档的未来。
1. 正则表达式文档的缺陷
历史上,许多轻量级文档工具依赖正则表达式。它们逐行扫描文件,寻找 def 或 class,提取后面的字符串,并尝试抓取其下方的文档字符串块。
这种做法对现代 Python 开发来说根本存在缺陷。为什么?因为 Python 语法极其灵活。
@cache(ttl=3600)
@validate_schema(UserSchema)
async def fetch_user_data(
user_id: uuid.UUID,
include_history: bool = False
) -> Dict[str, Any]:
"""Fetches user data from the primary replica."""
pass正则解析器必须设法知道装饰器属于该函数,正确识别它是异步的,处理多行签名,解析类型提示,并提取文档字符串。再加上嵌套类、闭包以及复杂的返回类型,你的正则很快就会沦为难以维护的噩梦。
正则并不 理解 代码;它只识别文本中的模式。我需要一种能够理解 Python 本身结构的工具。
2. 进入抽象语法树(AST)
Python 包含一个内置模块 ast。它允许你将 Python 源代码解析为一棵节点树,表示程序的语法结构。
AutoDocGen 并不是读取文本行,而是使用 ast.parse() 来读取代码的 “DNA”。
当你将上述代码片段喂给 AST 解析器时,它看到的不是一串文字,而是一个 AsyncFunctionDef 节点。它知道该节点拥有一个包含 Call 节点的 decorator_list。它会映射出 arguments(包括它们的类型注解),并优雅地使用 ast.get_docstring() 提取精确的文档字符串。
通过提取这些结构化数据,AutoDocGen 构建了代码库的高保真 “蓝图”。我们提取:
- 模块级变量和逻辑
- 类定义、它们的基类(继承关系)以及方法
- 独立函数(同步和异步)
- 精确的签名和类型提示
随后我们将此蓝图序列化为结构化格式(AST 摘要的 JSON 或 YAML 表示)。
这就是秘密武器。 我们并不是让 AI 从头读取你的代码并猜测它的功能,而是给 AI 一个结构化的地图,让它解释这张地图。这大幅降低了大语言模型的幻觉现象,显著提升生成文档的质量。
Source: …
3. 摆脱供应商锁定:多供应商支持
当我开始构建 AI 生成步骤时,我意识到当前 AI 开发者工具生态的一个主要痛点:几乎所有工具都硬编码了 OpenAI 的 API。
虽然 GPT‑4o 非常强大,但我们正处于开源模型和超高速推理 API 的黄金时代。我不希望用户在偏好 Google 工具或想要 Groq 的惊人速度时被锁定在 OpenAI 上。
因此,我在 AutoDocGen 中构建了一个抽象层,以支持多个 LLM 提供商:
| 提供商 | 使用理由 |
|---|---|
| OpenAI | 标准后备方案 |
| Groq | 使用 Llama‑3 在 LPU 上生成文档,单文件字面上只需 2 秒 |
| Google Gemini | 出色的上下文窗口,能够深入理解复杂模块之间的相互依赖关系 |
| OpenRouter | 终极自由——将请求路由到数十种模型(包括像 Stepfun 这样的免费层),无需更改核心集成 |
配置层级非常灵活。你可以通过环境变量(GROQ_API_KEY)、本地 .env 文件、autodocgen.yaml 配置,或直接在 pyproject.toml 中设置所有内容。
# autodocgen.yaml
version: 1
ai:
provider: groq
model: llama3-70b-8192
output:
dir: ./docs
format: markdown4. 输出模板化:使用 Jinja2 实现高级风格
拼图的最后一块是输出格式。大多数自动化文档工具会生成枯燥、缺乏灵感的文本块。我希望文档看起来像是由技术写作者手工编写的。
与其依赖 LLM 来格式化 Markdown(这往往会导致标题不一致、表格损坏),AutoDocGen 严格将生成过程与呈现过程分离。
LLM 返回 结构化数据(模块摘要、功能要点等)。随后 AutoDocGen 将这些数据注入 Jinja2 模板,让你完全掌控文档的最终外观和感觉。
# example_template.md.j2
# {{ module.name }}
{{ module.summary }}
{% for cls in module.classes %}Class {{ cls.name }}
{{ cls.docstring }}
{% for method in cls.methods %}
Method {{ method.name }}{{ method.signature }}
{{ method.docstring }}
{% endfor %} {% endfor %}
通过将生成和渲染分离,您可以:
- 强制在所有文档中遵循一致的风格指南
- 添加自定义章节(例如,使用示例、变更日志),无需触及 AI 代码
- 将模板替换为不同的输出格式(HTML、PDF 等)
## 5. 将所有内容整合在一起
Running AutoDocGen is as simple as:
```bash
autodocgen path/to/your/packageBehind the scenes it:
- Walks the source tree and parses each
.pyfile withast.
遍历源码树,并使用ast解析每个.py文件。 - Builds a unified JSON/YAML blueprint of the entire package.
构建整个包的统一 JSON/YAML 蓝图。 - Sends the blueprint (or relevant chunks) to the configured LLM.
将蓝图(或相关片段)发送给配置好的 LLM。 - Receives structured documentation fragments.
接收结构化的文档片段。 - Renders the fragments through your Jinja2 templates.
通过你的 Jinja2 模板渲染这些片段。 - Writes the final Markdown files to the
output.diryou specified.
将最终的 Markdown 文件写入你指定的output.dir。
The result is a set of clean, human‑readable docs that stay in sync with the codebase, require virtually no manual upkeep, and can be regenerated on every CI run.
结果是一套简洁、易于阅读的文档,能够与代码库保持同步,几乎不需要人工维护,并且可以在每次 CI 运行时重新生成。
6. 为什么这很重要
- 可靠性: AST 解析确保你看到的是真实的代码结构,而不是脆弱的文本模式。
- 速度: 再也不用等几分钟让基于正则的工具在大型仓库中卡死。
- 灵活性: 多供应商 LLM 支持意味着你可以选择符合预算、延迟或隐私需求的模型。
- 质量: 结构化提示 + Jinja2 渲染生成一致、专业级的文档。
简而言之,AutoDocGen 展示了将语言感知解析与现代 LLM 相结合,是保持文档活力的实用且可扩展的路径。
试一试
pip install pypiautodocgen
autodocgen ./my_project --config autodocgen.yaml欢迎打开 issue、提交 PR,或分享你为自己的风格指南定制的 Jinja2 模板。祝文档编写愉快!
一致的高级美感
通过使用 Jinja2(module.md.j2 和 index.md.j2),CLI 能够在整个文档站点中保证一致的高级美感。它能够完美格式化函数签名,自动生成目录,并交叉链接相关模块。
如果你不喜欢默认模板,可以轻松地 fork templates/ 目录并自行构建。
5. Security First: The “Zero‑Trust” QA Audit
因为我正在发布一个读取源代码的 AI 工具,我知道安全性和稳定性必须放在首位。我并没有只写几个单元测试就算了事。
在达到 v0.1.0 之前,项目经历了我所称的 Zero‑trust Forensic QA Audit。我假设最初的概念验证代码是完全错误的,并从零开始构建了测试套件。
我们使用了:
pytest进行全面的单元测试和集成测试。bandit进行安全扫描,以确保 API 密钥永不在日志中泄露,文件 I/O 操作安全可靠。- 对所有 LLM 提供商进行广泛的 mock,这样 CLI 可以在 CI/CD 中深度测试,而不会消耗 API 额度。
- 边缘案例测试,包括处理奇特的 Unicode 标识符(是的,
def grüne_äpfel()能完美解析)。
该仓库现已完整集成 Codecov,为任何未来的 Pull Request 维护严格的基准线。
如何开始
如果你厌倦了 README 文件与代码库不同步,我强烈建议你尝试 AutoDocGen。它已经在 PyPI 上正式发布。
安装
pip install pypiautodocgen运行
autodocgen -o ./docs --provider groq # 或者使用 openai、gemini、openrouter这将为当前目录生成文档,并将输出保存到 ./docs。
路线图
目前,AutoDocGen 能够生成出色的 Markdown 文件,完美适用于 MkDocs 等静态站点生成器,或直接在 GitHub 上使用。
展望未来,我想探索:
- Framework‑specific parsing – 为 FastAPI 端点或 Django 模型提供专门的模板。
- Diff‑based updating – 仅为提交中更改的函数重新生成文档,而不是重新生成整个文件。
- Mermaid diagram generation – 基于 AST 导入自动创建架构流程图。
让我们联系!
我创建 AutoDocGen 是为了解决我自己的痛点,但我知道社区有许多令人惊叹的想法可以让它更进一步。
查看 GitHub 上的源代码(如果觉得有用,请点星):
https://github.com/shifulegend/autodocgen
我很想在评论中听到你的反馈。你仍在手动编写文档吗?使用现有的自动生成文档工具时,你最大的挫败感是什么?告诉我吧!