메뉴
HN
Hacker News • 23일 전

AI 에이전트 시대, 사라져가는 리팩토링

IMP
7/10
핵심 요약

AI 코딩 에이전트는 인간과 달리 복잡한 코드에서 길을 잃지 않기 때문에 '더 이상 못 참겠으니 리팩토링하자'는 결정이 점점 일어나지 않는다는 문제를 지적한다. 모듈화와 캡슐화 같은 소프트웨어 설계 원칙은 본질적으로 인간의 작업 기억 용량에 대한 타협이었는데, 에이전트가 이 한계를 우회하면서 장기적 유지보수성을 지켜주던 핵심 방아쇠가 사라지고 있다는 것이다.

번역된 본문

로드리고 로젠펠트 로사스 — AI 에이전트와 일어나지 않는 리팩토링 (2026년 9월 2일 오후 12:00)

AI 에이전트와 매일 함께 일하면서, 나는 걱정스러운 경향 하나를 알아차리기 시작했다. 팀들이 — 예전엔 이유를 잘 알고 있던 경험 많은 엔지니어들까지 포함해서 — 시스템의 가장 지저분한 부분을 다시 쓰거나 재구조화하자고 주장하는 일을 조용히 멈췄다는 것이다. 문제는 에이전트가 쓰는 코드의 품질이 아니다. 문제는 예전에는 거의 반사적으로 일어나던 결정이 이제는 거의 일어나지 않는다는 것이다. 즉, 멈춰 서서 "이건 이제 관리 불가능해졌으니 더 진행하기 전에 리팩토링해야 한다"고 말하는 결 말이다.

인간의 컨텍스트는 작고, 그것이 우리가 소프트웨어를 만드는 방식을 결정했다

컴퓨터는 인간보다 훨씬 많은 것을 '작업 기억'에 담아둘 수 있다. 우리는 복잡한 시스템이 수십 갈래로 분기하고, 각 분기가 저마다의 함의를 갖고, 서로 얽혀 있을 때 그것에 대해 제대로 추론할 수 없다. 한 번에 머릿속에 담아두기엔 그냥 너무 많기 때문이다. 그래서 역사적으로 우리는 할 수 있는 유일한 일을 했다. 시스템을 따로 따로 이해할 수 있을 만큼 작은 모듈로 쪼개고, 그 모듈들을 우리가 이해할 수 있는 인터페이스로 연결하는 데 공을 들였다.

모듈화(modularity), 캡슐화(encapsulation), 계층화(layering) — 이것들은 미학적 취향이 아니다. 인간의 작업 기억 크기에 대한 양보다. 각 조각이 한 사람의 머릿속에 들어올 때까지 시스템을 쪼개는 이유는, 그것만이 사람이 그것에 대해 추론하고, 안전하게 변경하고, 다른 사람의 변경을 리뷰할 수 있는 유일한 방법이기 때문이다.

리팩토링 반사 작용

시스템이 처음부터 어수선한 경우는 드물다. 코드는 요구사항이 아직 단순할 때 작성되고, 처음엔 깔끔하게 읽힌다. 그러다 요구사항이 바뀐다. 개발자가 새로운 케이스에 대한 분기를 하나 추가하고, 예외 처리를 위한 분기를 또 추가하고, 그 예외 위에 특수 케이스를 또 얹는다. 충분한 반복이 지나면 코드가 원래 표현하던 '규칙'은 예외들 아래에 파묻힌다 — 때로는 요구사항이 너무 많이 변해서 코드에 남은 건 예외뿐이고 원래의 규칙은 전혀 남지 않기도 한다.

모든 경험 많은 개발자가 아는 순간이 있다. 버그를 디버깅하다가 코드를 따라가다가 길을 잃는 것이다. 분기들이 더 이상 머릿속에 담을 수 있는 그림을 이루지 않는다. 역사적으로 그 느낌은 신호였다. 시니어 엔지니어는 시스템의 한 부분에서 길을 잃으면 멈추고 말했다. "이건 이제 관리 불가능해졌다. 뭘 더 추가하기 전에 다시 쓰거나 리팩토링해서 다시 이해 가능하게 만들어야 한다." 우아함을 위해서가 아니라, 자기 자신과 이후의 모든 사람이 그것에 대해 추론하고 향후 변경을 안전하게 리뷰할 수 있도록 하기 위해서였다.

