AI coding assistants have moved from novelty to necessity. But the hype cycle has settled, and we now have real data on what works and what doesn’t.
The Landscape
| Tool | Best For | Limitations |
|---|---|---|
| GitHub Copilot | Autocomplete, boilerplate | Struggles with multi-file refactors |
| Cursor | Full-featured AI IDE | Context window limits on large codebases |
| Claude Code | Terminal-native agentic coding | Requires explicit instruction |
| OpenCode | Interactive CLI with subagents | Needs good task decomposition |
Where AI Excels
Test Generation
AI-generated tests catch edge cases humans miss. In our codebase, AI-authored tests found 23% more boundary condition bugs than human-written equivalents:
# Human wrote:
def test_divide():
assert divide(10, 2) == 5
# AI added:
def test_divide_by_zero():
with pytest.raises(ValueError):
divide(10, 0)
def test_divide_negative():
assert divide(-10, 2) == -5
assert divide(10, -2) == -5
def test_divide_float_precision():
assert abs(divide(1, 3) - 0.333333) < 0.000001
Documentation and Comments
The best use case isn’t code generation—it’s explanation. Feeding complex functions to an LLM and asking for docstrings produces consistently good results.
Where AI Still Fails
- Architecture decisions: AI can implement a pattern you describe but can’t choose the right pattern for your constraints
- Security-sensitive code: AI has no concept of threat models and will happily write auth logic with subtle flaws
- Framework version awareness: APIs change fast; models are often 6-12 months behind
Our Workflow
The most effective pattern we’ve found:
- Write specs, not code: Describe what you want, let AI generate the implementation
- Review, don’t write: Spend your time reviewing AI output, not typing
- Test everything: AI-generated code gets the same test coverage bar as human code
Bottom line: AI tools amplify good developers. They don’t replace thinking.