터미널 AI 에이전트 구축 (v27)
터미널에서 작동하는 AI 에이전트를 구축하는 것은 현대 개발자에게 매우 실용적인 도구입니다. 이 가이드에서는 실제 개발 workflow에 통합할 수 있는 로컬 LLM 기반 CLI 에이전트를 구축하는 방법을 설명합니다.
1. CLI AI 에이전트 생태계
현재 CLI AI 에이전트 시장에는 여러 선택지가 있습니다:
Aider: Git 기반 코드 수정을 위한 간단한 에이전트
pip install aider
aider --help
Continue.dev: VSCode 확장으로도 사용 가능하지만 CLI 버전도 존재
npm install -g continue
continue --help
OpenCode: 오픈소스 CLI 에이전트로 커스터마이징이 용이
git clone https://github.com/open-code/open-code
커스텀 스크립트: 최대한의 유연성을 위해 직접 구현
# simple-agent.py
import openai
import os
def main():
client = openai.Client(api_key=os.getenv("OPENAI_API_KEY"))
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[{"role": "user", "content": "Hello"}]
)
print(response.choices[0].message.content)
2. 로컬 LLM API 엔드포인트 설정
로컬 LLM을 사용하여 비용과 보안 문제를 해결할 수 있습니다. LM Studio 또는 Ollama를 사용하는 것을 추천합니다.
Ollama 설치 및 실행:
# Ubuntu/Debian
curl -fsSL https://ollama.com/install.sh | sh
# 시작
ollama serve
# 모델 다운로드
ollama pull llama3.2:3b
ollama pull codestral:22b
로컬 API 서버 구성:
# ollama-config.yaml
model: llama3.2:3b
host: 0.0.0.0
port: 11434
# API 서버 시작
ollama serve -c ollama-config.yaml
3. 간단한 Python CLI 에이전트 구축
#!/usr/bin/env python3
# ai-agent.py
import openai
import os
import json
import argparse
from pathlib import Path
class TerminalAgent:
def __init__(self):
# 로컬 Ollama 사용
self.client = openai.OpenAI(
base_url="http://localhost:11434/v1/",
api_key="ollama"
)
self.model = "llama3.2:3b"
def get_context(self):
"""현재 디렉토리의 코드 컨텍스트를 수집"""
context = []
# 현재 디렉토리 파일 목록
current_dir = Path(".")
for file_path in current_dir.rglob("*"):
if file_path.is_file() and file_path.suffix in ['.py', '.js', '.ts', '.html', '.css']:
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
context.append(f"File: {file_path}\n{content[:500]}...")
except Exception as e:
context.append(f"File: {file_path} - Error reading file")
return "\n\n".join(context)
def analyze_code(self, code_snippet, task):
"""코드 분석 및 제안"""
prompt = f"""
Analyze the following code and provide suggestions:
Task: {task}
Code:
{code_snippet}
Please provide:
1. Code quality assessment
2. Performance improvements
3. Security considerations
4. Best practices
"""
response = self.client.chat.completions.create(
model=self.model,
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
return response.choices[0].message.content
def main():
parser = argparse.ArgumentParser(description='Terminal AI Agent')
parser.add_argument('--analyze', help='Analyze specific code snippet')
parser.add_argument('--task', help='Task description for analysis')
parser.add_argument('--file', help='File to analyze')
args = parser.parse_args()
agent = TerminalAgent()
if args.file:
with open(args.file, 'r') as f:
code = f.read()
result = agent.analyze_code(code, args.task or "Code review")
print(result)
elif args.analyze:
result = agent.analyze_code(args.analyze, args.task or "Code review")
print(result)
else:
print("Usage: python ai-agent.py --file <filename> --task 'task description'")
print("OR: python ai-agent.py --analyze 'code snippet' --task 'task description'")
if __name__ == "__main__":
main()
4. tmux와 통합
tmux 세션에서 에이전트를 사용하면 작업 흐름을 더욱 효율적으로 관리할 수 있습니다.
# tmux 세션 생성
tmux new-session -s ai-agent -d
# 세션 내에서 에이전트 실행
tmux send-keys -t ai-agent "python ai-agent.py --file main.py --task 'Optimize database queries'" Enter
# 세션에 연결
tmux attach -t ai-agent
tmux 스크립트 (tmux-agent.sh):
#!/bin/bash
# tmux-agent.sh
SESSION="ai-agent"
WINDOW="code-review"
# 세션 존재 여부 확인
if ! tmux has-session -t $SESSION 2>/dev/null; then
tmux new-session -d -s $SESSION -n $WINDOW
fi
# 현재 작업 디렉토리에서 실행
tmux send-keys -t $SESSION:$WINDOW "cd $(pwd) && python ai-agent.py --file $1 --task '$2'" Enter
5. 사용자 정의 도구 개발
다음은 몇 가지 유용한 커스텀 도구입니다:
코드 검색 도구 (code-search.py):
#!/usr/bin/env python3
import os
import re
from pathlib import Path
class CodeSearcher:
def __init__(self, root_dir="."):
self.root_dir = Path(root_dir)
def search_functions(self, pattern):
"""함수 정의 검색"""
results = []
for py_file in self.root_dir.rglob("*.py"):
with open(py_file, 'r') as f:
content = f.read()
# 함수 정의 찾기
func_pattern = rf'def\s+({pattern})\s*\('
matches = re.finditer(func_pattern, content)
for match in matches:
line_num = content[:match.start()].count('\n') + 1
results.append({
'file': str(py_file),
'function': match.group(1),
'line': line_num
})
return results
def search_patterns(self, pattern):
"""일반 패턴 검색"""
results = []
for file_path in self.root_dir.rglob("*"):
if file_path.is_file() and file_path.suffix in ['.py', '.js', '.ts']:
try:
with open(file_path, 'r') as f:
content = f.read()
matches = re.finditer(pattern, content)
for match in matches:
line_num = content[:match.start()].count('\n') + 1
results.append({
'file': str(file_path),
'match': match.group(),
'line': line_num
})
except Exception:
continue
return results
# 사용법
searcher = CodeSearcher(".")
functions = searcher.search_functions(r"test_.*")
print(json.dumps(functions, indent=2))
Git 통합 도구 (git-tools.py):
import subprocess
import json
class GitTools:
@staticmethod
def get_changed_files():
"""변경된 파일 목록 가져오기"""
try:
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 []
except Exception as e:
return []
@staticmethod
def get_git_history():
"""Git 히스토리 가져오기"""
try:
result = subprocess.run(
['git', 'log', '--oneline', '-10'],
capture_output=True, text=True
)
return result.stdout.strip().split('\n')
except Exception as e:
return []
# 사용법
git_tool = GitTools()
changed_files = git_tool.get_changed_files()
print("Changed files:", changed_files)
6. 컨텍스트 창 관리
대규모
📥 Get the full guide on Gumroad: https://gumroad.com/l/auto ($5)
Top comments (0)