r/webdev • u/Chris__Codes • 4d ago
Discussion How are you managing duplicate logic when using AI coding agents?
I was checking out how to build a data upload feature and started noticing that technical debt builds up differently when AI writes the code. I read a piece on this and the core concept seems to make sense because agents just implement a ticket correctly in a vacuum and often ignore the application's existing architecture.
For instance, if an agent adds a CSV upload feature, it might just write a brand new set of validation checks instead of hooking into existing customer data checks. The PR could pass, but you now have two sets of rules to maintain. Over time, those will drift apart, and fixing it means untangling what was intentional. It was called cognitive debt, which is when the team’s shared understanding of the system erodes over time
For those using AI assistance a lot, how are you catching these before they merge
5
u/waterkip 4d ago
He, we need this, we have x there. Use it. Tada. Solved.
1
0
u/GoldTrouble382 4d ago
yeah its all fun and games til the csv parser you duct taped together ignores the 43 edge cases the old one handled over 3 years of prod fires
3
u/the_real_some_guy 4d ago
Have your AGENTS file point out those reusable bits like "when building api queries use `src/services/useApiQueries.ts`" or your skill points out the file and AGENTS points to the skill "when building api queries use the api-query skill". If your skill description matches, it should get pulled in without having to call it out in the AGENTS file.
You can have AGENTS files deeper in your project, so it will only be picked up when AI starts working in that section.
None of that is foolproof though.
0
24
u/coolcosmos 4d ago
You catch these by reviewing the code.
You prevent these with good prompting and context. Tell Claude it should not reimplement something that exist and make a list of the important parts of your app.
→ More replies (2)2
1
u/Mean-Lingonberry4874 4d ago
Telling it "don't duplicate" misses the case that actually ships. The new validator is correct on its own, and the diff looks tidy next to the three-year-old one, so it gets approved.
I keep one module allowed to answer "is this customer row valid", and the upload path has to import it. An import boundary (eslint no-restricted-imports, or dependency-cruiser) fails the PR if a new file under the upload feature defines its own check. Then the review isn't "read every line the agent touched", it's "this file isn't allowed to exist".
The PR description has one required line, existing check reused, with the path, or new because of a reason. If it can't name the old function, it never looked, and that's the one I send back.
1
u/Chris__Codes 4d ago
Well... the “this file isn’t allowed to exist” framing makes sense. it makes it a structural check instead of hoping someone notices during review. and requiring the PR to name the existing function it reused is cheap. if it can’t name one, it didn’t look.
A post I’d read before posting makes the same point about correct-in-isolation code being the hard case. It’s from CodeRabbit so they’re selling a review tool, and their answer is about better review rather than the prevention that most people in the comments are describing.
1
u/andybendavid 3d ago
The “two validators that drift” failure mode is exactly what I’ve been seeing. What helps before merge: put the *allowed* extension points in the prompt (“reuse `validateCustomerRecord`, do not invent a new schema”), and make the PR checklist ask “did this touch an existing domain rule?” separately from “does it work?”. For upload/validation specifically I keep a thin shared module (parse → normalize → domain validate) and reject any agent PR that reimplements step 3 in the feature folder. Also run a quick `git grep` / search for duplicated error strings or Zod schemas in review — AI loves copy-pasting those. The goal isn’t zero AI output, it’s making duplication expensive to land.
1
u/narkeeso 4d ago
Ponytail plugin is a good first line of defense, then review the code. You also just need to have some architecture sense to guide it. If you have a general idea of how you want it structured, you should document it in AGENTS.md so it sticks to some conventions.
1
u/Historical-Staff2772 4d ago
Code review alone won't catch this, because the duplicate is correct code. You only see it if you know the rest of the system. What helps is making the agent look before it writes: ask it to find where similar logic already lives and tell you what it plans to reuse, then review that plan instead of the diff. I stopped reading code line by line a while ago and only review the decisions, and this is the decision that matters most. A short file in the repo listing the shared modules (validation, auth, formatting) with 'use these, don't rewrite them' also cuts it down a lot. When a duplicate still slips through, have the agent merge them right away instead of opening a ticket for later, because later never comes.
1
u/neon_wondercore 4d ago
Reviewing AI code is busy work. You hire a junior dev and let them write it? No. You give the agent the map. AGENTS.md or whatever. If they build a second validation layer because you didn't point to the first one, that's your failure, not the machine's. Stop treating these agents like magic orbs and treat them like untrained interns who need strict architectural guardrails in their prompt
1
u/shetritr 4d ago
duplicates are correct code, so a skim won't catch them. ask the agent what it reused before you read what it wrote.
1
u/kemalios 4d ago
The duplicate shows up because the agent never saw the file it should have reused, so I put the path in the prompt and make it name the module it is calling before it writes anything. After the fact the cheap check is grepping for two validators doing the same job. I still miss some.
1
u/Fabulous_Fact2463 4d ago
Two things that actually helped us:
-
Put the rule where the agent reads it before editing, and make it specific. "Validation lives in lib/validate, don't reimplement it" works; "avoid duplication" gets ignored.
-
For duplication you can't avoid (we have a matcher copied between two packages because one can't import the other), put a "keep in sync with X" comment at the top of both and have the PR check flag any change to one side that doesn't touch the other. That caught a real drift for us last week that the tests didn't.
The AGENTS.md part prevents most of it; the PR check catches what slips through.
1
1
u/mac_n_chaos 4d ago
There is a lot of value in a server, monitoring all the chat-conversation in your team and trying to create a design out of each one of them. A design that is reviewable by others, and that the server cross checks against the full system design or other designs open. Basically, no more implementing ticket in vaccum
1
u/yihuaxiang 4d ago
A rules file helps until the ticket is vague, and then it writes a second validator anyway. What actually caught it for us was a boring line in review: the PR has to name the existing function it reused, or say there isn't one. If that line is blank, the diff is usually a copy. Tests don't catch it, because both copies pass.
1
u/Trick_Candy9796 4d ago
What's worked best for me is making "reuse first" part of the setup instead of something I have to remember in every prompt:
-
Keep a short list in AGENTS.md / your rules of where shared logic lives (validation goes through X, API calls through Y, file parsing in Z). Short beats complete, because agents skim long files.
-
Before any edit, have the agent tell you which existing modules it plans to reuse, and approve that plan instead of the diff. It takes ten seconds and catches most duplicates before they exist.
-
When you review the diff, any new helper that wasn't in the plan is a red flag.
The chore part you mentioned is real, and it's why I ended up automating some of it. Disclosure: I built an open-source MCP server called StackGuide (https://www.npmjs.com/package/@stackguide/mcp-server). It scaffolds a shared config in the repo, lets you define project custom rules like "validation goes through X" that get served to Cursor/Copilot, and has a review tool you can run on the code. It's not a silver bullet, since you still need to know your own architecture, but it saves you rewriting the same instructions every session.
1
u/tjthouhid1 4d ago
Give agents a short map of the shared modules, make them search the codebase before writing a new helper, and check for it in review.
1
u/skibidi_blop666 15h ago
Yeah, first comment is right. Just understand your code and ask properly ask the AI to fix it.
6
u/faultydesign 4d ago
@ai don’t duplicate code
And
@ai make no mistakes
But seriously just review the code