DEV Community

matias yoon
matias yoon

Posted on

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

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

터미널에서 AI 코딩 어시스턴트를 직접 구축하는 실전 가이드

1. CLI AI 에이전트 생태계 분석

현재 터미널 기반 AI 에이전트는 다양한 솔루션으로 구성되어 있습니다:

Aider: GitHub Copilot처럼 코드 생성 및 수정을 지원하는 에이전트

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

Continue.dev: VSCode 확장 프로그램이지만 CLI에서도 사용 가능

npm install -g continue
continue-cli --help
Enter fullscreen mode Exit fullscreen mode

OpenCode: 오픈소스 기반 CLI AI 에이전트

git clone https://github.com/open-code/open-code.git
cd open-code && python main.py --help
Enter fullscreen mode Exit fullscreen mode

Custom Scripts: 직접 개발한 스크립트로 최적화된 기능 제공

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

로컬에서 LLM을 실행하고 API 엔드포인트를 제공하기 위해 llama.cpp 사용:

# llama.cpp 설치
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
make

# 모델 다운로드 및 변환
wget https://huggingface.co/TheBloke/Mistral-7B-v0.1-GGUF/resolve/main/mistral-7b-v0.1.Q4_K_M.gguf
./llama.cpp/convert-hf-to-gguf.py mistral-7b-v0.1.Q4_K_M.gguf

# API 서버 실행
./llama.cpp/server -m mistral-7b-v0.1.Q4_K_M.gguf \
  --host 127.0.0.1 \
  --port 11434 \
  --ctx-size 8192
Enter fullscreen mode Exit fullscreen mode

API 테스트:

curl http://localhost:11434/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistral-7b-v0.1.Q4_K_M",
    "prompt": "Python으로 factorial 함수를 구현해줘",
    "stream": false
  }'
Enter fullscreen mode Exit fullscreen mode

3. 간단한 Python CLI 에이전트 구축

다음은 간단한 CLI 에이전트 코드:

# ai_agent.py
import openai
import json
import subprocess
import sys
from typing import Dict, Any

class TerminalAgent:
    def __init__(self, api_base="http://localhost:11434"):
        self.client = openai.OpenAI(
            base_url=api_base,
            api_key="ollama"
        )

    def call_llm(self, prompt: str, model: str = "mistral-7b-v0.1.Q4_K_M") -> str:
        try:
            response = self.client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": prompt}],
                temperature=0.7,
                max_tokens=2048
            )
            return response.choices[0].message.content
        except Exception as e:
            return f"Error: {str(e)}"

    def execute_command(self, command: str) -> str:
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True
            )
            return result.stdout + result.stderr
        except Exception as e:
            return f"Error: {str(e)}"

def main():
    agent = TerminalAgent()

    if len(sys.argv) < 2:
        print("Usage: python ai_agent.py \"prompt here\"")
        sys.exit(1)

    prompt = " ".join(sys.argv[1:])
    response = agent.call_llm(prompt)
    print(response)

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

사용법:

python ai_agent.py "Python으로 Flask 애플리케이션을 만들어줘"
Enter fullscreen mode Exit fullscreen mode

4. tmux와 통합

터미널 에이전트를 tmux 세션과 통합하여 멀티탭 작업 가능:

# tmux 세션 생성 및 스크립트 실행
tmux new-session -d -s ai_session
tmux send-keys -t ai_session "python ai_agent.py '코드 리뷰해줘'" Enter
tmux send-keys -t ai_session "python ai_agent.py '테스트 코드 작성해줘'" Enter
Enter fullscreen mode Exit fullscreen mode

tmux 키 설정 파일 (~/.tmux.conf):

# Ctrl+A, Ctrl+G: AI 에이전트 실행
bind-key -t vi-edit G run-shell "tmux display-message 'AI Agent: Running...'; python3 ai_agent.py 'code review'"
Enter fullscreen mode Exit fullscreen mode

5. 사용자 정의 도구 개발

코드 검색 도구

# code_search.py
import os
import re
from pathlib import Path

class CodeSearcher:
    def __init__(self, root_path: str = "."):
        self.root_path = Path(root_path)

    def search_pattern(self, pattern: str, file_extensions: list = None) -> list:
        results = []
        if file_extensions is None:
            file_extensions = ['.py', '.js', '.ts', '.java', '.cpp']

        for file_path in self.root_path.rglob("*"):
            if file_path.is_file() and file_path.suffix in file_extensions:
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()
                        if re.search(pattern, content):
                            results.append(str(file_path))
                except Exception:
                    continue
        return results

# 사용 예시
searcher = CodeSearcher()
matches = searcher.search_pattern(r"def.*\(.*\):")
for match in matches:
    print(match)
Enter fullscreen mode Exit fullscreen mode

Git 통합 도구

# git_tools.py
import subprocess
import json

class GitTools:
    @staticmethod
    def get_changed_files() -> list:
        try:
            result = subprocess.run(
                ['git', 'diff', '--name-only', 'HEAD~1', 'HEAD'],
                capture_output=True, text=True
            )
            return [f.strip() for f in result.stdout.split('\n') if f.strip()]
        except Exception:
            return []

    @staticmethod
    def get_commit_history(limit: int = 5) -> list:
        try:
            result = subprocess.run(
                ['git', 'log', f'--oneline -{limit}'],
                capture_output=True, text=True
            )
            return [line.strip() for line in result.stdout.split('\n') if line.strip()]
        except Exception:
            return []

# 사용 예시
git_tools = GitTools()
files = git_tools.get_changed_files()
commits = git_tools.get_commit_history()
print(f"Changed files: {files}")
print(f"Recent commits: {commits}")
Enter fullscreen mode Exit fullscreen mode

6. 컨텍스트 윈도우 관리

대용량 코드베이스를 처리하기 위한 컨텍스트 관리:

# context_manager.py
import os
from pathlib import Path

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

    def add_file_context(self, file_path: str, max_lines: int = 100) -> str:
        """파일 컨텍스트 추가 (줄 수 제한)"""
        try:
            with open(file_path, 'r') as f:
                lines = f.readlines()
                if len(lines) > max_lines:
                    # 중간 부분 슬라이싱
                    start = len(lines) // 2 - max_lines // 2
                    end = start + max_lines
                    lines = lines[start:end]

                content = ''.join(lines)
                return f"File: {file_path}\n{content}"
        except Exception as e:
            return f"Error reading {file_path}: {str(e)}"

    def build_prompt_with_context(self, base_prompt: str, files: list) -> str:
        """파일 컨텍스트를 포함한 프롬프트 생성"""
        context = []
        for file_path in files:
            if os.path.exists(file_path):
                context.append(self.add_file_context(file_path))

        context_str = "\n\n".join(context)
        return f"{base_prompt}\n\nContext:\n{context_str}"

# 사용 예시
context = ContextManager()
prompt = context.build_prompt_with_context(
    "이 코드를 리뷰해줘",
    ["main.py", "utils.py"]
)
Enter fullscreen mode Exit fullscreen mode

7. 비용/속도 최적화 전략

로컬 vs API 모델 비교


python
# model_optimizer.py
import time
from typing import Tuple

class ModelOptimizer:
    @staticmethod
    def benchmark_model(model_name: str, prompt: str, api_base: str = "http://localhost:11434") -> dict:
        """모델 성능 벤치마크"""
        import openai

        client = openai.OpenAI(base_url=api_base, api_key="ollama")


---

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

Top comments (0)