‘오류 발생’에서 ‘수정 PR’까지, 제가 직접 병합하는 과정
요약
본 글은 개발자가 겪는 '오류(Error)'와 사용자가 느끼는 '버그(Bug)' 사이의 간극을 메우기 위한 도구 Mushi를 소개합니다. 이 시스템은 사용자 보고서를 캡처, 필터링, 진단하는 과정을 거쳐 자동으로 수정 PR을 생성하고 CI 검증까지 진행합니다. 최종 병합 단계는 개발자의 수동 개입이 필요함을 강조하며, 전체 프로세스를 체계적으로 설명합니다.
핵심 포인트
- Mushi는 오류와 사용자 경험 간의 격차를 해소하려는 시도입니다.
- 사용자 보고서는 캡처, 필터링(Claude Haiku), 진단(Claude Sonnet/GPT-5.4) 등 다단계 과정을 거칩니다.
- 진단 과정에서 코드 검색을 통해 정확한 파일 이름을 지정할 수 있습니다.
- 자동 수정 기능은 PR을 생성하고 CI를 실행하지만, 최종 병합은 개발자가 직접 수행합니다.
Sentry는 코드가 던진 것(thrown)으로부터 시작합니다. Mushi는 사용자가 느낀 것(felt)으로부터 시작합니다.
이 글은 제가 Mushi를 만들기 전에 꼭 읽고 싶었던 포스팅입니다. 제 Sentry 대시보드는 녹색이었지만, 세 명의 사람이 연달아 iPad Safari에서 로그인 버튼이 ‘아무것도 하지 않는다’고 말했습니다. 아무 오류도 발생하지 않았고 콘솔도 깨끗했습니다. 하지만 사용자들은 여전히 막혀 있었습니다.
Mushi Mushi (虫虫)는 오류가 발생하는 것과 사용자가 느끼는 버그 사이의 간극을 좁히려는 저의 시도입니다. 아래에서는 하나의 보고서가 단계별로 어떻게 처리되는지, 그리고 왜 제 레포지토리를 건드리는 두 가지 단계가 아직 저를 기다리고 있는지 설명합니다.
하나의 보고서가 거치는 과정
사용자가 저희 앱의 위젯을 탭하고 한 문장을 입력합니다: “iPad에서 로그인 버튼이 아무것도 하지 않아요.”
- 캡처(Capture). 보고서는 사용자의 메모, 라우트, 브라우저 및 뷰포트와 함께 도착하며, 마지막 콘솔 및 네트워크 이벤트도 포함됩니다. 스크린샷이 첨부되며, 보고자는 전송 전에 이를 제거할 수 있습니다. 해당 세션에 세션 리플레이가 활성화되어 있다면, 지난 30초 분량의 데이터도 함께 옵니다.
- 필터링(Filter). Claude Haiku 4.5가 저렴한 첫 번째 검사를 수행하여 스팸과 노이즈를 걸러냅니다.
- 진단(Diagnose). 필터를 통과한 보고서는 두 번째 모델(기본값은 Claude Sonnet 5.5, 폴백은 GPT-5.4)로 전달됩니다. 이 모델은 카테고리, 심각도, 예상 컴포넌트, 일반 영어 요약 및 신뢰 점수를 작성합니다. 진단 과정에서 제 레포지토리에서 검색된 코드를 읽기 때문에 추측하는 대신 실제로 본 파일의 이름을 지정할 수 있습니다. 호스팅 서비스에서는 이 과정에 약 10초가 소요됩니다.
- 그룹화(Group). 각 보고서는 임베딩되어 pgvector를 사용하여 이전 보고서들과 비교됩니다. 0.82 이상일 경우(기본값; 프로젝트별로 변경 가능), 새 보고서는 새로운 행을 열지 않고 기존 그룹에 합류합니다. 중복된 그룹은 월간 진단 할당량에 포함되지 않습니다. 초기 10월까지는 프로젝트별 임계값이 저장만 되고 읽히지는 않았기 때문에 모든 프로젝트가 0.82로 설정되었습니다. 이제는 이 값이 읽힙니다.
- 수정(Fix). 자동 수정 기능은 제가 프로젝트에 대해 활성화할 때까지 꺼져 있습니다. 그 후 보고서에서 **수정 배포(Dispatch fix)**를 클릭합니다.
오류 수정 작업자(fix worker)는 고정된 커밋의 리포지토리 전체 파일을 로드하고, 타이핑된 스키마를 통해 모델에게 찾아서 대체하는 편집 내용을 요청합니다. 이 모델은 도구나 셸에 접근할 수 없습니다. 만약 편집 내용이 적용되지 않으면, 작업자는 정확한 오류와 함께 한 번 재시도한 후 중단됩니다. 단일 파일의 diff가 200개 변경 라인을 초과할 경우(프로젝트별 설정), 실행이 중단됩니다. 그렇지 않은 경우, PR을 드래프트로 열고 검토 준비 상태로 표시하여 CI가 실행되도록 합니다. 모든 LLM 호출은 Langfuse에 추적됩니다.
6. 확인. 수정 사항의 PDCA 수신증(receipt)은 콘솔에서 해당 PR의 CI가 보류 중인지, 통과했는지, 실패했는지를 보여줍니다.
7. 조치. 저는 병합하거나, 아니면 하지 않습니다. 병합할 경우, Mushi는 보고서가 수정되었음을 표시하고, Sentry 플러그인이 활성화되어 있다면 연결된 Sentry 이슈를 해결하며, 해당 보고서를 제출한 사람에게 '수정됨' 알림을 보냅니다.
제가 여전히 수동으로 병합하는 이유
이 루프는 저 없이도 실행될 수 있습니다. CI가 이미 모든 수정 PR에 대해 실행되기 때문입니다. 그럼에도 불구하고 저는 병합 과정을 수동으로 유지했습니다.
점수는 유용하지만 최종적이지 않다
별도의 백그라운드 작업인 '심사관(judge)'은 분류된 보고서를 배치 단위로 다시 읽습니다. 이 심사관은 정확도, 심각도 보정(severity calibration), 컴포넌트 태깅, 재현 품질을 0부터 1까지 점수화하고, 전체 호출과 일치하는지 여부를 판단합니다. 이러한 점수는 분류기 프롬프트 간의 A/B 테스트에 사용되어 더 나은 프롬프트가 승리할 수 있도록 합니다. 이 점수들은 보고서의 상태를 변경하지 않으며, 읽지 않은 수정 사항을 병합해야 할 이유도 아닙니다. 심각도가 잘못되었거나, 잘못된 컴포넌트를 목표로 하는 수정 사항은 아무도 지켜보지 않는 루프에서 배포될 수 있는 것과 같습니다.
잘못된 수정이 느린 수정보다 더 큰 비용을 초래한다
누군가 버그를 보고하고 나중에 그것이 '수정됨'으로 표시되는 것을 보면, 그들은 앱이 관리되고 있다는 것을 배웁니다. 잘못된 것을 변경하여 다른 무언가를 망가뜨리는 자동 수정은 정반대의 것을 가르칩니다. 수정 작업자의 헤더 주석에는 규칙이 명시되어 있습니다:
SDK는 MIT 라이선스입니다: 모든 사이트를 위한 @mushi-mushi/web 외에도 React, Vue, Svelte, Angular, React Native, Capacitor 및 Node를 지원합니다. CLI와 MCP 서버 역시 MIT 라이선스입니다. iOS, Android, Flutter SDK는 미리 보기(preview) 버전입니다. 서버(Supabase Edge Functions, Postgres, pgvector)는 AGPLv3 라이선스를 따릅니다. 자체 LLM 키만 사용하고 진단 횟수 제한 없이 무료로 자체 호스팅할 수 있습니다. 만약 수정된 서버를 다른 사람을 위한 서비스로 운영한다면, AGPL §13에 따라 변경 사항을 공개해야 하거나 상업용 라이선스를 구매할 수 있습니다.
유료 부분은 호스팅 서비스와 엔터프라이즈 에디션입니다. Mushi Cloud는 월 50건의 진단과 카드 정보가 필요 없는 무료 등급(free tier)을 제공하며, 이후 인디(Indie)는 월 $15, 프로(Pro)는 월 $49에 이용 가능합니다. 엔터프라이즈 에디션(SSO, 감사 내보내기(audit export), 지역 고정(region pinning))은 소스 코드가 공개되어 있으며(source-available), 프로덕션 사용을 위해서는 라이선스가 필요합니다.
사용해보기
- 제품 페이지 및 문서: kensaur.us/mushi-mushi
- 읽기 전용 데모, 가입 불필요: MCP를 통해 시드된 Mushi 프로젝트에 에디터를 연결하세요: connect your editor.
- 위젯 추가 (프레임워크 감지, SDK 설치, 환경 변수 작성):
npx mushi-mushi
- 에디터가 MCP를 통해 진단을 읽도록 설정: 에이전트가
get_fix_context를 호출하여 진단 내용, 재현 단계(repro steps), 관련 코드를 하나의 프롬프트로 받습니다:
npx mushi-mushi setup --ide cursor # 또는 --ide claude
- 소스 및 자체 호스팅 가이드: github.com/kensaurus/mushi-mushi
만약 아무것도 발생시키지 않는 사용자 보고 버그를 다뤄본 경험이 있다면, 어떻게 포착했는지 듣고 싶습니다. 댓글로 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기