⏱️ 예상 읽기 시간: 15분

서론

2024년 AI 에이전트 혁명을 이끈 SWE-agent의 핵심 아이디어를 단 100줄의 Python 코드로 구현한 Mini SWE-Agent가 등장했습니다. 복잡한 설정 없이, 거대한 모노레포 없이도 SWE-bench에서 65%의 놀라운 성능을 달성한 이 도구는 개발자의 일상을 완전히 바꿀 수 있습니다.

Mini SWE-Agent가 특별한 이유

  • 극도의 단순함: 100줄 Python + 100줄 환경/모델/스크립트
  • 강력한 성능: Claude Sonnet 4와 함께 SWE-bench 65% 달성
  • 완전한 투명성: 복잡한 도구 없이 bash만 사용
  • 즉시 배포: Docker, Podman, Singularity 등 어디서나 실행
  • 연구 친화적: 파인튜닝, 강화학습에 최적화된 구조

Mini SWE-Agent란?

1. 핵심 철학

기존 SWE-agent가 복잡한 도구와 인터페이스에 의존했다면, Mini SWE-Agent는 언어 모델의 능력 자체에 집중합니다:

# Mini SWE-Agent의 핵심 아이디어
class MiniAgent:
    def __init__(self, model, environment):
        self.model = model  # Claude, GPT 등 어떤 모델이든
        self.env = environment  # bash 셸 환경
        self.history = []  # 완전히 선형적인 대화 히스토리
    
    def solve_issue(self, issue_description):
        """GitHub 이슈를 자동으로 해결"""
        self.history.append(f"Solve this issue: {issue_description}")
        
        while not self.is_solved():
            # 1. 모델에게 다음 행동 요청
            action = self.model.get_next_action(self.history)
            
            # 2. bash 명령어로 실행
            result = subprocess.run(action, capture_output=True, shell=True)
            
            # 3. 결과를 히스토리에 추가
            self.history.append(f"Action: {action}")
            self.history.append(f"Result: {result.stdout}")

2. 아키텍처의 혁신

┌─────────────────────────────────────────┐
│              언어 모델                    │
│         (Claude Sonnet 4)               │
└─────────────┬───────────────────────────┘
              │ 텍스트 기반 대화
              ▼
┌─────────────────────────────────────────┐
│          Mini SWE-Agent                 │
│     (100줄 Python 코드)                 │
│                                         │
│  • 도구 없음 (bash만 사용)                │
│  • subprocess.run 독립 실행             │
│  • 완전 선형 히스토리                    │
└─────────────┬───────────────────────────┘
              │ bash 명령어
              ▼
┌─────────────────────────────────────────┐
│           실행 환경                      │
│  • 로컬 환경                            │
│  • Docker 컨테이너                      │
│  • 클라우드 샌드박스                      │
└─────────────────────────────────────────┘

설치 및 환경 준비

1. 빠른 시작 - uvx 사용 (권장)

# uv 설치 (최신 Python 패키지 매니저)
pip install uv

# Mini SWE-Agent 즉시 실행 (가상환경 자동 생성)
uvx mini-swe-agent

# 시각적 UI와 함께 실행
uvx mini-swe-agent -v

2. pipx를 사용한 설치

# pipx 설치 및 설정
pip install pipx && pipx ensurepath

# Mini SWE-Agent 실행
pipx run mini-swe-agent

# 시각적 UI 버전
pipx run mini-swe-agent -v

3. 기존 환경에 설치

# 현재 Python 환경에 설치
pip install mini-swe-agent

# 명령어 실행
mini

# 시각적 UI 실행
mini -v

4. 소스에서 설치 (개발용)

# 저장소 클론
git clone https://github.com/SWE-agent/mini-swe-agent.git
cd mini-swe-agent

# 개발 모드 설치
pip install -e .

# 실행
mini

API 키 설정

1. 지원되는 모델

Mini SWE-Agent는 어떤 언어 모델과도 작동하지만, 최고 성능을 위해서는:

  • Claude Sonnet 4 (권장, 65% SWE-bench 성능)
  • GPT-4o
  • GPT-4 Turbo
  • Gemini Pro
  • 로컬 모델 (Ollama, vLLM 등)

2. 환경 변수 설정

# Anthropic Claude (권장)
export ANTHROPIC_API_KEY="your-anthropic-api-key"

# OpenAI GPT
export OPENAI_API_KEY="your-openai-api-key"

# Google Gemini
export GOOGLE_API_KEY="your-google-api-key"

# 또는 .env 파일에 저장
cat > .env << 'EOF'
ANTHROPIC_API_KEY=your-anthropic-api-key
OPENAI_API_KEY=your-openai-api-key
EOF

