터미널 AI 에이전트 구축 (v32)
개발자용 CLI AI 에이전트 구축 가이드
터미널에서 작동하는 AI 에이전트는 개발자의 생산성을 높이는 강력한 도구입니다. 이 가이드에서는 실제 개발자들이 필요로 하는 3-7달러 범위의 실용적 CLI AI 에이전트를 구축하는 방법을 설명합니다.
1. CLI AI 에이전트 생태계 분석
현재 선택지 비교
Aider: GitHub Copilot 기반의 코드 생성 도구로, 현재 가장 인기 있는 선택입니다.
# Aider 설치
pip install aider
# 사용 예시
aider --model llama3:8b
Continue.dev: VSCode 확장으로 시작했지만 CLI 버전도 제공됩니다.
# Continue CLI 설치
npm install -g @continue-dev/cli
Custom Scripts: 직접 구축한 스크립트로 완전한 제어권 확보
2. 로컬 LLM API 엔드포인트 설정
로컬 LLM을 터미널에서 사용하기 위해 API 서버를 설정합니다.
Ollama 설치 및 실행
# Ollama 설치 (macOS)
curl -fsSL https://ollama.com/install.sh | sh
# Ollama 서버 시작
ollama serve
# 모델 다운로드
ollama pull llama3:8b
ollama pull codellama:7b
# 서버 상태 확인
ollama list
API 엔드포인트 테스트
# test_api.py
import requests
import json
def test_local_llm():
response = requests.post(
'http://localhost:11434/api/generate',
json={
'model': 'llama3:8b',
'prompt': 'Hello, how are you?',
'stream': False
}
)
print(response.json()['response'])
if __name__ == "__main__":
test_local_llm()
3. 간단한 Python CLI 에이전트 구축
# ai_agent.py
#!/usr/bin/env python3
import requests
import json
import sys
from typing import Dict, List, Any
class TerminalAgent:
def __init__(self, model="llama3:8b", base_url="http://localhost:11434"):
self.model = model
self.base_url = base_url
self.history = []
def call_llm(self, prompt: str, context: str = "") -> str:
full_prompt = f"{context}\n\n{prompt}"
response = requests.post(
f"{self.base_url}/api/generate",
json={
'model': self.model,
'prompt': full_prompt,
'stream': False,
'options': {
'temperature': 0.3,
'top_p': 0.9
}
}
)
if response.status_code == 200:
return response.json()['response']
else:
raise Exception(f"API Error: {response.status_code}")
def process_request(self, task: str) -> str:
return self.call_llm(task, self.get_context())
def get_context(self) -> str:
# 현재 디렉토리와 파일 정보 추가
import subprocess
try:
files = subprocess.check_output(['ls', '-la']).decode()
return f"Current directory files:\n{files}"
except:
return ""
def main():
if len(sys.argv) < 2:
print("Usage: python ai_agent.py \"task description\"")
sys.exit(1)
agent = TerminalAgent()
task = " ".join(sys.argv[1:])
try:
result = agent.process_request(task)
print(result)
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
4. tmux 통합
터미널 세션 관리를 위한 tmux 통합:
# tmux 세션 생성 및 관리 스크립트
# tmux_agent.sh
#!/bin/bash
SESSION_NAME="ai_agent"
if ! tmux has-session -t $SESSION_NAME 2>/dev/null; then
tmux new-session -d -s $SESSION_NAME
fi
# 에이전트 실행
tmux send-keys -t $SESSION_NAME "python ai_agent.py 'Write a Python function to sort a list'" Enter
# enhanced_agent.py
#!/usr/bin/env python3
import subprocess
import os
import sys
class EnhancedTerminalAgent(TerminalAgent):
def run_command(self, command: str) -> str:
"""명령어 실행 후 결과 반환"""
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 get_file_content(self, filename: str) -> str:
"""파일 내용 읽기"""
try:
with open(filename, 'r') as f:
return f.read()
except FileNotFoundError:
return f"File {filename} not found"
def write_file(self, filename: str, content: str) -> str:
"""파일 쓰기"""
try:
with open(filename, 'w') as f:
f.write(content)
return f"File {filename} written successfully"
except Exception as e:
return f"Error writing file: {e}"
# 사용 예시
if __name__ == "__main__":
agent = EnhancedTerminalAgent()
# 파일 내용 확인
if len(sys.argv) > 1:
command = sys.argv[1]
if command == "read_file":
print(agent.get_file_content(sys.argv[2]))
elif command == "write_file":
content = sys.argv[2]
filename = sys.argv[3]
print(agent.write_file(filename, content))
else:
print(agent.process_request(command))
5. 사용자 정의 도구 개발
코드 검색 도구
# search_tool.py
import os
import subprocess
from pathlib import Path
class CodeSearchTool:
def __init__(self, project_root: str = "."):
self.project_root = Path(project_root)
def search_code(self, pattern: str, file_types: list = None) -> list:
"""코드 검색"""
if file_types is None:
file_types = ['*.py', '*.js', '*.ts', '*.java', '*.cpp']
results = []
for file_type in file_types:
try:
cmd = f"find {self.project_root} -name '{file_type}' -type f"
files = subprocess.check_output(cmd, shell=True, text=True).strip().split('\n')
for file_path in files:
if file_path.strip():
with open(file_path, 'r') as f:
content = f.read()
if pattern in content:
results.append({
'file': file_path,
'line': self._find_pattern_line(content, pattern),
'context': self._get_context(content, pattern)
})
except Exception as e:
print(f"Search error: {e}")
return results
def _find_pattern_line(self, content: str, pattern: str) -> int:
lines = content.split('\n')
for i, line in enumerate(lines):
if pattern in line:
return i + 1
return -1
def _get_context(self, content: str, pattern: str, context_lines: int = 3) -> str:
lines = content.split('\n')
for i, line in enumerate(lines):
if pattern in line:
start = max(0, i - context_lines)
end = min(len(lines), i + context_lines + 1)
return '\n'.join(lines[start:end])
return ""
# 사용 예시
searcher = CodeSearchTool()
results = searcher.search_code("def calculate")
for result in results:
print(f"Found in {result['file']}: line {result['line']}")
Git 통합 도구
python
# git_tool.py
import subprocess
import json
class GitTool:
def __init__(self):
pass
def get_git_status(self) -> dict:
"""Git 상태 확인"""
try:
status = subprocess.check_output(['git', 'status', '--porcelain'], text=True)
return {'status': status.strip()}
except:
return {'error': 'Not a git repository'}
def get_last_commit(self) -> dict:
"""최근 커밋 정보"""
try:
commit = subprocess.check_output(['git', 'log', '-1', '--format=%H,%an,%ae,%s'], text=True)
parts = commit.strip().split(',')
return {
'hash': parts[0],
'author': parts[1],
'email': parts[2],
'message': parts[3]
}
except:
return {'error':
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)