본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 18. 10:41

무료 LLM을 활용한 Python 코드 리뷰 자동화 방법

요약

본 글은 무료로 접근 가능한 오픈 소스 LLM을 활용하여 Python 코드 리뷰 프로세스를 자동화하는 방법을 설명합니다. GitHub Actions 워크플로를 구축하고, Ollama와 같은 로컬 런타임을 사용하여 Mistral-7B와 같은 모델에 PR 코드를 전송함으로써 PEP-8 위반 사항, 잠재적 버그, 리팩터링 기회 등에 대한 즉각적인 자동 리뷰 코멘트를 생성하여 풀 리퀘스트에 게시하는 과정을 다룹니다.

핵심 포인트

  • GitHub Actions를 활용하여 코드 리뷰 워크플로를 구축할 수 있습니다.
  • Ollama와 같은 로컬 LLM 런타임을 사용하면 유료 API 없이도 강력한 코드 분석이 가능합니다.
  • LLM 프롬프트 엔지니어링을 통해 PEP-8, 버그 패턴, 리팩터링 제안 등 구조화된 피드백을 얻을 수 있습니다.
  • CI/CD 환경에 적합하도록 컨테이너 기반의 LLM 런타임(Ollama) 사용이 권장됩니다.

서론
코드 리뷰 (Code reviews)는 많은 Python 팀들에게 병목 현상의 원인이 됩니다. 사람이 리뷰할 때는 논리적 버그와 스타일 문제를 잡아낼 수 있지만, 시간과 가용성 측면에서 한계가 있습니다. 다행히 최근의 오픈 소스 대규모 언어 모델 (LLMs)은 유료 API 키 없이도 코드 품질에 대한 즉각적인 피드백을 제공하고, 개선 사항을 제안하며, 스타일 가이드를 강제할 수 있습니다. 이 글에서는 다음과 같은 기능을 수행하는 GitHub Actions 워크플로 (workflow)를 구축할 것입니다:

  • PR 코드를 체크아웃 (Check out) 합니다.
  • 무료 LLM (예: ollama 런타임(runtime)을 통한 Mistral-7B)을 실행하여 리뷰 코멘트를 생성합니다.
  • 생성된 코멘트를 풀 리퀘스트 (pull request)에 다시 게시합니다.

완료되면 모든 PR은 다음과 같은 사항을 강조하는 자동화된 리뷰를 받게 됩니다:

  • PEP-8 위반 사항
  • 잠재적 버그 (예: 가변 기본 인자 (mutable default arguments))
  • 리팩터링 (refactoring) 기회

사전 요구 사항: GitHub Actions, Docker, 그리고 Python에 대한 기본적인 이해가 필요합니다.

  1. 무료 LLM 런타임 선택
    여러 프로젝트를 통해 LLM을 로컬에서 무료로 실행할 수 있습니다:
  • Ollama – 간단한 CLI, Mistral, Llama 3 등을 지원합니다.
  • vLLM – 많은 GPU를 위한 고처리량 (high-throughput) 서버입니다.
  • LM Studio – 내장 서버가 포함된 데스크톱 UI입니다.

CI (지속적 통합)를 위해서는 헤드리스 (headless), 컨테이너 친화적인 솔루션이 필요합니다. Ollama는 첫 실행 시 모델을 가져올 수 있는 가벼운 Docker 이미지를 제공하므로 이에 완벽하게 부합합니다.

공식 Ollama 이미지 가져오기

docker pull ollama/ollama:latest

우리는 Apache-2.0 라이선스 하에 있으며 코드 작업에 잘 작동하는 Mistral-7B-Instruct 모델을 사용할 것입니다.

  1. 작은 리뷰 스크립트 생성
    스크립트는 다음과 같은 역할을 수행합니다:
  • 변경된 Python 파일 목록을 받습니다.
  • 각 파일의 내용을 프롬프트 (prompt)와 함께 LLM에 전송합니다.
  • 응답을 수집하여 GitHub 코멘트 형식으로 포맷팅합니다.

이를 저장소 루트에 reviewer.py로 저장하세요.

import os, json, subprocess, textwrap
from pathlib import Path

