AI for Code Documentation — Generate Docstrings, READMEs, and API Docs in 2026
Advertisement
Introduction
Why This Matters
Documentation is universally agreed to be important and universally agreed to be the last thing developers do. The result is codebases where the only documentation is the code itself — and often, code that is not self-explanatory. AI changes this economics: generating a docstring for a function takes seconds, and a full README for a project takes minutes. The bottleneck is no longer writing but knowing what to ask for and how to keep generated documentation accurate as code evolves.
Docstring Generation
Python — Google Style
Select a function and ask: "Generate a Google-style docstring for this function."
def calculate_compound_interest(
principal: float,
annual_rate: float,
compounds_per_year: int,
years: int
) -> float:
"""Calculate compound interest and return the final balance.
Uses the standard compound interest formula:
A = P * (1 + r/n)^(n*t)
Args:
principal: The initial investment amount in dollars.
annual_rate: Annual interest rate as a decimal (e.g., 0.05 for 5%).
compounds_per_year: Number of times interest compounds per year.
Common values: 12 (monthly), 4 (quarterly), 365 (daily).
years: Duration of the investment in years.
Returns:
The final account balance after compound interest is applied.
Raises:
ValueError: If principal or compounds_per_year is not positive.
Example:
>>> calculate_compound_interest(1000, 0.05, 12, 10)
1647.0094...
"""
if principal <= 0:
raise ValueError("Principal must be positive")
if compounds_per_year <= 0:
raise ValueError("compounds_per_year must be positive")
return principal * (1 + annual_rate / compounds_per_year) ** (compounds_per_year * years)TypeScript — JSDoc Style
/**
* Retries an async function with exponential backoff.
*
* @param fn - The async function to retry.
* @param maxAttempts - Maximum number of attempts before giving up.
* @param baseDelayMs - Initial delay in milliseconds. Doubles on each retry.
* @returns A promise that resolves with the function's return value.
* @throws The last error thrown by fn if all attempts fail.
*
* @example
* const result = await withRetry(() => fetchData(url), 3, 1000);
*/
async function withRetry<T>(
fn: () => Promise<T>,
maxAttempts: number = 3,
baseDelayMs: number = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
lastError = err as Error;
if (attempt < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, baseDelayMs * 2 ** (attempt - 1)));
}
}
}
throw lastError!;
}README Generation
Provide the AI with your project's structure and purpose. A useful prompt:
Generate a README.md for a Python FastAPI service that:
- Accepts CSV uploads and processes them into a PostgreSQL database
- Provides a REST API for querying the processed data
- Uses Redis for caching query results
- Requires Python 3.11, PostgreSQL 15, Redis 7
Include: overview, prerequisites, installation, running locally,
environment variables, API endpoints summary, and contributing guide.The AI will produce a structured README that you refine rather than write from scratch. Update it by pasting sections back to the AI with "Update the installation section to reflect that we now use Docker Compose."
OpenAPI / Swagger Doc Generation
For FastAPI, AI can generate the docstrings that FastAPI converts to OpenAPI automatically:
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
router = APIRouter()
class UserCreateRequest(BaseModel):
email: str
password: str
display_name: str
class UserResponse(BaseModel):
id: int
email: str
display_name: str
@router.post(
"/users",
response_model=UserResponse,
status_code=201,
summary="Create a new user account",
description="""
Creates a new user account with email/password authentication.
The password is hashed using bcrypt before storage. The email must be
unique — a 409 Conflict is returned if the email already exists.
Returns the created user without the password hash.
""",
responses={
201: {"description": "User created successfully"},
409: {"description": "Email already registered"},
422: {"description": "Invalid email format or password too short"},
}
)
async def create_user(request: UserCreateRequest) -> UserResponse:
...Architecture Documentation
For architecture docs, paste your system diagram description or list of components and ask for ADR (Architecture Decision Record) format:
Generate an Architecture Decision Record for our choice to use
PostgreSQL instead of DynamoDB for the user data store.
Context: we have a team of 4, 50k users, complex relational queries.The AI produces a structured ADR with Context, Decision, Consequences, and Alternatives Considered sections that you validate and refine.
Keeping Documentation Current
The biggest challenge with AI-generated docs is keeping them updated. Practical approaches:
Prompt on every PR: Add to your PR review checklist: "Does this change require updating any docstrings or README sections? If yes, ask AI to update them."
Generate changelog entries: After completing a feature, paste your git diff and ask: "Generate a changelog entry in Keep a Changelog format for these changes."
Test docstring examples: Use Python's doctest module to run examples embedded in docstrings:
python -m doctest src/utils.py -vIf an AI-generated example is wrong, the test fails immediately.
Common Mistakes
- Not providing schema or types: AI generates better docs when it knows the input and output types. Always include type annotations in the code before asking for docs.
- Accepting docs without reading them: AI occasionally generates examples with incorrect assumptions. Read every generated docstring before merging.
- Generating docs once and forgetting them: Documentation that is not updated is worse than no documentation — it actively misleads. Build doc updates into your change process.
- Over-documenting: Every function does not need a six-line docstring. Ask for docstrings only for public APIs and non-obvious implementations.
Best Practices
- Add type annotations to your code before asking for docstrings — they anchor the AI's output to the actual interface
- Use AI to generate the first draft, then edit for accuracy and tone rather than writing from scratch
- Include at least one runnable example in every public function's docstring; use
doctestto verify it - For changelog and release notes, paste the git diff rather than describing the changes — more accurate output
- Treat README sections as living documents — ask AI to update specific sections rather than regenerating the whole file
Key Takeaways
- AI generates Google-style Python docstrings and JSDoc TypeScript comments accurately when given well-typed functions
- FastAPI automatically converts docstrings and response model descriptions into OpenAPI documentation
- Architecture Decision Records (ADRs) benefit from AI drafting because they follow a consistent, learnable format
- Doctest-compatible examples embedded in Python docstrings can be run as tests to verify AI-generated examples are correct
- The key to accurate docs is providing type annotations before asking — they constrain the AI's output to the real interface
- Documentation debt compounds: build doc updates into PR checklists rather than treating them as a separate project
- Changelog generation from git diffs is one of the highest-accuracy AI documentation tasks — the input is precise
- AI documentation is a first draft, not a final artifact — always read and validate before merging
Advertisement