홈랩 AI 서버 가이드 4편: n8n 자동화 아키텍처 및 실전 워크플로우 20선

편수4편 / 5편
난이도⭐⭐⭐ 고급
다루는 내용n8n · Dify · MCP · LangChain · Open WebUI · 실전 워크플로우 20선
섹션 수19개 섹션
⚙️ n8n 자동화 🤖 Dify · MCP 🧠 LangChain · CrewAI 🖥️ Open WebUI 마스터 🚀 실전 워크플로우 20선 RAG · 멀티에이전트 · ROI
4편은 홈랩 AI 서버를 실제로 활용하는 자동화와 실전 워크플로우의 정수를 모았습니다. n8n·Dify·MCP·LangChain·AutoGen으로 자동화 아키텍처를 설계하고, Open WebUI의 모든 기능을 마스터합니다. 그리고 이 편의 하이라이트 — Telegram 봇·회의록·주식분석·코드리뷰·멀티에이전트까지 즉시 사용 가능한 실전 워크플로우 20선을 완전 수록했습니다. n8n에 JSON 임포트 후 환경변수만 수정하면 바로 동작합니다.
TABLE OFCONTENTS

4편 전체 목차

01
AI 자동화 아키텍처 설계 전략
이벤트 기반·오케스트레이션·트리거 분류
02
n8n — AI 워크플로우 자동화 완전 정복
설치·HTTP 노드·LLM 연동·에러 처리
03
Dify — 프라이빗 AI 앱 빌더
워크플로우·RAG 앱·API 게이트웨이
04
MCP 서버 — AI 에이전트 도구 생태계
Claude MCP·Filesystem·Postgres·커스텀 툴
05
LangChain & LangGraph — 코드 기반 에이전트
Chain·Agent·Graph·메모리 관리
06
AutoGen & CrewAI — 멀티 에이전트
역할 기반 팀·대화형 에이전트·태스크 분해
07
개인 생산성 혁신 — 연구·학습·창작
Obsidian 연동·지식 베이스·창작 보조
08
소상공인 AI 비즈니스 자동화
쇼핑몰·CS·마케팅·재고 자동화
09
개발자 AI 워크플로우
코드 리뷰·문서화·테스트·디버깅 자동화
10
중소기업 AI 도입 — 사내 지식 관리
사내 RAG·온보딩·보고서 자동화
11
프롬프트 엔지니어링 실전 완전 가이드
CoT·Few-shot·RAG 프롬프트·시스템 프롬프트
12
AI 서버 ROI 분석 & 비용 절감 계산
클라우드 vs 홈랩 TCO 비교·월 절감액 계산
13
Open WebUI 전체 기능 맵 & Admin 정복
모델 관리·사용자 권한·설정 전체 해설
14
Pipelines — 메시지 전처리·후처리 제어
파이프라인 구조·필터·변환·로깅
15
Functions & Tools — AI 에이전트 도구
커스텀 함수·외부 API·도구 체인
16
멀티유저 관리 & 권한 설계
역할별 접근·API 키·사용량 제한
17
모델 라우터 & 폴백 전략
자동 라우팅·비용 최적화·폴백 체인
18
RAG 고급 설정 & Knowledge Base 최적화
청킹 전략·임베딩 선택·재랭킹
19
🚀 실전 워크플로우 20선 — 바로 쓰는 n8n 자동화
Telegram봇·회의록·주식분석·코드리뷰·멀티에이전트
SECTION01

AI 자동화 아키텍처 설계 전략

AI 자동화는 단순히 “챗봇 만들기”가 아닙니다. 실제 운영 환경에서는 여러 도구를 조합해 사람이 개입하지 않아도 복잡한 작업을 완수하는 자율 시스템을 구축해야 합니다. 먼저 자동화 수준에 따라 올바른 도구를 선택하는 것이 중요합니다.

🗺️ 자동화 레이어별 도구 선택 매트릭스

자동화 수준도구특징추천 대상
L1. 노코드 자동화n8n드래그 앤 드롭, 500+ 통합, 빠른 구축비개발자, 반복 업무 자동화
L2. AI 앱 빌더DifyRAG + 에이전트 + API 서버 올인원AI 서비스 내부 배포
L3. 도구 프로토콜MCPAI가 외부 도구를 표준화된 방식으로 호출Claude Desktop 고급 활용
L4. 코드 에이전트LangChain/LangGraph완전한 프로그래밍 제어, 복잡한 로직Python 개발자
L5. 멀티 에이전트AutoGen/CrewAI여러 AI가 협업해 복잡한 문제 해결연구, 복잡한 업무 자동화
✅ AI 서버 자동화 실전 스택 추천
  • 일상 업무 자동화 — n8n + Ollama + Open WebUI (슬랙 알림, 이메일 요약, 일정 관리)
  • RAG 기반 AI 서비스 — Dify + Qdrant + nomic-embed-text (사내 지식 검색 봇)
  • Claude Desktop 고급 에이전트 — MCP 커스텀 서버 + n8n API (로컬 파일 조작, DB 쿼리)
  • 복잡한 리서치 에이전트 — LangGraph + Ollama + 웹 검색 + Qdrant RAG
  • 자율 코딩 에이전트 — AutoGen + Ollama + Code Executor (자동 코드 작성·테스트·수정)
SECTION02

n8n — AI 워크플로우 자동화 완전 정복

n8n은 500개 이상의 앱과 통합되는 오픈소스 자동화 플랫폼입니다. AI 서버와 결합하면 슬랙 메시지가 오면 Ollama가 요약하고, 새 이메일이 도착하면 AI가 분류해 자동 응답하는 등의 인텔리전트 자동화가 가능합니다.

yaml — ~/ai-server/automation/docker-compose.yml (n8n)
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=your_secure_password_here
      - GENERIC_TIMEZONE=Asia/Seoul
      - N8N_HOST=n8n.yourdomain.com       # Cloudflare 도메인
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.yourdomain.com
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=n8n_password
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres
    networks:
      - ai_net

  postgres:
    image: postgres:16-alpine
    container_name: n8n_postgres
    restart: unless-stopped
    environment:
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=n8n_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - ai_net

volumes:
  n8n_data:
  postgres_data:

networks:
  ai_net:
    external: true
    name: ai_network

🔗 n8n + Ollama 연동 설정

1
n8n 접속 및 자격증명 추가
Settings → Credentials → New Credential → Ollama API 선택 → Base URL: http://ollama:11434
2
AI Agent 노드 추가
워크플로우 → + 버튼 → AI → AI Agent 노드 선택 → Chat Model: Ollama → 모델 선택
3
도구 연결
AI Agent 노드에 Tools 연결 → HTTP Request, Code, Wikipedia, Calculator 등 추가. 에이전트가 자동으로 적절한 도구 선택.

⚡ 실전 n8n AI 워크플로우 6종

워크플로우트리거AI 처리출력
이메일 AI 비서새 Gmail 수신Ollama로 내용 분류·요약·초안 작성Slack 알림 + 초안 저장
블로그 자동 포스팅RSS 피드 변경기사 요약 + 한국어 번역 + SEO 최적화WordPress 자동 발행
회의록 자동 정리파일 업로드 웹훅Whisper 음성인식 + AI 요약 + 액션 아이템 추출Notion/Confluence 저장
소셜미디어 콘텐츠매일 오전 9시 Cron트렌드 분석 + 콘텐츠 생성 + 이미지 생성(A1111)Buffer/Hootsuite 예약 등록
고객 문의 자동 분류Webhook (폼 제출)AI 카테고리 분류 + 감정 분석 + 자동 응답 생성담당자 배정 + 메일 발송
코드 리뷰 봇GitHub PR 이벤트코드 분석 + 개선 제안 + 버그 탐지GitHub 코멘트 자동 게시
n8n — HTTP Request 노드로 Ollama 직접 호출 (Function 노드)
// n8n Code 노드에서 Ollama API 직접 호출
const response = await $http.request({
  method: 'POST',
  url: 'http://ollama:11434/api/generate',
  headers: { 'Content-Type': 'application/json' },
  body: {
    model: 'qwen2.5:14b',
    prompt: `다음 이메일을 한국어로 요약하고 중요도를 High/Medium/Low로 분류해줘:\n\n${$json.emailBody}`,
    stream: false,
    options: {
      temperature: 0.3,
      num_predict: 500
    }
  }
});

return {
  summary: response.response,
  originalEmail: $json.emailBody,
  processedAt: new Date().toISOString()
};
SECTION03

Dify — 프라이빗 AI 앱 빌더 완전 구축

Dify는 RAG, 에이전트, 채팅봇, 워크플로우를 노코드로 구성할 수 있는 오픈소스 AI 앱 빌더입니다. 완성된 앱은 REST API나 웹 인터페이스로 즉시 배포됩니다. Ollama와 연동하면 완전한 프라이빗 환경에서 ChatGPT급 AI 서비스를 구축할 수 있습니다.

bash — Dify Docker 완전 설치
# Dify 공식 docker-compose 클론
cd ~/ai-server/automation
git clone https://github.com/langgenius/dify.git
cd dify/docker

# 환경 설정
cp .env.example .env

# 핵심 환경변수 수정 (.env 파일)
sed -i "s/SECRET_KEY=.*/SECRET_KEY=$(openssl rand -hex 32)/" .env
sed -i "s/CONSOLE_API_URL=.*/CONSOLE_API_URL=https:\/\/dify.yourdomain.com/" .env

# 실행 (포트 3001에서 서비스)
docker compose up -d

# 초기 관리자 계정 생성 (최초 1회)
docker compose exec api flask db upgrade
docker compose exec api flask reset-email-and-password

🤖 Dify + Ollama 연동 설정

1
Dify Settings → Model Provider → Ollama
API Base URL: http://ollama:11434 → 연결 테스트 → 모델 목록 자동 로드
2
Knowledge Base (RAG) 생성
Knowledge → Create Knowledge → 문서 업로드 (PDF, DOCX, MD, TXT) → 임베딩 모델: nomic-embed-text → 인덱싱
3
AI 앱 생성 (Chat 또는 Agent)
Studio → Create App → Chat Assistant → Knowledge Base 연결 → 시스템 프롬프트 설정 → 게시
4
API 서버로 활용
앱 API → API Key 발급 → 외부 앱에서 REST API로 호출. n8n, Python, 모바일 앱 등에서 바로 사용 가능.
✅ Dify 실전 활용 시나리오
  • 사내 지식 검색봇 — 사내 문서 Knowledge Base → 직원이 질문하면 정확한 문서 위치와 내용 제공
  • 고객 지원 챗봇 — 제품 매뉴얼 + FAQ Knowledge Base → 24시간 자동 고객 응대
  • 코드 리뷰 에이전트 — Agent 앱 + GitHub 도구 → 코드 분석 + 개선안 자동 제시
  • 데이터 분석 워크플로우 — Workflow 앱 → CSV 입력 → AI 분석 → 리포트 생성 → 이메일 발송