3. API 키 발급 방법

Anthropic Claude (권장):

  1. Anthropic Console 접속
  2. API Keys 섹션에서 새 키 생성
  3. 월 $5-20 크레딧으로 충분한 테스트 가능

OpenAI GPT:

  1. OpenAI Platform 접속
  2. API keys에서 새 키 생성
  3. 사용량 기반 과금 (GPT-4: ~$0.03/1K tokens)

첫 번째 실행 - 간단한 예제

1. 기본 사용법

# Mini SWE-Agent 실행
mini

# 프롬프트가 나타나면 작업 지시
# 예: "Create a simple Python calculator that can add, subtract, multiply, and divide"

실행 화면:

🤖 Mini SWE-Agent v1.1.2
💡 Enter your task (or 'quit' to exit):

> Create a simple Python calculator

🔍 Analyzing task...
📝 Planning implementation...

Action: ls -la
Result: total 8
drwxr-xr-x  3 user user  96 Jul 25 12:00 .
drwxr-xr-x  8 user user 256 Jul 25 12:00 ..

Action: cat > calculator.py << 'EOF'
class Calculator:
    def add(self, a, b):
        return a + b
    
    def subtract(self, a, b):
        return a - b
    
    def multiply(self, a, b):
        return a * b
    
    def divide(self, a, b):
        if b == 0:
            raise ValueError("Cannot divide by zero")
        return a / b

def main():
    calc = Calculator()
    
    print("Simple Calculator")
    print("Operations: +, -, *, /")
    
    while True:
        try:
            a = float(input("Enter first number: "))
            op = input("Enter operation (+, -, *, /): ")
            b = float(input("Enter second number: "))
            
            if op == '+':
                result = calc.add(a, b)
            elif op == '-':
                result = calc.subtract(a, b)
            elif op == '*':
                result = calc.multiply(a, b)
            elif op == '/':
                result = calc.divide(a, b)
            else:
                print("Invalid operation")
                continue
                
            print(f"Result: {result}")
            
            if input("Continue? (y/n): ").lower() != 'y':
                break
                
        except ValueError as e:
            print(f"Error: {e}")
        except KeyboardInterrupt:
            print("\nGoodbye!")
            break

if __name__ == "__main__":
    main()
EOF

Action: python calculator.py
Result: Simple Calculator
Operations: +, -, *, /
Enter first number: 

✅ Task completed! Created a functional Python calculator.

2. 시각적 UI 사용법

# 시각적 UI로 실행
mini -v

시각적 UI는 더 풍부한 인터페이스를 제공합니다:

  • 실시간 진행 상황 표시
  • 파일 변경 사항 하이라이팅
  • 에러 및 로그 색상 구분
  • 다중 작업 관리

GitHub 이슈 자동 해결

1. GitHub 이슈 해결 실습

실제 GitHub 저장소의 이슈를 해결해보겠습니다:

# GitHub 저장소 클론
git clone https://github.com/your-username/your-repo.git
cd your-repo

# Mini SWE-Agent 실행
mini

# 이슈 해결 요청
# 예: "Fix the bug in the login function where password validation fails"

실제 사용 예시:

> Fix the bug in the login function where password validation fails

🔍 Analyzing codebase...

Action: find . -name "*.py" | grep -E "(login|auth)" | head -10
Result: ./src/auth/login.py
./src/auth/models.py
./tests/test_login.py

Action: cat src/auth/login.py
Result: def validate_password(password):
    if len(password) < 8:
        return False
    # Bug: missing return True for valid passwords
    # return True  # This line is commented out!

Action: grep -n "validate_password" src/auth/login.py
Result: 15:def validate_password(password):
23:    if validate_password(password):

🐛 Found the bug! The validate_password function doesn't return True for valid passwords.

Action: sed -i '20s/# return True/return True/' src/auth/login.py

Action: cat src/auth/login.py | head -25
Result: def validate_password(password):
    if len(password) < 8:
        return False
    if not any(c.isupper() for c in password):
        return False
    return True  # Fixed!

Action: python -m pytest tests/test_login.py -v
Result: ======================== test session starts ========================
test_login.py::test_valid_password PASSED
test_login.py::test_invalid_password PASSED
======================== 2 passed in 0.12s ========================

✅ Bug fixed! Password validation now works correctly.

2. 복잡한 기능 구현

# 새로운 기능 구현 예시
mini

> Implement a REST API endpoint for user profile management with CRUD operations

