Programming1,492 views4 likes

Your LLM Isn't Bad at Your Language. Your Codebase Is.

A senior dev told me Claude doesn't know Swift. Five minutes later, we realized the problem wasn't the model — it was the codebase. Your LLM mirrors what it sees. Full workflow and CONVENTIONS.md template inside.

Sahar Carmel

Sahar Carmel

Director AI enablement
December 21, 20259 min read
Your LLM Isn't Bad at Your Language. Your Codebase Is.

Your LLM Isn't Bad at Your Language. Your Codebase Is.

Why Claude writes garbage code — and how a single markdown file fixes it

Last week, a senior developer told me: "Claude doesn't know Swift."

He'd asked Claude to fix a bug. The bug got fixed. The code worked. But the code itself looked like this:

SWIFT
case .userLoggedIn:
return .userLoggedIn
case .userLoggedOut:
return .userLoggedOut
case .sessionExpired:
return .sessionExpired

"It works," he said, "but in six months this will be unmaintainable."

I asked him to do something for me: "Tell Claude the code isn't good. Don't explain why. Don't tell it how to fix it."

He did. Claude immediately rewrote it with proper pattern matching. No explanation needed.

So why did it write garbage in the first place?

The Codebase Is the Teacher

When I asked about the codebase itself, the picture became clear: legacy code, inherited from another team, four different coding styles in the same file, zero conventions documented.

Here's what most developers don't realize:

LLMs don't "know" or "not know" a programming language. They're pattern-matching machines.

They read everything in context — every file, every style, every inconsistency — and produce more of the same. Research on in-context learning for code generation confirms that performance heavily depends on the quality of examples the model sees. If your codebase is garbage, they'll write garbage that fits right in.

This isn't a bug. It's a feature.

The Science: Lost in the Middle

Stanford researchers published a paper called "Lost in the Middle" that explains why this happens at a deeper level.

They found that LLMs have a U-shaped attention curve: they pay the most attention to what's at the beginning and end of the context window. Information in the middle gets degraded — sometimes by more than 20%.

What does this mean for code generation?

If your context window is filled with 50 files of legacy code, and there's nothing at the start telling the model what good code looks like — it learns from the garbage. This is related to what researchers call the "Needle in a Haystack" problem — the model's ability to find and use specific information buried in a large context. Recent research shows that smaller, more specific instructions get lost more easily.

It's like hiring a new developer on day one, throwing them into a 30-year-old codebase with four different coding conventions in the same file, and expecting perfect output.

They won't write perfect code. They'll write code that matches what they see. MIT researchers recently discovered that this position bias is built into the architecture itself — certain design choices in how transformers process input data cause them to overemphasize beginnings and endings.

The Pirate Test

Here's how I explain this to teams:

If you write at the beginning of your conversation that your daughter loves pirates — I guarantee you'll see ships appearing in variable names, and every time Claude finishes a task it'll say "Ahoy! We've conquered another ticket!"

LLMs are mirrors. As Addy Osmani puts it: "LLMs are great at mimicry — show them one or two examples and they'll continue in that vein." They reflect what you show them.

The question isn't "does Claude know my language?"

The question is: "What am I teaching Claude about my codebase?"

The Solution: A Conventions Document

After working with roughly 20 companies on AI-first development transitions, I see the same pattern: teams blame the model, but the problem is the input.

The fix is a single file: CONVENTIONS.md in your project root.

But here's the critical insight — don't write it yourself. Ask the agent to analyze your codebase first.

Step Zero: Let the Agent Show You What It Sees

Before writing any conventions, run this prompt on your codebase:

Codebase Analysis Prompt

Code
Analyze this codebase and describe what you observe:
1. **Patterns you see**: What architectural patterns, coding styles, and conventions are actually being used? Don't guess what was intended — describe what exists.
2. **Inconsistencies**: Where do you see conflicting approaches? Different naming conventions? Mixed patterns?
3. **Code smells**: What patterns would you flag as problematic or hard to maintain?
4. **Implicit conventions**: What unwritten rules seem to be followed (even if inconsistently)?
5. **Technical debt markers**: What looks like it was "temporary" but became permanent?
Be specific. Give file names and line numbers where possible.

Why is this crucial?

Because the agent will learn from whatever it sees. If you don't know what it's seeing, you can't correct for it.

When I run this with teams, they're often shocked. The agent surfaces patterns they didn't know existed — copy-pasted code blocks, abandoned architectural decisions half-implemented, naming conventions from three CTOs ago.

This becomes your baseline. Now you can document the gap.

The Conventions Document: Current State vs. Target State

The key isn't just documenting what exists — it's documenting where you're going and explicitly naming what to stop doing.

Template: CONVENTIONS.md