SECTION04

MCP 서버 — AI 에이전트 도구 생태계 구축

MCP(Model Context Protocol)는 Anthropic이 설계한 AI 에이전트 표준 프로토콜입니다. AI가 파일 시스템 접근, 데이터베이스 쿼리, API 호출, 코드 실행 등의 외부 도구를 표준화된 방식으로 사용할 수 있게 합니다. Claude Desktop과 완벽하게 통합되며 커스텀 서버를 직접 개발해 AI 서버의 모든 기능을 도구로 노출할 수 있습니다.

🔧 커스텀 MCP 서버 개발 (n8n 연동)

python — 커스텀 MCP 서버 (AI 서버 워크플로우 트리거)
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import httpx
import asyncio

app = Server("ai-server-mcp")

N8N_BASE_URL = "http://192.168.1.253:5678"
OLLAMA_URL   = "http://192.168.1.253:11434"

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="generate_image",
            description="AI 이미지 생성 (ComfyUI/A1111 사용)",
            inputSchema={
                "type": "object",
                "properties": {
                    "prompt": {"type": "string", "description": "이미지 생성 프롬프트"},
                    "width":  {"type": "integer", "default": 1024},
                    "height": {"type": "integer", "default": 1024},
                },
                "required": ["prompt"]
            }
        ),
        types.Tool(
            name="trigger_n8n_workflow",
            description="n8n 워크플로우 트리거",
            inputSchema={
                "type": "object",
                "properties": {
                    "workflow_id": {"type": "string"},
                    "data": {"type": "object"}
                },
                "required": ["workflow_id"]
            }
        ),
        types.Tool(
            name="query_ollama",
            description="로컬 Ollama LLM에 직접 질문",
            inputSchema={
                "type": "object",
                "properties": {
                    "model":  {"type": "string", "default": "qwen2.5:14b"},
                    "prompt": {"type": "string"}
                },
                "required": ["prompt"]
            }
        ),
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
    async with httpx.AsyncClient(timeout=120) as client:

        if name == "generate_image":
            resp = await client.post(
                "http://192.168.1.253:7860/sdapi/v1/txt2img",
                json={
                    "prompt": arguments["prompt"],
                    "width":  arguments.get("width", 1024),
                    "height": arguments.get("height", 1024),
                    "steps":  20,
                }
            )
            return [types.TextContent(type="text",
                text=f"이미지 생성 완료. 결과: {resp.json()['images'][0][:50]}...")]

        elif name == "trigger_n8n_workflow":
            resp = await client.post(
                f"{N8N_BASE_URL}/webhook/{arguments['workflow_id']}",
                json=arguments.get("data", {})
            )
            return [types.TextContent(type="text",
                text=f"워크플로우 실행: {resp.status_code} - {resp.text[:200]}")]

        elif name == "query_ollama":
            resp = await client.post(
                f"{OLLAMA_URL}/api/generate",
                json={
                    "model":  arguments.get("model", "qwen2.5:14b"),
                    "prompt": arguments["prompt"],
                    "stream": False
                }
            )
            return [types.TextContent(type="text",
                text=resp.json()["response"])]

async def main():
    async with stdio_server() as streams:
        await app.run(*streams, app.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())

⚙️ Claude Desktop config.json 설정

json — ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "ai-server": {
      "command": "python",
      "args": ["/path/to/ai_server_mcp.py"],
      "env": {
        "AI_SERVER_IP": "192.168.1.253"
      }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem",
               "/Volumes/data", "/Volumes/storage"]
    },
    "n8n": {
      "command": "npx",
      "args": ["-y", "n8n-mcp"],
      "env": {
        "N8N_API_URL": "http://192.168.1.253:5678",
        "N8N_API_KEY": "your_n8n_api_key"
      }
    }
  }
}
SECTION05

LangChain & LangGraph — 코드 기반 AI 에이전트

LangChain은 LLM 기반 애플리케이션 개발 프레임워크입니다. LangGraph는 LangChain 위에서 상태 머신(State Machine) 방식으로 복잡한 에이전트 워크플로우를 구현합니다. Ollama와 조합하면 완전한 오프라인 AI 에이전트를 개발할 수 있습니다.

bash — LangChain 설치
pip install langchain langchain-community langgraph \
            langchain-ollama chromadb \
            tavily-python duckduckgo-search

🤖 ReAct 에이전트 — 웹 검색 + RAG + 코드 실행

python — LangChain ReAct 에이전트 (Ollama 로컬)
from langchain_ollama import ChatOllama
from langchain.agents import create_react_agent, AgentExecutor
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_community.tools.python.tool import PythonREPLTool
from langchain_community.vectorstores import Chroma
from langchain_ollama import OllamaEmbeddings
from langchain.tools.retriever import create_retriever_tool
from langchain import hub

# 로컬 Ollama LLM 설정
llm = ChatOllama(
    base_url="http://192.168.1.253:11434",
    model="qwen2.5:14b",
    temperature=0.1
)

# 임베딩 모델
embeddings = OllamaEmbeddings(
    base_url="http://192.168.1.253:11434",
    model="nomic-embed-text"
)

# 지식 베이스 (ChromaDB)
vectorstore = Chroma(
    persist_directory="./knowledge_base",
    embedding_function=embeddings
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 에이전트 도구 정의
tools = [
    DuckDuckGoSearchRun(name="web_search",
        description="최신 정보나 사실 확인이 필요할 때 사용"),
    PythonREPLTool(name="python_repl",
        description="Python 코드 실행, 계산, 데이터 분석에 사용"),
    create_retriever_tool(
        retriever,
        "knowledge_search",
        "내부 지식베이스에서 관련 문서 검색"
    ),
]

# ReAct 에이전트 생성
prompt  = hub.pull("hwchase17/react")
agent   = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(
    agent=agent, tools=tools,
    verbose=True,
    max_iterations=10,
    handle_parsing_errors=True
)

# 실행 예시
result = executor.invoke({
    "input": "2026년 최신 AI 모델 트렌드를 조사하고, "
             "우리 지식베이스와 비교해서 차이점을 Python으로 분석해줘"
})
print(result["output"])

🔀 LangGraph — 복잡한 에이전트 상태 머신

python — LangGraph 리서치 에이전트 (검색→분석→리포트)
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated, List
import operator

class ResearchState(TypedDict):
    topic:    str
    searches: Annotated[List[str], operator.add]
    findings: Annotated[List[str], operator.add]
    report:   str
    step:     int

def search_node(state: ResearchState) -> dict:
    """웹 검색 수행"""
    search = DuckDuckGoSearchRun()
    query  = f"{state['topic']} 최신 동향 2026"
    result = search.run(query)
    return {"searches": [result], "step": state["step"] + 1}

def analyze_node(state: ResearchState) -> dict:
    """검색 결과 분석"""
    prompt = f"""다음 검색 결과를 분석하고 핵심 인사이트를 추출해:
    {' '.join(state['searches'][-3:])}"""
    result = llm.invoke(prompt)
    return {"findings": [result.content], "step": state["step"] + 1}

def report_node(state: ResearchState) -> dict:
    """최종 리포트 작성"""
    prompt = f"""다음 분석 내용을 바탕으로 전문적인 리포트를 작성해:
    주제: {state['topic']}
    분석: {' '.join(state['findings'])}"""
    result = llm.invoke(prompt)
    return {"report": result.content}

def should_continue(state: ResearchState) -> str:
    """검색 3회 후 분석으로 전환"""
    return "analyze" if state["step"] >= 3 else "search"

# 그래프 구성
graph = StateGraph(ResearchState)
graph.add_node("search",  search_node)
graph.add_node("analyze", analyze_node)
graph.add_node("report",  report_node)

graph.set_entry_point("search")
graph.add_conditional_edges("search", should_continue, {
    "search":  "search",
    "analyze": "analyze"
})
graph.add_edge("analyze", "report")
graph.add_edge("report",  END)

app = graph.compile()

result = app.invoke({
    "topic": "AI 서버 구축 최신 기술 트렌드",
    "searches": [], "findings": [], "report": "", "step": 0
})
print(result["report"])
SECTION06

AutoGen & CrewAI — 멀티 에이전트 시스템

단일 AI가 해결하기 어려운 복잡한 작업은 여러 AI 에이전트가 역할을 분담해 협업하는 멀티 에이전트 아키텍처가 필요합니다. AutoGen은 Microsoft가 개발한 멀티 에이전트 프레임워크로, 에이전트들이 대화를 통해 문제를 해결합니다.

python — AutoGen 멀티 에이전트 (코딩 팀 자동화)
import autogen

# Ollama 로컬 모델 설정
config_list = [{
    "model":    "qwen2.5:14b",
    "base_url": "http://192.168.1.253:11434/v1",
    "api_key":  "ollama",
    "api_type": "openai"
}]

llm_config = {
    "config_list": config_list,
    "temperature": 0.1,
    "timeout": 180
}

# 에이전트 역할 정의
user_proxy = autogen.UserProxyAgent(
    name="ProductManager",
    system_message="제품 요구사항을 정의하고 팀을 조율하는 PM입니다.",
    human_input_mode="TERMINATE",
    code_execution_config={"work_dir": "/tmp/autogen"}
)

architect = autogen.AssistantAgent(
    name="SoftwareArchitect",
    llm_config=llm_config,
    system_message="""당신은 시니어 소프트웨어 아키텍트입니다.
    요구사항을 분석하고 최적의 시스템 설계를 제안합니다.
    코드를 직접 작성하지 않고 설계 방향을 제시합니다."""
)

developer = autogen.AssistantAgent(
    name="Developer",
    llm_config=llm_config,
    system_message="""당신은 풀스택 개발자입니다.
    아키텍트의 설계를 바탕으로 실제 Python 코드를 작성합니다.
    코드는 반드시 ```python 블록으로 감싸서 제공하세요."""
)

reviewer = autogen.AssistantAgent(
    name="CodeReviewer",
    llm_config=llm_config,
    system_message="""당신은 시니어 코드 리뷰어입니다.
    작성된 코드의 품질, 보안, 성능을 검토하고 개선점을 제시합니다."""
)

# 그룹 채팅으로 협업
groupchat = autogen.GroupChat(
    agents=[user_proxy, architect, developer, reviewer],
    messages=[],
    max_round=15,
    speaker_selection_method="round_robin"
)
manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=llm_config)

# 작업 시작
user_proxy.initiate_chat(
    manager,
    message="""
    다음 기능을 구현해주세요:
    - Ollama API에서 사용 가능한 모델 목록을 가져오는 함수
    - 각 모델의 크기와 최근 사용 시간을 포함
    - 결과를 pandas DataFrame으로 반환
    - 단위 테스트 포함
    """
)

⚓ CrewAI — 역할 기반 AI 팀 구성

python — CrewAI 콘텐츠 제작 팀 자동화
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool, WebsiteSearchTool
from langchain_ollama import ChatOllama

