n8n AI 워크플로우 구축
Claude·OpenAI·Gemini·Ollama를 n8n과 연동하여 AI 에이전트·RAG·멀티에이전트·Human-in-the-Loop 파이프라인을 구축하는 완전 실전 가이드
n8n AI 노드 생태계
n8n은 LangChain 기반의 AI 노드들을 기본 제공합니다. 코드 없이 AI 에이전트, RAG 파이프라인, 멀티모달 처리를 워크플로우로 구성할 수 있습니다.
n8n AI 노드 계층: AI Agent가 LLM 모델·메모리·도구를 조합하여 자율 실행
AI 노드 전체 카탈로그
| 카테고리 | 노드 | 역할 |
|---|---|---|
| Chain | Basic LLM Chain | 프롬프트 → LLM → 텍스트 출력 |
| Summarization Chain | 긴 문서 요약 (Map-Reduce 또는 Stuffing) | |
| Retrieval Q&A Chain | 문서 기반 Q&A (벡터 스토어 결합) | |
| Conversational Chain | 메모리 포함 대화형 체인 | |
| Agent | AI Agent | ReAct 패턴, 자율 도구 선택·실행 |
| LLM 모델 | Anthropic Chat Model | Claude API (claude-opus-4-7 등) |
| OpenAI Chat Model | GPT-4.1, GPT-4.1-mini 등 | |
| Google Gemini Chat Model | Gemini 3.1 Pro / 3 Flash | |
| Ollama Chat Model | 로컬 LLM (Llama, Mistral 등) | |
| Groq Chat Model | 초고속 Llama 추론 (무료 티어) | |
| Azure OpenAI Chat Model | Azure 배포 GPT 모델 | |
| 메모리 | Window Buffer Memory | 최근 N개 메시지 보관 (인메모리) |
| Redis Chat Memory | Redis 기반 세션별 영속 메모리 | |
| Postgres Chat Memory | PostgreSQL 기반 영속 메모리 | |
| Motorhead Memory | Motorhead 서버 기반 요약 메모리 | |
| 벡터 스토어 | In-Memory Vector Store | 임시 메모리 벡터 (테스트용) |
| Pinecone Vector Store | Pinecone 클라우드 | |
| Qdrant Vector Store | Qdrant 셀프호스팅 | |
| Supabase Vector Store | Supabase pgvector | |
| Chroma Vector Store | ChromaDB 셀프호스팅 | |
| 임베딩 | OpenAI Embeddings | text-embedding-3-small/large |
| Anthropic (via HTTP) | voyage-3 등 별도 호출 | |
| Ollama Embeddings | 로컬 임베딩 (무료) | |
| 문서 로더 | Default Data Loader | Binary 데이터(PDF, DOCX, CSV 등) |
| GitHub Document Loader | GitHub 저장소 파일 로드 | |
| Notion Document Loader | Notion 페이지/DB 로드 | |
| JSON Document Loader | JSON 파일 로드 | |
| Recursive URL Loader | 웹사이트 크롤링 + 로드 | |
| 텍스트 분할 | Recursive Character Text Splitter | 범용 (권장) |
| Character Text Splitter | 단순 문자 기준 분할 | |
| Token Text Splitter | 토큰 수 기준 정확한 분할 | |
| 출력 파서 | Auto-fixing Output Parser | 파싱 실패 시 LLM이 자동 수정 |
| Structured Output Parser | JSON Schema 기반 구조화 출력 | |
| Item List Output Parser | 목록 형태 출력 파싱 | |
| 도구 (Tool) | Calculator | 수학 계산 |
| HTTP Request Tool | 에이전트가 외부 API 호출 | |
| Wikipedia | Wikipedia 검색 | |
| SerpAPI | Google 검색 결과 | |
| n8n Workflow Tool | 서브워크플로우를 도구로 사용 |
AI 모델 연동 심화 (Anthropic·OpenAI·Gemini)
자격증명 설정
# UI에서 자격증명 추가 — 프로바이더별 설정
## Anthropic (Claude)
Settings → Credentials → Add Credential → Anthropic
API Key: sk-ant-api03-...
## OpenAI (GPT)
Settings → Credentials → Add Credential → OpenAI
API Key: sk-proj-...
## Google Gemini
Settings → Credentials → Add Credential → Google AI (Gemini)
API Key: AIza...
# 환경 변수로도 설정 가능 (n8n이 자동으로 자격증명 생성)
ANTHROPIC_API_KEY=sk-ant-api03-...
OPENAI_API_KEY=sk-proj-...
GOOGLE_AI_API_KEY=AIza...
Basic LLM Chain 구성
# Basic LLM Chain 노드 설정 (Anthropic 예시)
Chat Model → Anthropic Chat Model
Model: claude-opus-4-7
Max Tokens: 4096
Temperature: 0.7
Top P: 0.9
Extended Thinking: OFF (고급 추론 시 ON)
# 대안: OpenAI Chat Model → gpt-4.1 / gpt-4.1-mini
# 대안: Google Gemini Chat Model → gemini-3-flash
# 대안: Ollama Chat Model → llama3, mistral (로컬 무료)
Prompt:
System: |
당신은 전문적인 코드 리뷰어입니다.
코드의 문제점을 구체적으로 지적하고 개선 방안을 제시하세요.
응답은 반드시 한국어로 작성하세요.
Human: {{ $json.code }}
HTTP Request로 LLM API 직접 호출
멀티모달(이미지 분석), 스트리밍, 캐시 제어 등 고급 기능은 HTTP Request 노드로 직접 호출합니다.
아래는 Anthropic API 예시이며, OpenAI는 https://api.openai.com/v1/chat/completions,
Gemini는 https://generativelanguage.googleapis.com/v1beta/models/로 동일 패턴 적용이 가능합니다.
# HTTP Request 노드 — Anthropic Claude API 직접 호출 예시
Method: POST
URL: https://api.anthropic.com/v1/messages
Headers:
x-api-key: {{ $env.ANTHROPIC_API_KEY }}
anthropic-version: 2023-06-01
content-type: application/json
anthropic-beta: prompt-caching-2024-07-31 # 프롬프트 캐싱
Body (JSON):
{
"model": "claude-opus-4-7",
"max_tokens": 4096,
"system": [
{
"type": "text",
"text": "{{ $json.systemPrompt }}",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [
{
"role": "user",
"content": "{{ $json.userMessage }}"
}
]
}
// 응답 파싱 (Code 노드)
const resp = $json;
return [{
json: {
answer: resp.content[0].text,
inputTokens: resp.usage.input_tokens,
outputTokens: resp.usage.output_tokens,
cacheRead: resp.usage.cache_read_input_tokens ?? 0,
cacheWrite: resp.usage.cache_creation_input_tokens ?? 0,
stopReason: resp.stop_reason,
// 비용 추정 (claude-opus-4-7 기준, 모델별 단가 상이)
costUSD: (resp.usage.input_tokens / 1e6 * 5) +
(resp.usage.output_tokens / 1e6 * 25),
}
}];
이미지 분석 (Vision)
# 이미지 URL → Anthropic Vision 분석 (OpenAI·Gemini도 유사 API 제공)
## HTTP Request 노드 Body
{
"model": "claude-opus-4-7",
"max_tokens": 2048,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "{{ $json.imageUrl }}"
}
},
{
"type": "text",
"text": "이 이미지를 자세히 설명하고, 주요 객체를 JSON 배열로 나열하세요."
}
]
}
]
}
# Binary 이미지 → Base64 → LLM Vision API
## Code 노드 — Binary를 Base64로 변환
const item = $input.first();
const base64 = item.binary.data.data; // 이미 base64
const mimeType = item.binary.data.mimeType;
return [{ json: { base64, mimeType } }];
## HTTP Request Body (base64 이미지)
{
"model": "claude-opus-4-7",
"max_tokens": 2048,
"messages": [{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "{{ $json.mimeType }}",
"data": "{{ $json.base64 }}"
}
},
{ "type": "text", "text": "{{ $json.prompt }}" }
]
}]
}
출력 파서 (Output Parser)
LLM의 자유 형식 텍스트 출력을 구조화된 데이터로 변환합니다.
이후 노드에서 $json.fieldName으로 바로 접근할 수 있어 워크플로우 연결이 매우 간편해집니다.
Structured Output Parser
# Basic LLM Chain + Structured Output Parser 구성
Output Parser → Structured Output Parser
Schema Type: Manual
Attributes:
- Name: category
Type: string
Description: "분류 카테고리 (결제/기술/계정/기타 중 하나)"
- Name: severity
Type: options
Options: 긴급, 높음, 보통, 낮음
Description: "심각도 수준"
- Name: summary
Type: string
Description: "50자 이내 한국어 요약"
- Name: requiresHuman
Type: boolean
Description: "인간 담당자 처리 필요 여부"
# 프롬프트에 파서 지침이 자동 추가됨
# 출력 결과 → 바로 $json.category, $json.severity 로 접근
// 파싱 결과 예시
{
"category": "결제",
"severity": "긴급",
"summary": "신용카드 결제 실패, 즉시 처리 필요",
"requiresHuman": true
}
Auto-fixing Output Parser
LLM이 잘못된 형식을 반환하면, 에러 메시지와 함께 LLM에게 자동으로 재요청하여 수정합니다.
# Auto-fixing Output Parser 설정
Output Parser → Auto-fixing Output Parser
Parser: Structured Output Parser (내부에 구조 정의)
Max Retries: 3 # 최대 수정 재시도 횟수
# 동작 방식
1. LLM 출력 파싱 시도
2. 실패 → LLM에 에러 메시지와 함께 재요청
"다음 에러를 수정하세요: JSON parse error at line 3..."
3. 최대 Retry 횟수까지 반복
4. 여전히 실패 → 노드 에러 처리
Code 노드로 수동 파싱
// LLM 출력에서 JSON 추출 (마크다운 코드블록 포함 경우)
const text = $json.text || $json.output;
// ```json ... ``` 블록 추출
const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
if (jsonMatch) {
const parsed = JSON.parse(jsonMatch[1].trim());
return [{ json: parsed }];
}
// 순수 JSON 파싱 시도
try {
const parsed = JSON.parse(text.trim());
return [{ json: parsed }];
} catch {
// 정규식으로 키-값 추출 (폴백)
const category = text.match(/category[:\s]+([^\n,}]+)/i)?.[1]?.trim();
return [{ json: { category, rawText: text } }];
}
AI Agent 노드 완전 가이드
AI Agent 노드는 LLM이 스스로 "어떤 도구를 쓸지" 판단하고, 도구 실행 결과를 바탕으로 다음 행동을 결정하는 ReAct 패턴을 구현합니다.
AI Agent ReAct 루프: Thought → Action(도구 호출) → Observation → 반복 → Final Answer
AI Agent 핵심 설정
# AI Agent 노드 전체 설정 (Anthropic 예시)
Chat Model → Anthropic Chat Model
Model: claude-opus-4-7 # 또는 OpenAI: gpt-4.1 / Gemini: gemini-3-flash
Temperature: 0 # 도구 사용 시 결정론적 행동 권장
Max Tokens: 4096
Memory → Window Buffer Memory
Context Window Length: 10
Max Iterations: 10 # 무한 루프 방지 (도구 최대 호출 횟수)
Return Intermediate Steps: true # 중간 Thought/Action 포함 출력
System Prompt: |
당신은 유용한 AI 어시스턴트입니다.
주어진 도구를 적극 활용하여 정확한 답변을 제공하세요.
최종 답변은 반드시 한국어로 작성하세요.
모르는 정보는 추측하지 말고 도구로 확인하세요.
Human Message: {{ $json.userMessage }}
도구(Tool) 설정 상세
# HTTP Request Tool — 주식/암호화폐 가격 조회
Name: get_crypto_price
Description: |
암호화폐의 현재 가격과 24시간 변동률을 조회합니다.
id 파라미터에 코인 ID를 입력하세요.
예: bitcoin, ethereum, ripple
Method: GET
URL: https://api.coingecko.com/api/v3/simple/price
Query Parameters:
ids: {{ $parameter.id }}
vs_currencies: usd,krw
include_24hr_change: true
# n8n Workflow Tool — 복잡한 DB 조회를 서브워크플로우로
Name: get_customer_info
Description: |
고객 ID로 고객 정보(이름, 이메일, 주문 이력)를 조회합니다.
customer_id 파라미터에 고객 ID(숫자)를 입력하세요.
Workflow: "고객 정보 조회 서브워크플로우"
# 서브워크플로우 내부:
Execute Workflow Trigger
↓
PostgreSQL
Query: |
SELECT c.*, json_agg(o.*) as orders
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE c.id = {{ $json.customer_id }}
GROUP BY c.id
↓
Respond to Workflow
에이전트 시스템 프롬프트 설계
# 고객 지원 에이전트 시스템 프롬프트 예시
당신은 [회사명] 공식 고객 지원 AI입니다.
## 역할과 권한
- 주문 조회, 배송 상태 확인, 반품/교환 안내 가능
- 환불 처리는 50,000원 이하만 직접 처리 가능
- 50,000원 초과 또는 법적 분쟁 → 인간 담당자 연결
## 도구 사용 규칙
- 고객 정보 조회 시 반드시 get_customer_info 도구 사용
- 주문 상태 확인 시 반드시 get_order_status 도구 사용
- 추측으로 주문 상태를 답변하지 말 것
## 응답 형식
- 친절하고 공감적인 어조 유지
- 전문 용어 대신 쉬운 표현 사용
- 해결이 어려우면 담당자 연결 제안
## 개인정보 보호
- 전화번호, 신용카드 번호를 응답에 포함하지 말 것
- 이메일은 마스킹 처리: hong***@example.com
메모리 전략
메모리 종류 비교
| 메모리 타입 | 영속성 | 토큰 사용 | 적합한 사용처 | 세션 분리 |
|---|---|---|---|---|
| Window Buffer | 인메모리 (임시) | 최근 N개 × 메시지 길이 | 단일 실행 내 대화 | 실행 ID 기준 |
| Redis Chat | Redis에 영속 | 설정한 Window 크기 | 다중 세션, 챗봇 | Session ID 키 |
| Postgres Chat | DB에 영속 | 설정한 Window 크기 | 대화 이력 분석 필요 시 | Session ID 컬럼 |
| 없음(Stateless) | 없음 | 없음 | 단발성 질의, 분류·요약 | - |
세션별 메모리 관리
# Redis Chat Memory — 사용자별 독립 메모리
AI Agent
Memory → Redis Chat Memory
Session Key: {{ $json.userId }} # 사용자별 분리
Session ID: {{ $json.sessionId }} # 또는 대화 세션별 분리
Context Window Length: 20 # 최근 20개 메시지
Redis Credential: (Redis 자격증명)
# Telegram 봇 예시 — chat.id로 세션 분리
Session Key: {{ $json.message.chat.id }}
// Code 노드 — 오래된 메모리 수동 정리 (Redis)
// 특정 사용자의 대화 이력 초기화
const userId = $json.userId;
const sessionKey = `n8n:${userId}:history`;
// 다음 Redis 노드에서 DEL 명령 실행
return [{ json: { sessionKey } }];
RAG 파이프라인 완전 구축
문서 로더 종류
| 로더 | 지원 형식 | 특이사항 |
|---|---|---|
| Default Data Loader (Binary) | PDF, DOCX, TXT, HTML, CSV, JSON | Binary 노드 출력을 연결 |
| GitHub Document Loader | GitHub 저장소 파일 | 특정 디렉토리·확장자 필터 가능 |
| Notion Document Loader | Notion 페이지·DB | Notion API 자격증명 필요 |
| Recursive URL Loader | 웹페이지 (크롤링) | 최대 깊이, 도메인 제한 설정 |
| JSON Document Loader | JSON 파일/구조 | 특정 키만 텍스트로 추출 가능 |
텍스트 분할기 비교
| 분할기 | 분할 기준 | 권장 설정 | 적합한 경우 |
|---|---|---|---|
| Recursive Character | \n\n → \n → 공백 → 문자 | Chunk: 1000, Overlap: 200 | 범용 (가장 추천) |
| Character | 단일 구분자 (기본: \n\n) | Chunk: 2000, Overlap: 200 | 문단 기준 명확한 문서 |
| Token | LLM 토큰 수 기준 | Chunk: 512 tokens | 토큰 한도 정확히 제어 시 |
워크플로우 1: 문서 인덱싱 파이프라인
# 문서 → 청크 → 임베딩 → 벡터 DB 저장
## 트리거: 파일 업로드 Webhook
Webhook Trigger (multipart/form-data)
↓
## 메타데이터 추출
Code 노드
const filename = $binary.data.fileName;
const source = $json.source ?? 'upload';
const uploadedBy = $json.uploadedBy ?? 'system';
return [{ json: { filename, source, uploadedBy }, binary: $input.first().binary }];
↓
## 중복 체크 (선택)
Supabase 노드
Query: SELECT id FROM documents WHERE filename = '{{ $json.filename }}'
↓
IF (이미 존재하면) → 409 응답 반환
## 문서 → 텍스트 청크 분할
Default Data Loader
Data Type: Binary (자동 감지: PDF/DOCX/TXT)
Text Splitter → Recursive Character Text Splitter
Chunk Size: 1000
Chunk Overlap: 200
Separators: ["\n\n", "\n", " ", ""]
↓
## 임베딩 생성 + 벡터 DB 저장
Supabase Vector Store
Operation: Insert Documents
Embedding → OpenAI Embeddings (text-embedding-3-small)
Table: documents
Query Name: match_documents
Metadata:
source: {{ $json.filename }}
uploadedBy: {{ $json.uploadedBy }}
uploadedAt: {{ $now.toISO() }}
↓
## 완료 응답
Respond to Webhook
Body: { "success": true, "chunks": {{ $input.all().length }} }
워크플로우 2: RAG 질의응답
# 질문 → 벡터 검색 → LLM 답변 생성
Webhook Trigger
Body: { "question": "...", "userId": "...", "topK": 5 }
↓
## 방법 A: Retrieval Q&A Chain (간단)
Retrieval Q&A Chain
Chat Model → Anthropic (claude-opus-4-7) # 또는 OpenAI (gpt-4.1) / Gemini 등
Vector Store → Supabase (Retrieve Documents)
Query: {{ $json.question }}
Top K: {{ $json.topK ?? 5 }}
Prompt Template: |
다음 문서를 참고하여 질문에 답변하세요.
문서에 없는 내용은 "문서에서 확인할 수 없습니다"라고 답변하세요.
문서:
{context}
질문: {question}
↓
Respond to Webhook (answer + sources)
## 방법 B: AI Agent + Vector Store Tool (더 유연)
AI Agent
Chat Model: Anthropic claude-opus-4-7 # 또는 OpenAI gpt-4.1 등
Memory: Redis Chat Memory (userId 키)
Tools:
Vector Store Retriever Tool
Vector Store: Supabase
Name: search_documents
Description: "내부 문서에서 관련 정보를 검색합니다. query에 검색할 내용을 입력하세요."
Top K: 5
Filter: { "source": "{{ $json.docSource }}" } # 특정 문서만
System Prompt: |
당신은 내부 문서 기반 AI 어시스턴트입니다.
반드시 search_documents 도구로 문서를 확인한 후 답변하세요.
출처 파일명을 항상 명시하세요.
문서에 없는 내용은 솔직히 모른다고 하세요.
Human: {{ $json.question }}
고급 RAG 기법
// 하이브리드 검색: 벡터 유사도 + 키워드 검색 결합
// 1. 벡터 검색 (의미적 유사도)
Supabase Vector Store Retrieve → 상위 10개
// 2. PostgreSQL 키워드 검색 (Full-Text Search)
PostgreSQL:
SELECT *, ts_rank(to_tsvector('korean', content), query) AS rank
FROM documents, to_tsquery('korean', '{{ $json.keywords }}') query
WHERE to_tsvector('korean', content) @@ query
ORDER BY rank DESC LIMIT 10
// 3. Code 노드 — 결과 병합 및 중복 제거
const vector = $items("Vector Store").map(i => i.json);
const keyword = $items("PostgreSQL").map(i => i.json);
const merged = [...vector, ...keyword];
const seen = new Set();
const unique = merged.filter(d => {
if (seen.has(d.id)) return false;
seen.add(d.id);
return true;
});
return [{ json: { documents: unique.slice(0, 8) } }];
↓
// 4. LLM에 컨텍스트와 함께 전달
// 쿼리 재작성 (Query Rewriting) — 검색 품질 향상
Basic LLM Chain (쿼리 재작성 전용, 빠른 모델 사용)
Chat Model: claude-haiku-4-5 # 또는 gpt-4.1-mini, gemini-3-flash (경량 모델 권장)
Prompt: |
대화 이력과 사용자 질문을 보고, 문서 검색에 최적화된
독립적인 검색 쿼리를 한국어로 작성하세요.
대화 이력 없이도 이해 가능한 완전한 쿼리여야 합니다.
대화 이력: {{ $json.history ?? "없음" }}
사용자 질문: {{ $json.question }}
검색 쿼리만 출력 (설명 없이):
↓
벡터 DB 검색 (재작성된 쿼리로)
멀티에이전트 패턴
패턴 1: 병렬 전문가 에이전트
# 하나의 복잡한 질문을 여러 전문 에이전트가 병렬 처리
Webhook Trigger ("분기별 실적 분석해줘")
↓
Code 노드 (질문 분해)
return [
{ json: { question: "Q1-Q2 매출 트렌드", agent: "sales" } },
{ json: { question: "비용 구조 분석", agent: "finance" } },
{ json: { question: "시장 점유율 변화", agent: "market" } },
];
↓ (3개 아이템, 병렬 처리)
## 각 아이템에 대해 담당 에이전트 라우팅
Switch 노드 ({{ $json.agent }}으로 분기)
"sales" → 매출 분석 에이전트 (DB Tool + Chart Tool)
"finance"→ 재무 분석 에이전트 (DB Tool + Calculator)
"market" → 시장 분석 에이전트 (Web Search Tool + DB Tool)
↓ (Merge: Append)
## 결과 통합 에이전트
AI Agent (통합 요약)
System: "세 전문가의 분석을 종합하여 경영 보고서를 작성하세요."
Human: "분석 결과:\n{{ $json.allResults }}"
패턴 2: 슈퍼바이저 에이전트
# 슈퍼바이저가 전문 에이전트들을 지휘
Chat Trigger (사용자 요청)
↓
슈퍼바이저 AI Agent
System: |
당신은 팀 슈퍼바이저입니다.
사용자 요청을 분석하고 적절한 전문 에이전트에게 작업을 할당하세요.
사용 가능한 에이전트:
- research_agent: 웹 검색, 정보 수집
- code_agent: 코드 작성, 디버깅
- data_agent: 데이터 분석, 시각화
결과를 검토하고 최종 답변을 사용자에게 전달하세요.
Tools:
→ research_agent (Workflow Tool)
→ code_agent (Workflow Tool)
→ data_agent (Workflow Tool)
패턴 3: Human-in-the-Loop
# AI 처리 → 사람 검토 → 승인/거절 → 계속 실행
Webhook Trigger (자동화 요청)
↓
AI Agent (초안 작성)
↓
## 사람 검토 요청 (Slack에 승인 요청)
Slack 노드
Text: "AI가 다음 초안을 작성했습니다:\n{{ $json.draft }}\n승인하시겠습니까?"
Blocks:
- type: actions
elements:
- type: button
text: "✅ 승인"
action_id: approve
value: "{{ $execution.resumeUrl }}?action=approve"
- type: button
text: "❌ 거절"
action_id: reject
value: "{{ $execution.resumeUrl }}?action=reject"
style: danger
↓
## Webhook 재개 대기 (최대 24시간)
Wait 노드
Resume: On Webhook Call
Webhook Suffix: /approval/{{ $execution.id }}
Max Wait Time: 86400 # 24시간 후 자동 타임아웃
↓
## 승인/거절 처리
IF ({{ $json.action }} === "approve")
True → 실제 실행 (이메일 발송, DB 저장 등)
False → 취소 알림 + 로그
# Wait 노드 재개 URL 호출 방법
## Slack 버튼 클릭 시 n8n으로 재개 신호 전송
## action_id에 따라 resumeUrl에 파라미터 추가
## 외부에서 재개 호출 (curl 예시)
curl -X POST "{{ $execution.resumeUrl }}" \
-H "Content-Type: application/json" \
-d '{"action": "approve", "approvedBy": "manager@company.com"}'
실전 AI 자동화 사례
사례 1: Slack AI 분류 & 자동 라우팅
# Slack 새 메시지 → AI 분류 → 담당자 태그 + DB 로그
Slack Trigger (새 메시지)
Channel: #customer-support
↓
Basic LLM Chain (경량 모델: claude-haiku-4-5 / gpt-4.1-mini / gemini-3-flash)
System: |
고객 메시지를 JSON으로만 분류하세요.
category: ["결제", "기술", "계정", "배송", "일반", "기타"]
severity: ["긴급", "높음", "보통", "낮음"]
sentiment: ["화남", "불만", "중립", "만족"]
language: ["한국어", "영어", "기타"]
User: {{ $json.text }}
Output Parser → Structured Output Parser
category, severity, sentiment, language (모두 string)
↓
Code 노드 (담당자 매핑)
const assigneeMap = {
"결제": { user: "U01FINANCE", channel: "#finance-support" },
"기술": { user: "U02DEVTEAM", channel: "#dev-support" },
"계정": { user: "U03OPSCORE", channel: "#ops-support" },
};
const assignee = assigneeMap[$json.category] ?? { user: "U04GENERAL" };
return [{ json: { ...$json, assignee } }];
↓
[병렬]
Slack (원본 채널에 분류 태그 추가)
Thread TS: {{ $json.ts }}
Text: "카테고리: {{ $json.category }} | 심각도: {{ $json.severity }}"
PostgreSQL (티켓 생성)
INSERT INTO support_tickets ...
IF (severity == "긴급")
→ Slack DM to assignee.user (즉시 알림)
사례 2: GitHub PR AI 코드 리뷰
# PR 오픈 → diff 가져오기 → AI 리뷰 → GitHub 코멘트
GitHub Trigger
Event: Pull Request, Action: opened/synchronize
↓
Code 노드 (PR 메타데이터)
const pr = $json.pull_request;
return [{ json: {
title: pr.title,
author: pr.user.login,
diffUrl: pr.diff_url,
commentsUrl: pr.comments_url,
prNumber: pr.number,
repoFullName: $json.repository.full_name,
}}];
↓
HTTP Request (diff 다운로드)
URL: {{ $json.diffUrl }}
Headers: Authorization: token {{ $env.GITHUB_TOKEN }}, Accept: application/vnd.github.v3.diff
↓
Code 노드 (diff 전처리)
const diff = $json.data;
const MAX_CHARS = 12000;
const truncated = diff.length > MAX_CHARS
? diff.slice(0, MAX_CHARS) + '\n... (이하 생략)'
: diff;
const addedLines = (diff.match(/^\+[^+]/mg) ?? []).length;
const removedLines = (diff.match(/^-[^-]/mg) ?? []).length;
return [{ json: { diff: truncated, addedLines, removedLines } }];
↓
Basic LLM Chain (고성능 모델: claude-opus-4-7 / gpt-4.1 / gemini-3.1-pro)
System: |
당신은 시니어 소프트웨어 엔지니어입니다.
PR 코드 변경사항을 분석하고 건설적인 피드백을 작성하세요.
## 리뷰 항목 (중요도 순)
1. 🐛 버그 및 잠재적 오류
2. 🔒 보안 취약점
3. ⚡ 성능 이슈
4. 🏗️ 코드 구조 및 가독성
5. 🧪 테스트 커버리지
6. ✅ 잘된 점
각 항목에 해당하는 내용이 없으면 생략하세요.
구체적인 코드 라인을 인용하면 더 좋습니다.
User: |
PR 제목: {{ $node["Code"].json.title }}
작성자: {{ $node["Code"].json.author }}
변경: +{{ $node["Code 1"].json.addedLines }}줄 / -{{ $node["Code 1"].json.removedLines }}줄
코드 변경사항:
```diff
{{ $json.diff }}
```
↓
HTTP Request (GitHub 코멘트 등록)
URL: https://api.github.com/repos/{{ $node["Code"].json.repoFullName }}/issues/{{ $node["Code"].json.prNumber }}/comments
Method: POST
Headers: Authorization: token {{ $env.GITHUB_TOKEN }}
Body: { "body": "## 🤖 AI 코드 리뷰\n\n{{ $json.text }}\n\n---\n*자동 생성된 리뷰입니다. 참고용으로 활용하세요.*" }
사례 3: AI 콘텐츠 생성 파이프라인
# 주제 입력 → AI 리서치 → 초안 작성 → SEO 최적화 → 발행
Webhook Trigger
Body: { "topic": "n8n으로 AI 자동화 구축하기", "language": "ko", "targetLength": 1500 }
↓
AI Agent (리서치 에이전트)
Tools: Wikipedia, SerpAPI, HTTP Request (뉴스 API)
System: 주제에 대한 최신 정보를 수집하고 JSON으로 요약하세요.
↓
Basic LLM Chain (초안 작성, claude-opus-4-7 / gpt-4.1 등 고성능 모델)
Prompt: |
리서치 결과를 바탕으로 블로그 포스트 초안을 작성하세요.
- 언어: {{ $json.language }}
- 목표 길이: {{ $json.targetLength }}자
- H2/H3 구조, 예제 코드 포함
- SEO 최적화된 제목과 소제목
리서치 결과:
{{ $json.research }}
↓
Basic LLM Chain (SEO 메타데이터 추출, claude-haiku-4-5 / gpt-4.1-mini 등 경량 모델)
Prompt: |
다음 블로그 포스트에서 SEO 메타데이터를 JSON으로 추출하세요.
- title: SEO 최적화 제목 (60자 이내)
- description: 메타 설명 (160자 이내)
- keywords: 핵심 키워드 배열 (5-10개)
- readingTime: 예상 읽기 시간 (분)
{{ $json.text }}
Output Parser → Structured Output Parser
↓
[병렬]
HTTP Request (WordPress API 발행 또는 Notion 저장)
Google Sheets (콘텐츠 캘린더 기록)
Slack (팀 알림: 새 포스트 초안 완료)
사례 4: AI 장애 대응 자동화
# 모니터링 알림 → AI 원인 분석 → 자동 복구 시도 → 에스컬레이션
Webhook Trigger (Prometheus AlertManager)
Body: { "alertname": "HighCPUUsage", "service": "api-server", "severity": "critical" }
↓
Code 노드 (경보 파싱)
const alert = $json.alerts[0];
return [{ json: {
alertname: alert.labels.alertname,
service: alert.labels.service,
severity: alert.labels.severity,
startedAt: alert.startsAt,
description: alert.annotations.description,
}}];
↓
[병렬]
HTTP Request (최근 로그 조회 - Loki/Elasticsearch)
HTTP Request (메트릭 조회 - Prometheus)
PostgreSQL (최근 배포 이력)
↓ (Merge)
AI Agent (원인 분석 + 복구 방안)
System: |
DevOps 전문가로서 장애 원인을 분석하고 즉시 조치 방안을 제시하세요.
제공된 도구로 추가 조사를 할 수 있습니다.
복구 명령어는 반드시 실행 전 승인을 요청하세요.
Tools:
→ SSH Command Tool (서버 명령어 실행)
→ Kubernetes API Tool (Pod 재시작 등)
User: |
장애 내용:
{{ $json.description }}
최근 로그: {{ $json.logs }}
메트릭: {{ $json.metrics }}
최근 배포: {{ $json.deployments }}
↓
Slack 노드 (즉시 알림 + AI 분석 결과)
Channel: #incidents
Text: |
🚨 *{{ $json.alertname }}* - {{ $json.service }}
AI 분석: {{ $json.output }}
↓
IF (severity == "critical" && 자동 복구 제안 있음)
→ Human-in-the-Loop (승인 후 복구 실행)
→ PagerDuty (온콜 담당자 호출)
사례 5: AI 리드 스코어링
# CRM 신규 리드 → AI 분석 → 점수 산출 → 영업팀 라우팅
HubSpot Trigger (새 Contact 생성)
↓
HTTP Request (회사 정보 보강 - Clearbit/Apollo)
URL: https://company.clearbit.com/v2/companies/find
Query: domain={{ $json.company.domain }}
↓
Basic LLM Chain (claude-opus-4-7 / gpt-4.1 등 고성능 모델)
System: |
B2B SaaS 영업 전문가로서 리드를 분석하고 점수를 산출하세요.
점수 기준 (0-100점):
- 회사 규모 (직원 수): 대기업 30점, 중기업 20점, 소기업 10점
- 업종 적합성: AI/Tech 25점, 제조 15점, 서비스 10점
- 타이틀 적합성: C레벨/VP 20점, 매니저 15점, 일반 5점
- 인게이지먼트: 데모 신청 25점, 콘텐츠 다운 15점, 방문만 5점
JSON으로만 응답: { "score": number, "tier": "A|B|C", "reason": string, "nextAction": string }
User: |
이름: {{ $json.firstname }} {{ $json.lastname }}
직책: {{ $json.jobtitle }}
회사: {{ $json.company }}
직원 수: {{ $json.company_size }}
업종: {{ $json.industry }}
유입 경로: {{ $json.lead_source }}
Output Parser → Structured Output Parser
↓
HubSpot 노드 (리드 점수 업데이트)
Update Contact Property: lead_score, lead_tier, ai_reason
↓
Switch (tier)
"A" → 영업팀 즉시 알림 + 자동 미팅 일정 제안
"B" → 이메일 시퀀스 등록
"C" → 뉴스레터만 구독
프롬프트 보안
프롬프트 인젝션 방지
// Code 노드 — 사용자 입력 위생처리
const userInput = $json.userMessage;
// 1. 길이 제한
if (userInput.length > 2000) {
throw new Error('입력이 너무 깁니다 (최대 2000자)');
}
// 2. 인젝션 패턴 감지
const injectionPatterns = [
/ignore\s+(all\s+)?previous\s+instructions/i,
/system\s+prompt/i,
/jailbreak/i,
/\[INST\]/i,
/<system>/i,
];
for (const pattern of injectionPatterns) {
if (pattern.test(userInput)) {
throw new Error('허용되지 않는 입력입니다');
}
}
// 3. 특수 문자 이스케이프 (SQL 인젝션 방지)
const sanitized = userInput
.replace(/[<>&"']/g, c => ({
'<': '<', '>': '>', '&': '&',
'"': '"', "'": '''
}[c]));
return [{ json: { sanitizedInput: sanitized } }];
Rate Limiting
// Code 노드 — 사용자별 요청 제한 (Redis 기반)
const userId = $json.userId;
const key = `ratelimit:${userId}:${$now.toFormat('yyyy-MM-dd-HH')}`;
const MAX_REQUESTS_PER_HOUR = 20;
// 다음 Redis 노드에서:
// INCR key → TTL 3600 → IF count > MAX → 429 반환
return [{ json: { ratelimitKey: key, maxRequests: MAX_REQUESTS_PER_HOUR } }];
AI 비용 최적화
모델 라우팅 전략
// Code 노드 — 복잡도 기반 모델 자동 선택
const { prompt, taskType } = $json;
const tokenEstimate = Math.ceil(prompt.length / 3.5);
let model, temperature;
// Anthropic 모델 기준 예시 (OpenAI: gpt-4.1-mini → gpt-4.1, Gemini: flash → pro)
if (taskType === 'classification' || tokenEstimate < 500) {
model = 'claude-haiku-4-5'; // 빠르고 저렴 (대안: gpt-4.1-mini, gemini-3-flash)
temperature = 0;
} else if (taskType === 'code' || tokenEstimate < 2000) {
model = 'claude-sonnet-4-6'; // 균형 (대안: gpt-4.1, gemini-3.1-pro)
temperature = 0.3;
} else {
model = 'claude-opus-4-7'; // 복잡한 추론 (대안: gpt-4.1, gemini-3.1-pro)
temperature = 0.7;
}
return [{ json: { ...($json), model, temperature } }];
프롬프트 캐싱 (Anthropic 고유 기능)
Anthropic Claude API는 프롬프트 캐싱을 지원하여 반복 호출 시 비용을 크게 절감할 수 있습니다. OpenAI는 자동 캐싱(Predicted Outputs)을, Gemini는 Context Caching을 별도로 제공합니다.
# Anthropic 전용: 긴 시스템 프롬프트에 캐시 활성화 → 비용 90% 절감
# 최소 1024 토큰 이상인 시스템 프롬프트에 적용
{
"system": [
{
"type": "text",
"text": "{{ $json.longSystemPrompt }}",
"cache_control": { "type": "ephemeral" } # 이 부분 캐시
}
],
"messages": [
{ "role": "user", "content": "{{ $json.userMessage }}" }
]
}
# 캐시 히트 시 비용
# 입력 토큰: $5/MTok → $0.50/MTok (90% 절감)
# 유효 시간: 5분 또는 1시간 (호출할 때마다 갱신)
| 작업 유형 | 권장 모델 (Anthropic) | 대안 (OpenAI / Gemini) | 이유 |
|---|---|---|---|
| 분류·태깅·감정분석 | claude-haiku-4-5 | gpt-4.1-mini / gemini-3-flash | 단순 작업, 속도·비용 우선 |
| 요약·번역·추출 | claude-haiku-4-5 / sonnet | gpt-4.1-mini / gemini-3-flash | 충분한 품질, 저비용 |
| 코드 생성·리뷰 | claude-sonnet-4-6 | gpt-4.1 / gemini-3.1-pro | 품질-비용 균형 |
| 복잡한 추론·에이전트 | claude-opus-4-7 | gpt-4.1 / gemini-3.1-pro | 최고 품질 필요 |
| 대량 반복 처리 | Ollama (로컬 LLM: Llama, Mistral 등) | 비용 제로, 프라이버시 | |
| 빠른 추론 (저지연) | Groq (Llama) | 무료 티어, 초고속 | |
다음 단계
- n8n 기초 — 설치, 핵심 개념, 노드 레퍼런스
- n8n 고급 활용 — 커스텀 노드, 운영 배포, 보안
- Claude API 가이드 — Anthropic API 심층 활용
- MCP란? — AI 모델과 외부 도구 연동