터미널 AI 에이전트 구축 (v45)
요약
로컬 환경에서 작동하는 가벼운 터미널 AI 에이전트 구축 방법을 다룹니다. LM Studio를 활용해 로컬 LLM API를 설정하고, Python을 사용하여 코드 리뷰 및 프로젝트 탐색이 가능한 CLI 도구를 만드는 과정을 설명합니다.
핵심 포인트
- 기존 솔루션(Aider, Continue.dev)의 한계 분석
- LM Studio를 이용한 로컬 LLM API 서버 구축
- Python 기반의 커스텀 CLI 에이전트 구현 방법
- 코드 리뷰 및 자동화를 위한 프롬프트 활용
터미널 AI 에이전트 구축 (v45)
터미널에서 작동하는 AI 에이전트는 개발자들에게 강력한 도구가 되지만, 대부분의 기존 솔루션은 복잡하거나 클라우드 기반으로 의존합니다. 이 가이드는 로컬에서 작동하는 가벼운 AI 에이전트를 구축하여 코드 리뷰, 자동완성, 프로젝트 탐색을 수행하는 실용적인 방법을 설명합니다.
1. CLI AI 에이전트 랜드스케이프
기존 솔루션 비교
Aider: GitHub에서 개발한 코드 에이전트로, 코드 변경을 직접 수정합니다. 하지만 GUI 기반으로 구조화되어 있어 터미널에서 사용하기 어려움.
Continue.dev: VSCode 확장 기반의 AI 에이전트. 터미널에서 사용하려면 복잡한 설정 필요.
OpenCode: 코드 기반 LLM 도구로, 로컬 모델 사용 가능하지만 커스터마이즈가 어려움.
사용자 정의 스크립트: 터미널에서 사용 가능한 가장 유연한 방식으로, 필요한 기능만 포함 가능.
2. 로컬 LLM API 엔드포인트 설정
LM Studio를 통한 로컬 LLM 실행
# LM Studio 설치 (macOS)
brew install --cask lm-studio
# 또는 직접 다운로드
# https://lmstudio.ai/
# 로컬 서버 시작 (기본 포트 1234)
lm-studio-server --port 1234
API 서버 테스트
# 테스트 요청
curl -X POST http://localhost:1234/v1/completions \
-H "Content-Type: application/json" \
-d '{
"prompt": "Hello, how are you?",
"max_tokens": 100
}'
3. 간단한 Python CLI 에이전트 구축
기본 에이전트 스크립트
# aider_agent.py
import os
import json
import requests
import argparse
from typing import Dict, List, Any
class TerminalAgent:
def __init__(self, api_url: str = "http://localhost:1234/v1/completions"):
self.api_url = api_url
self.headers = {"Content-Type": "application/json"}
def call_model(self, prompt: str) -> str:
"""로컬 LLM API 호출"""
payload = {
"prompt": prompt,
"max_tokens": 500,
"temperature": 0.7
}
try:
response = requests.post(
self.api_url,
headers=self.headers,
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()['choices'][0]['text']
except Exception as e:
return f"에러 발생: {str(e)}"
def code_review(self, file_path: str) -> str:
"""코드 리뷰 요청"""
with open(file_path, 'r') as f:
code = f.read()
prompt = f"""
다음 코드를 분석하고, 개선 제안을 제공해주세요:
{code}
요청사항:
1. 버그나 문제점
2. 성능 개선 제안
3. 코드 스타일 개선
"""
return self.call_model(prompt)
def generate_docstring(self, function_code: str) -> str:
"""함수 문서화 생성"""
prompt = f"""
다음 함수의 문서화를 생성해주세요:
{function_code}
문서화 형식:
- 함수 설명
- 파라미터 설명
- 반환값 설명
"""
return self.call_model(prompt)
def main():
parser = argparse.ArgumentParser(description="터미널 AI 에이전트")
parser.add_argument("--review", help="리뷰할 파일 경로")
parser.add_argument("--docstring", help="문서화할 함수 코드")
args = parser.parse_args()
agent = TerminalAgent()
if args.review:
result = agent.code_review(args.review)
print("코드 리뷰 결과:")
print(result)
if args.docstring:
result = agent.generate_docstring(args.docstring)
print("문서화 결과:")
print(result)
if __name__ == "__main__":
main()
실행 방법
# 코드 리뷰
python aider_agent.py --review src/main.py
# 문서화 생성
python aider_agent.py --docstring "def hello(name): return f'Hello {name}'"
4. tmux/터미널 멀티플렉서 통합
tmux 세션에 에이전트 통합
# tmux 세션 생성
tmux new-session -d -s ai_agent
# 세션에 명령어 실행
tmux send-keys -t ai_agent "python aider_agent.py --review src/main.py" Enter
# 세션에 명령어 실행 (대화형)
tmux send-keys -t ai_agent "python aider_agent.py" Enter
tmux 스크립트 설정
# ai_session.sh
#!/bin/bash
SESSION="ai_dev"
# 새로운 세션 생성
tmux new-session -d -s $SESSION
# 첫 번째 윈도우: 코드 리뷰
tmux new-window -t $SESSION -n "review"
tmux send-keys -t $SESSION:0 "python aider_agent.py --review" Enter
# 두 번째 윈도우: 코딩
tmux new-window -t $SESSION -n "coding"
tmux send-keys -t $SESSION:1 "vim" Enter
# 세션에 연결
tmux attach -t $SESSION
5. 사용자 정의 도구 개발
코드 검색 도구
# code_search.py
import os
import re
from pathlib import Path
from typing import List, Dict
class CodeSearcher:
def __init__(self, project_root: str):
self.project_root = Path(project_root)
self.ignore_patterns = [
'.git', '__pycache__', '.venv', '.env'
]
def search_functions(self, pattern: str, file_extensions: List[str] = None) -> List[Dict]:
"""함수 검색"""
if file_extensions is None:
file_extensions = ['.py', '.js', '.ts']
results = []
for file_path in self.project_root.rglob('*'):
if file_path.is_file() and file_path.suffix in file_extensions:
if any(ignore in str(file_path) for ignore in self.ignore_patterns):
continue
try:
with open(file_path, 'r') as f:
content = f.read()
# 함수 정의 찾기
function_pattern = rf'def\s+(\w+)\s*\([^)]*\)'
functions = re.findall(function_pattern, content)
if pattern.lower() in file_path.name.lower():
results.append({
'file': str(file_path),
'functions': functions,
'line_count': len(content.split('\n'))
})
except Exception:
continue
return results
def search_imports(self, module_name: str) -> List[str]:
"""모듈 검색"""
results = []
for file_path in self.project_root.rglob('*.py'):
if any(ignore in str(file_path) for ignore in self.ignore_patterns):
continue
try:
with open(file_path, 'r') as f:
content = f.read()
if f'import {module_name}' in content or f'from {module_name}' in content:
results.append(str(file_path))
except Exception:
continue
return results
# 사용 예시
searcher = CodeSearcher('.')
functions = searcher.search_functions('database')
print(json.dumps(functions, indent=2))
Git 연동 도구
python
# git_tools.py
import subprocess
import json
from datetime import datetime
class GitTools:
@staticmethod
def get_recent_commits(limit: int = 5) -> List[Dict]:
"""최근 커밋 정보 가져오기"""
try:
result = subprocess.run(
['git', 'log', f'--max-count={limit}', '--format=%H|%an|%ae|%s|%ad'],
capture_output=True,
text=True,
check=True
)
commits = []
for line in result.stdout.strip().split('\n'):
if line:
parts = line.split('|')
commits.append({
'hash': parts[0],
'author': parts[1],
'email': parts[2],
'message': parts[3],
'date': parts[4]
})
return commits
except subprocess.CalledProcessError:
return []
@staticmethod
def get_branch_status() -> Dict:
"""브랜치 상태 정보"""
try:
#
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기