我如何使用 AST 解析和多供应商 LLM 自动化 Python 文档

发布: (2026年3月14日 GMT+8 03:17)
14 分钟阅读
原文: Dev.to

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. 正则表达式文档的缺陷

历史上,许多轻量级文档工具依赖正则表达式。它们逐行扫描文件,寻找 defclass,提取后面的字符串,并尝试抓取其下方的文档字符串块。

这种做法对现代 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: markdown

4. 输出模板化:使用 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/package

Behind the scenes it:

  1. Walks the source tree and parses each .py file with ast.
    遍历源码树,并使用 ast 解析每个 .py 文件。
  2. Builds a unified JSON/YAML blueprint of the entire package.
    构建整个包的统一 JSON/YAML 蓝图。
  3. Sends the blueprint (or relevant chunks) to the configured LLM.
    将蓝图(或相关片段)发送给配置好的 LLM。
  4. Receives structured documentation fragments.
    接收结构化的文档片段。
  5. Renders the fragments through your Jinja2 templates.
    通过你的 Jinja2 模板渲染这些片段。
  6. Writes the final Markdown files to the output.dir you 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.j2index.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

我很想在评论中听到你的反馈。你仍在手动编写文档吗?使用现有的自动生成文档工具时,你最大的挫败感是什么?告诉我吧!

0 浏览
Back to Blog

相关文章

阅读更多 »