DEV Community

matias yoon
matias yoon

Posted on

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

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

터미널에서 직접 작동하는 AI 에이전트를 구축하여 개발 워크플로우를 최적화하세요. 이 가이드는 개발자들이 직접 구축하고 커스터마이징할 수 있는 실질적인 터미널 AI 에이전트를 제공합니다.

1. CLI AI 에이전트 생태계

현재 CLI AI 에이전트 생태계는 다음과 같은 주요 도구들로 구성되어 있습니다:

Aider

# 설치
pip install aider

# 기본 사용
aider --help
Enter fullscreen mode Exit fullscreen mode

Continue.dev

# VS Code 확장으로 설치
# https://marketplace.visualstudio.com/items?itemName=Continue.continue
Enter fullscreen mode Exit fullscreen mode

OpenCode

# GitHub 저장소에서 직접 설치
git clone https://github.com/open-code/open-code.git
cd open-code
pip install -e .
Enter fullscreen mode Exit fullscreen mode

커스텀 스크립트

# 간단한 래퍼 스크립트 예제
#!/bin/bash
# aider-wrapper.sh
aider "$@" --model gpt-4-turbo
Enter fullscreen mode Exit fullscreen mode

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

로컬 LLM을 사용하여 비용을 절감하고 성능을 향상시키세요:

Ollama 설치

# Ubuntu/Debian
curl -fsSL https://ollama.com/install.sh | sh

# macOS
brew install ollama

# 시작
ollama serve

# 모델 다운로드
ollama pull llama3
ollama pull codellama:7b
Enter fullscreen mode Exit fullscreen mode

API 엔드포인트 생성

# llm_api.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', '')
    model = data.get('model', 'llama3')

    response = ollama.chat(
        model=model,
        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

3. 함수 호출 기능이 있는 Python CLI 에이전트

다음은 간단한 Python CLI 에이전트 예제입니다:

#!/usr/bin/env python3
# smart_agent.py
import subprocess
import json
import sys
from typing import Dict, List
import openai

class TerminalAgent:
    def __init__(self, api_key: str, model: str = "gpt-4-turbo"):
        self.client = openai.OpenAI(api_key=api_key)
        self.model = model

    def run_command(self, command: str) -> str:
        """명령어 실행"""
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True,
                timeout=30
            )
            return result.stdout
        except subprocess.TimeoutExpired:
            return "Command timed out"

    def call_function(self, function_name: str, args: Dict) -> str:
        """함수 호출"""
        if function_name == "run_command":
            return self.run_command(args.get("command", ""))
        elif function_name == "list_files":
            return self.run_command("ls -la")
        elif function_name == "git_status":
            return self.run_command("git status")
        else:
            return f"Unknown function: {function_name}"

    def process_request(self, user_prompt: str) -> str:
        """사용자 요청 처리"""
        system_prompt = """
        You are a terminal assistant. You can execute shell commands and 
        return their output. You have access to these functions:
        - run_command(command): execute shell command
        - list_files(): list all files in current directory
        - git_status(): show git status
        """

        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt}
                ],
                functions=[
                    {
                        "name": "run_command",
                        "description": "Execute shell command",
                        "parameters": {
                            "type": "object",
                            "properties": {
                                "command": {"type": "string"}
                            },
                            "required": ["command"]
                        }
                    },
                    {
                        "name": "list_files",
                        "description": "List all files in directory",
                        "parameters": {
                            "type": "object",
                            "properties": {}
                        }
                    },
                    {
                        "name": "git_status",
                        "description": "Show git status",
                        "parameters": {
                            "type": "object",
                            "properties": {}
                        }
                    }
                ],
                function_call="auto"
            )

            # 함수 호출 처리
            if response.choices[0].finish_reason == "function_call":
                function_call = response.choices[0].message.function_call
                result = self.call_function(
                    function_call.name,
                    json.loads(function_call.arguments)
                )

                return f"Command result: {result}"
            else:
                return response.choices[0].message.content

        except Exception as e:
            return f"Error: {str(e)}"

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

    agent = TerminalAgent(api_key="your-api-key-here")
    prompt = sys.argv[1]
    result = agent.process_request(prompt)
    print(result)

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

4. tmux와 통합

터미널 멀티플렉서와의 통합을 통해 더 효율적인 워크플로우 구축:

tmux 스크립트 생성

#!/bin/bash
# tmux_agent.sh
# 새로운 세션 생성
tmux new-session -d -s agent-session

# 창 분할
tmux split-window -h
tmux split-window -v

# 첫 번째 창에 에이전트 실행
tmux send-keys -t agent-session:0.0 "python smart_agent.py" Enter

# 두 번째 창에 코드 편집기 열기
tmux send-keys -t agent-session:0.0 "vim" Enter

# 세션 연결
tmux attach -t agent-session
Enter fullscreen mode Exit fullscreen mode

tmux와 에이전트 통신

# tmux_integration.py
import subprocess
import json

class TmuxAgent:
    def __init__(self, session_name: str = "agent-session"):
        self.session_name = session_name

    def send_to_window(self, window_index: int, command: str):
        """특정 창에 명령어 전송"""
        subprocess.run([
            "tmux", "send-keys", "-t", f"{self.session_name}:{window_index}", 
            command, "Enter"
        ])

    def create_window(self):
        """새 창 생성"""
        subprocess.run([
            "tmux", "new-window", "-t", self.session_name
        ])

    def get_window_output(self, window_index: int):
        """창의 출력 얻기"""
        result = subprocess.run([
            "tmux", "capture-pane", "-p", "-t", f"{self.session_name}:{window_index}"
        ], capture_output=True, text=True)
        return result.stdout

# 사용 예제
agent = TmuxAgent("my-session")
agent.send_to_window(0, "ls -la")
Enter fullscreen mode Exit fullscreen mode

5. 맞춤형 도구 개발

코드 검색 도구


python
# code_search.py
import os
import re
from typing import List, Dict

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

    def find_files(self, pattern: str, file_types: List[str] = None) -> List[str]:
        """파일 찾기"""
        matches = []
        for root, dirs, files in os.walk(self.root_dir):
            for file in files:
                if file_types and not any(file.endswith(ft) for ft in file_types):
                    continue
                if re.search(pattern, file):
                    matches.append(os.path.join(root, file))
        return matches

    def search_in_files(self, pattern: str, file_extensions: List[str] = None) -> Dict[str, List[str]]:
        """파일 내에서 패턴 검색"""
        results = {}
        search_files = self.find_files(r".*", file_extensions)

        for file_path in search_files:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                    matches = re.finditer(pattern, content)
                    line_numbers = [m.start() for m in matches]

                    if line_numbers:
                        results[file_path] = line_numbers
            except Exception:
                continue
        return results

# 사용 예제
searcher =

---

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

Top comments (0)