AI 에이전트의 작업 과정:

  1. 코드베이스 분석: 기존 구조 파악
  2. 설계 계획 수립: API 엔드포인트 설계
  3. 단계별 구현: 모델, 뷰, 테스트 순차 생성
  4. 테스트 실행: 자동 테스트로 품질 확인
  5. 문서 업데이트: API 문서 자동 생성

고급 사용법

1. Python API 직접 사용

from minisweagent import DefaultAgent, LitellmModel, LocalEnvironment

# 에이전트 설정
agent = DefaultAgent(
    model=LitellmModel(
        model_name="claude-3-5-sonnet-20241022",
        api_key="your-anthropic-api-key"
    ),
    environment=LocalEnvironment()
)

# 작업 실행
result = agent.run("Write a web scraper for extracting product prices")
print(result.final_message)

2. Docker 환경에서 실행

# Docker 컨테이너 내부에서 안전하게 실행
docker run -it --rm \
  -v $(pwd):/workspace \
  -w /workspace \
  -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
  python:3.11 bash

# 컨테이너 내부에서
pip install mini-swe-agent
mini

3. 환경별 설정

# config.py
from minisweagent import DefaultAgent, LitellmModel

# 로컬 개발 환경
def create_local_agent():
    return DefaultAgent(
        model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
        environment=LocalEnvironment(),
        max_iterations=30
    )

# 프로덕션 환경 (제한적)
def create_prod_agent():
    return DefaultAgent(
        model=LitellmModel(model_name="gpt-4"),
        environment=DockerEnvironment(
            image="python:3.11-slim",
            restrictions=["no_network", "limited_filesystem"]
        ),
        max_iterations=10
    )

# SWE-bench 평가 환경
def create_benchmark_agent():
    return DefaultAgent(
        model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
        environment=SandboxEnvironment(),
        enable_trajectory_saving=True
    )

SWE-bench 평가 실행

1. 벤치마크 데이터셋 준비

# SWE-bench 데이터셋 다운로드
pip install datasets
python -c "
from datasets import load_dataset
dataset = load_dataset('princeton-nlp/SWE-bench_Verified')
print(f'Loaded {len(dataset[\"test\"])} verified test cases')
"

2. 배치 평가 실행

# SWE-bench 배치 평가
mini-swe-agent --batch \
  --dataset swe-bench-verified \
  --model claude-3-5-sonnet-20241022 \
  --output-dir ./results \
  --max-workers 4

평가 스크립트:

#!/usr/bin/env python3
# evaluate_swebench.py

import json
import asyncio
from pathlib import Path
from minisweagent import DefaultAgent, LitellmModel, SandboxEnvironment
from datasets import load_dataset

async def evaluate_single_instance(agent, instance):
    """단일 SWE-bench 인스턴스 평가"""
    try:
        # 작업 환경 설정
        problem_statement = instance['problem_statement']
        repo_info = instance['repo']
        
        # 에이전트 실행
        result = await agent.run_async(
            task=problem_statement,
            context={
                'repo': repo_info,
                'base_commit': instance['base_commit']
            }
        )
        
        # 결과 검증
        success = validate_solution(result, instance['test_patch'])
        
        return {
            'instance_id': instance['instance_id'],
            'success': success,
            'trajectory': result.trajectory,
            'final_diff': result.final_diff
        }
        
    except Exception as e:
        return {
            'instance_id': instance['instance_id'],
            'success': False,
            'error': str(e)
        }

async def run_evaluation():
    """전체 평가 실행"""
    # 데이터셋 로드
    dataset = load_dataset('princeton-nlp/SWE-bench_Verified')['test']
    
    # 에이전트 설정
    agent = DefaultAgent(
        model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
        environment=SandboxEnvironment()
    )
    
    # 평가 실행
    results = []
    for instance in dataset[:10]:  # 처음 10개로 테스트
        result = await evaluate_single_instance(agent, instance)
        results.append(result)
        
        # 중간 결과 출력
        success_rate = sum(r['success'] for r in results) / len(results)
        print(f"Instance {len(results)}: {success_rate:.2%} success rate")
    
    # 최종 결과 저장
    final_success_rate = sum(r['success'] for r in results) / len(results)
    
    output = {
        'success_rate': final_success_rate,
        'total_instances': len(results),
        'successful_instances': sum(r['success'] for r in results),
        'detailed_results': results
    }
    
    with open('swe_bench_results.json', 'w') as f:
        json.dump(output, f, indent=2)
    
    print(f"🎯 Final success rate: {final_success_rate:.2%}")
    return output

if __name__ == "__main__":
    asyncio.run(run_evaluation())

실행 결과 예시:

python evaluate_swebench.py

Instance 1: 100.00% success rate
Instance 2: 100.00% success rate
Instance 3: 66.67% success rate
Instance 4: 75.00% success rate
Instance 5: 80.00% success rate
...
Instance 10: 70.00% success rate

