惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
D
DataBreaches.Net
GbyAI
GbyAI
Microsoft Security Blog
Microsoft Security Blog
博客园_首页
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
月光博客
月光博客
U
Unit 42
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
腾讯CDC
B
Blog RSS Feed
博客园 - Franky
爱范儿
爱范儿

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
터미널 AI 에이전트 구축 (v9)
matias yoon · 2026-05-24 · via DEV Community

터미널 AI 에이전트 구축 (v9): 로컬 LLM 기반 개발자용 CLI AI 에이전트 만들기

터미널에서 직접 작동하는 AI 에이전트를 구축하는 것은 개발자에게 큰 생산성 향상을 제공합니다. 이번 가이드에서는 로컬 LLM을 기반으로 한 커스텀 CLI AI 에이전트를 구축하는 방법을 실습 중심으로 설명합니다.

1. CLI AI 에이전트 생태계 분석

현재 CLI AI 에이전트 시장에는 여러 솔루션이 존재합니다:

주요 도구들:

  • Aider: GitHub Copilot 기반, 실시간 코드 수정 기능
  • Continue.dev: VSCode 기반, 복잡한 작업 처리
  • OpenCode: 오픈소스, 간단한 코딩 도움
  • Custom Scripts: 직접 제작한 스크립트로 커스터마이징

현재 문제점:

  • 대부분의 도구는 클라우드 API에 의존
  • 로컬 실행 시 성능 저하
  • 복잡한 툴링 기능 부족
  • 비용 문제

2. 로컬 LLM API 엔드포인트 설정

로컬에서 LLM을 실행하려면 다음과 같은 단계를 따릅니다:

1. LM Studio 설치:

# macOS
brew install lm-studio

# 또는 직접 다운로드
wget https://github.com/lmstudio-ai/LMStudio/releases/latest/download/LMStudio-MacOS.dmg

Enter fullscreen mode Exit fullscreen mode

2. 로컬 모델 실행:

# 모델 다운로드 후 실행
lm-studio --model "Nous-Hermes-2-Mistral-7B-DPO.Q4_K_M.gguf"

Enter fullscreen mode Exit fullscreen mode

3. API 서버 설정:

# Ollama 설치
curl -fsSL https://ollama.com/install.sh | sh

# 모델 다운로드
ollama pull mistral

# API 서버 실행
ollama serve

Enter fullscreen mode Exit fullscreen mode

3. 간단한 Python CLI 에이전트 구축

이제 기초적인 CLI 에이전트를 만들어보겠습니다:

# ai_agent.py
import os
import json
import subprocess
from typing import Dict, List, Any
import openai

class TerminalAIAgent:
    def __init__(self, model="ollama/mistral"):
        self.model = model
        self.client = openai.OpenAI(
            base_url="http://localhost:11434/v1",
            api_key="ollama"
        )
        self.conversation_history = []

    def run_command(self, command: str) -> str:
        """명령어 실행 및 결과 반환"""
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True,
                timeout=30
            )
            return result.stdout + result.stderr
        except Exception as e:
            return f"Error: {str(e)}"

    def get_context(self) -> str:
        """현재 작업 디렉토리 정보 수집"""
        pwd = os.getcwd()
        files = os.listdir(pwd)
        return f"Working directory: {pwd}\nFiles: {', '.join(files[:10])}"

    def chat(self, user_input: str) -> str:
        """AI와 대화"""
        self.conversation_history.append({
            "role": "user",
            "content": user_input
        })

        # 시스템 프롬프트
        system_prompt = """
        You are a helpful AI assistant that helps developers with coding tasks.
        Your responses should be concise and actionable.
        You can execute shell commands and modify files.
        """

        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": f"Context: {self.get_context()}"},
        ] + self.conversation_history

        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            temperature=0.3
        )

        ai_response = response.choices[0].message.content
        self.conversation_history.append({
            "role": "assistant",
            "content": ai_response
        })

        return ai_response

# 사용법
if __name__ == "__main__":
    agent = TerminalAIAgent()
    print("AI Agent 시작 (종료는 'exit' 입력)")

    while True:
        user_input = input("\n> ")
        if user_input.lower() == 'exit':
            break
        response = agent.chat(user_input)
        print(response)

Enter fullscreen mode Exit fullscreen mode

