터미널 AI 에이전트 구축 (v37)
터미널에서 AI 에이전트를 구축하는 것은 개발자에게 매우 실용적인 도구를 제공합니다. 이 가이드는 로컬 LLM을 활용한 CLI AI 에이전트를 구축하고, 실전 워크플로우에 적용하는 방법을 단계별로 설명합니다.
1. CLI AI 에이전트 생태계
현재 CLI AI 에이전트는 여러 형태로 존재합니다:
Aider: GitHub에서 개발된 코드 생성 도구로, 실제 파일에 직접 수정을 적용하는 기능이 강점입니다.
Continue.dev: VSCode 확장 프로그램이지만, 터미널에서도 사용 가능한 커스터마이징 가능한 에이전트입니다.
OpenCode: 직접 구축한 AI 에이전트로, 빠르고 간단한 커스터마이징이 가능합니다.
커스텀 스크립트: 가장 유연한 접근 방식으로, 특정 워크플로우에 맞춘 로직을 직접 구현할 수 있습니다.
2. 로컬 LLM API 엔드포인트 설정
먼저 로컬 LLM 서버를 실행해야 합니다. 이 예제에서는 LLaMA.cpp를 사용하겠습니다:
# 1. LLaMA.cpp 설치
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make
# 2. 모델 다운로드 및 변환
wget https://huggingface.co/TheBloke/Mistral-7B-v0.1-GGUF/resolve/main/mistral-7b-v0.1.Q4_K_M.gguf
# 3. 로컬 서버 시작
./server -m mistral-7b-v0.1.Q4_K_M.gguf -c 2048 --host 127.0.0.1 --port 1234
API 엔드포인트를 테스트하기 위해 curl 명령어를 사용합니다:
curl http://localhost:1234/v1/completions \
-H "Content-Type: application/json" \
-d '{
"prompt": "Write a Python function that calculates fibonacci numbers",
"max_tokens": 200,
"temperature": 0.7
}'
3. 간단한 Python CLI 에이전트 만들기
다음은 함수 호출 기능을 포함한 기초적인 Python CLI 에이전트입니다:
# agent.py
import requests
import json
import subprocess
import sys
class TerminalAgent:
def __init__(self, api_url="http://localhost:1234/v1/completions"):
self.api_url = api_url
def call_model(self, prompt, max_tokens=300):
"""LLM API 호출"""
headers = {"Content-Type": "application/json"}
data = {
"prompt": prompt,
"max_tokens": max_tokens,
"temperature": 0.3
}
response = requests.post(self.api_url, headers=headers, data=json.dumps(data))
return response.json()['choices'][0]['text'].strip()
def execute_command(self, command):
"""명령어 실행 및 결과 반환"""
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as e:
return f"Error: {e.stderr}"
def run(self, task):
"""주어진 작업을 실행"""
print(f"작업 요청: {task}")
# 작업 분석 및 분할
analysis_prompt = f"""
다음 작업을 분석하고 필요한 단계를 나열해주세요:
{task}
단계별로 JSON 형식으로 응답해주세요:
{{
"steps": ["step1", "step2", ...],
"summary": "작업 요약"
}}
"""
analysis = self.call_model(analysis_prompt, 150)
print(f"분석 결과: {analysis}")
# 각 단계별 실행
for i, step in enumerate(json.loads(analysis).get("steps", [])):
print(f"\n단계 {i+1}: {step}")
result = self.execute_command(step)
print(f"결과: {result}")
if __name__ == "__main__":
agent = TerminalAgent()
task = "Python으로 주어진 디렉토리 내 모든 .py 파일을 찾아서 'print('Hello World')'를 추가해주세요"
agent.run(task)
실행 방법:
python agent.py
4. tmux와 통합
tmux를 사용하여 에이전트가 작업을 수행하는 동안 터미널 세션을 유지하고, 다른 작업을 병행할 수 있습니다:
# tmux 세션 생성
tmux new-session -s ai_agent -d
# 에이전트 실행
tmux send-keys -t ai_agent "python agent.py" Enter
# 세션에 연결
tmux attach -t ai_agent
다음은 tmux 세션을 관리하는 스크립트입니다:
# tmux_helper.py
import subprocess
import os
class TmuxHelper:
def __init__(self, session_name="ai_agent"):
self.session_name = session_name
def create_session(self):
"""새 tmux 세션 생성"""
cmd = f"tmux new-session -s {self.session_name} -d"
subprocess.run(cmd, shell=True, check=True)
def send_command(self, command):
"""세션에 명령어 전송"""
cmd = f"tmux send-keys -t {self.session_name} '{command}' Enter"
subprocess.run(cmd, shell=True, check=True)
def attach(self):
"""세션 연결"""
cmd = f"tmux attach -t {self.session_name}"
subprocess.run(cmd, shell=True, check=True)
def kill_session(self):
"""세션 종료"""
cmd = f"tmux kill-session -t {self.session_name}"
subprocess.run(cmd, shell=True, check=True)
# 사용 예시
if __name__ == "__main__":
helper = TmuxHelper("my_ai")
helper.create_session()
helper.send_command("python agent.py")
5. 커스텀 도구 개발
다음은 코드 검색, git 연동, 파일 작업을 위한 커스텀 도구들입니다:
# tools.py
import os
import subprocess
import json
import re
class CodeSearchTool:
@staticmethod
def find_files(directory, extension=".py"):
"""지정된 확장자 파일 찾기"""
files = []
for root, dirs, filenames in os.walk(directory):
for filename in filenames:
if filename.endswith(extension):
files.append(os.path.join(root, filename))
return files
@staticmethod
def grep_in_files(pattern, files):
"""파일 내에서 패턴 검색"""
results = {}
for file_path in files:
try:
with open(file_path, 'r') as f:
content = f.read()
matches = re.findall(pattern, content)
if matches:
results[file_path] = matches
except Exception as e:
print(f"Error reading {file_path}: {e}")
return results
class GitTool:
@staticmethod
def get_git_status():
"""Git 상태 확인"""
result = subprocess.run(["git", "status", "--porcelain"],
capture_output=True, text=True)
return result.stdout.strip()
@staticmethod
def git_diff():
"""Git diff 출력"""
result = subprocess.run(["git", "diff"],
capture_output=True, text=True)
return result.stdout
class FileOperationTool:
@staticmethod
def create_directory(path):
"""디렉토리 생성"""
os.makedirs(path, exist_ok=True)
return f"Directory {path} created"
@staticmethod
def read_file(path):
"""파일 읽기"""
try:
with open(path, 'r') as f:
return f.read()
except Exception as e:
return f"Error reading {path}: {e}"
@staticmethod
def write_file(path, content):
"""파일 쓰기"""
try:
with open(path, 'w') as f:
f.write(content)
return f"File {path} written successfully"
except Exception as e:
return f"Error writing {path}: {e}"
# 사용 예시
if __name__ == "__main__":
search_tool = CodeSearchTool()
files = search_tool.find_files(".", ".py")
print(f"Found {len(files)} Python files")
git_tool = GitTool()
print("Git status:", git_tool.get_git_status())
6. 컨텍스트 윈도우 관리
대규모 코드베이스에서 성능을 최적화하기 위해 컨텍스트 윈도우를 관리해야 합니다:
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)