Markdown
# Project Conventions
## Architecture
- Pattern: MVVM
- ViewModels handle all business logic
- Views are stateless and dumb
- Dependencies injected via protocols
## Naming Conventions
- Boolean variables: `is`/`has`/`should` prefix
- Functions: verb + noun (`fetchUser`, `validateInput`, `handleError`)
- Private properties: underscore prefix `_internalState`
## Error Handling
- Never use silent catch blocks
- All custom errors inherit from `AppError`
- Errors must include context for debugging
## Code Style
- Max function length: 20 lines
- Max file length: 300 lines
- Prefer guard statements over nested if-else
---
## ⚠️ CRITICAL: This Codebase Is in Transition
### What the agent currently sees (DO NOT replicate):
- Massive ViewControllers (some are 2000+ lines)
- Stringly-typed APIs throughout `/Legacy/*`
- Callback pyramids in network layer
- Mixed use of singletons and dependency injection
- Four different date formatting approaches
### Target state (ALWAYS use for new code):
- Protocol-oriented design
- Type-safe routing via `AppRouter`
- Async/await for all network calls
- Explicit dependency injection
- Single `DateFormatter` extension
### When refactoring existing code:
- Always move toward target state
- Never replicate legacy patterns even if surrounding code uses them
- Flag any file over 500 lines for decomposition
---
## Agent-Specific Instructions
When generating code for this project:
1. Check if similar functionality exists before creating new
2. Prefer extending existing protocols over creating new ones
3. All new ViewModels must have corresponding unit tests
4. Use `// TODO: TECH-DEBT` marker for any temporary solutions

The magic is in the transition section. When you explicitly tell the model:

  • "Here's what you'll see in the codebase"
  • "Don't copy it"
  • "Here's what we want instead"

It understands the delta and writes toward the target, not the current state.

The Workflow: Incremental Refactoring

Here's the full workflow I use with teams:

Step 1: Analyze (Once)

Run the codebase analysis prompt. Document what the agent sees. This is your "before" snapshot.

Step 2: Define the gap

Write your CONVENTIONS.md with explicit current-state vs. target-state sections.

Step 3: Make it work first

For new features, get them working. Don't obsess over perfect code yet. Let the LLM match existing patterns if needed to ship.

Step 4: Expand the blast radius

Take the code that changed, plus roughly 20% of the surrounding code (imports, related functions, the file header).

Step 5: Refactor pass

Run it through the agent with this prompt:

Code
Refactor this code to match our CONVENTIONS.md.
Focus on: [specific convention — pick ONE per pass]
Keep functionality identical. Show me the diff.

Step 6: Small PRs

Submit as a focused PR. One convention at a time. Review. Merge. Repeat.

Why This Beats Manual Refactoring

The traditional approach to improving a legacy codebase requires convincing the entire team to invest effort. That's a hard sell when everyone has feature work.

This approach inverts it:

  • One person writes the conventions document once
  • One person runs the initial codebase analysis
  • Everyone benefits by just running their code through the agent
  • The codebase improves incrementally with every PR

No big-bang refactoring. No dedicated "tech debt sprints." Just steady improvement as part of normal work.

And here's the compounding effect: as more code gets refactored to target state, the agent sees more good examples. The baseline shifts. The garbage percentage drops. The agent gets better automatically.

For the Skeptics

I hear this constantly: "Our codebase is different. Our language is niche. Our architecture is unique."

Here's my challenge:

  1. Find a top-tier open source repo on GitHub in your language and domain
  2. Give Claude the exact same task in that repo
  3. Compare the output quality

The difference will be obvious.

The model isn't the problem. The input is.

The Deeper Insight

This connects to something I've been thinking about:

Current AI-first developers aren't just using tools. We're training the next generation of compilers.

Every conventions document we write, every pattern we establish, every refactoring workflow we build — we're creating the abstraction layer that will eventually make today's manual coding look like writing assembly.

The teams that figure this out now will have a massive advantage. Not because they have better AI tools — everyone has access to the same models. But because they've built the input layer that makes those tools actually work.

Your CONVENTIONS.md file isn't just documentation. It's the training data for your team's AI compiler.

Quick Reference: The Complete Workflow

StepActionFrequency
0Run codebase analysis promptOnce (update quarterly)
1Write CONVENTIONS.md with current/target statesOnce (update as needed)
2Build feature (working code first)Per feature
3Expand context (+20% surrounding code)Per feature
4Refactor pass against conventionsPer feature
5Small PR, review, mergePer feature

Further Reading

Join Squid Club

Want to go deeper on AI-first development?

Squid Club is a Hebrew-speaking community for practitioners navigating AI coding in Israel. Engineers, managers, executives — all experience levels welcome. We run workshops, meetups, and ongoing discussions about what actually works in production.

squid-club.com

Written by Sahar Carmel, Principal AI Engineer and AI-First Coding Consultant. After building production AI agents and guiding ~20 companies through AI adoption, I focus on the practical realities of AI coding — including the patterns that actually work and the psychological barriers that hold teams back.

Continue Reading

Contents
Your LLM Isn't Bad at Your Language. Your Codebase Is. | Squid Club | Squid Club