프롬프트 템플릿 – 속도를 위해 짧게 유지

PROMPT = textwrap.dedent('''
You are a senior Python developer reviewing a pull request.
'''

각 파일에 대해 다음 내용을 제공하세요:

  • PEP-8 스타일 이슈 (줄 번호)
  • 잠재적인 버그 또는 안티 패턴 (anti-patterns)
  • 가독성 또는 성능을 개선하기 위한 하나의 구체적인 제안
    오직 마크다운 리스트 형식으로만 출력하세요. 문제가 없다면 "No problems found."라고 말하세요.
    File: {filename}

{content}
--- ''' )

def run_ollama ( prompt : str ) -> str :
""" 로컬 Ollama 서버를 호출하고 모델의 응답을 반환합니다. """
# ollama CLI를 사용합니다. 이는 stdin에서 JSON을 읽고 stdout에 JSON을 씁니다.
request = {
"model" : "mistral",
"prompt" : prompt,
"stream" : False
}
result = subprocess.run(
["ollama", "run", "--json"],
input=json.dumps(request).encode(),
capture_output=True,
check=True,
)
response = json.loads(result.stdout)
return response.get("response", "")

def main ():
# GitHub는 GITHUB_EVENT_PATH를 통해 변경된 파일 목록을 제공합니다.
event_path = os.getenv("GITHUB_EVENT_PATH")
if not event_path:
raise SystemExit("Missing GITHUB_EVENT_PATH")

with open(event_path) as f:
    event = json.load(f)

files = [f["filename"] for f in event["pull_request"]["files"] if f["filename"].endswith('.py')]

if not files:
    print("::notice::No Python files changed.")
    return

comments = []
for file in files:
    content = Path(file).read_text()
    prompt = PROMPT.format(filename=file, content=content)
    review = run_ollama(prompt)
    comments.append(f"### Review for `{file}`\n{review}\n")

# Action 단계에서 읽을 수 있도록 결합된 코멘트를 파일에 작성합니다.
Path("/tmp/review_comment.md").write_text("\n---\n".join(comments))

if name == "main":
main()

설명
이 스크립트는 GitHub 이벤트 페이로드(payload)를 읽어 변경된 Python 파일들을 찾아냅니다. 각 파일에 대해 간결한 프롬프트(prompt)를 생성하고 ollama run을 호출합니다. 결과는 마크다운 파일로 결합되며, 이후 워크플로(workflow)가 이를 게시합니다.

리뷰 환경 도커화 (Dockerize the Review Environment)

GitHub Actions는 깨끗한 가상 머신 (VM)에서 실행되므로, 다음 항목들을 포함하는 컨테이너가 필요합니다:

  • Python 3.11
  • 모델이 미리 다운로드된 ollama 런타임 (runtime)
  • 우리의 reviewer.py

Dockerfile 생성:

FROM python:3.11-slim

# curl (Ollama에 필요) 및 git 설치
RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*

# Ollama 설치
RUN curl -fsSL https://ollama.com/install.sh | sh

# 모델 가져오기 (첫 실행 시 몇 분 소요)
RUN ollama pull mistral

# 리뷰어 스크립트 복사
WORKDIR /app
COPY reviewer.py .

# Python 의존성 설치 (현재는 필요 없으나 단계를 유지함)
RUN pip install --no-cache-dir pyyaml

ENTRYPOINT ["python", "reviewer.py"]

로컬 머신 또는 CI 작업에서 이미지를 빌드하고 GitHub Container Registry (GHCR)로 푸시합니다:

# GHCR 인증
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin

# 이미지 빌드
docker build -t ghcr.io/<owner>/<repo>/code-reviewer:latest .

# 이미지 푸시
docker push ghcr.io/<owner>/<repo>/code-reviewer:latest

<owner><repo>를 사용자의 GitHub 네임스페이스로 교체하세요.

GitHub Action 워크플로 (Workflow) 정의

.github/workflows/auto-code-review.yml 생성:

name: Automated Code Review
on:
  pull_request:
    paths:
      - '**/*.py'
jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write # 댓글을 게시하기 위해 필요
    steps:
      - name: Checkout PR
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Pull reviewer image
        run: |
          docker pull ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/code-reviewer:latest
      - name: Run reviewer container
        env:
          GITHUB_EVENT_PATH: ${{ github.event_path }}
        run: |
          docker run --rm \
            -e GITHUB_EVENT_PATH=/github/event.json \
            -v ${{ github.event_path }}:/github/event.json:ro \
            -v ${{ github.workspace }}:/app \
            ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/code-reviewer:latest
      - name: Post comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const comment = fs.readFileSync('/tmp/review_comment.md', 'utf8');
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.pull_request.number,
              body: comment
            });

주요 포인트 (Key points)
이 워크플로는 *.py 파일을 수정하는 모든 PR (Pull Request)에서 트리거됩니다. 코드를 체크아웃(Checkout)하고, 미리 빌드된 컨테이너를 풀(Pull)한 뒤, 이벤트 페이로드 (Event payload)를 마운트하여 실행합니다. 컨테이너는 마크다운 (Markdown) 리뷰 내용을 /tmp/review_comment.md에 작성합니다 (호스트 파일 시스템을 통해 공유됨). 마지막으로 actions/github-script가 해당 댓글을 PR에 게시합니다.

  1. 프롬프트 (Prompt) 미세 조정 (선택 사항)
    모델이 특정 패턴을 놓치는 것을 발견하면 프롬프트를 조정하세요:
  • 타입 힌트 (Type-hint) 제안을 위한 섹션을 추가합니다.
  • 원하는 출력 형식의 짧은 예시를 포함합니다.
  • 실행 속도가 느리다면 Ollama 요청을 통해 토큰 예산 (max_tokens)을 제한합니다.
    피드백이 팀의 표준과 일치할 때까지 반복합니다.
  1. 장점 및 한계 (Benefits and Limitations)
장점한계
즉각적인 피드백 – 리뷰어가 PR이 열리자마자 댓글을 받을 수 있습니다.

LLM이 환각 (Hallucination)을 일으킬 수 있으므로, 출력 결과는 항상 규칙이 아닌 제안으로 취급해야 합니다. API 비용 제로 – 완전히 무료인 오픈 소스 (Open-source) 모델로 실행됩니다. 모델 크기 (7 B)는 약 4 GB의 RAM을 소모하므로, CI 러너 (Runner)에 충분한 리소스가 있는지 확인하십시오. 커스터마이징 가능 – 코드 변경 없이 프롬프트 (Prompt)를 변경하거나 모델을 교체할 수 있습니다. 심층적인 정적 분석 (Static analysis, 예: 데이터 흐름 분석) 불가 – 완전성을 위해 ruff와 같은 도구와 결합하십시오.

  1. 다음 단계
    린터 (Linter)와 결합 – 동일한 컨테이너에서 ruff 또는 flake8을 실행하고 그 출력 결과를 병합하십시오. 모델 캐싱 – CI 속도를 높이기 위해 Ollama 모델 레이어를 별도의 Docker 레이어에 저장하십시오. 리뷰 배지 추가 – 자동화된 리뷰가 통과되었음을 보여주는 상태 체크 (Status check)를 표시하십시오. 더 큰 모델로 실험 – CI 예산이 허용한다면, 더 풍부한 제안을 위해 Llama 3-8B를 시도해 보십시오.

요약
Ollama를 통해 Mistral-7B와 같은 무료 로컬 호스팅 LLM을 활용함으로써, GitHub Actions에서 Python 코드 리뷰의 첫 번째 단계를 직접 자동화할 수 있습니다. 이 설정은 가볍고, 비용이 들지 않으며, 확장 가능합니다. 이를 통해 개발자에게는 더 빠른 피드백을 제공하는 동시에, 인간 리뷰어는 더 높은 수준의 설계 결정에 집중할 수 있도록 합니다. 지금 바로 시도해 보세요: 테스트 저장소에 Dockerfile과 워크플로 (Workflow)를 추가하고, 간단한 Python 변경 사항이 담긴 PR을 열어 AI 기반 리뷰가 즉시 나타나는 것을 확인하십시오.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0