그 반사 작용 — "길을 잃았으니 리팩토링할 때다" — 은 오래 살아남는 시스템을 유지보수 가능하게 지켜주는 가장 중요한 힘 중 하나로 조용히 자리 잡아 왔다. 그리고 그것은 인간의 한계, 즉 더 이상 코드를 따라갈 수 없게 되는 순간에 의해 작동했다.

공정하게 말하자면, 그 반사 작용은 AI 에이전트 이전부터 이미 압박을 받고 있었다. 마감일, 로드맵, 그리고 "잘 돌아가는 걸 왜 다시 쓰냐"고 묻는 관리자들은 항상 그것과 맞서 왔고, 리팩토링은 대개 우선순위에서 밀려나는 첫 번째 항목이었다. 시니어 엔지니어들도 수년에 걸쳐 시스템이 관리 불가능해졌을 때 예전만큼 강하게 반대하지 않게 됐다. 에이전트가 그 약점을 만든 건 아니다. 에이전트가 한 일은 그 약점에도 불구하고 여전히 작동하던 마지막 내부 방아쇠 — 인간이 길을 잃는 생생한 경험 — 를 제거한 것이다.

AI 에이전트는 길을 잃지 않는다

문제는 이것이다. AI 에이전트는 인간의 컨텍스트 한계에 같은 방식으로 묶여 있지 않다. 에이전트는 얽힌 함수를 읽고, 모든 호출자를 추적하고, 인간을 완전히 멈춰 세웠을 엉망진창을 이해할 수 있다. 다음 분기를 정확히 추가할 수 있고, 그다음 것도 그렇게, 팀의 그 누구도 완전히 이해하지 못하는 코드 안에서 자신 있게 작업할 수 있다.

이건 강점처럼 들리고, 단기적으로는 실제로 강점이다. 하지만 무엇이 빠졌는지 보라. 에이전트는 절대 길을 잃지 않으므로, 신호가 절대 발사되지 않는다. 에이전트에게는 "이건 이제 관리 불가능하니 멈추고 리팩토링해야 한다"는 반사 작용이 없다. 그냥 분기 더미에 계속 분기를 얹을 뿐이다. 명시적으로 지시하지 않는 한.

