DEV Community

matias yoon
matias yoon

Posted on

터미널 AI 에이전트 구축 (v6)

터미널 AI 에이전트 구축 (v6)

터미널에서 직접 작동하는 AI 에이전트를 구축하는 것은 개발자들이 코드를 빠르게 작성하고 문제를 해결하는 데 있어 귀중한 도구가 됩니다. 이 가이드에서는 현대적인 CLI 기반 AI 에이전트를 구축하고 최적화하는 실용적인 방법을 다룹니다.

1. CLI AI 에이전트 생태계

현재 CLI AI 에이전트 시장은 다음과 같은 주요 솔루션으로 구성되어 있습니다:

Aider: Python 기반 코드 편집 도구로, GitHub Copilot과 유사한 기능을 제공합니다. 간단한 설치로 사용 가능합니다.

pip install aider
aider --help
Enter fullscreen mode Exit fullscreen mode

Continue.dev: VS Code 확장이지만 CLI도 지원하며, LLM 기반 코드 완성 도구입니다.

OpenCode: GitHub에서 개발된 오픈소스 CLI 에이전트로, 다양한 언어 지원을 제공합니다.

사용자 정의 스크립트: 최소한의 의존성으로 직접 구축하여 맞춤형 기능을 제공할 수 있습니다.

2. 로컬 LLM API 엔드포인트 설정

로컬 LLM을 사용하여 빠르고 안전한 작업을 위해 로컬 API 서버를 설정합니다.

먼저 Ollama를 설치합니다:

# macOS
brew install ollama

# Ubuntu/Debian
curl -fsSL https://ollama.com/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

이제 LLaMA3 모델을 다운로드하고 실행합니다:

ollama pull llama3
ollama run llama3
Enter fullscreen mode Exit fullscreen mode

다른 LLM도 사용 가능합니다:

ollama pull codellama:7b
ollama run codellama:7b
Enter fullscreen mode Exit fullscreen mode

API 서버로 사용하기 위해 다음 Python 스크립트를 사용합니다:

# local_llm_server.py
from flask import Flask, request, jsonify
import ollama

app = Flask(__name__)

@app.route('/chat', methods=['POST'])
def chat():
    data = request.json
    prompt = data.get('prompt', '')

    response = ollama.chat(
        model='llama3',
        messages=[{'role': 'user', 'content': prompt}]
    )

    return jsonify({
        'response': response['message']['content']
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=11434)
Enter fullscreen mode Exit fullscreen mode

실행:

python local_llm_server.py
Enter fullscreen mode Exit fullscreen mode

3. 기능 호출을 포함한 Python CLI 에이전트 구축

다음은 기능 호출을 지원하는 간단한 CLI 에이전트입니다:

# ai_agent.py
import requests
import subprocess
import json
import os

class TerminalAgent:
    def __init__(self, api_url='http://localhost:11434'):
        self.api_url = api_url

    def chat(self, prompt):
        response = requests.post(
            f'{self.api_url}/chat',
            json={'prompt': prompt}
        )
        return response.json()['response']

    def execute_command(self, command):
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True
            )
            return {
                'stdout': result.stdout,
                'stderr': result.stderr,
                'returncode': result.returncode
            }
        except Exception as e:
            return {'error': str(e)}

    def search_code(self, pattern, file_type='*.py'):
        cmd = f'find . -name "{file_type}" -exec grep -l "{pattern}" {{}} \\;'
        return self.execute_command(cmd)

    def get_git_status(self):
        return self.execute_command('git status')

    def git_commit(self, message):
        self.execute_command(f'git add .')
        return self.execute_command(f'git commit -m "{message}"')

# 사용 예시
if __name__ == '__main__':
    agent = TerminalAgent()

    # 일반 질문
    response = agent.chat("Python에서 requests 라이브러리를 사용하여 HTTP GET 요청을 하는 코드를 작성해주세요")
    print(response)

    # 코드 검색
    search_result = agent.search_code("def calculate")
    print(json.dumps(search_result, indent=2))
Enter fullscreen mode Exit fullscreen mode

4. tmux/터미널 멀티플렉서 통합

