DEV Community

matias yoon
matias yoon

Posted on

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

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

터미널에서 AI를 활용한 개발 도구는 점점 더 인기를 끌고 있습니다. 오픈소스 커뮤니티와 전문 개발자들 사이에서 로컬 LLM 추론과 자가 호스팅 AI 솔루션에 대한 관심이 높아지고 있습니다. 이 가이드에서는 터미널 내에서 작동하는 AI 에이전트를 구축하는 실용적인 방법을 제공합니다.

1. CLI AI 에이전트 생태계

현재 CLI AI 에이전트의 주요 도구들:

  • Aider: GitHub Copilot과 유사하지만 로컬에서 실행되는 에이전트. Python, JavaScript, Go 등 다양한 언어 지원
  • Continue.dev: VSCode 확장과 유사한 터미널 기반 개발 환경
  • OpenCode: OpenAI API 기반의 코드 생성 도구
  • 사용자 정의 스크립트: 자신만의 커스텀 에이전트 생성
# Aider 설치
pip install aider-chat

# 사용 예시
aider --help
Enter fullscreen mode Exit fullscreen mode

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

로컬 LLM을 사용하기 위해 FastAPI 기반 API 서버를 구축:

# server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

app = FastAPI()
model_name = "TheBloke/Llama-2-7B-Chat-GGUF"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)

class PromptRequest(BaseModel):
    prompt: str
    max_tokens: int = 256

@app.post("/generate")
async def generate_text(request: PromptRequest):
    try:
        inputs = tokenizer(request.prompt, return_tensors="pt")
        outputs = model.generate(
            inputs.input_ids,
            max_new_tokens=request.max_tokens,
            temperature=0.7,
            do_sample=True
        )
        response = tokenizer.decode(outputs[0], skip_special_tokens=True)
        return {"response": response}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)
Enter fullscreen mode Exit fullscreen mode
# 실행 명령
pip install fastapi uvicorn transformers torch
python server.py
Enter fullscreen mode Exit fullscreen mode

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

기본 기능을 갖춘 CLI 에이전트 구현:

# ai_agent.py
import requests
import json
import subprocess
import os
from pathlib import Path

class TerminalAgent:
    def __init__(self, api_url="http://localhost:8000"):
        self.api_url = api_url

    def generate_code(self, prompt, context=""):
        full_prompt = f"{context}\n\n{prompt}"
        response = requests.post(
            f"{self.api_url}/generate",
            json={"prompt": full_prompt, "max_tokens": 512}
        )
        return response.json()["response"]

    def execute_command(self, command):
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True,
                timeout=30
            )
            return result.stdout + result.stderr
        except subprocess.TimeoutExpired:
            return "Command timed out"

    def save_to_file(self, content, filename):
        with open(filename, 'w') as f:
            f.write(content)
        print(f"Saved to {filename}")

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

    # 코드 생성
    prompt = "Python으로 Flask 앱을 생성하려고 해요. 루트 페이지는 'Hello World'를 출력하고, /api/users는 JSON 데이터를 반환합니다."

    generated_code = agent.generate_code(prompt)
    agent.save_to_file(generated_code, "app.py")

    print("생성된 코드:")
    print(generated_code)
Enter fullscreen mode Exit fullscreen mode
# 실행
python ai_agent.py
Enter fullscreen mode Exit fullscreen mode

4. tmux와 통합

터미널 다중화를 활용한 개발 환경 구축:

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

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

# 세션에 코드 에디터 열기
tmux send-keys -t ai_dev "code app.py" Enter

# 세션에 터미널 탭 추가
tmux split-window -h -t ai_dev
tmux send-keys -t ai_dev:0 "ls -la" Enter
Enter fullscreen mode Exit fullscreen mode
# tmux_integration.py
import subprocess
import json

class TmuxAgent(TerminalAgent):
    def __init__(self, session_name="ai_dev"):
        super().__init__()
        self.session_name = session_name

    def create_session(self):
        subprocess.run(["tmux", "new-session", "-d", "-s", self.session_name])

    def create_window(self, window_name):
        subprocess.run(["tmux", "new-window", "-n", window_name])

    def send_command(self, command, window_index=0):
        subprocess.run([
            "tmux", "send-keys", "-t", f"{self.session_name}:{window_index}", 
            command, "Enter"
        ])

    def attach_session(self):
        subprocess.run(["tmux", "attach-session", "-t", self.session_name])

# 사용 예시
agent = TmuxAgent("my_ai_project")
agent.create_session()
agent.create_window("editor")
agent.send_command("code app.py")
Enter fullscreen mode Exit fullscreen mode

5. 사용자 정의 도구 개발

Git과 파일 시스템 통합:

# custom_tools.py
import subprocess
import os
import json
from pathlib import Path

class CodeTools:
    @staticmethod
    def search_code(pattern, directory="."):
        """코드 검색 도구"""
        try:
            result = subprocess.run(
                ["grep", "-r", pattern, directory],
                capture_output=True,
                text=True,
                cwd=directory
            )
            return result.stdout.strip()
        except Exception as e:
            return f"Error: {str(e)}"

    @staticmethod
    def get_git_status():
        """Git 상태 확인"""
        try:
            result = subprocess.run(
                ["git", "status", "--porcelain"],
                capture_output=True,
                text=True
            )
            return result.stdout.strip()
        except Exception as e:
            return f"Error: {str(e)}"

    @staticmethod
    def list_files(directory=".", pattern="*"):
        """파일 목록 조회"""
        try:
            result = subprocess.run(
                ["find", directory, "-name", pattern],
                capture_output=True,
                text=True
            )
            return result.stdout.strip().split('\n')
        except Exception as e:
            return [f"Error: {str(e)}"]

# 확장된 에이전트
class EnhancedAgent(TerminalAgent):
    def __init__(self, api_url="http://localhost:8000"):
        super().__init__(api_url)
        self.tools = CodeTools()

    def search_and_generate(self, search_pattern, prompt):
        """검색 결과를 기반으로 코드 생성"""
        search_result = self.tools.search_code(search_pattern)
        context = f"Search results:\n{search_result}\n\n"
        return self.generate_code(prompt, context)

    def get_project_info(self):
        """프로젝트 정보 수집"""
        git_status = self.tools.get_git_status()
        files = self.tools.list_files(".")
        return {
            "git_status": git_status,
            "file_count": len(files),
            "files": files[:10]  # 최대 10개만 표시
        }
Enter fullscreen mode Exit fullscreen mode

6. 컨텍스트 윈도우 관리

대형 코드베이스에서의 메모리 최적화:


python
# context_manager.py
import os
import hashlib
from typing import List, Dict
import pickle

class ContextManager:
    def __init__(self, max_context_size=10000):
        self.max_context_size = max_context_size
        self.context_cache = {}

    def hash_content(self, content: str) -> str:
        return hashlib.md5(content.encode()).hexdigest()

    def add_context(self, key: str, content: str):
        """컨텍스트 추가 및 크기 제한"""
        if len(content) > self.max_context_size:
            content = content[:self.max_context_size]

        self.context_cache[key] = content

    def get_context(self, keys: List[str]) -> str:
        """지정된 키들의 컨텍스트 결합"""
        combined_context = []
        for key in keys:
            if key in self.context_cache:
                combined_context.append(f"## {key}\n

---

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

Top comments (0)