ollama_llm = ChatOllama(
    base_url="http://192.168.1.253:11434",
    model="qwen2.5:14b"
)

# AI 팀 구성
researcher = Agent(
    role="수석 리서처",
    goal="정확하고 최신의 기술 정보를 수집·검증한다",
    backstory="10년 경력의 기술 리서처. 허위 정보를 절대 허용하지 않는다.",
    llm=ollama_llm,
    tools=[SerperDevTool()],
    verbose=True
)

writer = Agent(
    role="기술 블로그 작가",
    goal="복잡한 기술 내용을 쉽고 흥미롭게 설명하는 글을 쓴다",
    backstory="개발자 출신 테크 라이터. SEO와 가독성을 동시에 추구한다.",
    llm=ollama_llm,
    verbose=True
)

editor = Agent(
    role="편집장",
    goal="글의 품질, 정확성, 일관성을 최종 검토한다",
    backstory="20년 경력 편집장. 오탈자, 논리 오류, 사실 오류를 절대 놓치지 않는다.",
    llm=ollama_llm,
    verbose=True
)

# 작업 정의
research_task = Task(
    description="2026년 로컬 AI 서버 구축 트렌드를 조사. GPU 선택, 모델 트렌드, 비용 분석 포함.",
    agent=researcher,
    expected_output="5개 이상의 핵심 인사이트가 담긴 리서치 리포트"
)

writing_task = Task(
    description="리서치 결과를 바탕으로 3000자 이상의 기술 블로그 포스트 작성. 실전 코드 예시 포함.",
    agent=writer,
    expected_output="Markdown 형식의 완성된 블로그 포스트"
)

editing_task = Task(
    description="작성된 블로그 포스트를 검토하고 최종 편집. SEO 키워드 최적화 포함.",
    agent=editor,
    expected_output="최종 편집 완료된 블로그 포스트"
)

# 크루 실행
crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, writing_task, editing_task],
    process=Process.sequential,
    verbose=True
)
result = crew.kickoff()
print(result)

글 4 완료! n8n 자동화부터 LangGraph 에이전트, AutoGen 멀티에이전트까지 AI 자동화 전체 스택이 완성됐습니다. 글 5에서는 벡터DB·RAG 파이프라인·GPU 모니터링·트러블슈팅으로 AI 서버 운영의 마지막 조각을 완성합니다.

SECTIONC1

개인 생산성 혁신 — 연구·학습·창작 AI 활용

📚
논문·기술 문서 RAG 연구 어시스턴트
SCENARIO 01
PDF 논문 수십 편을 Qdrant에 인덱싱해두고 자연어로 검색합니다. “2025년 이후 Transformer 아키텍처 효율화 연구 트렌드를 비교해줘” 한 문장으로 수십 편 논문의 핵심을 교차 분석합니다.
Qdrantbge-m3 임베딩Qwen2.5:14bLangChain RAG
🧠
Obsidian + AI 개인 지식 관리 시스템
SCENARIO 02
Obsidian 볼트를 시놀로지 NAS에 동기화 → 파일 변경 감지 → 자동 임베딩. “지난달에 내가 도커 네트워크에 대해 적어둔 내용 찾아줘” → 관련 노트 즉시 검색 및 요약.
Obsidian SyncFolder WatchChromaDBOpen WebUI RAG
✍️
내 문체를 학습한 블로그 창작 어시스턴트
SCENARIO 03
기존 발행 글 전체를 Knowledge Base로 등록 → “내 글쓰기 스타일과 톤을 분석해서, 이 주제로 새 포스트 초안을 작성해줘” → 내 문체와 동일한 글 자동 생성.
RAG KnowledgeQwen2.5:14bn8n 자동 발행
🌏
무제한 번역 & 언어 학습 AI
SCENARIO 04
DeepL 월 $30 대신 로컬 Qwen2.5으로 무제한 번역. 영어 원서 PDF 업로드 → 챕터별 한국어 번역 + 핵심 어휘 추출 + 예문 생성. 일일 학습 자료 자동 생성.
Qwen2.5:14bn8n 스케줄Open WebUI

🔑 개인 생산성 향상을 위한 핵심 프롬프트 템플릿

txt — 자주 쓰는 개인 생산성 프롬프트 컬렉션
## 논문 요약 프롬프트
다음 논문을 분석해줘. 구성:
1. 핵심 기여(Contribution) — 3문장
2. 방법론 요약 — 5~7문장
3. 실험 결과 핵심 수치
4. 한계점 및 향후 연구 방향
5. 실무 적용 가능성 (내 분야: [분야 입력])
[논문 텍스트 붙여넣기]

## 회의 준비 프롬프트
내일 [주제] 회의에 참석합니다.
배경 정보: [컨텍스트]
회의 목적: [목적]
다음을 준비해줘:
- 예상 의제 5가지
- 각 의제별 내가 준비해야 할 질문 2개
- 주의해야 할 반대 의견과 대응 방법
- 회의 전 확인해야 할 사항 체크리스트

## 학습 자료 생성 프롬프트
[주제]를 처음 배우는 사람을 위한 학습 계획을 만들어줘.
내 배경: [현재 수준]
목표: [달성하고 싶은 것]
가용 시간: 하루 [X]시간, 총 [N]주
출력 형식:
- 주차별 학습 목표
- 각 주제별 추천 학습 순서
- 실습 프로젝트 아이디어 3개
- 학습 체크포인트 (스스로 평가 방법)
SECTIONC2

소상공인 · 1인 창업자 AI 비즈니스 자동화

📱
SNS 콘텐츠 자동 생산 공장
SCENARIO 05
매일 오전 9시 n8n 트리거 → 업종 관련 트렌드 검색 → LLM으로 인스타그램 캡션 + 카카오채널 메시지 + 블로그 포스트 동시 생성 → A1111으로 썸네일 이미지 자동 생성 → Buffer로 예약 포스팅.
n8n 스케줄웹 검색Qwen2.5A1111 APIBuffer
🛍️
쇼핑몰 상품 설명 & SEO 자동화
SCENARIO 06
상품명 + 사진 업로드 → Vision AI로 제품 분석 → LLM으로 상품 설명 5종(네이버, 쿠팡, 카카오, 인스타, 블로그) 자동 생성 → 키워드 최적화 → CSV로 일괄 등록.
Vision LLMQwen2.5n8nWordPress API
💬
24시간 카카오톡 고객 상담 봇
SCENARIO 07
카카오 비즈메시지 Webhook → n8n 수신 → FAQ 문서 RAG 검색 → AI 답변 생성 → 자동 응답. 해결 불가 시 담당자 슬랙 알림. 처리 시간 평균 3초 이내.
카카오 APIn8n WebhookDify RAGSlack 알림
python — 상품 설명 자동 생성 API (n8n에서 호출)
from fastapi import FastAPI
from pydantic import BaseModel
import httpx, asyncio

app = FastAPI()

class ProductRequest(BaseModel):
    product_name: str
    category:     str
    price:        int
    features:     list[str]
    target:       str = "일반 소비자"

@app.post("/generate-description")
async def generate_product_description(req: ProductRequest):
    """상품 설명 5가지 플랫폼별 자동 생성"""

    prompt = f"""다음 상품의 판매 설명을 5개 플랫폼별로 작성해줘.

상품명: {req.product_name}
카테고리: {req.category}
가격: {req.price:,}원
주요 특징: {', '.join(req.features)}
타겟 고객: {req.target}

JSON 형식으로 출력:
{{
  "naver_smart_store": "네이버 스마트스토어용 (500자 내외, SEO 키워드 포함)",
  "coupang": "쿠팡 상세페이지용 (300자 내외, 혜택 강조)",
  "instagram": "인스타그램 캡션 (150자 내외, 해시태그 10개 포함, 이모지 활용)",
  "kakao_channel": "카카오채널 메시지 (100자 내외, 친근한 말투)",
  "blog_intro": "블로그 포스팅 도입부 (200자 내외, 스토리텔링)",
  "seo_keywords": ["핵심 키워드 10개"]
}}"""

    async with httpx.AsyncClient(timeout=60) as client:
        resp = await client.post(
            "http://ollama:11434/api/generate",
            json={"model": "qwen2.5:14b", "prompt": prompt, "stream": False,
                  "options": {"temperature": 0.8}}
        )

    import json, re
    raw = resp.json()["response"]
    json_match = re.search(r'\{.*\}', raw, re.DOTALL)
    result = json.loads(json_match.group()) if json_match else {"raw": raw}

    return {"product": req.product_name, "descriptions": result}

# FastAPI 실행: uvicorn main:app --host 0.0.0.0 --port 8500
# n8n HTTP Request 노드: POST http://ai-server:8500/generate-description
SECTIONC3

개발자 · 엔지니어 AI 워크플로우

🔍 Open WebUI System Prompt — 코딩 전문가 페르소나

txt — 개발자용 Open WebUI 시스템 프롬프트
당신은 10년 경력의 시니어 풀스택 개발자입니다.
주요 스택: Python, Docker, Kubernetes, PostgreSQL, React

답변 원칙:
1. 코드는 항상 실행 가능한 완전한 형태로 제공
2. 보안 취약점과 엣지 케이스를 먼저 언급
3. 성능 최적화 관점에서 개선점 제안
4. 대안적인 접근 방법 1~2가지 함께 제시
5. 코드에는 반드시 한국어 주석 포함
6. 복잡한 로직은 단계별로 설명

응답 형식:
- 핵심 답변 (3~5문장)
- 코드 (완전한 실행 가능 형태)
- 주의사항 및 개선 포인트
- 참고 사항 (관련 라이브러리, 문서 링크)

🤖 GitHub PR 자동 코드 리뷰 설정

python — GitHub PR 자동 AI 코드 리뷰 (n8n Webhook 연동)
from fastapi import FastAPI, Request
import httpx, asyncio

app = FastAPI()