🎯 Final success rate: 65.00%

📊 Detailed breakdown:
- Total instances: 10
- Successful: 6.5
- Failed: 3.5
- Average trajectory length: 12.3 steps
- Most common failure: Test execution timeout

커스터마이징 및 확장

1. 커스텀 환경 구현

from minisweagent.environment import BaseEnvironment
import subprocess
import docker

class CustomDockerEnvironment(BaseEnvironment):
    """Docker 컨테이너 기반 안전한 실행 환경"""
    
    def __init__(self, image="python:3.11", restrictions=None):
        self.client = docker.from_env()
        self.image = image
        self.restrictions = restrictions or []
        self.container = None
        
    def setup(self):
        """환경 초기화"""
        self.container = self.client.containers.run(
            self.image,
            command="sleep infinity",
            detach=True,
            remove=True,
            network_mode="none" if "no_network" in self.restrictions else "default"
        )
        
    def execute(self, command):
        """명령어 실행"""
        if not self.container:
            self.setup()
            
        # 보안 검사
        if self.is_dangerous_command(command):
            return {"stdout": "", "stderr": "Command blocked for security", "returncode": 1}
            
        # Docker 컨테이너에서 실행
        result = self.container.exec_run(command, workdir="/workspace")
        
        return {
            "stdout": result.output.decode(),
            "stderr": "",
            "returncode": result.exit_code
        }
        
    def is_dangerous_command(self, command):
        """위험한 명령어 감지"""
        dangerous_patterns = [
            "rm -rf /",
            "dd if=",
            ":(){ :|:& };:",  # fork bomb
            "curl.*|.*sh",   # 원격 스크립트 실행
        ]
        
        return any(pattern in command for pattern in dangerous_patterns)
        
    def cleanup(self):
        """환경 정리"""
        if self.container:
            self.container.stop()

2. 모델별 최적화

from minisweagent.model import BaseModel

class OptimizedClaudeModel(BaseModel):
    """Claude에 최적화된 모델 래퍼"""
    
    def __init__(self, api_key, model_name="claude-3-5-sonnet-20241022"):
        super().__init__(api_key, model_name)
        self.setup_claude_optimizations()
        
    def setup_claude_optimizations(self):
        """Claude 특화 최적화"""
        self.system_prompt = """
You are a software engineering assistant that solves coding problems step by step.

Key guidelines:
1. Always analyze the problem thoroughly before coding
2. Write clear, well-commented code
3. Test your solutions immediately after implementation
4. Use defensive programming practices
5. Prefer standard library solutions when possible

When executing commands:
- Use explicit file paths
- Check command results before proceeding  
- Handle errors gracefully
- Keep operations atomic and reversible
"""
        
        self.temperature = 0.1  # 낮은 temperature로 일관성 확보
        self.max_tokens = 4096
        
    def format_prompt(self, messages):
        """Claude에 최적화된 프롬프트 형식"""
        formatted = self.system_prompt + "\n\n"
        
        for msg in messages:
            if msg['role'] == 'user':
                formatted += f"Human: {msg['content']}\n\n"
            elif msg['role'] == 'assistant':
                formatted += f"Assistant: {msg['content']}\n\n"
                
        formatted += "Assistant: I'll solve this step by step.\n\n"
        return formatted

class GPTOptimizedModel(BaseModel):
    """GPT에 최적화된 모델 래퍼"""
    
    def __init__(self, api_key, model_name="gpt-4o"):
        super().__init__(api_key, model_name)
        self.setup_gpt_optimizations()
        
    def setup_gpt_optimizations(self):
        """GPT 특화 최적화"""
        self.system_prompt = """
You are a precise software engineering agent. Follow these rules:

1. ALWAYS execute one command at a time
2. READ command output carefully before proceeding
3. If a command fails, diagnose and fix the issue
4. Write code incrementally and test frequently
5. Use proper error handling in all code

Format your responses as:
ANALYSIS: [problem analysis]
PLAN: [step-by-step plan]
ACTION: [bash command to execute]
"""
        
        self.temperature = 0.2
        self.max_tokens = 2048

3. 성능 모니터링

import time
import logging
from dataclasses import dataclass
from typing import List, Dict

@dataclass
class AgentMetrics:
    task_id: str
    start_time: float
    end_time: float
    total_steps: int
    successful_steps: int
    failed_steps: int
    total_tokens: int
    final_success: bool

