터미널 AI 에이전트 구축 (v23)
터미널에서 AI를 활용한 개발 도구는 점점 더 인기를 끌고 있습니다. 오픈소스 커뮤니티와 전문 개발자들 사이에서 로컬 LLM 추론과 자가 호스팅 AI 솔루션에 대한 관심이 높아지고 있습니다. 이 가이드에서는 터미널 내에서 작동하는 AI 에이전트를 구축하는 실용적인 방법을 제공합니다.
1. CLI AI 에이전트 생태계
현재 CLI AI 에이전트의 주요 도구들:
- Aider: GitHub Copilot과 유사하지만 로컬에서 실행되는 에이전트. Python, JavaScript, Go 등 다양한 언어 지원
- Continue.dev: VSCode 확장과 유사한 터미널 기반 개발 환경
- OpenCode: OpenAI API 기반의 코드 생성 도구
- 사용자 정의 스크립트: 자신만의 커스텀 에이전트 생성
# Aider 설치
pip install aider-chat
# 사용 예시
aider --help
2. 로컬 LLM API 엔드포인트 설정
로컬 LLM을 사용하기 위해 FastAPI 기반 API 서버를 구축:
# server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
app = FastAPI()
model_name = "TheBloke/Llama-2-7B-Chat-GGUF"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
class PromptRequest(BaseModel):
prompt: str
max_tokens: int = 256
@app.post("/generate")
async def generate_text(request: PromptRequest):
try:
inputs = tokenizer(request.prompt, return_tensors="pt")
outputs = model.generate(
inputs.input_ids,
max_new_tokens=request.max_tokens,
temperature=0.7,
do_sample=True
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
return {"response": response}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
# 실행 명령
pip install fastapi uvicorn transformers torch
python server.py
3. 간단한 Python CLI 에이전트 구축
기본 기능을 갖춘 CLI 에이전트 구현:
# ai_agent.py
import requests
import json
import subprocess
import os
from pathlib import Path
class TerminalAgent:
def __init__(self, api_url="http://localhost:8000"):
self.api_url = api_url
def generate_code(self, prompt, context=""):
full_prompt = f"{context}\n\n{prompt}"
response = requests.post(
f"{self.api_url}/generate",
json={"prompt": full_prompt, "max_tokens": 512}
)
return response.json()["response"]
def execute_command(self, command):
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30
)
return result.stdout + result.stderr
except subprocess.TimeoutExpired:
return "Command timed out"
def save_to_file(self, content, filename):
with open(filename, 'w') as f:
f.write(content)
print(f"Saved to {filename}")
# 사용 예시
if __name__ == "__main__":
agent = TerminalAgent()
# 코드 생성
prompt = "Python으로 Flask 앱을 생성하려고 해요. 루트 페이지는 'Hello World'를 출력하고, /api/users는 JSON 데이터를 반환합니다."
generated_code = agent.generate_code(prompt)
agent.save_to_file(generated_code, "app.py")
print("생성된 코드:")
print(generated_code)
# 실행
python ai_agent.py
4. tmux와 통합
터미널 다중화를 활용한 개발 환경 구축:
# tmux 세션 생성
tmux new-session -d -s ai_dev
# 세션에 명령 실행
tmux send-keys -t ai_dev "python ai_agent.py" Enter
# 세션에 코드 에디터 열기
tmux send-keys -t ai_dev "code app.py" Enter
# 세션에 터미널 탭 추가
tmux split-window -h -t ai_dev
tmux send-keys -t ai_dev:0 "ls -la" Enter
# tmux_integration.py
import subprocess
import json
class TmuxAgent(TerminalAgent):
def __init__(self, session_name="ai_dev"):
super().__init__()
self.session_name = session_name
def create_session(self):
subprocess.run(["tmux", "new-session", "-d", "-s", self.session_name])
def create_window(self, window_name):
subprocess.run(["tmux", "new-window", "-n", window_name])
def send_command(self, command, window_index=0):
subprocess.run([
"tmux", "send-keys", "-t", f"{self.session_name}:{window_index}",
command, "Enter"
])
def attach_session(self):
subprocess.run(["tmux", "attach-session", "-t", self.session_name])
# 사용 예시
agent = TmuxAgent("my_ai_project")
agent.create_session()
agent.create_window("editor")
agent.send_command("code app.py")
5. 사용자 정의 도구 개발
Git과 파일 시스템 통합:
# custom_tools.py
import subprocess
import os
import json
from pathlib import Path
class CodeTools:
@staticmethod
def search_code(pattern, directory="."):
"""코드 검색 도구"""
try:
result = subprocess.run(
["grep", "-r", pattern, directory],
capture_output=True,
text=True,
cwd=directory
)
return result.stdout.strip()
except Exception as e:
return f"Error: {str(e)}"
@staticmethod
def get_git_status():
"""Git 상태 확인"""
try:
result = subprocess.run(
["git", "status", "--porcelain"],
capture_output=True,
text=True
)
return result.stdout.strip()
except Exception as e:
return f"Error: {str(e)}"
@staticmethod
def list_files(directory=".", pattern="*"):
"""파일 목록 조회"""
try:
result = subprocess.run(
["find", directory, "-name", pattern],
capture_output=True,
text=True
)
return result.stdout.strip().split('\n')
except Exception as e:
return [f"Error: {str(e)}"]
# 확장된 에이전트
class EnhancedAgent(TerminalAgent):
def __init__(self, api_url="http://localhost:8000"):
super().__init__(api_url)
self.tools = CodeTools()
def search_and_generate(self, search_pattern, prompt):
"""검색 결과를 기반으로 코드 생성"""
search_result = self.tools.search_code(search_pattern)
context = f"Search results:\n{search_result}\n\n"
return self.generate_code(prompt, context)
def get_project_info(self):
"""프로젝트 정보 수집"""
git_status = self.tools.get_git_status()
files = self.tools.list_files(".")
return {
"git_status": git_status,
"file_count": len(files),
"files": files[:10] # 최대 10개만 표시
}
6. 컨텍스트 윈도우 관리
대형 코드베이스에서의 메모리 최적화:
python
# context_manager.py
import os
import hashlib
from typing import List, Dict
import pickle
class ContextManager:
def __init__(self, max_context_size=10000):
self.max_context_size = max_context_size
self.context_cache = {}
def hash_content(self, content: str) -> str:
return hashlib.md5(content.encode()).hexdigest()
def add_context(self, key: str, content: str):
"""컨텍스트 추가 및 크기 제한"""
if len(content) > self.max_context_size:
content = content[:self.max_context_size]
self.context_cache[key] = content
def get_context(self, keys: List[str]) -> str:
"""지정된 키들의 컨텍스트 결합"""
combined_context = []
for key in keys:
if key in self.context_cache:
combined_context.append(f"## {key}\n
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)