터미널 AI 에이전트 구축 (v24)
터미널에서 작동하는 AI 에이전트를 구축하면 개발자들이 코드를 더 빠르고 효율적으로 작성할 수 있습니다. 이 가이드에서는 실제 사용 가능한 터미널 AI 에이전트를 구축하는 방법을 단계별로 설명합니다.
1. CLI AI 에이전트 랜드스케이프
현재 CLI AI 에이전트 시장에는 여러 선택지가 있습니다:
Aider: Git 기반 코드 변경을 위한 자동화 도구로, 터미널에서 직접 작동합니다.
pip install aider
aider --help
Continue.dev: VSCode와 연동된 AI 코드 작성 도구.
npm install -g continue
OpenCode: GitHub에서 직접 제공하는 CLI 도구.
# GitHub에서 설치
git clone https://github.com/openai/open-code.git
커스텀 스크립트: 직접 제작한 간단한 에이전트. 가장 유연한 접근입니다.
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
./convert-hf-to-gguf.py mistral-7b-v0.1.Q4_K_M.gguf
# API 서버 실행
./server -m mistral-7b-v0.1.Q4_K_M.gguf -c 2048 --host 127.0.0.1 --port 8080
API 엔드포인트를 사용하여 테스트:
curl -X POST http://127.0.0.1:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "Write a Python function that calculates factorial",
"max_tokens": 100,
"temperature": 0.7
}'
3. 간단한 Python CLI 에이전트 구축
기본적인 CLI 에이전트를 구현해봅니다:
#!/usr/bin/env python3
# agent.py
import os
import json
import requests
import argparse
from typing import Dict, List
class TerminalAgent:
def __init__(self, api_url: str = "http://127.0.0.1:8080"):
self.api_url = api_url
def generate_code(self, prompt: str, context: str = "") -> str:
"""코드 생성"""
payload = {
"prompt": f"{context}\n\nPrompt: {prompt}\n\nCode:",
"max_tokens": 500,
"temperature": 0.7,
"stop": ["\n\n"]
}
try:
response = requests.post(
f"{self.api_url}/completion",
json=payload,
timeout=30
)
return response.json()['content']
except Exception as e:
return f"Error: {str(e)}"
def explain_code(self, code: str) -> str:
"""코드 설명"""
prompt = f"Explain the following Python code:\n\n{code}"
return self.generate_code(prompt, "Explain code:")
def fix_errors(self, code: str, error: str) -> str:
"""코드 오류 수정"""
prompt = f"Fix the following Python error in the code:\n\nCode:\n{code}\n\nError:\n{error}"
return self.generate_code(prompt, "Fix error:")
def main():
parser = argparse.ArgumentParser(description="Terminal AI Agent")
parser.add_argument("--generate", "-g", help="Generate code from prompt")
parser.add_argument("--explain", "-e", help="Explain code")
parser.add_argument("--fix", "-f", help="Fix code errors")
parser.add_argument("--context", "-c", help="Additional context")
args = parser.parse_args()
agent = TerminalAgent()
if args.generate:
result = agent.generate_code(args.generate, args.context or "")
print(result)
elif args.explain:
result = agent.explain_code(args.explain)
print(result)
elif args.fix:
result = agent.fix_errors(args.fix, args.context or "")
print(result)
else:
print("Usage: python agent.py --generate 'prompt' [--context 'context']")
if __name__ == "__main__":
main()
실행 방법:
# 코드 생성
python agent.py --generate "Write a function to sort a list of dictionaries by a key"
# 코드 설명
python agent.py --explain "def bubble_sort(arr): n = len(arr); for i in range(n): for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j]"
# 오류 수정
python agent.py --fix "import pandas as pd; df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}); print(df.colums)" --context "AttributeError: 'DataFrame' object has no attribute 'colums'"
4. tmux와 통합
터미널 세션을 관리하기 위해 tmux와 연동합니다:
# tmux 세션 생성
tmux new-session -d -s ai-agent
# 세션 내부에 에이전트 실행
tmux send-keys -t ai-agent "python agent.py --generate 'create a Flask route for user login'" Enter
# 세션 연결
tmux attach -t ai-agent
tmux 스크립트를 사용한 자동화:
#!/bin/bash
# tmux-agent.sh
SESSION="ai-agent"
# 세션 존재 여부 확인
if ! tmux has-session -t $SESSION 2>/dev/null; then
tmux new-session -d -s $SESSION
fi
# 현재 세션에서 새로운 윈도우 생성
tmux new-window -t $SESSION -n "code"
tmux new-window -t $SESSION -n "chat"
# 세션에 연결
tmux attach -t $SESSION
5. 커스텀 도구 개발
기본적인 도구들을 개발해보겠습니다:
python
# tools.py
import os
import subprocess
import json
from pathlib import Path
class CodeSearchTool:
def __init__(self, project_path: str):
self.project_path = Path(project_path)
def search_files(self, pattern: str, file_types: list = None) -> list:
"""파일 검색"""
cmd = ["find", str(self.project_path), "-name", f"*{pattern}*"]
if file_types:
type_args = []
for ext in file_types:
type_args.extend(["-o", "-name", f"*.{ext}"])
cmd.extend(["(", *type_args[1:], ")"])
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout.strip().split('\n') if result.stdout.strip() else []
def search_code(self, term: str, file_types: list = None) -> dict:
"""코드 검색"""
files = self.search_files(term, file_types)
results = {}
for file_path in files:
try:
with open(file_path, 'r') as f:
content = f.read()
if term in content:
results[file_path] = {
"line_count": len(content.split('\n')),
"contains": term
}
except Exception as e:
continue
return results
class GitTool:
def __init__(self, repo_path: str = "."):
self.repo_path = Path(repo_path)
def get_changed_files(self) -> list:
"""변경된 파일 목록"""
result = subprocess.run(
["git", "diff", "--name-only", "HEAD~1", "HEAD"],
cwd=self.repo_path,
capture_output=True,
text=True
)
return result.stdout.strip().split('\n') if result.stdout.strip() else []
def get_branch_info(self) -> dict:
"""브랜치 정보"""
result = subprocess.run(
["git", "branch", "--show-current"],
cwd=self.repo_path,
capture_output=True,
text=True
)
return {
"current_branch": result.stdout.strip()
}
class FileTool:
@staticmethod
def read_file(path: str) -> str:
"""파일 읽기"""
try:
with open(path, 'r') as f:
return f.read()
except Exception as e:
return f"Error reading file: {str(e)}"
@
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)