본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 25. 18:00

GitHub 이슈 분류(Triage)를 담당하는 AI 에이전트 도입하기

요약

GitHub 이슈 관리의 번거로움을 해결하기 위해 LLM 기반의 AI 에이전트를 도입하는 방법을 소개합니다. GitHub Actions와 Python을 활용하여 레이블링, 중복 확인, 정보 요청을 자동화하는 에이전트 구조를 설명합니다.

핵심 포인트

  • GitHub Actions를 활용한 서버리스 에이전트 구현
  • 하드코딩 대신 도구 호출(Tool Call) 기반의 에이전트 설계
  • 이슈 분류, 레이블링, 중복 확인 및 정보 요청 자동화
  • 오픈소스 관리자의 운영 부담 경감

레이블을 달고, 중복을 제거하며, 누락된 세부 정보를 요청하는 GitHub Actions 봇, 그리고 마침내 이 봇이 조용히 있도록 가르친 단 하나의 지침.

활발하게 운영되는 GitHub 저장소(repo)를 관리하고 있다면, 여러분은 이미 그 번거로움을 알고 있을 것입니다. 모호한 제목, 재현 단계(steps to reproduce)가 없고, 세 가지 정도의 그럴듯한 의미로 해석될 수 있는 새로운 이슈가 올라옵니다. 내용을 읽고, 레이블(label)을 추가하고, 더 자세한 내용을 요청하고, 지난주에 올라온 내용과 중복되는지 확인한 다음, 한 시간 뒤에 똑같은 일을 다시 반복합니다. 이 중 어려운 일은 하나도 없습니다. 하지만 이 모든 것이 쌓이면, 실제 코드를 작성하는 데 쓰고 싶었던 시간을 조용히 갉아먹게 됩니다.

이것은 작은 문제도 아닙니다. Tidelift의 2024년 관리자 설문조사에 따르면, 오픈 소스 관리자의 약 60%가 활동을 중단했거나 중단을 진지하게 고려했다고 답했습니다. 그리고 커뮤니티 및 이슈 관리 측면의 업무는 코드를 작성하는 것보다 더 힘들고 보람이 적은 일로 반복해서 언급됩니다.

그래서 저는 첫 번째 검토 단계를 대신 수행할 작은 봇을 만들었습니다. 이 봇은 각 새로운 이슈를 읽고, 제가 정의한 세트에서 레이블을 적용하며, 짧은 이유와 함께 중복 가능성이 높은 이슈를 표시하고, 설명이 너무 빈약하여 조치를 취할 수 없는 경우 누락된 정보를 요청합니다. 전체 과정은 언어 모델(language model)을 기반으로 하는 GitHub Actions 워크플로(workflow) 내에서 실행되므로, 호스팅할 서버가 필요 없으며 이벤트 사이에 실행되는 것도 없습니다. 저는 제가 관리하는 것을 돕고 있는 FINOS git-proxy 프로젝트를 위해 이 봇을 만들었습니다.

Issue triage bot in action

구조: 세 가지 작은 조각

내부적으로는 세 부분으로 구성됩니다. 이슈가 오픈될 때 실행되는 GitHub Actions 워크플로, 워크플로가 실행하는 Python 스크립트, 그리고 그 스크립트 내부에서 이슈에 대해 조치를 취할 수 있는 도구(tools) 세트를 전달받은 모델에 대한 호출(call)입니다.

그 마지막 부분이 바로 이것을 고정된 스크립트가 아닌 에이전트(agent)로 만드는 요소입니다. "분류하고, 댓글을 달고, 라벨을 붙여라"와 같이 경직된 순서로 하드코딩(hard-coding)하는 대신, 사용 가능한 작업들을 도구(tools)로서 모델에게 설명하면, 모델은 이슈가 실제로 필요로 하는 것에 따라 어떤 도구를 어떤 순서로 호출할지 스스로 결정합니다. 깔끔한 이슈라면 단 한 번의 도구 호출(tool call)만 사용할 수도 있고, 복잡한 이슈라면 세 번을 사용할 수도 있습니다. 전체 루프와 도구 정의에 대해서는 제 블로그의 전체 글에서 다룹니다.

침묵을 유지하도록 가르치기

첫 번째 버전은 댓글을 너무 많이 달았습니다. 저는 작성자가 이슈가 접수되었음을 알 수 있도록 항상 확인 메시지를 게시하라고 명령했는데, 모델은 이미 명확하여 답변이 필요 없는 이슈에 대해서도 정확히 그 명령을 수행했습니다. 깔끔한 이슈에 댓글이 두 개나 달리면 소음(noise)으로 느껴지며, 이러한 소음은 사람들이 봇을 무시하도록 학습시킵니다.