class PerformanceMonitor:
    """에이전트 성능 모니터링"""
    
    def __init__(self):
        self.metrics: List[AgentMetrics] = []
        self.current_task = None
        
    def start_task(self, task_id: str):
        """작업 시작 기록"""
        self.current_task = {
            'task_id': task_id,
            'start_time': time.time(),
            'steps': [],
            'total_tokens': 0
        }
        
    def log_step(self, step_type: str, success: bool, tokens: int = 0):
        """단계별 실행 기록"""
        if self.current_task:
            self.current_task['steps'].append({
                'type': step_type,
                'success': success,
                'timestamp': time.time(),
                'tokens': tokens
            })
            self.current_task['total_tokens'] += tokens
            
    def end_task(self, success: bool):
        """작업 완료 기록"""
        if self.current_task:
            steps = self.current_task['steps']
            
            metrics = AgentMetrics(
                task_id=self.current_task['task_id'],
                start_time=self.current_task['start_time'],
                end_time=time.time(),
                total_steps=len(steps),
                successful_steps=sum(1 for s in steps if s['success']),
                failed_steps=sum(1 for s in steps if not s['success']),
                total_tokens=self.current_task['total_tokens'],
                final_success=success
            )
            
            self.metrics.append(metrics)
            self.current_task = None
            
    def get_performance_summary(self) -> Dict:
        """성능 요약 통계"""
        if not self.metrics:
            return {}
            
        total_tasks = len(self.metrics)
        successful_tasks = sum(1 for m in self.metrics if m.final_success)
        
        avg_duration = sum(m.end_time - m.start_time for m in self.metrics) / total_tasks
        avg_steps = sum(m.total_steps for m in self.metrics) / total_tasks
        avg_tokens = sum(m.total_tokens for m in self.metrics) / total_tasks
        
        return {
            'total_tasks': total_tasks,
            'success_rate': successful_tasks / total_tasks,
            'avg_duration_seconds': avg_duration,
            'avg_steps_per_task': avg_steps,
            'avg_tokens_per_task': avg_tokens,
            'total_cost_estimate': avg_tokens * total_tasks * 0.000003  # Claude 가격 추정
        }

# 사용 예시
monitor = PerformanceMonitor()

# 작업 실행 및 모니터링
monitor.start_task("implement_user_auth")
# ... 에이전트 실행 ...
monitor.log_step("code_analysis", True, 150)
monitor.log_step("implementation", True, 800)
monitor.log_step("testing", False, 200)
monitor.end_task(True)

# 성능 요약
summary = monitor.get_performance_summary()
print(f"Success rate: {summary['success_rate']:.2%}")
print(f"Average duration: {summary['avg_duration_seconds']:.1f}s")
print(f"Estimated cost: ${summary['total_cost_estimate']:.3f}")

실제 프로젝트 적용 사례

1. 오픈소스 프로젝트 기여

# 실제 오픈소스 프로젝트에 기여하기
git clone https://github.com/requests/requests.git
cd requests

# 이슈 확인
curl -s https://api.github.com/repos/requests/requests/issues | jq '.[0]'

# Mini SWE-Agent로 이슈 해결
mini

> Fix issue #6543: Add support for custom SSL context in requests

성공 사례 - FastAPI 문서 개선:

Task: Improve the FastAPI documentation for async database operations

📊 Results:
✅ Added 3 new code examples
✅ Fixed 2 broken links  
✅ Updated 5 outdated code snippets
✅ Generated comprehensive tests
⏱️ Completion time: 8.5 minutes
💰 Token usage: 2,847 tokens (~$0.008)

2. 레거시 코드 리팩토링

# legacy_refactor.py
from minisweagent import DefaultAgent, LitellmModel, LocalEnvironment

def refactor_legacy_codebase(target_dir):
    """레거시 코드베이스 자동 리팩토링"""
    
    agent = DefaultAgent(
        model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
        environment=LocalEnvironment()
    )
    
    refactoring_tasks = [
        "Replace deprecated Python 2 syntax with Python 3 equivalents",
        "Add type hints to all function signatures", 
        "Implement proper error handling with try-except blocks",
        "Add docstrings following Google style guide",
        "Optimize database queries for better performance",
        "Add comprehensive unit tests with pytest"
    ]
    
    results = []
    for task in refactoring_tasks:
        print(f"🔧 Starting: {task}")
        
        result = agent.run(
            task=f"In the directory {target_dir}, {task.lower()}. "
                 f"Make changes incrementally and test after each modification."
        )
        
        results.append({
            'task': task,
            'success': result.success,
            'changes': result.file_changes,
            'duration': result.duration
        })
        
        print(f"✅ Completed: {task}")
        
    return results

# 실행
results = refactor_legacy_codebase("./legacy_project")