@app.post("/github-webhook")
async def handle_pr_webhook(request: Request):
    """GitHub PR 생성/업데이트 시 자동 AI 코드 리뷰"""
    payload = await request.json()

    if payload.get("action") not in ["opened", "synchronize"]:
        return {"status": "skipped"}

    pr       = payload["pull_request"]
    pr_title = pr["title"]
    pr_body  = pr.get("body", "")
    diff_url = pr["diff_url"]
    comments_url = pr["comments_url"]

    # PR diff 가져오기
    async with httpx.AsyncClient() as client:
        diff_resp = await client.get(
            diff_url,
            headers={"Authorization": f"token {GITHUB_TOKEN}"}
        )
        diff_text = diff_resp.text[:8000]  # 토큰 한도

    # AI 코드 리뷰 생성
    review_prompt = f"""다음 Pull Request를 시니어 개발자 관점에서 리뷰해줘.

PR 제목: {pr_title}
PR 설명: {pr_body}

변경 코드 (diff):
{diff_text}

리뷰 항목:
1. 🐛 잠재적 버그 및 오류 (심각도: 높음/중간/낮음)
2. 🔒 보안 취약점 (SQL Injection, XSS, 인증 우회 등)
3. ⚡ 성능 이슈 (N+1 쿼리, 불필요한 루프, 메모리 누수)
4. 📖 코드 가독성 및 유지보수성
5. ✅ 잘된 점 (긍정적 피드백 필수)
6. 💡 개선 제안 (선택적)

각 항목은 구체적인 라인 번호나 코드 예시와 함께."""

    async with httpx.AsyncClient(timeout=120) as client:
        ai_resp = await client.post(
            "http://ollama:11434/api/generate",
            json={"model": "qwen2.5:14b", "prompt": review_prompt, "stream": False}
        )
        review = ai_resp.json()["response"]

        # GitHub에 리뷰 코멘트 게시
        await client.post(
            comments_url,
            headers={"Authorization": f"token {GITHUB_TOKEN}",
                     "Content-Type": "application/json"},
            json={"body": f"## 🤖 AI 코드 리뷰\n\n{review}\n\n---\n*AI 리뷰는 참고용입니다.*"}
        )

    return {"status": "review_posted"}

GITHUB_TOKEN = "your_github_token"

📝 개발자 AI 활용 시나리오 총정리

시나리오AI 도구시간 절감구현 복잡도
PR 코드 리뷰 자동화Qwen2.5:14b + GitHub Webhook30분/PR → 0분중간
API 문서 자동 생성LLM + FastAPI OpenAPI2시간 → 10분낮음
에러 로그 자동 분석n8n + Ollama + Slack즉시 원인 파악중간
단위 테스트 자동 생성vLLM + LangChain1시간 → 5분중간
코드 마이그레이션 보조RAG (기존 코드베이스)40% 속도 향상높음
리팩토링 제안Open WebUI + 코드 업로드즉시 피드백낮음
보안 취약점 스캔LLM + 정적 분석 결합보안 감사 70% 자동화높음
SECTIONC4

중소기업 AI 도입 — 사내 지식 관리 & 업무 자동화

중소기업에서 AI 서버 도입이 가장 빠른 ROI를 내는 영역은 사내 문서 검색·고객 지원·보고서 작성·데이터 분석입니다. 외부 API에 기밀 문서를 보낼 필요 없이 내부망에서 완전히 처리됩니다.

🏢
사내 AI 검색 시스템 (ChatGPT 사내 버전)
ENTERPRISE SCENARIO 01
사내 규정집, 제품 매뉴얼, 과거 계약서, 기술 문서, 회의록을 모두 Qdrant에 인덱싱. 직원이 자연어로 질문하면 관련 문서를 근거로 정확히 답변. “산업재해 처리 절차가 어떻게 되나요?” → 사내 규정집 참조 후 단계별 답변.
Dify + RAGQdrantQwen2.5:14bLDAP 인증
📊
경영 보고서 자동 생성 시스템
ENTERPRISE SCENARIO 02
매월 말 n8n 자동 실행 → PostgreSQL에서 매출·비용·KPI 데이터 추출 → LLM이 분석 코멘트 생성 → 전월 대비 증감 원인 추론 → Word/PDF 보고서 자동 생성 → 경영진 이메일 발송.
n8n CronPostgreSQLPython 분석LLM 인사이트
📞
고객 지원 AI — 티켓 분류 & 자동 응답
ENTERPRISE SCENARIO 03
고객 이메일 수신 → AI 카테고리 자동 분류(기술지원/환불/일반문의) → 유사 해결 사례 RAG 검색 → 초안 응답 생성 → 담당자 검토 후 1클릭 발송. 응답 시간 24시간 → 2시간으로 단축.
Gmail 연동n8nRAG 검색초안 자동화

👥 멀티유저 AI 서버 구성 — 부서별 접근 제어

부서접근 허용 Knowledge Base사용 모델특수 기능
인사팀인사규정, 급여체계, 복리후생Qwen2.5:7b (빠름)개인정보 필터링 활성화
개발팀기술문서, API 명세, 코드 가이드Qwen2.5:14b (고품질)코드 실행 허용
영업팀제품 카탈로그, 가격표, 계약 템플릿Qwen2.5:7b고객사 정보 격리
경영진전체 Knowledge BaseAPI 연결 가능 (Claude)모든 권한
SECTIONC5

프롬프트 엔지니어링 실전 완전 가이드

같은 LLM이라도 프롬프트 품질에 따라 결과가 10배 이상 달라집니다. 로컬 모델은 클라우드 API보다 더 명확하고 구체적인 프롬프트를 요구합니다.

🧠 핵심 프롬프트 기법 6가지

기법언제 사용효과예시
Role Prompting전문 지식 필요 시도메인 특화 답변“당신은 10년 경력 Python 보안 전문가입니다”
Chain-of-Thought복잡한 추론 문제정확도 30~60%↑“단계별로 생각하면서 답해줘. 먼저…”
Few-shot특정 형식 출력 필요형식 정확도↑입력/출력 예시 2~3개 제공
구조화된 출력파싱·자동화 연동코드 처리 가능“반드시 JSON 형식으로만 출력해”
제약 조건 명시범위 제한 필요할루시네이션↓“제공된 정보 외 추측 금지”
반복 정제품질 개선점진적 향상“위 답변을 더 간결하게 다시 작성해”
txt — 강력한 프롬프트 템플릿 라이브러리
## 📋 구조화된 분석 프롬프트 (Chain-of-Thought + 구조화 출력)
[역할]
당신은 비즈니스 전략 컨설턴트입니다.

[작업]
다음 상황을 분석하고 전략을 제안해줘.

[상황]
{상황 설명}

[분석 단계 — 반드시 순서대로 수행]
Step 1: 핵심 문제 정의 (1~2문장)
Step 2: 주요 원인 분석 (3가지)
Step 3: 선택 가능한 전략 (3가지, 각각 장단점)
Step 4: 최적 전략 추천 및 근거
Step 5: 실행 계획 (30일/90일/1년)

[제약 조건]
- 실행 예산: {예산}
- 팀 규모: {규모}
- 주어진 기간: {기간}

[출력 형식]
마크다운 형식으로 각 Step을 헤더로 구분

---

## 🔄 Few-shot 예시 — 감정 분석 + 응대 초안
다음은 고객 메시지를 분석하는 예시야:

입력: "배송이 3일이나 늦었어요. 너무 실망입니다."
출력: {{"감정": "실망/불만", "긴급도": "높음", "카테고리": "배송문제", "추천응대": "먼저 사과 후 보상 제안"}}

입력: "상품 색상이 사진과 달라요."  
출력: {{"감정": "불만", "긴급도": "중간", "카테고리": "상품불일치", "추천응대": "환불 또는 교환 안내"}}

입력: "{실제 고객 메시지}"
출력:

⚡ Open WebUI에서 프롬프트 템플릿 관리

1
Workspace → Prompts → New Prompt
자주 쓰는 프롬프트를 저장. 채팅창에서 / 입력 시 빠른 검색으로 불러오기.
2
변수 플레이스홀더 활용
{{topic}}, {{language}} 같은 플레이스홀더를 포함하면 프롬프트 불러올 때 자동으로 입력창이 뜹니다.
3
모델별 최적 Temperature 설정
창의적 글쓰기: 0.8~1.0 / 분석·코딩: 0.1~0.3 / 일반 대화: 0.5~0.7. Modelfile에서 모델별 기본값 설정 가능.
SECTIONC6

AI 서버 ROI 분석 & 비용 절감 계산

AI 서버 구축 비용이 아깝지 않으려면 명확한 ROI 계산이 필요합니다. 실제 사용 패턴을 기반으로 클라우드 API 대비 절감액을 계산해봅니다.

💰 클라우드 API vs AI 서버 비용 비교 (월간 기준)

📊 월 사용량: LLM 100만 토큰 + 이미지 생성 1,000장 기준
GPT-4o (input $2.5/1M + output $10/1M)약 $125 / 월
Claude Sonnet ($3/1M + $15/1M)약 $150 / 월
DALL-E 3 이미지 ($0.04/장 × 1,000)$40 / 월
Whisper API ($0.006/분 × 600분)$3.6 / 월
클라우드 API 합계≈ $320 / 월 (약 44만원)
💡 AI 서버 (RTX 3090 + Ryzen 9) 월간 비용
전기세 (350W 평균 × 24시간 × 30일 × 130원/kWh)약 3.3만원 / 월
인터넷 비용 (기존 회선 사용)0원
Cloudflare 터널무료
하드웨어 감가상각 (350만원 ÷ 48개월)약 7.3만원 / 월
AI 서버 합계≈ 10.6만원 / 월

🎯 월 절감액: 약 33만원 (75% 절감)
350만원 초기 투자 → 손익분기점: 약 10.6개월
이후 월 33만원 × 12개월 = 연 396만원 순절감. 2년 총 절감: 800만원+
5명 팀이 무제한 사용해도 비용 동일. 클라우드는 사람 수 × 사용량만큼 비용 증가.

📈 사용량 증가 시 절감 효과 (팀 규모별)

팀 규모월 클라우드 API 예상 비용AI 서버 비용월 절감액연 절감액
1인 (개인)$100~200 (14~28만원)10.6만원4~17만원50~200만원
3~5인 팀$400~800 (56~112만원)10.6만원45~100만원540~1,200만원
10~20인 팀$1,500~3,000 (210~420만원)15~20만원190~400만원2,300~4,800만원
50인+ 기업$10,000+ (1,400만원+)50~80만원1,300만원+1.5억원+
🚀 AI 서버 투자 가치를 극대화하는 핵심 전략
  • 이미지 생성 무제한화 — DALL-E 비용 절감이 가장 빠른 ROI. 마케팅팀에 ComfyUI 도입 즉시 효과
  • Whisper 회의록 자동화 — 회의 1시간 녹음 → 10분 내 회의록 자동 완성. 인당 주 2~3시간 절감
  • 사내 문서 RAG 검색 — 신입 온보딩 시간 50% 단축. 반복 질문 80% 자동 처리
  • 코드 리뷰 자동화 — PR 처리 속도 향상 + 시니어 개발자 리뷰 부담 감소
  • n8n 업무 자동화 — 반복 업무 자동화로 인당 주 5~10시간 회복
SECTIOND1

Open WebUI 전체 기능 맵 & Admin 완전 정복

Open WebUI는 지속적으로 기능이 추가되어 2026년 기준 단순 채팅 인터페이스를 훨씬 넘어섭니다. Admin Panel에만 50개 이상의 설정 항목이 있으며, 대부분의 사용자가 기본값으로만 사용합니다. 아래 설정들을 제대로 구성하면 완전히 다른 수준의 AI 플랫폼이 됩니다.

⚙️ 반드시 변경해야 할 Admin 핵심 설정

