On this page
How to Write Comments That AI Assistants Actually Read and Use
AI assistants read your comments to understand intent and constraints. But they ignore noise and copy bad patterns. Here's what to write — intent over mechanics, constraints over descriptions, and contracts over implementation.
Quick answer
- AI assistants read comments to infer intent, constraints, and patterns. Write comments the AI can use.
- Intent over mechanics: explain why, not what. The AI can read the code; it can’t read your mind.
- Constraints prevent breakage: mark values, patterns, and assumptions the AI must not change.
- Full guide: How to Make Your Codebase AI-Friendly
What the AI reads from your comments
When an AI assistant opens your file, it reads:
- The code (mechanics)
- The comments (intent, constraints, contracts)
- The function signatures (types, parameters)
It uses comments to understand what you want, not what the code does. A comment that says “loop through orders and sum totals” is redundant — the AI can read the loop. A comment that says “exclude refunded orders because they’re counted in a separate refund report” tells the AI something it can’t infer from the code.
The three types of comments AI assistants use
1. Intent comments: why this code exists
# Bad (describes mechanics — AI already sees this):
# Loop through users and check if they're active
for user in users:
if user.is_active:
send_email(user)
# Good (describes intent — AI uses this to understand purpose):
# Send the weekly digest to all active users. This runs Sunday
# at 8 AM via cron (see crontab in deploy/config). Non-active
# users are excluded — they opted out or were deactivated.
for user in users:
if user.is_active:
send_email(user)The intent comment tells the AI: this runs on a schedule (don’t add it to a request handler), it excludes opted-out users (don’t “fix” the filter), and it’s a digest (don’t replace it with a transactional email).
2. Constraint comments: what must not change
# WARNING: This timeout must stay between 25-30 seconds. The
# downstream payment gateway closes connections at exactly 30s.
# Reducing it causes premature timeouts during peak loads;
# increasing it causes the gateway to 500 on our requests.
PAYMENT_TIMEOUT = 28
# Dependency ordering matters here. SessionMiddleware must run
# before AuthMiddleware because Auth reads the session cookie.
# Do not reorder without updating the session configuration.
app.add_middleware(SessionMiddleware)
app.add_middleware(AuthMiddleware)
app.add_middleware(RateLimitMiddleware)Without these comments, the AI might “optimize” the timeout to 5 seconds or reorder middleware alphabetically — both breaking changes that look like improvements.
3. Contract comments: what a function guarantees
def apply_refund(order_id: int, amount: float, reason: str) -> Refund:
"""
Issue a refund for an order.
Args:
order_id: The order to refund. Must exist and be in 'completed' status.
amount: Amount to refund in the order's currency. Must be > 0 and
<= the order's remaining refundable amount.
reason: Why the refund is being issued. Used for audit logs.
Returns:
Refund object with status 'pending' (processed async by RefundWorker).
Raises:
ValueError: If order not found, not completed, or amount invalid.
InsufficientFundsError: If amount exceeds remaining refundable amount.
Side effects:
Creates a Refund record, enqueues a RefundWorker job.
Does NOT update the order status — RefundWorker does that.
"""The AI reads this and generates code that respects: the order must be completed, the amount must be positive, the refund is async, and the order status isn’t changed in this function. Without the contract, the AI guesses at all of these.
Comments the AI ignores (don’t write these)
# Useless to AI (all describe mechanics it can read):
# Increment counter
counter += 1
# Return the result
return result
# Set default value
name = name or "Unknown"
# Call the function
process_order(order)The AI sees counter += 1 and knows it increments. The comment adds nothing. Worse: if your codebase has many of these, the AI learns that comments are noise and stops reading them.
Comments the AI copies (be careful)
The AI pattern-matches on your comments too. If you write:
# TODO: fix this later
# HACK: works but ugly
# FIXME: race condition hereThe AI generates more of these — because it sees them as a pattern. Remove TODO/HACK/FIXME comments or use them intentionally as signals (the AI will flag them in its own output).
Strategic placement
Put the most important constraint comments where the AI is most likely to change things:
# Top of file: architecture constraints
# This module handles order processing. All state changes go through
# OrderService — never modify Order objects directly in routes.
# Before sensitive values: operational constraints
# WARNING: Changing this cache key format breaks cache invalidation.
# The cache warmer in warmers/ uses the same format.
CACHE_KEY = "orders:v2:{user_id}"
# Before critical logic: business constraints
# Refunds are idempotent — calling this twice with the same
# idempotency_key returns the same refund, not two refunds.
def process_refund(order_id, amount, idempotency_key):Where this bites vibecoders
The AI generates a “cleanup” that renames the cache key format, and the cache warmer breaks because the vibecoder didn’t document the coupling. One constraint comment prevents it. The rule: any value, ordering, or pattern the AI might change — and that would break something if changed — gets a
WARNINGcomment.