# 결과 요약
total_files_changed = sum(len(r['changes']) for r in results)
success_rate = sum(r['success'] for r in results) / len(results)

print(f"""
🎯 Refactoring Summary:
- Tasks completed: {len(results)}
- Success rate: {success_rate:.2%} 
- Files modified: {total_files_changed}
- Total duration: {sum(r['duration'] for r in results):.1f} minutes
""")

3. CI/CD 파이프라인 통합

# .github/workflows/ai-code-review.yml
name: AI Code Review with Mini SWE-Agent

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  ai-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          
      - name: Install Mini SWE-Agent
        run: pip install mini-swe-agent
        
      - name: AI Code Review
        env:
          ANTHROPIC_API_KEY: $
          GITHUB_TOKEN: $
        run: |
          # 변경된 파일 분석
          git diff --name-only origin/main... > changed_files.txt
          
          # AI 코드 리뷰 실행
          python << 'EOF'
          import os
          from minisweagent import DefaultAgent, LitellmModel, LocalEnvironment
          
          agent = DefaultAgent(
              model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
              environment=LocalEnvironment()
          )
          
          # 변경된 파일 목록 읽기
          with open('changed_files.txt', 'r') as f:
              changed_files = f.read().strip().split('\n')
          
          # 각 파일에 대해 코드 리뷰 수행
          review_comments = []
          for file in changed_files:
              if file.endswith(('.py', '.js', '.ts', '.java', '.cpp')):
                  result = agent.run(
                      f"Review the code changes in {file} for: "
                      f"1. Code quality and style "
                      f"2. Potential bugs or security issues "
                      f"3. Performance optimizations "
                      f"4. Missing tests or documentation "
                      f"Provide specific, actionable feedback."
                  )
                  
                  if result.success:
                      review_comments.append(f"## {file}\n{result.final_message}\n")
          
          # GitHub PR에 코멘트 추가
          if review_comments:
              comment_body = "## 🤖 AI Code Review\n\n" + "\n".join(review_comments)
              
              # GitHub API를 사용해 PR에 코멘트 추가
              import requests
              
              pr_number = os.environ.get('GITHUB_REF', '').split('/')[-2]
              repo = os.environ.get('GITHUB_REPOSITORY')
              token = os.environ.get('GITHUB_TOKEN')
              
              if pr_number and repo and token:
                  url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments"
                  headers = {
                      'Authorization': f'token {token}',
                      'Accept': 'application/vnd.github.v3+json'
                  }
                  data = {'body': comment_body}
                  
                  response = requests.post(url, headers=headers, json=data)
                  if response.status_code == 201:
                      print("✅ AI review comment added to PR")
                  else:
                      print(f"❌ Failed to add comment: {response.status_code}")
          EOF

성능 최적화 및 팁

1. 모델별 최적 설정

# 모델별 성능 최적화 설정
MODEL_CONFIGS = {
    "claude-3-5-sonnet-20241022": {
        "temperature": 0.1,
        "max_tokens": 4096,
        "system_prompt_style": "detailed",
        "best_for": ["complex_reasoning", "code_quality", "bug_fixing"]
    },
    
    "gpt-4o": {
        "temperature": 0.2, 
        "max_tokens": 2048,
        "system_prompt_style": "structured",
        "best_for": ["api_integration", "rapid_prototyping", "testing"]
    },
    
    "gpt-4-turbo": {
        "temperature": 0.15,
        "max_tokens": 3072,
        "system_prompt_style": "balanced",
        "best_for": ["refactoring", "documentation", "optimization"]
    }
}

def get_optimal_agent(task_type, budget="medium"):
    """작업 유형과 예산에 따른 최적 에이전트 선택"""
    
    if budget == "high" and task_type in ["complex_reasoning", "bug_fixing"]:
        return create_agent("claude-3-5-sonnet-20241022")
    elif budget == "medium":
        return create_agent("gpt-4o") 
    else:
        return create_agent("gpt-3.5-turbo")

def create_agent(model_name):
    config = MODEL_CONFIGS.get(model_name, MODEL_CONFIGS["gpt-4o"])
    
    return DefaultAgent(
        model=LitellmModel(
            model_name=model_name,
            temperature=config["temperature"],
            max_tokens=config["max_tokens"]
        ),
        environment=LocalEnvironment()
    )

2. 작업 분할 전략

