Skip to content

Can Managers Detect AI-Written Code in Pull Requests? The Signs They Look For

Problem

My boss dropped a bomb during our last team meeting: “Don’t let AI write your code. I’ll be able to tell in your PRs if you do.”

I sat there wondering: was he bluffing? Or can experienced developers actually spot AI-generated code? I decided to find out.

After researching and talking to senior engineers, I learned that yes, managers can often detect AI-generated code. Not through some magical ability, but through specific patterns that give it away.

The Training Data Problem

Here’s the fundamental issue with AI code:

Why AI Code is Detectable
AI Training Data:
├── StackOverflow answers (often quick hacks)
├── Tutorial code (verbose, educational)
├── Open source projects (varying quality)
└── Documentation examples (simplified)
What's missing:
├── Your team's conventions
├── Your project's architecture
├── Your domain-specific edge cases
└── Your security requirements

As one Reddit commenter put it: “AI is still, and probably will only ever be, a junior dev at most. It’s trained on bad code, and even if you give it a bunch of rules, it still gets it wrong.”

The Telltale Signs

Sign 1: Excessive Comments

This is the most obvious giveaway. AI loves tutorial-style comments for trivial code.

AI-generated code with excessive comments
def calculate_total(items):
"""
Calculate the total price of all items in the list.
Args:
items: A list of item dictionaries containing price information.
Returns:
float: The total price of all items.
"""
total = 0 # Initialize total to 0
for item in items: # Iterate through each item
total += item['price'] # Add item price to total
return total # Return the calculated total
Human code (knows this is obvious)
def calculate_total(items):
return sum(item['price'] for item in items)

I’ve seen this pattern countless times. The AI-generated version is correct but verbose. Humans who’ve been on the team for a while know we don’t comment the obvious.

Sign 2: Context Mismatch

This is where it gets interesting. AI generates code that works in isolation but ignores your project’s conventions.

AI suggests (ignores project's custom logger)
import logging
logger = logging.getLogger(__name__)
def process_order(order_id):
logger.info(f"Processing order {order_id}")
# ...
Project actually uses structured logging
from app.logging import StructuredLogger
logger = StructuredLogger(__name__, context={'service': 'billing'})
def process_order(order_id):
logger.info("Processing order", {'order_id': order_id})
# ...

When a reviewer sees standard logging instead of our StructuredLogger, it raises a red flag. The code works, but it doesn’t fit.

Sign 3: Ignoring Existing Utilities

AI often writes code from scratch instead of using your project’s utilities.

AI suggests (ignores existing utilities)
import requests
def fetch_user(user_id):
response = requests.get(f"{API_URL}/users/{user_id}")
return response.json()
Project has a dedicated API client
from app.api import api_client # With retry, auth, logging built-in
def fetch_user(user_id):
return api_client.get(f"/users/{user_id}")

The AI version:

  • Misses built-in retry logic
  • Skips authentication headers
  • Ignores request logging
  • Hardcodes the API URL

Sign 4: The “Correct but Wrong” Problem

This is the most insidious issue. AI generates code that technically works but violates your architecture.

AI code that works but doesn't fit
# AI generates:
class UserCache:
def __init__(self):
self._cache = {}
def get(self, user_id):
return self._cache.get(user_id)
def set(self, user_id, data):
self._cache[user_id] = data

Then the code review comment arrives: “Why isn’t this using our RedisCache class? We need cache invalidation across instances. Did you read ARCHITECTURE.md?”

The AI code is correct for a single-instance scenario. But your production environment runs multiple instances. The cache won’t sync.

Sign 5: Subtle Style Patterns

I noticed AI has consistent preferences that humans rarely use:

AI coding tics
from typing import Dict, List, Optional, Any # Imports everything even when not needed
result = [] # Uses loops when list comprehension would be idiomatic
for item in items:
result.append(process(item))
if __name__ == "__main__": # Adds this to non-script files
raise Exception("error") # Uses generic Exception instead of project's CustomError

Real Example: The Prefetching Disaster

The Reddit thread shared a perfect example of AI’s context blindness:

AI suggested prefetching on hover for a data-heavy application. The problem? This would fire “potentially hundreds” of requests as users moved their mouse around.

The code was technically correct - prefetching on hover is a valid pattern. But without understanding the application’s data volume and user behavior, it created a potential DDoS attack on their own backend.

The Confidence Trap

Here’s what makes AI code dangerous:

The Confidence Problem
AI Output:
├── Looks correct at first glance
├── Follows syntax rules perfectly
├── Has comprehensive error handling (sometimes)
└── Appears well-structured
What's hidden:
├── Security blind spots
├── Performance issues in your specific context
├── Missing domain knowledge
└── Architectural violations

One commenter nailed it: “It will suggest all kinds of egregious bullshit and you will have no idea if it’s secure, performant, and maintainable.”

What Reviewers Actually Look For

I asked several senior engineers what signals they watch for:

Detection Checklist
Style Consistency:
[ ] Variable naming matches codebase conventions?
[ ] Comment style matches team standards?
[ ] Import order follows project rules?
[ ] Formatting consistent with existing code?
Context Awareness:
[ ] Uses project's existing utilities?
[ ] Follows established architectural patterns?
[ ] Integrates with error handling/logging?
[ ] Respects dependency injection patterns?
Domain Knowledge:
[ ] Handles business-specific edge cases?
[ ] Understands data constraints?
[ ] Knows about existing rate limits?
[ ] Aware of multi-tenancy requirements?

Why This Matters for Your Career

If you’re a junior developer letting AI write your code:

The Learning Gap
Using AI for research:
├── You understand the problem
├── You write the solution
├── You learn patterns
└── You grow as a developer
Letting AI write code:
├── You skip the thinking
├── You paste the solution
├── You miss the patterns
└── You stagnate

The real problem isn’t getting caught. It’s that you’re not learning. When your boss reviews your PR and asks “why did you choose this approach?”, you need an answer.

How to Use AI Without Getting Flagged

1. Use AI for Research, Not Output

Good AI Workflow
1. Ask AI: "How do I implement X?"
2. Read the explanation
3. Close the AI window
4. Write the code yourself
5. Apply your team's patterns

2. Always Adapt to Your Context

If AI suggests code, adapt it:

Before adaptation
# AI suggestion
import requests
response = requests.get(url)
After adaptation to your project
# Your code
from app.http import HttpClient
response = HttpClient.get(url, timeout=30, retry=3)

3. Document Your Reasoning

When you submit a PR, explain your choices:

PR description template
## Approach
- Used [pattern] because [reason]
- Considered [alternative] but chose against it because [reason]
- Followed existing code in [file] as reference
## Testing
- Added tests for [specific cases]
- Manual testing: [what you tested]

4. Know Your Codebase

Before writing any feature:

  1. Search for similar implementations
  2. Check existing utilities
  3. Read relevant architecture docs
  4. Ask teammates about conventions

Summary

In this post, I explored how managers can often detect AI-generated code in pull requests. The key point is that AI code has consistent “tells”: excessive comments, context mismatches, ignored utilities, and style inconsistencies. These patterns emerge because AI lacks understanding of your specific codebase, conventions, and domain requirements. The detection isn’t magic - it’s pattern recognition based on what AI training data lacks. The better approach is to use AI for research and learning, then write the code yourself. This way, you actually understand your solution and can defend your design decisions in code review.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments