터미널 AI 에이전트 구축 (v25)
터미널에서 AI를 활용한 개발 흐름을 구축하는 것은 현대 개발자에게 필수적인 기술입니다. 이 가이드에서는 실제 개발자들이 실제로 사용할 수 있는 터미널 AI 에이전트를 구축하는 방법을 단계별로 안내합니다.
1. CLI AI 에이전트 랜드스케이프
현재 터미널 AI 에이전트 시장은 다양합니다:
Aider: GitHub의 오픈소스 에이전트로, VS Code와 같은 IDE에서 사용할 수 있습니다. 하지만 명령줄에서 사용하기에는 제한적입니다.
Continue.dev: VS Code 확장 프로그램으로, 터미널에서 직접 작동하지 않습니다.
OpenCode: GitHub에서 제공하는 LLM 기반 코드 생성 도구로, API 기반 접근이 필요합니다.
커스텀 스크립트: 가장 유연한 접근 방식으로, 필요에 맞게 정확하게 커스터마이징 가능합니다.
# 현재 터미널에서 사용 가능한 대안들 확인
pip install aider
pip install openai
2. 로컬 LLM API 엔드포인트 설정
로컬에서 LLM을 실행하여 빠르고 안전하게 작업을 수행하려면 로컬 API 서버를 설정해야 합니다.
# GGUF 모델 다운로드 및 실행
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
# 로컬 서버 실행
./server -m ./mistral-7b-v0.1.Q4_K_M.gguf -c 2048 --host 127.0.0.1 --port 8080
# api_client.py - 로컬 API 클라이언트
import requests
import json
class LocalLLMClient:
def __init__(self, base_url="http://127.0.0.1:8080"):
self.base_url = base_url
def generate(self, prompt, max_tokens=500):
response = requests.post(
f"{self.base_url}/completion",
json={
"prompt": prompt,
"max_tokens": max_tokens,
"temperature": 0.7
}
)
return response.json()['content']
# 사용 예시
client = LocalLLMClient()
result = client.generate("Hello, world!")
3. 함수 호출 기능이 있는 간단한 Python CLI 에이전트
# ai_agent.py
import subprocess
import json
import sys
from typing import Dict, Any
class TerminalAgent:
def __init__(self):
self.llm = LocalLLMClient()
def execute_command(self, command: str) -> str:
"""명령어 실행 및 결과 반환"""
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True
)
return result.stdout + result.stderr
except Exception as e:
return f"Error: {str(e)}"
def analyze_code(self, file_path: str) -> str:
"""코드 분석"""
with open(file_path, 'r') as f:
code = f.read()
prompt = f"""
Analyze the following code and provide:
1. Code quality assessment
2. Potential bugs or improvements
3. Performance suggestions
Code:
{code}
"""
return self.llm.generate(prompt, max_tokens=1000)
def generate_test(self, file_path: str) -> str:
"""테스트 코드 생성"""
with open(file_path, 'r') as f:
code = f.read()
prompt = f"""
Generate unit tests for this code:
{code}
"""
return self.llm.generate(prompt, max_tokens=1000)
# CLI 사용법
if __name__ == "__main__":
agent = TerminalAgent()
if len(sys.argv) > 1:
action = sys.argv[1]
if action == "analyze":
print(agent.analyze_code(sys.argv[2]))
elif action == "test":
print(agent.generate_test(sys.argv[2]))
4. tmux/터미널 멀티플렉서 통합
# tmux 세션 생성 및 스크립트 실행
tmux new-session -d -s ai_agent
tmux send-keys -t ai_agent 'python ai_agent.py' Enter
# terminal_integration.py
import os
import subprocess
import json
class TerminalIntegration:
def __init__(self):
self.tmux_session = "ai_agent"
def create_tmux_session(self):
"""tmux 세션 생성"""
subprocess.run([
'tmux', 'new-session', '-d', '-s', self.tmux_session
])
def send_to_tmux(self, command: str):
"""tmux 세션에 명령어 전송"""
subprocess.run([
'tmux', 'send-keys', '-t', self.tmux_session, command, 'Enter'
])
def get_tmux_output(self):
"""tmux 세션 출력 가져오기"""
result = subprocess.run([
'tmux', 'capture-pane', '-p', '-t', self.tmux_session
], capture_output=True, text=True)
return result.stdout
# 사용 예시
integration = TerminalIntegration()
integration.create_tmux_session()
5. 커스텀 도구 개발
# custom_tools.py
import os
import subprocess
from pathlib import Path
class CodeSearchTool:
def __init__(self, project_root: str):
self.project_root = Path(project_root)
def find_files_by_extension(self, extension: str) -> list:
"""확장자별 파일 찾기"""
files = list(self.project_root.rglob(f"*.{extension}"))
return [str(f) for f in files]
def search_in_files(self, pattern: str, file_extensions: list = None) -> dict:
"""파일 내에서 패턴 검색"""
results = {}
if file_extensions:
files = []
for ext in file_extensions:
files.extend(self.project_root.rglob(f"*.{ext}"))
else:
files = self.project_root.rglob("*")
for file_path in files:
if file_path.is_file():
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if pattern in content:
results[str(file_path)] = self.extract_context(content, pattern)
except Exception:
continue
return results
def extract_context(self, content: str, pattern: str, context_lines: int = 3) -> list:
"""패턴 주변의 문맥 추출"""
lines = content.split('\n')
matches = []
for i, line in enumerate(lines):
if pattern in line:
start = max(0, i - context_lines)
end = min(len(lines), i + context_lines + 1)
matches.append({
'line_number': i + 1,
'context': lines[start:end]
})
return matches
# Git 통합 도구
class GitTool:
def __init__(self):
pass
def get_changed_files(self) -> list:
"""변경된 파일 목록 가져오기"""
result = subprocess.run(
['git', 'diff', '--name-only', 'HEAD~1', 'HEAD'],
capture_output=True, text=True
)
return result.stdout.strip().split('\n') if result.stdout.strip() else []
def get_git_log(self, limit: int = 5) -> str:
"""Git 로그 가져오기"""
result = subprocess.run(
['git', 'log', f'-{limit}', '--oneline'],
capture_output=True, text=True
)
return result.stdout
6. 대용량 코드베이스를 위한 컨텍스트 창 관리
python
# context_manager.py
import hashlib
from typing import List, Dict
class ContextManager:
def __init__(self, max_context_tokens: int = 4000):
self.max_context_tokens = max_context_tokens
self.context_cache = {}
def add_file_context(self, file_path: str, content: str) -> str:
"""파일 컨텍스트 추가"""
file_hash = hashlib.md5(file_path.encode()).hexdigest()
self.context_cache[file_hash] = {
'path': file_path,
'content': content,
'tokens': self.estimate_tokens(content)
}
return file_hash
def get_context_window(self, file_hashes: List[str]) -> str:
"""컨텍스트 창 구성"""
window_content = ""
total
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)