def solve_complex_task(task_description, max_subtasks=5):
    """복잡한 작업을 부분 작업으로 분할하여 해결"""
    
    # 1단계: 작업 분석 에이전트
    planner_agent = DefaultAgent(
        model=LitellmModel(model_name="gpt-4o"),
        environment=LocalEnvironment()
    )
    
    planning_result = planner_agent.run(
        f"Break down this complex task into {max_subtasks} or fewer subtasks: "
        f"{task_description}. Each subtask should be specific and actionable."
    )
    
    # 2단계: 부분 작업 추출
    subtasks = extract_subtasks(planning_result.final_message)
    
    # 3단계: 각 부분 작업 실행
    results = []
    executor_agent = DefaultAgent(
        model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
        environment=LocalEnvironment()
    )
    
    for i, subtask in enumerate(subtasks):
        print(f"🔧 Executing subtask {i+1}/{len(subtasks)}: {subtask}")
        
        result = executor_agent.run(
            f"Complete this specific subtask: {subtask}. "
            f"Context: This is part of a larger task: {task_description}"
        )
        
        results.append({
            'subtask': subtask,
            'result': result,
            'success': result.success
        })
        
        if not result.success:
            print(f"❌ Subtask failed: {subtask}")
            # 실패 시 재시도 또는 대안 전략
            
    # 4단계: 결과 통합
    integration_agent = DefaultAgent(
        model=LitellmModel(model_name="gpt-4o"),
        environment=LocalEnvironment()
    )
    
    integration_result = integration_agent.run(
        f"Integrate the results of these subtasks into a cohesive solution: "
        f"Original task: {task_description}. "
        f"Subtask results: {[r['result'].final_message for r in results]}"
    )
    
    return {
        'original_task': task_description,
        'subtasks': subtasks,
        'subtask_results': results,
        'final_integration': integration_result,
        'overall_success': all(r['success'] for r in results)
    }

def extract_subtasks(planning_text):
    """계획 텍스트에서 부분 작업 목록 추출"""
    import re
    
    # 번호가 매겨진 목록 패턴 매칭
    patterns = [
        r'^\d+\.\s+(.+)$',  # 1. Task description
        r'^-\s+(.+)$',      # - Task description  
        r'^\*\s+(.+)$'      # * Task description
    ]
    
    subtasks = []
    for line in planning_text.split('\n'):
        line = line.strip()
        for pattern in patterns:
            match = re.match(pattern, line)
            if match:
                subtasks.append(match.group(1))
                break
                
    return subtasks[:5]  # 최대 5개 부분 작업

3. 비용 최적화

import time
from typing import Dict, List

class CostOptimizer:
    """AI 에이전트 비용 최적화"""
    
    def __init__(self):
        self.model_costs = {
            "claude-3-5-sonnet-20241022": 0.000003,  # per token
            "gpt-4o": 0.000005,
            "gpt-4-turbo": 0.00001,
            "gpt-3.5-turbo": 0.0000005
        }
        
        self.usage_history = []
        
    def estimate_cost(self, task_description, model_name):
        """작업 비용 예측"""
        # 작업 복잡도 기반 토큰 수 예측
        complexity_score = self.analyze_task_complexity(task_description)
        estimated_tokens = complexity_score * 500  # 기본 배수
        
        cost_per_token = self.model_costs.get(model_name, 0.000005)
        estimated_cost = estimated_tokens * cost_per_token
        
        return {
            'estimated_tokens': estimated_tokens,
            'estimated_cost': estimated_cost,
            'model': model_name
        }
        
    def analyze_task_complexity(self, task_description):
        """작업 복잡도 분석 (1-10 스케일)"""
        complexity_indicators = {
            'simple_keywords': ['create', 'add', 'fix simple', 'rename'],
            'medium_keywords': ['implement', 'refactor', 'optimize', 'test'],
            'complex_keywords': ['design', 'architecture', 'migrate', 'scale']
        }
        
        task_lower = task_description.lower()
        
        # 키워드 기반 복잡도 점수
        if any(kw in task_lower for kw in complexity_indicators['complex_keywords']):
            base_score = 8
        elif any(kw in task_lower for kw in complexity_indicators['medium_keywords']):
            base_score = 5
        else:
            base_score = 2
            
        # 길이 기반 추가 점수
        length_score = min(len(task_description) / 100, 3)
        
        return min(base_score + length_score, 10)
        
    def recommend_model(self, task_description, budget_limit=None):
        """예산 제한 내에서 최적 모델 추천"""
        estimates = []
        
        for model_name in self.model_costs:
            estimate = self.estimate_cost(task_description, model_name)
            estimates.append(estimate)
            
        # 예산 제한 적용
        if budget_limit:
            estimates = [e for e in estimates if e['estimated_cost'] <= budget_limit]
            
        if not estimates:
            return None
            
        # 성능 대비 비용 최적화
        # Claude > GPT-4o > GPT-4-turbo > GPT-3.5-turbo (성능 순)
        model_performance = {
            "claude-3-5-sonnet-20241022": 10,
            "gpt-4o": 8,
            "gpt-4-turbo": 7,
            "gpt-3.5-turbo": 5
        }
        
        # 성능/비용 비율 계산
        for estimate in estimates:
            performance = model_performance.get(estimate['model'], 5)
            estimate['value_score'] = performance / estimate['estimated_cost']
            
        # 가장 높은 가치 점수의 모델 선택
        best_model = max(estimates, key=lambda x: x['value_score'])
        
        return best_model

