터미널 AI 에이전트 구축 (v16)
터미널에서 직접 작동하는 AI 에이전트를 구축하는 것은 현대 개발자에게 매우 실용적인 도구입니다. 이 가이드는 개발자가 직접 자신의 터미널 환경에서 효율적인 AI 코딩 어시스턴트를 구축하는 방법을 설명합니다.
1. CLI AI 에이전트 생태계
현재 CLI 기반 AI 에이전트는 다음과 같은 주요 플랫폼이 있습니다:
Aider: Git 기반의 코딩 에이전트로, 코드 변경 사항을 자동으로 추적합니다.
pip install aider
aider --help
Continue.dev: VSCode 확장이지만 CLI도 지원합니다.
npm install -g continue
continue --help
OpenCode: 개방형 오픈소스 CLI 에이전트입니다.
pip install opencode
opencode --help
사용자 정의 스크립트: 최소한의 코드로 자신만의 에이전트를 만들 수 있습니다.
2. 로컬 LLM API 엔드포인트 설정
로컬 LLM을 위한 API 엔드포인트를 설정하여 빠른 응답 속도를 얻습니다:
# llm-api.yaml
api:
port: 8000
host: 0.0.0.0
model:
path: ./models/gemma-2b-it-Q4_K_M.gguf
context: 4096
gpu_layers: 32
# server.py
from fastapi import FastAPI, Request
import llama_cpp
import json
app = FastAPI()
model = llama_cpp.Llama(
model_path="./models/gemma-2b-it-Q4_K_M.gguf",
n_gpu_layers=32,
n_ctx=4096
)
@app.post("/v1/chat/completions")
async def chat_completion(request: Request):
body = await request.json()
prompt = body['messages'][-1]['content']
response = model(
prompt,
max_tokens=512,
temperature=0.7,
stop=["</s>"]
)
return {
"choices": [{
"message": {
"content": response['choices'][0]['text']
}
}]
}
시작 명령어:
python server.py
3. 간단한 Python CLI 에이전트 구축
기본적인 기능을 갖춘 CLI 에이전트를 구축합니다:
# ai_agent.py
import openai
import json
import subprocess
import sys
from typing import Dict, List
class TerminalAgent:
def __init__(self, api_base: str = "http://localhost:8000"):
self.client = openai.OpenAI(
base_url=api_base,
api_key="EMPTY"
)
def get_context(self) -> str:
"""현재 디렉토리의 파일 목록과 git 상태를 가져옴"""
files = subprocess.run(["ls", "-la"], capture_output=True, text=True)
git_status = subprocess.run(["git", "status", "--porcelain"],
capture_output=True, text=True)
return f"""
Files in current directory:
{files.stdout}
Git status:
{git_status.stdout}
"""
def query(self, prompt: str) -> str:
"""LLM에게 질문을 하고 응답을 받음"""
response = self.client.chat.completions.create(
model="gemma",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": f"{prompt}\nContext: {self.get_context()}"}
],
max_tokens=1024,
temperature=0.7
)
return response.choices[0].message.content
# 사용법
if __name__ == "__main__":
agent = TerminalAgent()
prompt = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Help me understand this code"
print(agent.query(prompt))
사용 예시:
python ai_agent.py "Explain how this function works"
4. tmux와 통합
터미널 멀티플렉서와 통합하여 더 나은 개발 환경을 제공합니다:
# tmux 설정 추가 (.tmux.conf)
bind-key C-a send-keys 'aider' Enter
bind-key C-b send-keys 'continue' Enter
# 새로운 창 만들기
tmux new-window -n 'ai-agent'
tmux send-keys 'python ai_agent.py' Enter
# tmux_integration.py
import subprocess
import os
class TmuxIntegrator:
@staticmethod
def create_window(window_name: str, command: str):
"""새로운 tmux 창 생성"""
subprocess.run([
"tmux", "new-window", "-n", window_name,
"bash", "-c", f"{command}; exec bash"
])
@staticmethod
def send_to_window(window_name: str, command: str):
"""특정 창에 명령어 전송"""
subprocess.run([
"tmux", "send-keys", "-t", window_name, command, "Enter"
])
# 사용 예시
integrator = TmuxIntegrator()
integrator.create_window("coding", "python ai_agent.py")
5. 사용자 정의 도구 개발
다양한 개발 작업을 위한 도구를 구축합니다:
# tools.py
import subprocess
import os
from typing import Dict, Any
class CodeSearchTool:
def __init__(self, root_dir: str = "."):
self.root_dir = root_dir
def search_code(self, pattern: str, file_extensions: list = None) -> list:
"""코드 검색 도구"""
if file_extensions is None:
file_extensions = [".py", ".js", ".ts", ".java", ".cpp"]
cmd = [
"find", self.root_dir, "-type", "f",
"-name", f"*.{file_extensions[0]}" if file_extensions else "*"
]
result = subprocess.run(cmd, capture_output=True, text=True)
files = result.stdout.strip().split('\n')
matches = []
for file_path in files:
if file_path.endswith(tuple(file_extensions)):
try:
with open(file_path, 'r') as f:
content = f.read()
if pattern in content:
matches.append({
"file": file_path,
"match": pattern
})
except Exception:
continue
return matches
class GitTool:
@staticmethod
def get_changes() -> str:
"""Git 변경 사항 가져오기"""
result = subprocess.run(
["git", "diff", "--stat"],
capture_output=True, text=True
)
return result.stdout
@staticmethod
def commit_changes(message: str) -> str:
"""Git 커밋"""
subprocess.run(["git", "add", "."])
result = subprocess.run(
["git", "commit", "-m", message],
capture_output=True, text=True
)
return result.stdout
# 사용 예시
search_tool = CodeSearchTool()
results = search_tool.search_code("def setup")
print(json.dumps(results, indent=2))
6. 컨텍스트 창 관리
대규모 코드베이스에서 메모리 사용량을 줄이기 위한 방법:
python
# context_manager.py
import os
import re
from typing import List, Dict, Any
class ContextWindow:
def __init__(self, max_tokens: int = 2048):
self.max_tokens = max_tokens
self.context = []
self.token_count = 0
def add_file(self, file_path: str, max_lines: int = 100) -> bool:
"""파일을 컨텍스트에 추가"""
try:
with open(file_path, 'r') as f:
content = f.read()
# 파일의 최대 라인 수 제한
lines = content.split('\n')[:max_lines]
file_context = {
"path": file_path,
"lines": lines,
"line_count": len(lines)
}
# 토큰 계산 (간단한 추정)
token_estimate = len(content) // 4 # 실제 토큰 수는 더 복잡함
if self.token_count + token_estimate > self.max_tokens:
return False
self.context.append(file_context)
self.token_count += token_estimate
return True
except Exception as e:
print(f"Error reading {file_path}: {e}")
return False
def get_context_prompt(self) -> str:
"""컨텍스트를 프롬프트 형식으로 변환"""
prompt_parts = []
for item in self.context:
prompt_parts.append(f"File: {item['path']}")
prompt_parts
---
📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)
Top comments (0)