4. tmux와 통합

터미널 멀티플렉서와 통합하여 작업 흐름을 개선합니다:

# tmux 세션 생성
tmux new-session -d -s ai_agent

# 세션 내에서 에이전트 실행
tmux send-keys -t ai_agent "python ai_agent.py" Enter

Enter fullscreen mode Exit fullscreen mode

tmux 스크립트:

# tmux_ai.sh
#!/bin/bash
SESSION="ai_agent"

# 세션 존재 여부 확인
if ! tmux has-session -t $SESSION 2>/dev/null; then
    tmux new-session -d -s $SESSION
    tmux send-keys -t $SESSION "python ai_agent.py" Enter
fi

tmux attach -t $SESSION

Enter fullscreen mode Exit fullscreen mode

5. 사용자 정의 도구 개발

코드 검색 도구:

# tools/code_search.py
import os
import re
from typing import List, Dict

class CodeSearchTool:
    def __init__(self, root_dir: str = "."):
        self.root_dir = root_dir

    def search_in_files(self, pattern: str, file_extensions: List[str] = None) -> List[Dict]:
        """파일 내에서 패턴 검색"""
        results = []
        if file_extensions is None:
            file_extensions = ['.py', '.js', '.ts', '.java', '.cpp']

        for root, dirs, files in os.walk(self.root_dir):
            for file in files:
                if any(file.endswith(ext) for ext in file_extensions):
                    file_path = os.path.join(root, file)
                    try:
                        with open(file_path, 'r', encoding='utf-8') as f:
                            content = f.read()
                            matches = re.finditer(pattern, content)
                            for match in matches:
                                results.append({
                                    'file': file_path,
                                    'line': content[:match.start()].count('\n') + 1,
                                    'context': self.get_context(content, match.start())
                                })
                    except Exception:
                        continue

        return results

    def get_context(self, content: str, position: int, context_lines: int = 3) -> str:
        """문맥 추출"""
        lines = content.split('\n')
        line_num = content[:position].count('\n')
        start = max(0, line_num - context_lines)
        end = min(len(lines), line_num + context_lines + 1)
        return '\n'.join(lines[start:end])

# 사용 예제
search_tool = CodeSearchTool()
results = search_tool.search_in_files(r"def\s+(\w+)\s*\(")
print(json.dumps(results, indent=2))

Enter fullscreen mode Exit fullscreen mode

Git 도구:

# tools/git_tool.py
import subprocess
import json
from typing import Dict, List

class GitTool:
    def get_status(self) -> Dict:
        """Git 상태 확인"""
        try:
            result = subprocess.run(['git', 'status', '--porcelain'], 
                                  capture_output=True, text=True)
            return {
                'status': result.stdout.strip(),
                'has_changes': bool(result.stdout.strip())
            }
        except Exception as e:
            return {'error': str(e)}

    def get_branch_info(self) -> Dict:
        """브랜치 정보"""
        try:
            branch = subprocess.run(['git', 'branch', '--show-current'], 
                                   capture_output=True, text=True).stdout.strip()
            return {'branch': branch}
        except Exception as e:
            return {'error': str(e)}

    def commit_changes(self, message: str) -> Dict:
        """변경사항 커밋"""
        try:
            subprocess.run(['git', 'add', '.'], capture_output=True)
            result = subprocess.run(['git', 'commit', '-m', message], 
                                  capture_output=True, text=True)
            return {
                'success': True,
                'output': result.stdout,
                'error': result.stderr
            }
        except Exception as e:
            return {'success': False, 'error': str(e)}

# 사용 예제
git_tool = GitTool()
status = git_tool.get_status()
print(json.dumps(status, indent=2))

Enter fullscreen mode Exit fullscreen mode

6. 컨텍스트 윈도우 관리

대규모 코드베이스를 처리하기 위한 컨텍스트 관리:


python
# context_manager.py
import os
import hashlib
from typing import List, Dict, Set

class ContextManager:
    def __init__(self, max_tokens: int = 8000):
        self.max_tokens = max_tokens
        self.token_cache = {}

    def calculate_tokens(self, text: str)

---

📥 **Get the full guide on Gumroad**: https://gumroad.com/l/auto ($5)

Enter fullscreen mode Exit fullscreen mode