해결책은 코드에 전혀 있지 않았습니다. 시스템 프롬프트(system prompt)에 짧은 문구 하나를 추가하여 모델에게 아무것도 하지 않을 권한을 부여하고, 불확실할 때는 침묵을 선호하는 결과로 만들었습니다. 모델은 도움을 주려는 경향이 있으며, 이는 실제로는 수다스럽게 행동한다는 것을 의미합니다. 따라서 침묵을 유지하는 것이 종종 정답이라는 점을 명확하게 말해주는 것이, 규칙을 아무리 엄격하게 다듬는 것보다 모델의 행동을 더 효과적으로 변화시켰습니다. 제가 사용한 정확한 문구는 복사해서 쓰기에 충분히 짧으므로 제 사이트의 포스트에 기재해 두었습니다.

하나의 봇, Claude 또는 GPT 또는 Gemini

처음에는 단일 모델과 한 벤더의 SDK로 시작했습니다. 이는 누군가 이미 비용을 지불하고 있는 모델에서 동일한 봇을 실행하고 싶어 하기 전까지는 괜찮습니다. 스크립트를 LiteLLM으로 옮기면서, 모델 문자열에 제공자(provider)를 인코딩하여 동일한 워크플로우(workflow)가 Claude, GPT 또는 Gemini를 가리킬 수 있게 되었습니다. 봇 전체가 도구(tools)를 기반으로 구축되었기 때문에, 세 모델 모두에서 작동하는 함수 호출(function calling) 기능이 가장 중요했습니다. 응답 형태(response shapes)는 몇 가지 짜증 나는 방식으로 다르며, 이에 대해서는 전체 버전에서 목록을 정리해 두었습니다.

LiteLLM - the gateway to any AI provider

나를 괴롭혔던 부분들

실제 환경에 적용하고 나서야 발견된 몇 가지 문제들이 있었으며, 이는 제가 직접 구축하기 전에 미리 읽어두었으면 하는 내용들입니다.

봇은 제가 직접 푸시(push)할 때는 잘 작동했지만, 외부 기여자가 처음으로 풀 리퀘스트 (Pull Request, PR)를 열었을 때 환경 내의 모든 비밀 값(secret)이 갑자기 빈 상태가 되면서 실패했습니다. 이는 비밀 이름의 오타가 아니라 GitHub의 의도적인 보안 조치이며, 이를 해결하는 방법에는 그 자체로 날카로운 안전 주의 사항이 따릅니다. 또한, 신뢰할 수 없는 이슈(issue) 및 PR 텍스트를 프롬프트 (prompt)에 직접 입력하는 것은 프롬프트 인젝션 (prompt injection)의 문을 열어주는 격이 됩니다. 즉, 텍스트 자체가 모델에 새로운 지침을 내리려고 시도할 수 있으므로, 이 포스트의 상당 부분은 이를 어떻게 제어할 것인지에 대해 다루고 있습니다.

더 작은 함정들도 있습니다. 워크플로 토큰 (workflow token)에 권한이 누락되었음을 의미하는 Resource not accessible by integration: 403 오류나, 보통 결제 문제가 아님에도 발생하는 Your credit balance is too low to access the Anthropic API 메시지 같은 것들입니다. 해결 방법이 유용한 부분이고 각각 한 단락씩 설명이 필요하기 때문에, 이 포스트를 늘리는 대신 모든 디버깅 노트는 원문 포스트에 남겨두었습니다.

내가 고수할 한 가지 원칙

저는 PR 리뷰어가 일반적인 코드 품질이 아닌 오직 보안에만 집중하도록 유지했습니다. 사람이 확인하기 전에 디프 (diff)를 스캔하여 하드코딩된 비밀 값이나 인젝션 위험을 찾아내는 것은 유용하며, 개인적으로 받아들이기 어려운 일도 아닙니다. 누군가의 설계를 평가하는 봇은 가장 붙잡고 싶은 기여자를 쫓아버리는 좋은 방법이 될 수 있으므로, 그러한 판단은 사람의 몫으로 남겨두었습니다.

만약 이슈(Issue)와 PR(Pull Request)을 둘러싼 문서 작업이 당신을 지치게 한다면, 이 방법은 주말 동안의 설정만으로 반복적인 1차 검토 작업을 당신의 부담에서 덜어내고 모든 실질적인 결정은 당신이 내릴 수 있도록 해줄 것입니다. 워크플로 파일(Workflow file), 도구 정의(Tool definitions), 그리고 모든 디버깅 과정을 포함한 전체 가이드는 제 블로그에서 확인할 수 있습니다. 코드는 agentic-repo-manager에 있으며, PR #1503을 통해 FINOS git-proxy로 업스트림(Upstream)되었습니다.

이 포스트가 도움이 되었다면 - GitHub에서 GitProxy에 스타(Star)를 누르는 것을 잊지 마세요!

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0