Your README lies. Your docstrings are from two refactors ago. And nobody — nobody — volunteers to write the docs. I know because I've let docstrings rot in at least six repos, and I once shipped a package whose README described an API that had already changed two releases earlier.
This year I stopped choosing between rot and a wasted weekend: I built a pipeline that generates project documentation with AI, then reviews the output like a hostile pull request. Everything below comes from one real repo — a 40-module image-processing package I maintain, documented end to end with this pipeline in a single afternoon. The tools are the ones you already know (pydoc, pdoc, MkDocs, mkdocstrings), AI writes the boring 80%, and I show you exactly where it gets things wrong. Every command here is one I actually ran.
Originally published on AI Stack Lab.
What "documentation" actually means in a Python project
Before automating anything, split the job into four layers, because AI and tooling are good at different ones:
- Docstrings — per-module, per-class, per-function. Pure mechanical description. AI's favorite target.
- API reference — the rendered site generated from those docstrings. This is a tooling problem, not a writing problem. You should never maintain it by hand.
- Guides and README — why the project exists, how to install it, worked examples. AI drafts well here, but examples must run.
- The "why" — design decisions, gotchas, migration notes. Still human territory in 2026. AI can rephrase what you tell it; it cannot know what you decided at 2 a.m.
Auto-generating documentation with AI works when you respect that split: let AI draft layers one and three, let static-site tooling own layer two, and keep layer four honest.
The toolchain, verified against current docs
Here is the stack I tested, with facts checked against each project's own documentation today rather than copied from a stale listicle:
-
pydoc — already installed with Python.
python -m pydoc mypkgprints text documentation straight from your docstrings;pydoc -w mypkgwrites an HTML file. Zero setup, ugly output — I use it as a quick sanity check that docstrings parse, not as a deliverable. -
pdoc — at version 16.0.0 right now.
pdoc ./mypkgopens a browser tab with your API docs and live-reloads as you edit;pdoc ./mypkg -o ./docsexports static HTML. Docstrings are rendered as Markdown, Google-style and numpydoc docstrings are both understood natively, and type annotations become clickable links automatically. No configuration file exists to write — that is the whole design philosophy. -
MkDocs + mkdocstrings — MkDocs is a static site generator fed by Markdown files and a single
mkdocs.ymlconfig, with a built-in dev server that reloads as you write. mkdocstrings is the plugin that pulls your live Python objects into those pages: you write:::plus your identifier, and it injects the rendered docstring, with cross-references that work like Sphinx's intersphinx. One honest caveat I found on their site today: mkdocstrings currently displays a maintenance-mode banner. It still works and ships widely (Ansible and other large projects use it), but factor that into long-term planning. - Sphinx — the industry heavyweight, reStructuredText-first, right for large multi-project documentation sets. For a single library it is more machinery than I wanted, so it is not in this workflow, but nothing below contradicts using it as the renderer instead of pdoc.
Manual vs AI-assisted documentation: the comparison
| Task | By hand | AI-assisted | What I do now |
|---|---|---|---|
| Docstrings for ~40 modules | 3–5 focused hours of typing | First pass in minutes, then review time | AI drafts, I edit the lies out |
| API reference site | One pdoc command, or an hour of MkDocs config | Same tools — AI writes the config file too | pdoc for libraries, MkDocs for product docs |
| Tutorials and how-tos | The part that never gets written | Solid drafts from code and tests, examples need checking | AI drafts, I rewrite every example until it runs |
| Keeping up with refactors | Manual; rots silently | Regenerated on demand from current code | Regenerate on every minor release |
| Review burden | None — it's your writing | Real: AI hallucinates plausible wrongness | Doctests + a 30-minute human pass |
The workflow, step by step
Step 1: Generate the docstrings
Once the API of a module stabilizes, I run an AI first pass over the source: Google-style docstrings for every public function, class, and module — parameter types pulled from the actual signatures, not invented. The rule I hold the output to: if a docstring mentions a parameter that does not exist in the signature, it goes. I covered the mechanics and the failure modes of this step in depth in Stop Writing Docstrings by Hand, and if you want to compare dedicated docstring tools before choosing one, my AI docstring generators comparison tests the field head to head.
Step 2: Render the API reference
For a plain library, run pdoc ./mypkg -o ./docs and commit the output — genuinely that fast. For a product site mixing guides with API pages, I generate an mkdocs.yml and a docs skeleton with AI, then let mkdocstrings inject the live API objects into the pages. AI writing this config is where the tool earns its keep: mkdocs.yml syntax is boring to learn and the model already knows it cold.
Step 3: Draft the README and guides
I feed the AI the package's entry points and its test suite and ask for a README draft: install, three worked examples, one troubleshooting section. The test suite matters — an example the AI can ground in a real passing test is an example that runs.
Step 4: The review pass (the part that makes it trustworthy)
Every generated docstring and example goes through the same gauntlet: run the doctests (python -m doctest -v mypkg/*.py), build the docs and click every link, and read the diff of the docstrings themselves the way you would review code. This is 30 minutes against 5 hours of manual writing, and it is not optional — see the failure list below for why.
The tool I use for the first pass: AI Doc Generator
I use AI Doc Generator as the engine for steps 1 and 3 in my own repos — it reads a Python package and produces the docstring and README first pass that I then review. What made it stick for me is the price model: $49 one-time (I re-checked this at publish time — ld+json on the Gumroad page confirms 49 USD, no subscription, no per-seat nonsense), against subscription doc tools that charge monthly forever for the same job. I run it on every new package the day the API stabilizes, then hand the output to the review pass like anything else. If you write Python for a living, it pays for itself the first time you skip an evening of docstring typing. Disclosure: that is an affiliate link — if you buy through it, I earn a commission at no extra cost to you.
Where AI-generated documentation still breaks
Honesty section, because "AI writes your docs" demos never include it. What I have actually caught in generated output:
- Parameters that don't exist. The model documents the signature it expected, not the one you shipped — usually on functions whose signature changed recently.
- Confident exception lists. "Raises ValueError if input is invalid" — and the function raises nothing at all. Docstring lies about error behavior are worse than no docstring.
- Stale intent. A docstring describing what a function used to do survives refactors because nothing forces it to change with the code. Regenerate on release, or it rots exactly like hand-written docs.
- Examples that almost run. Off-by-one arguments, imports you removed, deprecated call paths. If it isn't in a doctest, assume it doesn't run.
- Adjective soup. "Efficiently processes…" — delete on sight. Docs describe behavior, not enthusiasm.
Who this is NOT for
Skip this workflow if: your "project" is a handful of one-off scripts and notebooks — a README paragraph serves you better than a docs site. You're documenting a non-Python stack — the rendering tools translate, but this specific pipeline is Python-first. You won't do any review pass — then AI-generated docs will ship you confident nonsense and quietly cost you trust with your users; write nothing instead. Or you maintain a huge multi-project documentation set where Sphinx with intersphinx is already the right answer — swap the renderer in, keep the AI drafting.
The honest verdict
AI cannot replace your reviewer, and it shouldn't replace your judgment — but it can absolutely replace the blank page, which was always the real enemy. The workflow that survives contact with real projects is boring and repeatable: generate docstrings with AI, render the reference with pdoc or MkDocs plus mkdocstrings, draft guides from the test suite, then run doctests and a 30-minute human pass over the diff. That is roughly 30 minutes of review per release instead of a lost weekend per project, and the docs stay tied to the code instead of drifting away from it. Start with one package. If your first review pass catches nothing at all, either the AI has finally become trustworthy — or you didn't read closely enough.
Questions, corrections, or a documentation horror story? Email nandminc2020@gmail.com and I will read every one.
Keep reading
- Stop Writing Docstrings by Hand: Automate Python Documentation — the docstring-layer deep dive this workflow builds on
- AI Docstring Generators Compared — which dedicated tools are worth installing
- 10 Best AI Coding Tools in 2026, Tested — the broader tool landscape this pipeline sits inside
Top comments (0)