원문 보기
원문 보기 (영어)
Rodrigo Rosenfeld Rosas AI Agents and the Refactoring That Never Happens September 2, 2026 at 12:00 PM Working with AI agents day to day, I’ve started noticing a trend that worries me. Teams — including experienced engineers who used to know better — have quietly stopped pushing to rewrite or restructure the gnarliest parts of their systems. It’s not about the quality of the code the agents write. It’s about a decision that used to happen almost reflexively and now rarely does: the decision to stop and say this has become unmanageable, we need to refactor it before we go any further. Human context is small, and that shaped how we build software A computer can hold far more in “working memory” than a human can. We can’t reason about a complex system when it branches in dozens of directions, each branch with its own implications, all interconnected. It’s simply too much to keep in our heads at once. So historically we did the only thing we could: we split systems into modules small enough to understand in isolation, and then we spent effort connecting those modules together with interfaces we could also understand. Modularity, encapsulation, layering — these aren’t aesthetic preferences. They’re concessions to the size of human working memory. We break the system down until each piece fits in one person’s head, because that’s the only way a person can reason about it, change it safely, and review someone else’s change. The refactoring reflex Systems rarely start out confusing. A piece of code is written when the requirements are still simple, and at first it reads cleanly. Then the requirements change. A developer adds a branch for a new case, then another for an exception, then a special case on top of that exception. Over enough iterations the original “rule” the code expressed is buried under exceptions — sometimes the requirements have shifted so far that the code is now nothing but exceptions, with no clear rule left at all. There’s a moment every experienced developer recognizes: you’re debugging an issue, you follow the code, and you get lost. The branches no longer form a picture you can hold in your head. Historically, that feeling was a signal . A senior engineer, upon getting lost in a piece of the system, would pause and say: this has become unmanageable — before I add anything else, I need to rewrite or refactor this so it’s understandable again. Not for elegance, but so that they and everyone after them could reason about it and safely review future changes. That reflex — “I’m lost, therefore it’s time to refactor” — has quietly been one of the most important forces keeping long-lived systems maintainable. And it was triggered by a human limitation: the moment a person could no longer follow the code. To be fair, that reflex was already under pressure long before AI agents. Deadlines, roadmaps, and managers asking “why are you rewriting something that works?” have always fought against it, and refactoring was usually the first thing to get deprioritized. Senior engineers had already, over the years, stopped pushing back as hard as they once did when a system got unmanageable. Agents didn’t create that weakness. What they did was remove the last internal trigger that used to fire in spite of it — the visceral experience of a human getting lost. AI agents don’t get lost Here’s the problem. AI agents are not bound by human context limits in the same way. An agent can read the tangled function, trace every caller, and make sense of the mess that would have stopped a human cold. It can add the next branch correctly, and the one after that, working confidently inside code that no human on the team fully understands anymore. That sounds like a strength, and in the short term it is. But notice what’s missing: the agent never gets lost, so the signal never fires. The agent has no reflex that says “this has become unmanageable, we should stop and refactor.” It just keeps adding branches to the pile. Unless it’s specifically instructed — through its harness, its prompt, or explicit review criteria — to step back and question the structure, it will happily maintain a mess indefinitely, because the mess isn’t a problem for the agent . The real risk: humans stop being able to police the code The failure mode isn’t that the agent writes bad code. It’s that the natural checkpoint disappears, and the humans stop noticing the code has drifted beyond their understanding. Over time you arrive at a system where: No developer on the team can fully reason about key parts of the code. Reviews become rubber stamps, because the reviewer can’t actually follow the change well enough to judge it. The team increasingly trusts the agent precisely because they no longer understand the code themselves — which is exactly backwards from how trust should work. At that point you’ve lost something important: the ability to reason about your own system without an agent as an intermediary. And you lost it gradually, without any single alarming moment, because the moment that used to raise the alarm — a human getting lost — was quietly removed from the loop. Clean code is cheaper for the agents too It’s tempting to frame all of this as a purely principled concern — we ought to understand our own systems — and leave it there. But there’s a hard-nosed, practical reason to keep the code organized, and it’s one that survives even if you’re perfectly happy to let agents do the work. An agent that never gets lost still pays a price for a mess. The more tangled and interconnected a piece of code is, the more context the agent has to load and hold to make a correct change: more files to read, more branches to trace, more tokens burned on every single edit. A system built from small, self-contained modules that are easy to reason about isn’t just kinder to humans — it’s cheaper to operate, because every future change costs the agent less to understand. And it isn’t only about cost. When the relevant logic doesn’t fit into a bounded, coherent slice, agents are more likely to lose the thread and hallucinate — to assume a branch does something it doesn’t, or to miss an exception buried three levels deep. The same modularity that keeps a system inside a human’s head keeps each change inside a well-defined boundary the agent can reason about reliably. Clean boundaries reduce mistakes on both sides, for the same reason. So keeping the source organized isn’t a favor we do for humans at the agents’ expense. It benefits humans, it improves the agents’ accuracy, and it lowers the token cost of every change we’ll ever make to that code again. The refactoring reflex we’re at risk of losing was never only about human comfort — it turns out to be good economics too. Policing ourselves I don’t think the answer is to hobble the agents. The answer is for us to bring back the checkpoint deliberately, since it no longer happens on its own. We have to keep asking the question the agent won’t ask: Do I still understand this part of the system, or have I been letting the agent understand it for me? If a human had to debug this without the agent, could they follow it? Have the requirements drifted so far that this code is now all exceptions and no rule — the classic signal that it’s time to rewrite? Is now the moment to pause feature work and refactor this into something a person can hold in their head again? You can also push some of this into the harness — instruct your agents to flag when a module has grown beyond a reasonable size or branching complexity, to propose refactorings rather than only extending, and to call out when a change is getting hard to reason about. That helps. But the ultimate responsibility stays with us, because we’re the ones who need to be able to understand our systems, and we’re the ones who lose that ability if we’re not paying attention. The convenience of an agent that never gets lost is real. But “the agent can still make sense of it” is not the same as “the system is health