설정 위치항목권장값이유
GeneralDefault User Rolepending신규 가입자 관리자 승인 후 사용
GeneralEnable Community SharingOFF내부 서버에서 외부 공유 차단
GeneralEnable Message RatingON응답 품질 피드백 수집
GeneralEnable ChannelsONSlack형 채널로 팀 협업
ModelsDefault Modelqwen2.5:14b신규 대화 기본 모델 지정
AudioSTT/TTS EngineOpenAI 호환 (로컬)Whisper + Kokoro 연동
ImagesImage Generation EngineAUTOMATIC1111/ComfyUI로컬 이미지 생성 활성화
SearchWeb Search EngineSearXNG (self-hosted)프라이빗 웹 검색
SecurityJWT Token Expiry24h보안 강화 (기본값 너무 김)
SecurityEnable API Key AuthON외부 스크립트 API 접근

📦 Open WebUI 고급 환경변수 완전 가이드

yaml — Open WebUI docker-compose 환경변수 완전판
open-webui:
  image: ghcr.io/open-webui/open-webui:main
  environment:
    ## ── 핵심 설정 ────────────────────────────────
    - OLLAMA_BASE_URL=http://ollama:11434
    - WEBUI_SECRET_KEY=생성한_32자_랜덤_키
    - WEBUI_NAME=My Private AI            # 브랜딩명
    - WEBUI_URL=https://ai.yourdomain.com

    ## ── 데이터베이스 (기본은 SQLite, 프로덕션 권장) ─
    - DATABASE_URL=postgresql://user:pass@postgres/openwebui

    ## ── 사용자 인증 ──────────────────────────────
    - ENABLE_SIGNUP=false                 # 초기 설정 후 차단
    - DEFAULT_USER_ROLE=pending
    - JWT_EXPIRES_IN=86400               # 24시간 (초)
    - ENABLE_OAUTH_SIGNUP=true

    ## ── OAuth / Google 로그인 ───────────────────
    - GOOGLE_CLIENT_ID=your_google_client_id
    - GOOGLE_CLIENT_SECRET=your_google_secret
    - OAUTH_MERGE_ACCOUNTS_BY_EMAIL=true

    ## ── RAG 설정 ─────────────────────────────────
    - VECTOR_DB=qdrant
    - QDRANT_URI=http://qdrant:6333
    - QDRANT_API_KEY=your_qdrant_key
    - RAG_EMBEDDING_MODEL=BAAI/bge-m3    # 한국어 최강
    - RAG_EMBEDDING_ENGINE=ollama
    - RAG_OLLAMA_BASE_URL=http://ollama:11434
    - CHUNK_SIZE=1000
    - CHUNK_OVERLAP=100
    - RAG_TOP_K=5
    - RELEVANCE_THRESHOLD=0.35           # 낮을수록 많이 검색
    - ENABLE_RAG_HYBRID_SEARCH=true      # 하이브리드 검색 ON
    - RAG_RERANKING_MODEL=cross-encoder/ms-marco-MiniLM-L-6-v2

    ## ── 이미지 생성 ──────────────────────────────
    - IMAGE_GENERATION_ENGINE=comfyui
    - COMFYUI_BASE_URL=http://comfyui:8188
    - IMAGE_SIZE=1024x1024
    - IMAGE_STEPS=20

    ## ── 음성 ─────────────────────────────────────
    - AUDIO_STT_ENGINE=openai
    - AUDIO_STT_OPENAI_API_BASE_URL=http://whisper-api:8000/v1
    - AUDIO_STT_OPENAI_API_KEY=any
    - AUDIO_STT_MODEL=large-v3-turbo
    - AUDIO_TTS_ENGINE=openai
    - AUDIO_TTS_OPENAI_API_BASE_URL=http://kokoro-tts:8880/v1
    - AUDIO_TTS_OPENAI_API_KEY=any
    - AUDIO_TTS_MODEL=kokoro
    - AUDIO_TTS_VOICE=af_sarah

    ## ── 웹 검색 ──────────────────────────────────
    - ENABLE_RAG_WEB_SEARCH=true
    - RAG_WEB_SEARCH_ENGINE=searxng
    - SEARXNG_QUERY_URL=http://searxng:8080/search?q=<query>&format=json
    - RAG_WEB_SEARCH_RESULT_COUNT=5

    ## ── 외부 API 연결 ────────────────────────────
    - OPENAI_API_BASE_URL=https://api.openai.com/v1
    - OPENAI_API_KEY=sk-your-key          # 클라우드 폴백용

    ## ── 성능 & 로깅 ──────────────────────────────
    - WEBUI_AUTH_TRUSTED_EMAIL_HEADER=X-Forwarded-Email
    - ENABLE_ADMIN_CHAT_ACCESS=true       # Admin이 모든 대화 확인
    - ENABLE_ADMIN_EXPORT=true
SECTIOND2

Pipelines — 메시지 전처리·후처리 완전 제어

Pipelines는 Open WebUI의 가장 강력하면서도 덜 알려진 기능입니다. 모든 채팅 메시지가 LLM에 도달하기 전·후에 파이썬 코드로 가로채 처리할 수 있습니다. 콘텐츠 필터링, 자동 번역, 컨텍스트 주입, 응답 후처리, 외부 API 라우팅 등 거의 모든 것이 가능합니다.

🔍
Filter Pipeline
메시지 입출력 검사·수정. 욕설 필터, PII 제거, 자동 번역, 길이 제한.
Action Pipeline
특정 명령어에 반응. “/summarize”, “/translate” 같은 슬래시 명령어 구현.
🔀
Pipe (모델 라우터)
요청 내용에 따라 다른 모델로 자동 라우팅. 코딩→코딩모델, 창작→창작모델.
🌐
Manifold Pipeline
외부 API(Claude, Gemini 등)를 Ollama 모델처럼 표시. 통합 인터페이스.
yaml — Pipelines 서버 Docker 설정
services:
  pipelines:
    image: ghcr.io/open-webui/pipelines:main
    container_name: owui_pipelines
    restart: unless-stopped
    ports:
      - "9099:9099"
    volumes:
      - pipelines_data:/app/pipelines
    environment:
      - PIPELINES_API_KEY=your_pipeline_secret_key
    networks:
      - ai_net

volumes:
  pipelines_data:

networks:
  ai_net:
    external: true
    name: ai_network
python — Filter Pipeline — 한국어 자동 감지 + 컨텍스트 주입
"""
파일명: korean_context_filter.py
기능: 메시지 언어 감지 → 한국어 시 시스템 프롬프트 강화
     + 개인정보(전화번호·이메일·주민번호) 자동 마스킹
"""
from typing import Optional
from pydantic import BaseModel
import re


class Filter:
    class Valves(BaseModel):
        priority: int = 0
        enable_pii_masking: bool = True
        enable_language_detection: bool = True
        korean_system_suffix: str = "답변은 반드시 한국어로 작성하세요."

    def __init__(self):
        self.valves = self.Valves()

    def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
        """메시지가 LLM에 도달하기 전 처리 (입력 필터)"""
        messages = body.get("messages", [])

        for msg in messages:
            if msg.get("role") == "user":
                content = msg.get("content", "")

                # 1. PII 마스킹
                if self.valves.enable_pii_masking:
                    content = self._mask_pii(content)

                # 2. 한국어 감지 → 시스템 프롬프트 강화
                if self.valves.enable_language_detection:
                    if self._is_korean(content):
                        self._inject_korean_context(body)

                msg["content"] = content

        return body

    def outlet(self, body: dict, user: Optional[dict] = None) -> dict:
        """LLM 응답 후처리 (출력 필터)"""
        # 응답에서 불필요한 패턴 정리
        messages = body.get("messages", [])
        for msg in messages:
            if msg.get("role") == "assistant":
                content = msg.get("content", "")
                # 과도한 이모지 정리, 특수문자 정규화 등
                content = self._clean_response(content)
                msg["content"] = content
        return body

    def _mask_pii(self, text: str) -> str:
        """개인정보 마스킹"""
        # 전화번호
        text = re.sub(r'01[0-9]-?\d{3,4}-?\d{4}', '010-****-****', text)
        # 이메일
        text = re.sub(r'[\w\.-]+@[\w\.-]+\.\w+',
                      lambda m: m.group()[0] + '***@***.***', text)
        # 주민번호
        text = re.sub(r'\d{6}-[1-4]\d{6}', '******-*******', text)
        return text

    def _is_korean(self, text: str) -> bool:
        korean_chars = sum(1 for c in text if '\uAC00' <= c <= '\uD7A3')
        return korean_chars / max(len(text), 1) > 0.3

    def _inject_korean_context(self, body: dict):
        """시스템 메시지에 한국어 지시 추가"""
        messages = body.get("messages", [])
        for msg in messages:
            if msg.get("role") == "system":
                if self.valves.korean_system_suffix not in msg["content"]:
                    msg["content"] += f"\n\n{self.valves.korean_system_suffix}"
                return
        # 시스템 메시지 없으면 추가
        body["messages"].insert(0, {
            "role": "system",
            "content": self.valves.korean_system_suffix
        })

    def _clean_response(self, text: str) -> str:
        # 연속 빈 줄 3개 이상 → 2개로 정리
        text = re.sub(r'\n{3,}', '\n\n', text)
        return text.strip()
python — Manifold Pipeline — Claude API를 Ollama처럼 사용
"""
파일명: claude_manifold.py
기능: Anthropic Claude API를 Open WebUI 모델 목록에 추가
     → 로컬 Ollama 모델과 함께 선택 가능
"""
from typing import List, Union, Generator, Iterator
from pydantic import BaseModel
import anthropic


class Pipe:
    class Valves(BaseModel):
        ANTHROPIC_API_KEY: str = ""

    def __init__(self):
        self.valves = self.Valves()
        self.client = None

    def pipes(self) -> List[dict]:
        """Open WebUI 모델 목록에 추가할 모델 정의"""
        return [
            {"id": "claude-opus-4-5",    "name": "Claude Opus 4.5 (Cloud)"},
            {"id": "claude-sonnet-4-5",  "name": "Claude Sonnet 4.5 (Cloud)"},
            {"id": "claude-haiku-4-5-20251001", "name": "Claude Haiku 4.5 (Cloud, 빠름)"},
        ]

    def pipe(self, body: dict) -> Union[str, Generator, Iterator]:
        """실제 API 호출"""
        if not self.valves.ANTHROPIC_API_KEY:
            return "오류: Anthropic API Key가 설정되지 않았습니다."

        client = anthropic.Anthropic(api_key=self.valves.ANTHROPIC_API_KEY)

        # 모델 ID 추출
        model_id = body["model"].split(".", 1)[-1]

        # 시스템 프롬프트 분리
        system_msg = ""
        messages   = []
        for msg in body.get("messages", []):
            if msg["role"] == "system":
                system_msg = msg["content"]
            else:
                messages.append(msg)

        # 스트리밍 응답
        with client.messages.stream(
            model=model_id,
            max_tokens=body.get("max_tokens", 2048),
            system=system_msg,
            messages=messages,
        ) as stream:
            for text in stream.text_stream:
                yield text
