DEV Community

matias yoon
matias yoon

Posted on

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

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

Product ID: Terminal AI Agent Builder v19

Price: $5

Target: Developers seeking local AI coding assistants

1. CLI AI 에이전트 생태계 (CLI AI Agent Landscape)

현재 터미널 기반 AI 에이전트는 두 가지 주요 경로로 나뉩니다:

Aider vs Continue.dev

# Aider: 단순한 코드 생성 도구
pip install aider
aider --help

# Continue.dev: VSCode 기반 에이전트
# 하지만 터미널에서 사용 가능
Enter fullscreen mode Exit fullscreen mode

OpenCode vs 커스텀 스크립트

# OpenCode는 GitHub에서 검색
# 커스텀 스크립트 예제
git clone https://github.com/your-repo/ai-agent.git
cd ai-agent
python setup.py install
Enter fullscreen mode Exit fullscreen mode

내가 추천하는 접근법:

  • Aider + 커스텀 툴 조합
  • Local LLM API + Prompt Engineering
  • 터미널 내에서 코드 생성/수정

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

# 1. Ollama 설치 (가장 간단한 방법)
curl -fsSL https://ollama.com/install.sh | sh

# 2. 모델 다운로드
ollama pull llama3.2:3b
ollama pull codellama:7b

# 3. API 엔드포인트 확인
ollama serve

# 4. 터미널에서 테스트
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2:3b",
  "prompt": "Hello, how are you?",
  "stream": false
}'
Enter fullscreen mode Exit fullscreen mode

프로젝트 구성:

# config.yaml
api:
  host: "localhost"
  port: 11434
  model: "llama3.2:3b"
tools:
  - name: "code_search"
    path: "./tools/code_search.py"
  - name: "git_operations"
    path: "./tools/git_ops.py"
Enter fullscreen mode Exit fullscreen mode

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

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

import json
import requests
import argparse
import sys
from pathlib import Path
from typing import Dict, List, Any

class TerminalAgent:
    def __init__(self, config_path: str = "config.yaml"):
        self.config = self.load_config(config_path)
        self.api_url = f"http://{self.config['api']['host']}:{self.config['api']['port']}/api/generate"

    def load_config(self, config_path: str) -> Dict:
        import yaml
        with open(config_path, 'r') as f:
            return yaml.safe_load(f)

    def call_llm(self, prompt: str, functions: List[Dict] = None) -> str:
        payload = {
            "model": self.config['api']['model'],
            "prompt": prompt,
            "stream": False
        }

        if functions:
            payload["functions"] = functions

        response = requests.post(self.api_url, json=payload)
        return response.json()['response']

    def execute_tool(self, tool_name: str, **kwargs) -> str:
        tool_path = self.config['tools'][tool_name]
        # 간단한 실행 예제
        return f"Tool {tool_name} executed with {kwargs}"

def main():
    parser = argparse.ArgumentParser(description='Terminal AI Agent')
    parser.add_argument('--prompt', '-p', help='Prompt to send to LLM')
    parser.add_argument('--tool', '-t', help='Tool to execute')
    parser.add_argument('--args', '-a', help='Tool arguments')

    args = parser.parse_args()

    agent = TerminalAgent()

    if args.prompt:
        result = agent.call_llm(args.prompt)
        print(result)
    elif args.tool:
        tool_args = json.loads(args.args) if args.args else {}
        result = agent.execute_tool(args.tool, **tool_args)
        print(result)

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

사용법:

# 기본 프롬프트
python agent.py --prompt "Write a Python function to calculate fibonacci"

# 툴 실행
python agent.py --tool "code_search" --args '{"query": "fast json parsing"}'
Enter fullscreen mode Exit fullscreen mode

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

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

# 세션에 명령어 실행
tmux send-keys -t ai_agent "python agent.py --prompt 'Fix this code'" Enter

# 터미널 분할
tmux split-window -h -t ai_agent
tmux send-keys -t ai_agent:0 "vim main.py" Enter
Enter fullscreen mode Exit fullscreen mode

tmux 통합 스크립트:

#!/bin/bash
# ai_tmux.sh

SESSION="ai_agent"

if ! tmux has-session -t $SESSION 2>/dev/null; then
    tmux new-session -s $SESSION -d
    tmux split-window -h -t $SESSION
    tmux send-keys -t $SESSION:0 "vim" Enter
    tmux send-keys -t $SESSION:1 "python agent.py" Enter
fi

tmux attach -t $SESSION
Enter fullscreen mode Exit fullscreen mode

5. 커스텀 툴 개발

코드 검색 도구

# tools/code_search.py
import os
import subprocess
import json

def search_code(query: str, file_extensions: list = None):
    """
    코드 검색 툴: grep + 파일 확장자 필터
    """
    if file_extensions is None:
        file_extensions = ['.py', '.js', '.ts', '.go', '.rs']

    search_cmd = [
        'find', '.', '-type', 'f',
        '-name', f'*.{file_extensions[0]}' if file_extensions else '*',
        '-exec', 'grep', '-l', query, '{}', '+'
    ]

    try:
        result = subprocess.run(search_cmd, capture_output=True, text=True)
        return result.stdout.strip().split('\n') if result.stdout.strip() else []
    except Exception as e:
        return [f"Error: {str(e)}"]

def search_code_with_context(query: str, context_lines: int = 3):
    """
    코드 검색 + 컨텍스트 출력
    """
    cmd = ['grep', '-n', '-A', str(context_lines), '-B', str(context_lines), query, '-r', '.']
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.stdout

# 사용 예제
if __name__ == "__main__":
    print("Search results:")
    print(json.dumps(search_code("def main"), indent=2))
Enter fullscreen mode Exit fullscreen mode

Git 연동 툴

# tools/git_ops.py
import subprocess
import json
from datetime import datetime

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

def get_recent_commits(n: int = 5):
    """최근 커밋 목록"""
    try:
        cmd = ['git', 'log', '--oneline', f'-{n}']
        result = subprocess.run(cmd, capture_output=True, text=True)
        return result.stdout.strip().split('\n') if result.stdout.strip() else []
    except Exception as e:
        return [f"Error: {str(e)}"]

def create_git_summary():
    """Git 요약 생성"""
    status = get_git_status()
    commits = get_recent_commits(3)

    return {
        "status": status,
        "recent_commits": commits,
        "timestamp": datetime.now().isoformat()
    }

# 사용 예제
if __name__ == "__main__":
    print(json.dumps(create_git_summary(), indent=2))
Enter fullscreen mode Exit fullscreen mode

6. 컨텍스트 윈도우 관리


python
# context_manager.py
import os
from pathlib import Path

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

    def add_file_context(self, file_path: str, max_lines: int = 200):
        """파일의 컨텍스트 추가"""
        try:
            with open(file_path, 'r') as f:
                content = f.read()

            lines = content.split('\n')
            if len(lines) > max_lines:
                # 중간 부분만 유지
                half = max_lines // 2
                lines = lines[:half] + ['... [truncated] ...'] + lines[-half:]

            self.context.append({
                "file": file_path,
                "content": '\n'.join(lines),
                "tokens

---

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

Top comments (0)