터미널 AI 에이전트 구축 (v15)
터미널에서 직접 작동하는 AI 에이전트를 구축하는 것은 현대 개발자의 생산성을 높이는 가장 효과적인 방법 중 하나입니다. 이 가이드에서는 개발자가 직접 구축할 수 있는 로컬 LLM 기반 CLI AI 에이전트를 구축하는 방법을 설명합니다.
1. CLI AI 에이전트 생태계
현재 CLI 기반 AI 에이전트 생태계는 다음과 같은 주요 도구들로 구성되어 있습니다:
Aider
가장 인기 있는 도구 중 하나로, Git 기반 코드 수정을 지원합니다.
pip install aider
aider --help
Continue.dev
VS Code 확장으로 개발되었지만, CLI 버전도 제공됩니다.
npm install -g continue
continue --help
OpenCode
Python 기반으로 구축된 로컬 AI 에이전트입니다.
pip install opencode
opencode --help
사용자 정의 스크립트
가장 유연한 접근 방식으로, 자신의 필요에 맞춘 에이전트를 직접 구축할 수 있습니다.
2. 로컬 LLM API 엔드포인트 설정
로컬 LLM을 사용하여 높은 성능과 낮은 지출로 AI 에이전트를 구축하려면 로컬 API 엔드포인트를 설정해야 합니다.
LM Studio 설치 및 실행
# macOS
brew install lm-studio
# Linux
wget https://github.com/lmstudio/lm-studio/releases/latest/download/LM-Studio-0.2.5-linux-x86_64.deb
sudo dpkg -i LM-Studio-0.2.5-linux-x86_64.deb
# 시작
lm-studio
LocalAI로 API 서버 실행
# LocalAI 설치
git clone https://github.com/go-skynet/LocalAI.git
cd LocalAI
# Docker로 실행 (권장)
docker run -p 8080:8080 -v $(pwd)/models:/models localai/localai:latest
# 또는 로컬에서 직접 실행
make build
./local-ai server
3. 간단한 Python CLI 에이전트 구축
이제 로컬 LLM API에 연결하는 간단한 Python CLI 에이전트를 만들어보겠습니다.
# ai_agent.py
import os
import json
import requests
import argparse
from typing import Dict, List, Any
class TerminalAIAgent:
def __init__(self, api_url: str = "http://localhost:8080/v1/chat/completions"):
self.api_url = api_url
self.headers = {"Content-Type": "application/json"}
def chat(self, prompt: str, context: str = "") -> str:
"""LLM에 요청을 보내 응답을 받습니다"""
messages = [
{"role": "system", "content": "You are a helpful coding assistant. Respond in Markdown."}
]
if context:
messages.append({"role": "user", "content": f"Context: {context}"})
messages.append({"role": "user", "content": prompt})
data = {
"model": "ggml-model.bin", # 또는 사용하는 모델 이름
"messages": messages,
"temperature": 0.7,
"max_tokens": 1024
}
try:
response = requests.post(
self.api_url,
headers=self.headers,
json=data,
timeout=30
)
response.raise_for_status()
return response.json()['choices'][0]['message']['content']
except Exception as e:
return f"Error: {str(e)}"
def run(self, prompt: str, context: str = "") -> None:
"""에이전트 실행"""
print(f"Prompt: {prompt}")
response = self.chat(prompt, context)
print(response)
def main():
parser = argparse.ArgumentParser(description='Terminal AI Agent')
parser.add_argument('--prompt', '-p', required=True, help='Prompt to send to AI')
parser.add_argument('--context', '-c', help='Context information')
parser.add_argument('--api-url', default="http://localhost:8080/v1/chat/completions",
help='API endpoint URL')
args = parser.parse_args()
agent = TerminalAIAgent(api_url=args.api_url)
agent.run(args.prompt, args.context)
if __name__ == "__main__":
main()
실행 방법:
python ai_agent.py --prompt "Python에서 Flask 애플리케이션을 만드는 방법을 설명해주세요."
4. tmux와 통합
터미널 세션 관리를 위해 tmux와 통합하는 방법을 살펴보겠습니다.
# tmux 설치
sudo apt install tmux # Ubuntu/Debian
brew install tmux # macOS
# 새 세션 생성
tmux new-session -s ai-agent
# 세션에 연결
tmux attach -t ai-agent
tmux 스크립트 생성
# ai_session.sh
#!/bin/bash
SESSION="ai-agent"
# 새 세션 생성
tmux new-session -d -s $SESSION
# 첫 번째 윈도우 생성
tmux new-window -t $SESSION:1 -n "agent"
# 두 번째 윈도우 생성 (파일 탐색)
tmux new-window -t $SESSION:2 -n "files"
# 세 번째 윈도우 생성 (에이전트 테스트)
tmux new-window -t $SESSION:3 -n "test"
# 윈도우 전환
tmux select-window -t $SESSION:1
# 세션에 연결
tmux attach -t $SESSION
실행:
chmod +x ai_session.sh
./ai_session.sh
5. 사용자 정의 도구 개발
코드 검색 도구
# code_search.py
import os
import subprocess
import re
from typing import List
class CodeSearchTool:
def __init__(self, root_dir: str = "."):
self.root_dir = root_dir
def search_in_files(self, pattern: str, file_types: List[str] = None) -> List[str]:
"""파일 내에서 패턴 검색"""
if file_types is None:
file_types = [".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_types):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
matches = re.finditer(pattern, content)
for match in matches:
results.append({
'file': file_path,
'line': content[:match.start()].count('\n') + 1,
'match': match.group()
})
except Exception as e:
continue
return results
def search_code(self, query: str) -> str:
"""코드 검색 결과를 포맷팅하여 반환"""
results = self.search_in_files(query)
if not results:
return f"No results found for '{query}'"
formatted_results = [f"\nFile: {r['file']} (line {r['line']})" for r in results[:5]]
return "\n".join(formatted_results) + f"\n... and {len(results) - 5} more results"
# 사용 예
search_tool = CodeSearchTool()
print(search_tool.search_code("def main"))
Git 통합 도구
python
# git_tool.py
import subprocess
import json
from typing import Dict, List
class GitTool:
def __init__(self):
pass
def get_git_status(self) -> Dict:
"""Git 상태 정보 가져오기"""
try:
status = subprocess.run(['git', 'status', '--porcelain'],
capture_output=True, text=True)
return {
'status': status.stdout.strip(),
'has_changes': bool(status.stdout.strip())
}
except Exception as e:
return {'error': str(e)}
def get_recent_commits(self, count: int = 5) -> List[Dict]:
"""최근 커밋 목록 가져오기"""
try:
result = subprocess.run([
'git', 'log', f'-{count}', '--oneline', '--no-color'
], capture_output=True, text=True)
commits = []
for line in result.stdout.strip().split('\n'):
if line:
parts = line.split(' ', 1)
commits.append({
'hash': parts[0],
'message': parts[1] if len(parts) > 1 else ''
})
return commits
except Exception as e:
return [{'error': str(e)}]
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)