SECTIOND3

Functions & Tools — AI 에이전트 도구 생태계

Open WebUI의 Tools는 AI가 채팅 중에 직접 호출할 수 있는 함수입니다. AI가 날씨를 실시간으로 조회하거나, 데이터베이스를 쿼리하거나, 파일을 생성하는 행동을 채팅 맥락 안에서 자연스럽게 수행합니다. MCP와 유사하지만 Open WebUI 내장 방식으로 더 간단하게 구현됩니다.

python — Open WebUI Tool 개발 (DB 조회 + AI 서버 상태 확인)
"""
파일명: ai_server_tools.py
Admin Panel → Tools → + New Tool 에서 코드 붙여넣기
"""
import subprocess
import httpx
from datetime import datetime
from pydantic import BaseModel


class Tools:

    def get_gpu_status(self) -> str:
        """
        현재 GPU 상태와 메모리 사용량을 확인합니다.
        :return: GPU 상태 정보 문자열
        """
        try:
            result = subprocess.run(
                ["nvidia-smi",
                 "--query-gpu=name,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw",
                 "--format=csv,noheader,nounits"],
                capture_output=True, text=True, timeout=10
            )
            if result.returncode != 0:
                return "GPU 정보를 가져올 수 없습니다."

            lines = result.stdout.strip().split('\n')
            statuses = []
            for i, line in enumerate(lines):
                parts = [p.strip() for p in line.split(',')]
                if len(parts) >= 6:
                    statuses.append(
                        f"GPU {i}: {parts[0]}\n"
                        f"  온도: {parts[1]}°C | 사용률: {parts[2]}%\n"
                        f"  VRAM: {parts[3]}MB / {parts[4]}MB\n"
                        f"  전력: {parts[5]}W"
                    )
            return "\n".join(statuses)
        except Exception as e:
            return f"GPU 상태 조회 실패: {e}"

    def get_ollama_models(self) -> str:
        """
        현재 Ollama에 설치된 AI 모델 목록을 조회합니다.
        :return: 모델 목록과 크기 정보
        """
        try:
            resp = httpx.get("http://ollama:11434/api/tags", timeout=10)
            models = resp.json().get("models", [])
            if not models:
                return "설치된 모델이 없습니다."
            lines = [f"설치된 모델 ({len(models)}개):"]
            for m in models:
                size_gb = m.get("size", 0) / 1e9
                lines.append(f"  - {m['name']} ({size_gb:.1f}GB)")
            return "\n".join(lines)
        except Exception as e:
            return f"모델 목록 조회 실패: {e}"

    def get_service_health(self) -> str:
        """
        AI 서버의 핵심 서비스 상태를 확인합니다.
        :return: 각 서비스의 헬스 상태
        """
        services = {
            "Ollama":    "http://ollama:11434/api/tags",
            "Qdrant":    "http://qdrant:6333/healthz",
            "n8n":       "http://n8n:5678/healthz",
            "ComfyUI":   "http://comfyui:8188/",
        }
        results = [f"서비스 상태 ({datetime.now().strftime('%H:%M:%S')})"]
        for name, url in services.items():
            try:
                resp = httpx.get(url, timeout=3)
                status = "✅ 정상" if resp.status_code < 400 else f"⚠️ {resp.status_code}"
            except:
                status = "❌ 연결 실패"
            results.append(f"  {name}: {status}")
        return "\n".join(results)

    def calculate(self, expression: str) -> str:
        """
        수학 계산을 수행합니다.
        :param expression: 계산할 수식 (예: '2 ** 10', 'sum([1,2,3,4,5])')
        :return: 계산 결과
        """
        try:
            allowed = {
                "__builtins__": {},
                "sum": sum, "max": max, "min": min,
                "abs": abs, "round": round, "len": len,
                "range": range, "list": list,
            }
            result = eval(expression, allowed)
            return f"{expression} = {result}"
        except Exception as e:
            return f"계산 오류: {e}"

    def get_current_time(self) -> str:
        """
        현재 한국 시간과 날짜를 반환합니다.
        :return: 현재 날짜시간 정보
        """
        from datetime import timezone, timedelta
        kst = timezone(timedelta(hours=9))
        now = datetime.now(kst)
        return (f"현재 시간: {now.strftime('%Y년 %m월 %d일 %H시 %M분 %S초')}\n"
                f"요일: {['월','화','수','목','금','토','일'][now.weekday()]}요일\n"
                f"Unix Timestamp: {int(now.timestamp())}")

🔗 Tool 등록 및 모델에 연결하는 방법

1
Admin Panel → Tools → + New Tool
위 코드를 붙여넣고 저장. 이름과 설명을 명확하게 작성 (AI가 언제 쓸지 판단에 사용됨).
2
Workspace → Models → 모델 편집
사용할 모델 선택 → Tools 탭 → 방금 만든 Tool 체크박스 활성화.
3
채팅에서 테스트
“현재 GPU 온도 알려줘” → AI가 자동으로 get_gpu_status() 호출 → 결과 해석해서 답변.
SECTIOND4

멀티유저 관리 & 권한 설계

팀이나 기업에서 Open WebUI를 운영할 때 사용자 관리와 권한 설계가 핵심입니다. 잘못된 권한 설정은 민감한 Knowledge Base가 모든 직원에게 노출되거나, 고비용 모델을 무제한 사용하게 만듭니다.

👥 역할(Role) 체계 설계

역할모델 접근Knowledge BaseTool 사용이미지 생성관리 기능
Admin전체전체 (생성/삭제)전체무제한전체
User (고급)14B+ 모델할당된 KB승인된 Tool일 50장자기 관리
User (기본)7B 모델만공개 KB만기본 Tool일 10장없음
Pending없음없음없음없음없음

🔐 Google OAuth 연동 설정 (팀 계정으로 자동 로그인)

bash — Google OAuth 환경변수 설정
# Google Cloud Console에서 OAuth 2.0 자격증명 생성 후
# Authorized redirect URI: https://ai.yourdomain.com/oauth/google/callback

# docker-compose 환경변수 추가
- ENABLE_OAUTH_SIGNUP=true
- OAUTH_MERGE_ACCOUNTS_BY_EMAIL=true
- GOOGLE_CLIENT_ID=123456789-abcdefg.apps.googleusercontent.com
- GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxx

# 특정 도메인 계정만 허용 (예: company.com 직원만)
# Admin Panel → Auth → OAuth 설정에서 Allowed Email Domain: company.com

# 처음 OAuth 로그인 시 자동으로 pending 상태로 생성됨
# Admin이 Admin Panel → Users에서 승인 (Role을 user로 변경)

📊 사용량 모니터링 & 비용 추적

python — Open WebUI API로 사용 통계 조회
import httpx
from collections import defaultdict

WEBUI_URL = "http://localhost:3000"
ADMIN_KEY  = "your_admin_api_key"  # Admin Panel → Account → API Key

def get_usage_stats() -> dict:
    """사용자별 채팅 사용량 통계"""
    headers = {"Authorization": f"Bearer {ADMIN_KEY}"}

    # 전체 채팅 목록 (관리자 권한)
    resp = httpx.get(f"{WEBUI_URL}/api/v1/chats/all/db",
                     headers=headers, timeout=30)
    chats = resp.json()

    stats = defaultdict(lambda: {"chats": 0, "messages": 0, "models": set()})
    for chat in chats:
        uid   = chat.get("user_id", "unknown")
        msgs  = chat.get("chat", {}).get("messages", [])
        model = chat.get("chat", {}).get("models", ["?"])[0]

        stats[uid]["chats"]    += 1
        stats[uid]["messages"] += len([m for m in msgs if m.get("role") == "user"])
        stats[uid]["models"].add(model)

    return dict(stats)

stats = get_usage_stats()
for user_id, data in sorted(stats.items(),
                            key=lambda x: x[1]["messages"], reverse=True)[:10]:
    models = ", ".join(list(data["models"])[:3])
    print(f"사용자: {user_id[:8]}..."
          f" | 채팅: {data['chats']}개"
          f" | 메시지: {data['messages']}개"
          f" | 모델: {models}")
SECTIOND5

모델 라우터 & 폴백 전략

모든 쿼리에 14B 대형 모델을 쓸 필요가 없습니다. “안녕”이나 “감사합니다” 같은 간단한 메시지는 7B 모델이 충분하고, 복잡한 코딩 문제는 특화 모델이 더 정확합니다. 지능형 모델 라우터로 속도와 품질을 동시에 최적화합니다.

python — 지능형 모델 라우터 Pipeline
"""
파일명: smart_router_pipe.py
기능: 쿼리 복잡도·유형에 따라 최적 모델 자동 선택
     단순 질문 → qwen2.5:7b (빠름)
     코딩 문제 → deepseek-coder:6.7b (전문)
     복잡한 추론 → qwen2.5:14b (고품질)
     이미지 관련 → gemma3:12b (Vision)
"""
from typing import Union, Generator, Iterator
from pydantic import BaseModel
import httpx, re


class Pipe:
    class Valves(BaseModel):
        OLLAMA_URL:     str = "http://ollama:11434"
        SIMPLE_MODEL:   str = "qwen2.5:7b"
        CODING_MODEL:   str = "deepseek-r1:8b"
        COMPLEX_MODEL:  str = "qwen2.5:14b"
        VISION_MODEL:   str = "gemma3:12b"
        MIN_TOKENS_FOR_COMPLEX: int = 200

    def __init__(self):
        self.valves = self.Valves()

    def pipes(self):
        return [{"id": "smart-router", "name": "🧠 Smart Router (자동 모델 선택)"}]

    def _detect_intent(self, text: str) -> str:
        """쿼리 의도 분류"""
        text_lower = text.lower()
        code_keywords = ["코드","함수","클래스","python","javascript","sql",
                         "def ","class ","import ","error","bug","디버그","구현"]
        complex_keywords = ["분석","비교","설계","아키텍처","전략","최적화",
                            "장단점","차이점","원인","메커니즘","심층"]

        # 이미지 포함 여부 (Vision)
        has_image = any(isinstance(c, dict) and c.get("type") == "image_url"
                        for c in ([text] if isinstance(text, str) else text))
        if has_image:
            return "vision"

        if any(kw in text_lower for kw in code_keywords):
            return "coding"

        if (any(kw in text_lower for kw in complex_keywords)
                or len(text) > self.valves.MIN_TOKENS_FOR_COMPLEX):
            return "complex"

        return "simple"

    def pipe(self, body: dict) -> Union[str, Generator, Iterator]:
        messages = body.get("messages", [])
        last_user = next((m["content"] for m in reversed(messages)
                          if m["role"] == "user"), "")

        intent = self._detect_intent(
            last_user if isinstance(last_user, str)
            else str(last_user)
        )
        model_map = {
            "simple":  self.valves.SIMPLE_MODEL,
            "coding":  self.valves.CODING_MODEL,
            "complex": self.valves.COMPLEX_MODEL,
            "vision":  self.valves.VISION_MODEL,
        }
        selected_model = model_map[intent]
        print(f"[SmartRouter] intent={intent} → model={selected_model}")

        # 선택된 모델로 요청 전달
        body["model"] = selected_model
        with httpx.stream(
            "POST",
            f"{self.valves.OLLAMA_URL}/api/chat",
            json=body,
            timeout=180
        ) as response:
            for line in response.iter_lines():
                if line:
                    import json
                    data = json.loads(line)
                    if content := data.get("message", {}).get("content"):
                        yield content
                    if data.get("done"):
                        break