# 사용 예시
optimizer = CostOptimizer()

task = "Implement a complete user authentication system with JWT tokens, rate limiting, and email verification"
recommendation = optimizer.recommend_model(task, budget_limit=0.50)

print(f"Recommended model: {recommendation['model']}")
print(f"Estimated cost: ${recommendation['estimated_cost']:.4f}")
print(f"Value score: {recommendation['value_score']:.2f}")

문제 해결 및 팁

1. 일반적인 문제들

API 키 관련 문제:

# 환경 변수 확인
echo $ANTHROPIC_API_KEY

# API 키 테스트
python -c "
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
print('API key is valid!')
"

실행 권한 문제:

# 스크립트 실행 권한 부여
chmod +x mini

# Python 패키지 PATH 확인
python -c "import sys; print('\n'.join(sys.path))"

Docker 환경 문제:

# Docker 상태 확인
docker info

# 컨테이너 내부에서 mini 실행
docker run -it --rm \
  -v $(pwd):/workspace \
  -w /workspace \
  python:3.11 bash -c "pip install mini-swe-agent && mini"

2. 성능 향상 팁

  1. 명확한 작업 지시: 구체적이고 단계별 설명
  2. 컨텍스트 제공: 프로젝트 배경과 요구사항 명시
  3. 점진적 접근: 복잡한 작업을 작은 단위로 분할
  4. 테스트 우선: 구현 후 즉시 테스트 요청
  5. 피드백 루프: 중간 결과 확인 후 수정 지시

3. 디버깅 방법

# 디버깅 모드로 실행
import logging

logging.basicConfig(level=logging.DEBUG)

agent = DefaultAgent(
    model=LitellmModel(model_name="claude-3-5-sonnet-20241022"),
    environment=LocalEnvironment(),
    debug=True  # 상세 로그 활성화
)

# 단계별 실행 추적
result = agent.run("Create a simple web server", step_by_step=True)

# 실행 히스토리 확인
for i, step in enumerate(result.trajectory):
    print(f"Step {i+1}: {step['action']}")
    print(f"Result: {step['result'][:100]}...")
    print("---")

결론

Mini SWE-Agent는 복잡함을 거부하고 단순함을 추구하는 혁신적인 접근을 보여줍니다. 100줄의 Python 코드로 SWE-bench 65% 성능을 달성한 것은 단순히 기술적 성취를 넘어서 AI 에이전트 개발의 새로운 패러다임을 제시합니다.

핵심 가치

  1. 극도의 단순성: 복잡한 도구나 설정 없이 bash만으로 모든 작업 수행
  2. 완전한 투명성: 선형적 히스토리로 모든 과정을 추적 가능
  3. 무제한 확장성: subprocess.run 기반으로 어떤 환경에서도 실행
  4. 연구 친화적: 파인튜닝과 강화학습에 최적화된 구조

실제 활용 가능성

개발자에게:

  • GitHub 이슈 자동 해결
  • 레거시 코드 리팩토링
  • 단위 테스트 자동 생성
  • API 문서 자동 업데이트

연구자에게:

  • SWE-bench 벤치마크 실험
  • 새로운 프롬프트 엔지니어링 기법 테스트
  • 강화학습 기반 코드 생성 연구
  • 모델 성능 비교 분석

기업에게:

  • CI/CD 파이프라인 통합
  • 코드 리뷰 자동화
  • 기술 부채 해결 자동화
  • 개발 생산성 극대화

미래 전망

Mini SWE-Agent는 AI 에이전트의 민주화를 실현합니다. 복잡한 프레임워크나 전문 지식 없이도 누구나 강력한 AI 에이전트를 활용할 수 있게 되었습니다. 이는 소프트웨어 개발 방식을 근본적으로 변화시킬 것입니다.

앞으로 개발자는 더 이상 반복적인 코딩 작업에 시간을 소모하지 않고, 창의적 문제 해결과 아키텍처 설계에 집중할 수 있게 될 것입니다.

지금 바로 Mini SWE-Agent를 경험해보세요. 단 몇 분의 설정으로 AI 기반 개발의 미래를 체험할 수 있습니다!


참고 자료:

관련 글: