1P by GN⁺ | ★ favorite | 댓글 1개
  • LLM이 코드를 계속 대신 써주더라도, 중복 조건문과 임시 구현을 그대로 병합하면 이후 생성 코드가 그 관행을 프로젝트 규칙처럼 따라갈 수 있음
  • 접근 권한 확인 로직을 route handler, background job, API endpoint, webhook 등에 반복해 넣으면 테스트는 통과해도 유지보수 부담은 그대로 남음
  • 모델은 열린 파일, 기존 패턴, 최근 변경사항을 보고 다음 코드를 만들기 때문에, 복사된 조건문 4개는 다섯 번째 복사본을 부르는 신호가 됨
  • 나중에 리팩터링을 요청해도 LLM이 기존 복사본을 모두 제대로 정리한다고 보장하기 어렵고, 나쁜 패턴은 일회성 실수보다 코드베이스의 스타일에 가까워짐
  • 중복 조건문, “god” 함수, “나중에 정리” 병합이 쌓이면 프롬프트만으로 되돌리기 어려워지고 결국 사람이 직접 고쳐야 함

LLM이 참고하는 것은 현재 코드베이스임

  • LLM은 코드를 “진공 상태”에서 작성하지 않고, 사용자의 코드베이스를 읽음
    • 열린 파일
    • 이미 존재하는 패턴
    • 최근 변경사항
  • 코드베이스에 병합된 지름길은 “여기서는 이렇게 한다”는 학습 신호가 됨
  • 같은 접근 제어 조건이 여러 위치에 반복될 수 있음
if (user.isActive && user.hasPermission('read') &&
!user.isSuspended && account.status === 'open') {
  // do a thing
}
  • 이 조건문은 공유 헬퍼로 추출할 수 있지만, LLM이 만든 코드가 동작하고 테스트가 통과한다는 이유로 그대로 병합될 수 있음
  • 같은 규칙을 가진 다섯 번째 엔드포인트를 요청하면, 모델은 처음부터 설계하기보다 저장소 안의 기존 복사본들을 따라갈 가능성이 커짐

유지보수를 LLM에 맡긴다는 착각

  • “나중에 바꿀 때도 LLM이 해줄 것”이라는 생각은 중복과 코드 냄새를 방치하게 만듦
  • 몇 개의 중복 조건문은 치명적이지 않을 수 있지만, 이런 코드 냄새는 계속 쌓임
    • 중복 조건문
    • “god” 함수
    • “나중에 정리”하기로 한 병합
  • 나쁜 패턴이 늘어나면 다음 프롬프트의 결과에도 영향을 주고, 나중에 모든 인스턴스를 LLM이 빠짐없이 고칠 것이라고 믿기 어려워짐
  • 유지보수를 LLM에 아웃소싱한다고 생각해도, 실제로는 점점 나빠지는 습관을 반복하도록 만드는 상황이 될 수 있음
  • 사람이 유지보수할 것처럼 코드를 작성해야 하며, LLM이 흡수해 되돌려줄 코드 패턴은 좋은 상태로 유지해야 함

댓글과 토론