SECTIOND6

RAG 고급 설정 & Knowledge Base 최적화

🌐 웹 크롤링 자동화 — URL 지정으로 실시간 RAG 구성

python — Open WebUI API로 웹페이지 자동 RAG 인덱싱
import httpx, asyncio WEBUI_URL = “http://localhost:3000” API_KEY = “your_user_api_key” async def add_url_to_knowledge(collection_id: str, url: str) -> dict: “””웹 URL을 Knowledge Base에 자동 추가 (크롤링 + 임베딩)””” async with httpx.AsyncClient(timeout=120) as client: resp = await client.post( f”{WEBUI_URL}/api/v1/knowledge/{collection_id}/file/add”, headers={“Authorization”: f”Bearer {API_KEY}”}, json={“url”: url} ) return resp.json() async def batch_add_urls(collection_id: str, urls: list[str]): “””여러 URL 배치 추가””” for url in urls: print(f”인덱싱 중: {url}”) result = await add_url_to_knowledge(collection_id, url) print(f” → {result.get(‘status’, ‘unknown’)}”) await asyncio.sleep(2) # 서버 부하 방지 # 사용 예시 — 블로그 글 전체 자동 RAG 인덱싱 urls_to_index = [ “https://agibop.com/ai-server-guide-1”, “https://agibop.com/docker-complete-guide”, “https://agibop.com/qdrant-vector-db”, ] asyncio.run(batch_add_urls(“your_collection_id”, urls_to_index))

📺 유튜브 자막 RAG — 영상 내용을 지식베이스로

python — 유튜브 자막 → Qdrant RAG 자동 파이프라인
from youtube_transcript_api import YouTubeTranscriptApi  # pip install youtube-transcript-api
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct
from sentence_transformers import SentenceTransformer
import uuid, re

embedder = SentenceTransformer("BAAI/bge-m3")
qdrant   = QdrantClient(host="192.168.1.253", port=6333, api_key="your_key")

def youtube_to_rag(video_url: str, collection: str = "ai_knowledge_base"):
    """유튜브 영상 자막을 RAG 지식베이스로 자동 변환"""
    # 영상 ID 추출
    video_id = re.search(r'(?:v=|/)([A-Za-z0-9_-]{11})', video_url)
    if not video_id:
        raise ValueError("올바른 유튜브 URL을 입력하세요")
    vid_id = video_id.group(1)

    # 자막 가져오기 (한국어 우선, 영어 폴백)
    try:
        transcript = YouTubeTranscriptApi.get_transcript(vid_id, languages=['ko', 'en'])
    except Exception as e:
        print(f"자막 없음: {e}")
        return

    # 자막을 30초 단위로 청킹
    CHUNK_SEC = 30
    chunks    = []
    current   = {"text": "", "start": 0}

    for entry in transcript:
        current["text"] += " " + entry["text"]
        if entry["start"] - current["start"] >= CHUNK_SEC:
            if current["text"].strip():
                chunks.append({
                    "content":    current["text"].strip(),
                    "start_time": current["start"],
                    "source":     video_url,
                    "type":       "youtube_transcript"
                })
            current = {"text": "", "start": entry["start"]}

    if current["text"].strip():
        chunks.append({"content": current["text"].strip(),
                       "start_time": current["start"],
                       "source": video_url, "type": "youtube_transcript"})

    # 임베딩 & Qdrant 삽입
    texts   = [c["content"] for c in chunks]
    vectors = embedder.encode(texts, normalize_embeddings=True).tolist()

    points = [
        PointStruct(
            id=str(uuid.uuid4()),
            vector=vectors[i],
            payload={
                "content":    chunks[i]["content"],
                "source":     chunks[i]["source"],
                "start_time": f"{int(chunks[i]['start_time']//60)}:{int(chunks[i]['start_time']%60):02d}",
                "type":       "youtube_transcript",
                "category":   "video"
            }
        )
        for i in range(len(chunks))
    ]
    qdrant.upsert(collection_name=collection, points=points)
    print(f"✅ 유튜브 자막 RAG 완료: {len(chunks)}개 청크 인덱싱")

# 사용 예시
youtube_to_rag("https://www.youtube.com/watch?v=example_video_id")
# → Open WebUI에서 "영상에서 RAG 설정 방법 설명해줘" 로 검색 가능
✅ 추가편 D로 완성되는 Open WebUI 마스터 환경
  • 모든 채팅이 한국어 자동 감지 → 시스템 프롬프트 강화 + PII 마스킹 자동 처리
  • 채팅에서 “GPU 상태 확인해줘” → AI가 직접 서버 상태 조회 후 분석 답변
  • Claude Opus 4.5와 로컬 Qwen 모델이 같은 UI에서 선택 가능
  • 쿼리 유형에 따라 최적 모델 자동 선택 → 속도·품질 동시 최적화
  • 팀원별 권한·사용량 관리 + Google 계정으로 간편 로그인
  • 유튜브 영상·웹페이지를 즉시 Knowledge Base에 추가해 RAG 검색
SECTION19

🚀 실전 워크플로우 완전 모음 — 바로 쓰는 n8n 자동화 20선

💡
이 섹션 사용법

아래 20개 워크플로우는 모두 홈랩 AI 서버(Ollama + n8n)와 연동되는 실전 예제입니다. 각 워크플로우의 JSON을 n8n에서 Import → 환경변수만 수정하면 바로 동작합니다. Ollama URL: http://ollama:11434

🗂️ WF-01 — Telegram → AI 질문답변 봇

n8n 워크플로우 개요 (JSON 임포트용)
흐름: Telegram Trigger → Ollama Chat → Telegram 답장
용도: 어디서나 로컬 LLM에 질문
설정:
  - Telegram Bot Token: @BotFather에서 발급
  - Ollama URL: http://ollama:11434
  - 모델: qwen2.5:14b (한국어 최적)
  - System Prompt: "당신은 친절한 AI 어시스턴트입니다. 한국어로 답하세요."
핵심 노드:
  [Telegram Trigger] → [Ollama: /api/chat POST] → [Telegram: sendMessage]

📄 WF-02 — URL 입력 → 웹 요약 → Obsidian 저장

웹페이지 자동 요약 저장 워크플로우
흐름: Telegram "요약 https://..." → Firecrawl 크롤링 → Ollama 요약 → Obsidian REST API 저장
용도: 읽고 싶은 아티클을 AI가 요약해 내 지식 베이스에 자동 저장
설정:
  - Firecrawl URL: http://firecrawl:3002
  - Obsidian Local REST API: http://192.168.1.100:27123
  - 저장 경로: /vault/.raw/web/{{날짜}}_{{제목}}.md
프롬프트:
  "다음 웹페이지 내용을 한국어로 요약하세요.
  형식: YAML 프론트매터(title, url, date, tags) + 핵심 요점 5개 + 상세 요약"

🎤 WF-03 — 회의 녹음 → STT → 회의록 → Notion 저장

회의록 자동 생성 파이프라인
흐름: 파일 드롭(mp3/wav) → Whisper STT → Ollama 회의록 작성 → Notion API 저장
용도: 회의 후 자동으로 회의록·액션아이템 정리
Whisper 설정:
  - URL: http://whisper:9000/asr
  - 언어: ko (한국어)
  - 모델: large-v3
Ollama 프롬프트:
  "다음 회의 녹취록에서 추출하세요:
  1. 회의 제목 및 일시
  2. 참석자 목록
  3. 주요 논의 사항 (번호 목록)
  4. 결정된 사항
  5. 액션 아이템 (담당자, 기한 포함)
  6. 다음 회의 안건"

📊 WF-04 — 주식 뉴스 자동 수집 → AI 분석 → 리포트

주식 뉴스 AI 분석 자동화
흐름: Cron(매일 07:00) → RSS/API 뉴스 수집 → Ollama 감성분석 → Telegram 리포트
용도: 관심 종목 뉴스를 매일 아침 AI가 분석해서 알림
뉴스 소스:
  - 한국경제TV RSS: https://www.wowtv.co.kr/NewsCenter/RSS
  - 네이버 금융 API
  - KIS Developers (주가 데이터)
Ollama 프롬프트:
  "다음 뉴스들에서 {{종목명}} 관련 내용을 분석하세요.
  출력: 긍정/부정/중립 판단, 핵심 이슈, 투자 시사점 (3줄 이내)"

📧 WF-05 — 이메일 자동 분류 & 요약 답장 초안 생성

이메일 AI 비서 워크플로우
흐름: Gmail Trigger(새 메일) → Ollama 분류/요약 → 카테고리별 레이블 → 답장 초안 → Telegram 알림
용도: 중요 이메일 놓치지 않고, 답장 초안 자동 생성
분류 카테고리: [긴급/업무/광고/구독/개인]
프롬프트:
  "다음 이메일을 분석하세요:
  1. 카테고리: [긴급/업무/광고/구독/개인] 중 선택
  2. 한 줄 요약
  3. 필요한 경우 한국어 답장 초안 (200자 이내)
  4. 긴급 여부 (true/false)"

🔬 WF-06 — 논문/PDF → AI 분석 → 지식 베이스 자동 구축

흐름: 폴더 감시(새 PDF) → PyMuPDF 텍스트 추출 → Ollama 논문 분석 → Obsidian 위키 생성
용도: 논문 읽을 때마다 자동으로 개인 지식 베이스 구축
Ollama 프롬프트:
  "다음 논문을 분석해 Obsidian 마크다운 형식으로 정리하세요:
  ---
  type: source
  source_type: paper
  title: [논문 제목]
  authors: [저자]
  year: [연도]
  tags: [핵심 키워드 3~5개]
  ---
  ## 핵심 기여
  ## 방법론
  ## 실험 결과
  ## 한계점
  ## 내 생각
  ## 관련 개념 [[링크]]"

🛒 WF-07 — 쇼핑몰 리뷰 자동 수집 & 감성분석 리포트