tmux를 사용하여 에이전트를 터미널 세션에 통합합니다:

# tmux 세션 생성
tmux new-session -d -s ai_agent

# 세션에 명령어 실행
tmux send-keys -t ai_agent "python ai_agent.py" Enter

# 세션 접속
tmux attach -t ai_agent
Enter fullscreen mode Exit fullscreen mode

다음은 tmux 통합 스크립트:

# tmux_integration.py
import subprocess
import os

def create_tmux_session(session_name):
    subprocess.run(['tmux', 'new-session', '-d', '-s', session_name])

def run_in_tmux(session_name, command):
    subprocess.run(['tmux', 'send-keys', '-t', session_name, command, 'Enter'])

def attach_to_session(session_name):
    subprocess.run(['tmux', 'attach', '-t', session_name])

# 사용 예시
if __name__ == '__main__':
    create_tmux_session('ai_dev')
    run_in_tmux('ai_dev', 'python ai_agent.py')
Enter fullscreen mode Exit fullscreen mode

5. 맞춤형 도구 개발

다음은 자주 사용되는 도구들입니다:

코드 검색 도구:

# code_search.py
import os
import re

class CodeSearcher:
    def __init__(self, root_dir='.'):
        self.root_dir = root_dir

    def search_in_files(self, pattern, file_extensions=['.py', '.js', '.ts']):
        results = []
        regex = re.compile(pattern, re.IGNORECASE)

        for root, dirs, files in os.walk(self.root_dir):
            for file in files:
                if any(file.endswith(ext) for ext in file_extensions):
                    file_path = os.path.join(root, file)
                    try:
                        with open(file_path, 'r', encoding='utf-8') as f:
                            content = f.read()
                            if regex.search(content):
                                results.append({
                                    'file': file_path,
                                    'line_numbers': [
                                        i+1 for i, line in enumerate(content.split('\n')) 
                                        if regex.search(line)
                                    ]
                                })
                    except Exception as e:
                        print(f"Error reading {file_path}: {e}")

        return results

# 사용 예시
searcher = CodeSearcher('.')
results = searcher.search_in_files('def calculate')
print(json.dumps(results, indent=2))
Enter fullscreen mode Exit fullscreen mode

Git 통합 도구:

# git_tools.py
import subprocess
import json

class GitTools:
    @staticmethod
    def get_branches():
        result = subprocess.run(['git', 'branch', '-a'], 
                              capture_output=True, text=True)
        return result.stdout.strip().split('\n')

    @staticmethod
    def get_recent_commits(count=5):
        result = subprocess.run([
            'git', 'log', f'-{count}', '--oneline'
        ], capture_output=True, text=True)
        return result.stdout.strip().split('\n')

    @staticmethod
    def get_diff_stats():
        result = subprocess.run(['git', 'diff', '--stat'], 
                              capture_output=True, text=True)
        return result.stdout.strip()

# 사용 예시
git_tools = GitTools()
print("Branches:", git_tools.get_branches())
print("Recent commits:", git_tools.get_recent_commits())
Enter fullscreen mode Exit fullscreen mode

6. 컨텍스트 윈도우 관리

대규모 코드베이스를 처리하기 위해 컨텍스트 윈도우를 관리합니다:


python
# context_manager.py
import os
from pathlib import Path

class ContextManager:
    def __init__(self, max_tokens=4096):
        self.max_tokens = max_tokens
        self.context = []

    def add_file(self, file_path, max_lines=100):
        try:
            with open(file_path, 'r') as f:
                lines = f.readlines()[:max_lines]
                content = ''.join(lines)

                # 토큰 수 계산 (간단한 추정)
                token_count = len(content) // 4  # rough estimate

                if token_count > self.max_tokens:
                    # 필요한 경우 줄이기
                    content = self._truncate_content(content, self.max_tokens)

                self.context.append({
                    'file': file_path,
                    'content': content,
                    'token_count': token_count
                })
        except Exception as e:
            print(f"Error reading {file_path}: {e}")

    def _truncate_content(self, content, max_tokens):
        # 간단한 토큰 기반 자르기
        max_chars = max_tokens * 4  # 예상 토큰 수
        return content[:max_chars

---

📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)