Hacker News 의견들
  • .claude/commands/review.md에 빈 Markdown 파일로 /review 명령을 만들고, 에이전트가 확인해야 할 체크리스트를 넣어두면 좋음
    코드 리뷰가 필요할 때 /review를 입력하면 그 체크리스트를 보고 수정할 만한 항목을 계획한 뒤 물어봄
    내 파일은 “계획 모드로 들어가라. 이 브랜치와 main의 차이를 살펴라. 고려할 것: ...”로 시작하고, 코드 리뷰 중 발견해 에이전트에게 고치게 한 항목을 계속 추가했더니 이제 200개쯤 됨
    에이전트는 일반적인 피드백 벽을 받아도 개의치 않고 항목을 하나씩 살펴보며, “새로 만든 것들이 기존 코드와 중복되지 않는지 확인하라”를 넣었더니 실제로 정리 작업을 계획하기 시작해서 놀랐음
    아직 표면만 긁고 있는 수준이고, 도구가 더 나은 도구가 되도록 도구를 위한 도구를 줘야 함

    • 목록에 항목을 많이 넣을수록 에이전트 성능은 더 나빠지는 쪽에 가까웠음
      지금도 꽤 단순한 지시만 쓰는데 Claude는 “허락 없이 git에 커밋하지 말 것”, “커밋 메시지에 서명하지 말 것” 같은 첫 지시를 자주 어김
      물어보면 “맞다, 그 지시가 있었는데 무시했다”고 답하고, 세션에서 정중히 고치면 이해는 하지만 이후엔 아예 커밋을 못 하는 상태가 되기도 함
      200개 체크리스트를 검토시키면 그중 상당수를 조용히 놓치고 있을 가능성이 높음
    • AI 도구에서 늘 불만이던 부분이 바로 품질 기대치를 알기 어렵다는 점임
      사람 엔지니어라면 기존 테스트 200개가 쓰는 단언 라이브러리가 있는데 새 테스트에 전혀 다른 라이브러리를 쓰지는 않을 텐데, Claude는 그런 일을 여러 번 했음
      그래서 “작성 전에 테스트 관례를 살펴보라” 같은 항목을 계속 추가하게 됨
      반대로 함수가 무엇인지, 테스트가 변경 diff를 다뤄야 한다는 식의 기본은 굳이 말하지 않아도 되는데, 어느 쪽을 말해야 하고 어느 쪽은 괜찮은지 명확한 목록이 없어서 시행착오로 쓸 만한 방법을 만드는 느낌임
    • 그 목록을 공유해줄 수 있는지 궁금함
      내 경우 에이전트와 오가며 “내 눈과 취향에 괜찮아 보일 때까지” 다듬는 일이 많지만 아직 그런 목록은 만들지 않았음
      프로젝트에 따라 사소한 문제나 매직 넘버를 허용하기도 하고, 다른 프로젝트에서는 SECONDS_IN_A_DAY = 24 * 60 * 60처럼 의미 있는 이름의 상수를 강제하기도 해서 맥락 의존적
    • open-code-review를 써보고 좋은 결과를 얻었음
      https://github.com/alibaba/open-code-review
      https://layandreas.github.io/personal-blog/posts/beyond-vide...
    • 자체 리뷰 스킬을 쓰고 있는데, 설명에 하나 덧붙이자면 전체 코드를 먼저 살펴본 뒤 변경 내용에 맞춰 다중 역할 리뷰를 다시 하라고 시키면 좋음
      예를 들어 Senior Engineer, Security Engineer, WCAG specialist 같은 긴 역할 목록에서 변경에 가장 적절한 N개 역할을 고르게 함
      Claude는 그 리뷰들을 병렬로 실행한 뒤 피드백을 합쳐줌
      명세 기반 개발을 하기 때문에, 발견된 이슈를 명세에 덧붙여 이슈와 결정의 흔적을 남기고 있음
  • 여기서 많은 엔지니어가 또 다른 프롬프트를 얹고 있다는 게 이상할 정도임
    내 경험상 그럴수록 더 나빠졌고, 추상화는 하되 잘못된 추상화를 만들며, 주석을 과하게 달아 이후 LLM 호출까지 헷갈리게 함
    좋은 코드베이스에서는 그럭저럭 동작하지만 코드를 점점 나쁘게 만들고, 계속 쓰다가 어느 순간 작동하지 않으면 그동안 직접 만들지 않은 대가를 치르며 고쳐야 함
    새 코드베이스에 에이전트를 넣으면 보통 코드에 대한 정신 모델이 있고 코드도 어느 정도 간결하지만, 반복이 쌓이면 둘 다 사라지고 LLM 성능도 떨어짐
    그래서 LLM은 탐색과 리뷰에 쓰고, 코드는 직접 작성함
    코딩이 시간이 크게 들지도 않고 가장 즐거운 부분인데 왜 피하려는지 이해하기 어렵고, 가끔 /bug 프롬프트로 AI와 동시에 디버깅 경주를 해보면 AI가 항상 빠르지도 않음

    • “코드는 직접 작성한다. 왜 많은 엔지니어가 그걸 피하려 하는지 믿기 어렵다”는 말에 공감함
      최근 몇 년 사이 소프트웨어 일은 호기심 많은 땜장이와 퍼즐 중독자들의 실용적 공학 피난처 중 하나에서, 금융·법률·의학처럼 돈을 노리는 똑똑한 사람들의 경력 경로로 바뀌었음
      지금 “소프트웨어 엔지니어” 직함을 가진 많은 사람은 애초에 그 작업을 즐긴 적이 없고, 똑똑하고 책임감이 있어 고용주가 준 적당한 목표를 달성했을 뿐임
      그런 사람들이 AI 에이전트가 엄밀한 설계와 퍼즐 작업을 막아주고 타고난 영리함을 더 게으르게 활용하게 해주길 가장 원함
      코딩과 공학 원칙을 내면화하지 못했기 때문에, 같은 마음가짐의 동료들에게 둘러싸이면 이 방식이 앞으로 어떤 결과를 만들지 예측하기 어려움
      코딩 자체가 처음부터 매우 답답하고 마찰 많은 경험이었다면 AI가 더 빠르다고 느끼기 쉬움
    • 에이전트가 코드를 “더 잘” 쓰는 세상에서도 사람들이 직접 코드를 써야 한다고 보는 이유가 여기에 있음
      코드는 읽는 것만으로 충분하지 않고, 고통스럽게 겪어야 내면화됨
      에이전트는 기존 경로가 아직 존재해야 하는지 묻기보다 오래된 코드를 방어적으로 감싸는 일이 잦아서, 엄청난 양의 방어 코드가 러시아 인형처럼 겹겹이 쌓이는 효과가 생김
      https://softwaredoug.com/blog/2026/07/09/write-code
    • 꽤 오래 전부터 AI와 “디버깅 경주”를 해왔는데, Opus 4.8 이전에는 조금만 복잡해도 비교가 안 됐음
      Opus 4.8이 전환점이었고, 특히 복잡한 문제에서는 이제 Opus 4.8을 상대로 많이 이기지 못함
      모두가 모든 작업과 질문에 Opus 4.8 이상을 쓴다면 전체 분위기는 훨씬 달라질 것이고, AI 회의론자도 많이 남지 않을 것 같음
    • 품질을 신경 쓰지 않고 티켓을 닫기 위해 최대한 빨리 코드를 찍어내야 한다면 AI는 항상 더 빠름
    • 비슷한 흐름으로 작업함
      여전히 코드는 손으로 직접 쓰고, 전부는 아니지만 일부는 Opus가 생성함
  • 엉뚱한 생각일 수 있지만 그냥 코드를 직접 쓰면
    AI 시대에는 믿기 힘든 개념처럼 들리겠지만, 사람이 읽고 유지보수해야 할 코드라면 그 사람들을 위해 직접 쓰는 편이 낫음
    지나치게 장황하고 복사·붙여넣기된 코드를 읽다 보면 짜증이 날 것이고, 다른 사람도 마찬가지임
    직접 쓰면 스스로 고치고, 다른 사람이 유지보수하기에 말이 되는 방식으로 작성하게 됨
    아니면 미래 유지보수자가 기대할 코드 모양을 에이전트와 루프가 이해하도록 Markdown 파일의 복잡한 그물을 만들어 달랠 수도 있음
    장기적으로 어느 길이 더 쉬울지는 모르겠고, 루프 기반 에이전트 주도 코드베이스를 물려받아 이해해본 사람이 있는지 궁금함

  • “다음에 같은 접근 규칙을 가진 엔드포인트를 LLM에 요청하면 모델은 처음부터 생각하지 않고 저장소에 이미 있는 네 개의 복사본에서 시작한다”는 말이 얼마나 맞는지 잘 모르겠음
    실제로는 기본 구조를 반복하고 재사용이나 추상화를 덜 하려는 내장된 편향이 있는 것 같음
    기존 패턴이 그렇다면 그걸 따르는 것처럼 보이지만, 실제로는 어느 쪽이든 그렇게 했을 가능성이 큼
    엄격한 추상화와 사용 예시를 먼저 깔아두고, 특정 추상화 API만 쓰고 내가 쓴 방식까지 복사하라고 명시적으로 지시해도, 최신 LLM이 둘 다 하지 않고 아래에서부터 기본 구조를 다시 구현하며 추상화를 부분적으로 또는 완전히 무시한 경우가 많았음
    왜 그런지는 정확히 모르겠지만, 훈련 코드에 이런 식의 코드가 너무 많아서 가중치가 이 방식으로 결과를 내는 법을 더 잘 “알고” 있는 게 아닐까 싶음

    • 지금의 안타까운 현실이 바로 그거고, 피하려면 모델에게 구현 방법을 아주 구체적으로 지시해야 함
      그래도 LLM을 빠른 구현 엔진으로 쓰는 건 괜찮다고 봄
      과제는 모델이 잘못된 방향으로 달려가기 전에 이런 구현 결정을 먼저 드러내게 만드는 것임
  • 큰 변경 뒤에는 다음 프롬프트로 좋은 결과를 얻었음
    “이제 최종 코드 점검을 하라. 모든 것이 정돈되어 있고 컴포넌트가 관심사의 분리 원칙을 따르는가? 이해 가능하고 유지보수 가능한 상태인가? 더 이상 참이 아닐 수 있는 가정을 하고 있지는 않은가? 이전 편집이나 실험에서 남은 코드가 코드베이스에 들어가 있지는 않은가? 문서는 여전히 현재 코드 상태를 반영하는가?”

    • 보통은 “이 코드가 시니어 엔지니어가 납품할 만한 전문적인 상태인지 확인해줘” 정도로 말함
      그러면 위에서 말한 것과 그 이상을 대체로 추론해냄
      다만 계속 직접 짚어줘야 하는 건 “진행 추적”용 주석을 모두 지우고, 장기 유지보수에 적합한 주석만 남기라는 점임
      Claude는 “버튼 클릭이 이제 저장을 유발하며 더 이상 onBlur를 쓰지 않음” 같은 주석을 남기는데, 실제 코드는 onBlur를 쓴 적이 없고 같은 작업/브랜치에서 Claude가 아까 하려던 것을 내가 돌려세운 흔적일 뿐인 경우가 있음
    • 이건 장황한 “실수하지 마”에 가깝고, 차라리 전날 작업을 훑어 같은 성격의 아침 작업을 만들어주는 야간 cron 작업을 두는 편이 더 말이 될 수 있음
      모델은 제멋대로 해석하겠지만, 그래도 아무것도 안 하는 것보다는 나을 때가 많음
    • AI 네이티브 사고의 좋은 예임
      AI에게 전부 가르치고 제대로 배웠는지 물어보는 방식인데, 결과가 의외로 좋음
      이 글과 비슷한 단계를 따르고 있음
      https://www.lucasfcosta.com/blog/backpressure-is-all-you-nee...
  • 오래된 격언이 있음
    “다음 유지보수자가 네가 사는 곳을 아는 살인광이라고 가정하고 코드에 주석을 달아라”

    • 요즘 가장 화나게 하는 주석은 함수 정의 바로 위에서 그 함수의 현재 특정 호출자 동작을 말해 캡슐화를 깨는 LLM식 과잉 정보 주석임
      최근 PR 리뷰에서 그런 걸 몇 번째로 마주치고 화를 내며 댓글을 달았는데, 스스로도 놀랐음
      내가 그런 반응을 할 수 있는 줄 몰랐음
    • 예전에 같이 일하던 사람이 “주석은 사과다”라고 자주 말했음
      즉 코드 자체가 명확하지 않기 때문에 주석이 있다는 뜻인데, 그런 경우도 있지만 일반적으로는 주석이 적은 것보다 많은 편이 낫다고 봄
      특히 코드가 실제 비즈니스나 기능 요구사항과 어떻게 연결되는지 설명하고, 단순히 코드가 하는 일을 반복하지 않는다면 더 좋음
      몇 년 전에는 주석을 먼저 쓰곤 했음
      전체 목표를 설명하고, 루틴과 작업 순서로 나눈 뒤, 만족스러워지면 주석 사이에 코드 블록을 채워 넣는 방식이었음
      일종의 문학적 프로그래밍 같지만 그 용어를 알기 전부터 하던 방식이고, 목표를 향해 스스로에게 프롬프트를 주는 것에 가까웠음
      단점은 주석이 결국 코드가 하는 일을 영어로 설명하는 수준이 되기 쉬워 미래 유지보수자에게 그리 유용하지 않을 수 있다는 점임
    • 살인 충동을 가장 크게 부르는 건 주석이 없는 코드가 아니라 오래됐거나 부정확한 주석
    • 과도한 주석을 부르는 처방처럼 들림
      코드는 스스로 설명되어야 하고, 주석은 용이 있는 곳에 쓰는 것임
  • 비슷한 맥락에서 내가 좋아하는 프롬프트는 “네가 작성한 테스트를 검토해줘. 이 테스트가 정말 의도한 것을 테스트하나? 코드가 깨지면 테스트도 실패하나?”임
    LLM이 아무것도 검증하지 않는 빈 테스트를 얼마나 자주 쓰는지 놀라울 정도임

    • 사람이 작성한 테스트도 실제 코드는 검증하지 않고 테스트 프레임워크만 검증하는 경우를 많이 봤음
    • 내 작업 흐름은 먼저 테스트를 작성하고 실패를 확인한 뒤, 그 테스트를 통과시키는 최소 코드를 작성하고, 초록색인지 확인하는 것임
  • 아직도 이런 걸 진지하게 논의해야 하나 싶음
    LLM으로 그렇게 “실험”을 해봤으면 이제 당연히 받아들여야 하는 것 아닌가 싶음
    언제쯤 손코딩을 다시 금기처럼 다루지 않고 이야기할 수 있을지 궁금함
    LLM은 여러 방식으로 유용하지만, 사람들이 전체 소스 코드 타이핑을 에이전트에 위임하는 걸 보면 지침
    웹이 좋으니 우리가 행복해야 한다는 말을 듣는 것과 비슷하게 느껴짐

  • 코드베이스를 여러 모델에 계속 돌려 중복 코드 같은 나쁜 냄새를 찾게 하고 있음
    꽤 효과적이었고, 시간이 지나도 계속 관리하지 않으면 지저분한 덩어리가 되며 그게 누적될 것 같음

    • 순환 복잡도나 코드 중복을 결정적으로 잡아내는 SonarQube, Rubocop 같은 AST 기반 정적 분석기는 어떻게 생각하는지 궁금함
      빌드 파이프라인에 넣을 수도 있고, 토큰도 전혀 쓰지 않음
    • 다른 모델을 쓰는 게 중요하다고 보는지 궁금함
      아니면 리뷰 과정과 맥락 초기화가 더 중요한 걸까?
  • 사람들이 20년 동안 유지보수한 코드에서도 이런 중복과 더 나쁜 것들을 많이 봤음
    솔직히 지금 LLM이 만드는 것보다 사람이 작성하고 유지보수한 코드가 더 나쁜 경우가 대부분이었음
    경험 부족일 때도 있고, 고의적 태만일 때도 있지만, 대체로는 빡빡한 일정과 당장 끝내야 한다는 압박 때문임
    사람들은 더 잘하는 법을 알지만, 실제로 그렇게 할 시간과 예산이 없음
    LLM도 그걸 배웠음

    • LLM 이전에는 Copilot이 많이 반복했고, 그 전에는 복사·붙여넣기와 Stack Overflow가 있었음