흐름: Cron(매일) → 쇼핑 API 리뷰 수집 → Ollama 감성분석 → Meilisearch 저장 → 대시보드
용도: 소상공인 상품 리뷰 자동 모니터링 & 개선점 도출
지원 플랫폼: 쿠팡·네이버스마트스토어·G마켓 API
분석 항목:
  - 긍정/부정 비율
  - 자주 언급되는 키워드
  - 개선 요구사항 Top 5
  - 경쟁 제품 언급 감지

✍️ WF-08 — 키워드 입력 → SEO 블로그 포스트 자동 생성

흐름: Telegram "블로그 [키워드]" → Meilisearch 기존 글 검색 → Ollama 포스트 작성 → WordPress API 임시저장
용도: 블로그 콘텐츠 반자동화 (초안 생성 → 사람이 검토 후 발행)
설정:
  - WordPress REST API: https://agibop.com/wp-json/wp/v2/posts
  - 상태: draft (바로 발행 안 함)
프롬프트:
  "다음 키워드로 한국어 블로그 포스트를 작성하세요.
  키워드: {{keyword}}
  형식: HTML (WordPress용)
  구조: 서론 → H2 섹션 4~6개 → 결론
  분량: 2000~3000자
  SEO: 키워드를 자연스럽게 포함, 관련 LSI 키워드 활용"

🔔 WF-09 — 서버 이상 감지 → AI 진단 → 자동 알림

흐름: Cron(5분마다) → Prometheus API 메트릭 수집 → 이상치 감지 → Ollama 원인 분석 → Telegram 알림
용도: 서버 이상 시 원인과 해결책을 AI가 자동 분석해서 알림
감지 조건:
  - GPU 온도 > 85°C
  - 메모리 사용률 > 90%
  - 컨테이너 재시작 횟수 증가
  - 디스크 사용률 > 85%
Ollama 프롬프트:
  "다음 서버 메트릭 이상 상황을 분석하세요:
  {{metrics_json}}
  1. 예상 원인
  2. 즉시 조치 사항
  3. 장기 해결 방안"

🎓 WF-10 — YouTube 영상 → 자막 추출 → 학습 노트 자동화

흐름: Telegram "유튜브 https://youtube.com/..." → yt-dlp 자막 추출 → Whisper STT(자막없을때) → Ollama 학습노트 → Obsidian 저장
용도: 유튜브 강의·컨퍼런스 영상을 구조화된 학습 노트로 자동 변환
yt-dlp 명령:
  yt-dlp --write-auto-sub --sub-lang ko,en --skip-download -o /tmp/%(id)s {{url}}
Ollama 프롬프트:
  "다음 영상 자막을 학습 노트 형식으로 정리하세요:
  ## 핵심 개념 (3~5개)
  ## 타임스탬프별 주요 포인트
  ## 내가 배운 것
  ## 실천할 것
  ## 관련 자료 추천"

🏪 WF-11 — 고객 문의 자동 1차 응답 시스템

흐름: 이메일/폼 문의 수신 → Qdrant FAQ 검색 → Ollama 답변 생성 → 자동 이메일 발송 → 미해결 시 담당자 알림
용도: 반복 문의는 AI가 처리, 복잡한 문의만 사람에게 전달
RAG 설정:
  - Qdrant에 FAQ·제품설명·정책 문서 임베딩
  - 유사도 임계값: 0.8 이상 = 자동 답변, 미만 = 담당자 전달
프롬프트:
  "당신은 {{회사명}} 고객 서비스 담당자입니다.
  다음 FAQ를 참고해 고객 문의에 정중하게 답변하세요.
  FAQ: {{context}}
  문의: {{query}}
  답변은 200자 이내, 공손하게, 해결 불가 시 '담당자 연결 안내'"

📱 WF-12 — SNS 콘텐츠 자동 생성 & 예약 발행

흐름: Cron(매일 08:00) → 트렌드 수집(Google Trends API) → Ollama 포스트 작성 → Buffer/Meta API 예약 발행
용도: SNS 일일 콘텐츠 반자동화
플랫폼별 형식:
  Instagram: 해시태그 30개 포함, 1200자 이내, 이모지 활용
  X(Twitter): 280자 이내, 링크 포함, 스레드 구성
  LinkedIn: 전문적 톤, 인사이트 중심, 1500자
  블로그: HTML 2000자 이상, SEO 최적화

📝 WF-13 — 코드 리뷰 봇 (GitHub PR 자동 검토)

흐름: GitHub Webhook(PR 생성) → 변경 파일 diff 수집 → Ollama 코드리뷰 → PR 코멘트 자동 게시
용도: PR 올릴 때마다 AI가 코드 품질·버그·보안 이슈 1차 검토
Ollama 프롬프트:
  "다음 코드 변경사항을 리뷰하세요.
  언어: {{language}}
  diff: {{diff}}
  검토 항목:
  1. 잠재적 버그 및 오류
  2. 성능 개선 제안
  3. 보안 취약점
  4. 코드 가독성 개선
  5. 테스트 커버리지 제안
  형식: 마크다운, 심각도(🔴/🟡/🟢) 표시"

🌐 WF-14 — 다국어 문서 자동 번역 & 용어집 관리

흐름: 파일 감시(새 문서) → Ollama 번역 → 용어집 일관성 검사 → 번역 파일 저장
용도: 기술 문서·매뉴얼 자동 다국어화
지원 언어쌍: 영→한, 한→영, 영→일, 영→중
용어집 관리:
  - Meilisearch에 도메인별 용어집 저장
  - 번역 전 용어집 검색 → 일관된 번역어 사용
  - 새 용어 발견 시 용어집 자동 추가
프롬프트:
  "다음 기술 문서를 {{대상언어}}로 번역하세요.
  용어집: {{glossary}}
  원문: {{source}}
  주의: 용어집에 있는 단어는 반드시 정의된 번역어 사용"

📅 WF-15 — 일정 관리 AI 비서 (Google Calendar 연동)

흐름: Telegram "내일 일정?" → Google Calendar API → Ollama 일정 요약 & 준비사항 → Telegram 답장
추가 기능:
  - "회의 추가: 내일 2시 팀미팅 30분" → 파싱 → Calendar 이벤트 생성
  - 매일 아침 7시 당일 일정 브리핑 자동 발송
  - 회의 전 30분 Telegram 알림 + 안건 준비사항 AI 생성
프롬프트:
  "다음 일정들을 바탕으로 오늘 하루를 브리핑하세요:
  {{events_json}}
  포함 사항: 시간순 일정, 준비할 것, 이동 시간, 여유 시간 분석"

🔍 WF-16 — 경쟁사 모니터링 & AI 분석 리포트

흐름: Cron(주 1회) → 경쟁사 웹사이트 크롤링(Firecrawl) → 변경사항 감지(diff) → Ollama 분석 → 리포트 이메일
용도: 경쟁사 신제품·가격 변경·공지사항 자동 모니터링
모니터링 항목:
  - 메인 페이지 변경
  - 가격 페이지 변경
  - 블로그/공지 신규 포스팅
  - LinkedIn 채용 공고 (전략 방향 파악)
Ollama 분석:
  "다음 경쟁사 웹사이트 변경사항을 분석하세요:
  이전: {{old_content}}
  현재: {{new_content}}
  분석: 변경의 의미, 우리에게 미치는 영향, 대응 방안"

📦 WF-17 — 재고 관리 AI 자동화 (소상공인용)

흐름: 판매 데이터 수집(Google Sheets) → Ollama 수요 예측 → 발주 시점 계산 → Telegram 발주 알림
용도: 소규모 쇼핑몰 재고 부족·과잉 방지
분석 요소:
  - 최근 30일 판매 트렌드
  - 계절성 패턴
  - 현재 재고 수준
  - 납기 기간
Ollama 프롬프트:
  "다음 재고·판매 데이터를 분석해 발주 추천을 해주세요:
  {{inventory_data}}
  출력: 발주 필요 품목, 추천 발주량, 긴급 여부"

🎵 WF-18 — 텍스트 → AI 음악 생성 자동화 (ACE-Step 연동)

흐름: Telegram "음악생성 [설명]" → Ollama 프롬프트 최적화 → ACE-Step API → 완성 MP3 → Telegram 전송
용도: 텍스트로 AI 음악 자동 생성
ACE-Step 설정:
  - URL: http://ace-step:7865/api/generate
  - 모델: ACE-Step 1.5 Turbo
  - 파라미터: duration=120, batch_size=4
Ollama 역할: 사용자의 자연어 요청을 ACE-Step 전용 스타일 프롬프트로 변환
예: "신나는 운동 음악" → "upbeat EDM, punchy drums, 128 BPM, energetic, no vocals"

🧪 WF-19 — A/B 테스트 콘텐츠 자동 생성 & 결과 분석

흐름: 캠페인 설정 → Ollama 변형 콘텐츠 N개 생성 → 플랫폼 배포 → 성과 수집 → Ollama 승자 분석
용도: 이메일·광고·랜딩페이지 자동 A/B 테스트
Ollama 역할 1 (생성):
  "다음 광고 문구의 A/B 테스트 변형 4개를 만드세요.
  원본: {{original}}
  변형 전략: 제목 변경, CTA 변경, 감성 톤 변경, 길이 변경"
Ollama 역할 2 (분석):
  "A/B 테스트 결과를 분석하세요:
  {{results_json}}
  출력: 승자 및 이유, 통계적 유의성, 다음 테스트 제안"

🤖 WF-20 — AI 에이전트 팀 오케스트레이션 (멀티에이전트)

흐름: 복잡한 태스크 입력 → 오케스트레이터 LLM이 서브태스크 분해 → 각 에이전트 병렬 실행 → 결과 통합
구성:
  오케스트레이터: qwen2.5:32b (태스크 분해·할당·통합)
  리서치 에이전트: qwen2.5:14b + Firecrawl (웹 검색·수집)
  분석 에이전트: qwen2.5:14b (데이터 분석·인사이트)
  작성 에이전트: qwen2.5:14b (문서·보고서 작성)
  검증 에이전트: qwen2.5:7b (사실 확인·품질 검수)

n8n 구현:
  [입력] → [오케스트레이터: 태스크 분해 JSON] → [Switch 노드]
    → [에이전트1 HTTP] ──┐
    → [에이전트2 HTTP] ──┤→ [Merge] → [오케스트레이터: 통합] → [출력]
    → [에이전트3 HTTP] ──┘
🎯
n8n 워크플로우 관리 팁

① 모든 워크플로우에 에러 핸들러 노드를 추가해 실패 시 Telegram 알림 받기
n8n 환경변수로 API URL을 관리 → 서버 IP 변경 시 일괄 수정 가능
③ 개발 완료 후 n8n Export → GitHub에 JSON 백업
④ 프로덕션 워크플로우는 실행 로그를 7일 보존 설정 (n8n Settings)

← 이전 편
3편 — 이미지·음성·비전 AI 완전 구현
다음 편 →
5편 — RAG·데이터파이프라인·모니터링·운영

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here

Stay on op - Ge the daily news in your inbox