DEV Community

matias yoon
matias yoon

Posted on

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

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

터미널에서 작동하는 AI 에이전트를 구축하는 것은 현대 개발 워크플로우를 혁신할 수 있는 실용적인 도구입니다. 이 가이드는 실제 개발자가 사용할 수 있는 터미널 기반 AI 에이전트를 구축하는 방법을 자세히 설명합니다.

1. CLI AI 에이전트 생태계

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

Aider: GitHub Copilot과 유사한 기능을 제공하며, 코드 생성 및 수정을 자동화합니다.

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

Continue.dev: VS Code와 연동되는 에이전트로, 터미널에서 사용 가능한 확장 기능이 있습니다.

OpenCode: 오픈소스 기반의 코드 생성 도구로, 로컬 LLM과 연동하여 작동합니다.

커스텀 스크립트: 직접 개발한 CLI 에이전트로, 특정 작업을 자동화하는 데 최적화되어 있습니다.

각각의 도구는 특정 사용 사례에 맞춰 선택할 수 있으며, 로컬 환경에서 작동하는 데 최적화된 에이전트를 구축하는 것이 목표입니다.

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

로컬에서 작동하는 LLM을 사용하기 위해 API 엔드포인트를 설정해야 합니다. llama-cpp-python을 사용하여 로컬 LLM을 실행하는 방법은 다음과 같습니다:

# 필요 패키지 설치
pip install llama-cpp-python

# 로컬 LLM 서버 실행 (예시: LLaMA 2)
llama-server --model /path/to/llama2-7b-q4.bin --port 8000
Enter fullscreen mode Exit fullscreen mode

또는 text-generation-webui을 사용하는 방법:

# 설치
git clone https://github.com/oobabooga/text-generation-webui
cd text-generation-webui
pip install -r requirements.txt

# 실행
python server.py --listen --port 8000
Enter fullscreen mode Exit fullscreen mode

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

다음은 함수 호출 기능을 포함한 기본적인 Python CLI 에이전트입니다:

# ai_agent.py
import openai
import json
import argparse
from typing import List, Dict

class TerminalAgent:
    def __init__(self, api_key: str, model: str = "gpt-4"):
        openai.api_key = api_key
        self.model = model
        self.functions = [
            {
                "name": "execute_command",
                "description": "터미널 명령어를 실행합니다",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "command": {
                            "type": "string",
                            "description": "실행할 명령어"
                        }
                    },
                    "required": ["command"]
                }
            }
        ]

    def call_function(self, name: str, arguments: Dict):
        if name == "execute_command":
            import subprocess
            result = subprocess.run(
                arguments["command"], 
                shell=True, 
                capture_output=True, 
                text=True
            )
            return result.stdout + result.stderr

    def chat(self, user_input: str):
        response = openai.ChatCompletion.create(
            model=self.model,
            messages=[
                {"role": "system", "content": "You are a helpful terminal assistant that can execute commands."},
                {"role": "user", "content": user_input}
            ],
            functions=self.functions,
            function_call="auto"
        )

        message = response.choices[0].message
        if message.get("function_call"):
            function_name = message["function_call"]["name"]
            function_args = json.loads(message["function_call"]["arguments"])
            result = self.call_function(function_name, function_args)

            # 결과를 다시 전달하여 다음 단계 처리
            response2 = openai.ChatCompletion.create(
                model=self.model,
                messages=[
                    {"role": "system", "content": "You are a helpful terminal assistant."},
                    {"role": "user", "content": user_input},
                    {"role": "function", "name": function_name, "content": result}
                ],
                functions=self.functions
            )
            return response2.choices[0].message.content
        else:
            return message.content

def main():
    parser = argparse.ArgumentParser(description='터미널 AI 에이전트')
    parser.add_argument('--api-key', required=True, help='OpenAI API 키')
    parser.add_argument('--input', required=True, help='질문 입력')

    args = parser.parse_args()

    agent = TerminalAgent(api_key=args.api_key)
    response = agent.chat(args.input)
    print(response)

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

사용 방법:

python ai_agent.py --api-key your-api-key --input "현재 디렉토리의 파일 목록을 보여줘"
Enter fullscreen mode Exit fullscreen mode

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

터미널 에이전트를 tmux와 통합하여 멀티탭 작업을 지원합니다:

# tmux_integration.py
import subprocess
import json

class TmuxAgent:
    def __init__(self):
        self.session_name = "ai_session"
        self._create_session()

    def _create_session(self):
        try:
            subprocess.run(["tmux", "new-session", "-d", "-s", self.session_name])
        except:
            pass

    def create_window(self, window_name: str):
        subprocess.run(["tmux", "new-window", "-t", f"{self.session_name}:{window_name}"])

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

    def list_windows(self):
        result = subprocess.run(
            ["tmux", "list-windows", "-t", self.session_name],
            capture_output=True, text=True
        )
        return result.stdout

# 사용 예제
agent = TmuxAgent()
agent.create_window("coding")
agent.send_command("coding", "ls -la")
Enter fullscreen mode Exit fullscreen mode

5. 사용자 정의 도구 개발

다음은 코드 검색 및 Git 연동 기능을 포함한 사용자 정의 도구입니다:

# custom_tools.py
import subprocess
import os
import re

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

    def search_code(self, pattern: str, file_extensions: list = None) -> list:
        """코드 검색"""
        if file_extensions is None:
            file_extensions = [".py", ".js", ".ts", ".java", ".cpp", ".c"]

        results = []
        for root, dirs, files in os.walk(self.root_dir):
            for file in files:
                if any(file.endswith(ext) for ext in file_extensions):
                    filepath = os.path.join(root, file)
                    try:
                        with open(filepath, 'r', encoding='utf-8') as f:
                            content = f.read()
                            if re.search(pattern, content):
                                results.append({
                                    "file": filepath,
                                    "matches": len(re.findall(pattern, content))
                                })
                    except:
                        continue
        return results

class GitTool:
    def __init__(self):
        self.repo_path = "."

    def get_status(self):
        result = subprocess.run(["git", "status", "--porcelain"], 
                              capture_output=True, text=True)
        return result.stdout

    def get_log(self, limit: int = 10):
        result = subprocess.run([
            "git", "log", "--oneline", f"-{limit}"
        ], capture_output=True, text=True)
        return result.stdout

# 사용 예제
search_tool = CodeSearchTool()
results = search_tool.search_code("def main")
print(json.dumps(results, indent=2))
Enter fullscreen mode Exit fullscreen mode

6. 대규모 코드베이스를 위한 컨텍스트 윈도우 관리

대규모 프로젝트에서는 컨텍스트 윈도우를 관리하는 것이 중요합니다:


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

class ContextManager:
    def __init__(self, model: str = "gpt-4"):
        self.encoding = tiktoken.encoding_for_model(model)
        self.max_tokens = 8192  # GPT-4의 최대 토큰 수
        self.context = []

    def add_context(self, content: str, role: str = "user"):
        """문맥 추가"""
        token_count = len(self.encoding.encode(content))
        self.context.append({
            "role": role,
            "content": content,
            "token_count": token_count
        })

    def get_context(self, max_tokens: int = None) -> str:
        """최대 토큰 수 제한으로 문맥 가져오기"""
        if max

---

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

Top comments (0)