AI Agent ที่ขับเคลื่อนด้วย RAG: การสร้างระบบอัตโนมัติที่เน้นความรู้ด้วย n8n, Vector Database และ GPT-5.5
AI Agent ที่ขับเคลื่อนด้วย RAG: การสร้างระบบอัตโนมัติที่เน้นความรู้ด้วย n8n, Vector Database และ GPT-5.5
การเปิดตัว GPT-5.5 ของ OpenAI เมื่อวันที่ 5 พฤษภาคม 2026 นับเป็นจุดเปลี่ยนสำคัญสำหรับแอปพลิเคชัน AI ที่เน้นความรู้ ด้วยความสามารถในการให้เหตุผลที่ดีขึ้นอย่างมากและการลดการใช้ token ลง 40% เมื่อเทียบกับ GPT-5.4 GPT-5.5 ได้รับการออกแบบมาโดยเฉพาะสำหรับงานองค์กรแบบ agent และการเข้าใจเอกสารที่ซับซ้อน - ซึ่งเป็นพื้นฐานที่สมบูรณ์แบบสำหรับระบบ Retrieval-Augmented Generation (RAG)
องค์กรที่นำ workflow ที่ขับเคลื่อนด้วย RAG ไปใช้กำลังเห็นผลลัพธ์ที่เปลี่ยนแปลงเกม: การลดอัตราการหลอนจาก AI (hallucination) ลง 73% การปรับปรุงความแม่นยำในการค้นหาเอกสาร 4.2 เท่า และการดึงความรู้ที่เร็วขึ้น 67% เมื่อเทียบกับการค้นหาแบบ keyword แบบดั้งเดิม การสำรวจล่าสุดพบว่า 57.3% ของผู้สร้าง AI agent ตอนนี้มี agent ที่ใช้ RAG ในระบบ production เพิ่มขึ้นจากเพียง 23% ในต้นปี 2025
คู่มือที่ครอบคลุมนี้จะสำรวจวิธีการสร้างระบบ RAG ที่พร้อมใช้งานจริงด้วย n8n, vector database และ GPT-5.5 ตั้งแต่การออกแบบ ingestion pipeline ไปจนถึงการใช้กลยุทธ์การค้นหาแบบไฮบริด จากการปรับแต่งอัลกอริทึมการแบ่งข้อความ (chunking) ไปจนถึงการสร้าง agent ที่สามารถสนทนาและเข้าใจความรู้ของธุรกิจได้จริง - เราจะครอบคลุมทุกอย่างที่คุณต้องการเพื่อสร้างระบบอัตโนมัติที่เน้นความรู้พร้อม ROI ที่วัดได้
การเข้าใจสถาปัตยกรรม RAG: มากกว่าแค่ Chatbot ธรรมดา
รูปแบบ RAG อธิบาย
Retrieval-Augmented Generation สะพานช่องว่างระหว่าง Large Language Model และความรู้ส่วนตัว ไม่เหมือนกับ fine-tuning ที่ฝังความรู้ถาวรลงใน weights ของโมเดล RAG จะดึง context ที่เกี่ยวข้องแบบไดนามิกตอน query - ทำให้ AI ตอบสนองได้ทันสมัย ตรวจสอบได้ และลดอาการหลอน
┌─────────────────────────────────────────────────────────────────────────────┐
│ กระแสข้อมูลสถาปัตยกรรม RAG │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ เอกสาร │───▶│ แบ่ง & │───▶│ Vector │───▶│ Vector │ │
│ │ แหล่งที่มา │ │ Embed │ │ Database │ │ เก็บข้อมูล│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ PDFs, URLs, การแบ่งข้อความ, Pinecone, การค้นหา │
│ Database, OpenAI/GPT-5.5 Qdrant, เชิงความหมาย│
│ APIs Embeddings Weaviate แบบเรียลไทม์│
│ │
│ เวลา QUERY │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ คำถาม │───▶│ ดึง │───▶│ สร้าง │───▶│ คำตอบ │ │
│ │ ผู้ใช้ │ │ Context │ │ คำตอบ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │
│ │ │
│ ▼ │
│ การค้นหาความคล้ายคลึง + │
│ การจัดอันดับใหม่ (Re-ranking) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
ข้อดีหลักของ RAG เทียบกับ Fine-Tuning:
| ด้าน | Fine-Tuning | RAG |
|---|---|---|
| ความทันสมัยของข้อมูล | ต้องเทรนใหม่ | ทันสมัยเสมอ |
| การระบุแหล่งที่มา | ยาก | มีมาในตัว |
| อัตราการหลอนของ AI | สูงกว่า | ลดลง 73% |
| เวลาดำเนินการ | สัปดาห์ถึงเดือน | วันถึงสัปดาห์ |
| ต้นทุนต่อการอัปเดต | สูง (ต้องเทรนใหม่) | ต่ำ (จัดทำดัชนีใหม่) |
| การเปลี่ยนโดเมน | ต้องใช้โมเดลใหม่ | ไดนามิกตอน query |
ข้อดีของ GPT-5.5 สำหรับ RAG
GPT-5.5 นำการปรับปรุงเฉพาะที่ทำให้เหมาะสมกับ RAG workflow:
1. การติดตาม Context ที่ดีขึ้น
// GPT-5.5 เข้าใจดีขึ้นว่าเมื่อใดควรใช้ context ที่ดึงมากับความรู้ทั่วไป
const systemPrompt = `
คุณเป็นผู้ช่วยที่มีประโยชน์พร้อมเข้าถึงความรู้ของบริษัทต่อไปนี้:
<context_ที่ดึงมา>
{{ $json.retrievedDocuments }}
</context_ที่ดึงมา>
คำสั่งสำคัญ:
- หาก context ที่ดึงมามีคำตอบ ใช้เฉพาะข้อมูลนั้นเท่านั้น
- หาก context ไม่เพียงพอ ระบุชัดเจนว่าต้องการข้อมูลเพิ่มเติมใด
- อย่าสร้างข้อมูลที่ไม่มีอยู่ใน context
- อ้างอิงแหล่งที่มาของเอกสารเฉพาะเมื่อให้คำตอบ
`;
// GPT-5.5 แสดงความแม่นยำ 89% ในการปฏิบัติตามคำสั่งเหล่านี้ เทียบกับ 67% ของ GPT-4
2. การใช้ Token ที่ลดลง
// ด้วยการปรับปรุงประสิทธิภาพ token 40% ของ GPT-5.5:
// ก่อน: 15,000 token ต่อ RAG query = $0.45 (GPT-4)
// GPT-5.5: 9,000 token ต่อ RAG query = $0.27 (ประหยัด 40%)
// การประหยัดรายเดือนสำหรับ 10,000 query: $1,800
const costComparison = {
model: 'gpt-5.5',
inputCostPer1k: 5.00, // $5 ต่อล้าน token
outputCostPer1k: 30.00, // $30 ต่อล้าน token
averageInputTokens: 6000,
averageOutputTokens: 3000,
costPerQuery: (6000 * 5 + 3000 * 30) / 1000000, // $0.12
gpt4CostPerQuery: 0.20, // ต้นทุนก่อนหน้า
savings: '40%'
};
3. Output ที่มีโครงสร้างดีขึ้น
// GPT-5.5 มีจุดแข็งในการส่งคืนข้อมูลที่มีโครงสร้างจาก RAG query
const structuredOutputExample = {
answer: "บริษัทก่อตั้งขึ้นในปี 2018 โดย Jane Smith และ John Doe",
sources: [
{
document_id: "company-history-2024.pdf",
page: 3,
confidence: 0.94,
excerpt: "ก่อตั้งในปี 2018 Tropical Media เริ่มต้นเป็นที่ปรึกษาด้านระบบอัตโนมัติขนาดเล็ก..."
},
{
document_id: "founder-bios.docx",
page: 1,
confidence: 0.91,
excerpt: "Jane Smith (CEO) และ John Doe (CTO) ก่อตั้งบริษัทด้วยวิสัยทัศน์..."
}
],
confidence_score: 0.92,
additional_info_needed: null
};
การตั้งค่า Vector Database ใน n8n
ตัวเลือกที่ 1: Qdrant (แนะนำสำหรับ Self-Hosted)
Qdrant กลายเป็นตัวเลือกที่นิยมสำหรับระบบ RAG production เนื่องจากความสามารถในการค้นหาแบบไฮบริด re-ranking ที่มีมาในตัว และการผสานรวมกับ n8n ที่ยอดเยี่ยม
ขั้นตอนที่ 1: Deploy Qdrant
# docker-compose.yml สำหรับ Qdrant
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:latest
ports:
- "6333:6333"
- "6334:6334"
volumes:
- qdrant_storage:/qdrant/storage
environment:
QDRANT__LOG_LEVEL: INFO
QDRANT__SERVICE__MAX_REQUEST_SIZE_MB: 32
# เปิดใช้งาน GPU acceleration สำหรับการ deploy ขนาดใหญ่
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
volumes:
qdrant_storage:
ขั้นตอนที่ 2: n8n Qdrant Integration
// สร้าง collection ด้วยการตั้งค่าที่เหมาะสมสำหรับ RAG
const createCollection = {
url: 'http://localhost:6333',
collectionName: 'company-knowledge-base',
vectorSize: 1536, // OpenAI embedding dimension
distance: 'Cosine', // เหมาะที่สุดสำหรับความคล้ายคลึงเชิงความหมาย
optimizersConfig: {
defaultSegmentNumber: 2,
maxSegmentSize: 100000,
memmapThreshold: 20000
},
hnswConfig: {
m: 16, // สูงกว่า = recall ดีขึ้น, หน่วยความจำมากขึ้น
efConstruct: 100, // สูงกว่า = คุณภาพการสร้างดีขึ้น
fullScanThreshold: 10000
},
quantizationConfig: {
scalar: {
type: 'int8',
quantile: 0.99,
alwaysRam: true
}
}
};
// Response: Collection สร้างเสร็จพร้อมการลดหน่วยความจำ 90% ผ่าน quantization
ขั้นตอนที่ 3: Document Ingestion Pipeline
// n8n workflow แบบสมบูรณ์สำหรับการนำเข้าเอกสาร
// Trigger: Manual หรือ Scheduled (sync รายวัน)
// Node 1: ดึงเอกสาร (HTTP Request หรือ File Read)
const fetchDocuments = {
url: 'https://company-docs.s3.amazonaws.com/knowledge-base/',
options: {
headers: {
'Authorization': 'Bearer {{ $env.S3_ACCESS_TOKEN }}'
}
}
};
// Node 2: แยกวิเคราะห์เอกสาร (หลายรูปแบบ)
const parseDocuments = {
// PDF
pdf: {
operation: 'Extract',
options: {
metadata: true,
pageNumbers: true
}
},
// Word documents
docx: {
operation: 'Extract Text',
includeHeaders: true,
includeFooters: true
},
// Web pages
html: {
operation: 'Extract Content',
selector: 'article, .content, main', // เน้นที่เนื้อหา
removeSelectors: 'nav, footer, .ads, .sidebar'
}
};
// Node 3: Chunking ที่ชาญฉลาด
const chunkingStrategy = {
method: 'Recursive Character',
chunkSize: 512, // เหมาะสมสำหรับ context window ของ GPT-5.5
chunkOverlap: 128, // ซ้อนทับ 25% รักษา context
separators: [
'\n\n', // ย่อหน้า
'\n', // บรรทัด
'. ', // ประโยค
' ' // คำ (fallback)
],
// รักษาขอบเขตทางความหมาย
preserveContext: true,
// เพิ่ม metadata ให้แต่ละ chunk
metadata: {
source: '{{ $json.sourceUrl }}',
title: '{{ $json.title }}',
category: '{{ $json.category }}',
created_at: '{{ $json.date }}',
author: '{{ $json.author }}',
file_type: '{{ $json.fileType }}'
}
};
// Node 4: สร้าง Embeddings ด้วย GPT-5.5
const embeddingConfig = {
model: 'text-embedding-3-large', // 3072 dimensions, คุณภาพดีกว่า
// หรือ 'text-embedding-3-small' สำหรับการประหยัดต้นทุน
// GPT-5.5 ยังสามารถสร้าง embeddings แบบกำหนดเองผ่าน API
customModel: 'gpt-5.5-embedding',
input: '{{ $json.chunkText }}',
// ประมวลผลเป็นชุดเพื่อประสิทธิภาพ
batchSize: 100,
// Retry logic สำหรับ rate limits
retry: {
maxRetries: 3,
backoffMultiplier: 2,
initialDelay: 1000
}
};
// Node 5: Upsert ไปยัง Qdrant
const upsertConfig = {
collection: 'company-knowledge-base',
points: {
id: '{{ $json.uuid }}', // สร้าง UUID ต่อ chunk
vector: '{{ $json.embedding }}',
payload: {
text: '{{ $json.chunkText }}',
metadata: '{{ $json.metadata }}',
// เพิ่ม timestamp สำหรับ versioning
indexed_at: '{{ new Date().toISOString() }}'
}
},
// Batch upsert เพื่อประสิทธิภาพ
batchSize: 50
};
ตัวเลือกที่ 2: Pinecone (Cloud-Native)
Pinecone นำเสนอ vector search แบบ serverless พร้อมลักษณะการ scale ที่ยอดเยี่ยม
// Pinecone setup สำหรับ n8n RAG workflows
// Node: Pinecone Vector Store
const pineconeConfig = {
apiKey: '{{ $env.PINECONE_API_KEY }}',
environment: 'us-east-1',
// Serverless index configuration
serverless: {
cloud: 'aws',
region: 'us-east-1'
},
// Index specifications
indexName: 'rag-knowledge-base',
dimension: 1536,
metric: 'cosine',
// Pod-based สำหรับ high-throughput (optional)
// pods: 2,
// podType: 'p1.x1',
// Metadata configuration
metadataConfig: {
indexed: [
'category',
'source',
'created_at',
'author'
]
}
};
// Query พร้อม metadata filtering
const queryConfig = {
index: 'rag-knowledge-base',
vector: '{{ $json.queryEmbedding }}',
topK: 10,
includeMetadata: true,
includeValues: false, // ลดขนาด payload
filter: {
category: { $eq: '{{ $json.category }}' },
created_at: { $gte: '{{ $json.sinceDate }}' }
},
// Hybrid search configuration
query: '{{ $json.queryText }}', // สำหรับ sparse-dense fusion
searchType: 'hybrid' // ผสม semantic + keyword search
};
ตัวเลือกที่ 3: Weaviate (Graph + Vector Hybrid)
Weaviate โดดเด่นเมื่อคุณต้องการความสัมพันธ์แบบกราฟควบคู่กับ vector search
// Weaviate schema สำหรับ RAG พร้อมความสัมพันธ์
const weaviateSchema = {
class: 'DocumentChunk',
description: 'Chunk ของความรู้บริษัทพร้อมความสัมพันธ์',
vectorizer: 'text2vec-openai',
moduleConfig: {
'text2vec-openai': {
model: 'ada',
modelVersion: '002',
type: 'text'
}
},
properties: [
{
name: 'content',
dataType: ['text'],
moduleConfig: {
'text2vec-openai': { skip: false, vectorizePropertyName: false }
}
},
{
name: 'source',
dataType: ['text'],
tokenization: 'word'
},
{
name: 'category',
dataType: ['text'],
tokenization: 'field' // กรองแบบ exact match
},
{
name: 'relatedChunks',
dataType: ['DocumentChunk'], // ความสัมพันธ์แบบกราฟ
description: 'Chunks ที่มีความหมายใกล้เคียง'
},
{
name: 'parentDocument',
dataType: ['Document'], // เชื่อมโยงกับแม่
}
],
// Hybrid search settings
vectorIndexConfig: {
ef: 256,
efConstruction: 128,
maxConnections: 64,
dynamicEfFactor: 8
}
};
// Graph query สำหรับ contextual retrieval
const graphQuery = `
{
Get {
DocumentChunk(
nearText: {
concepts: ["{{ $json.query }}"]
certainty: 0.7
}
limit: 5
) {
content
source
category
// Traverse ความสัมพันธ์
relatedChunks {
content
source
}
parentDocument {
title
author
publishDate
}
}
}
}
`;
กลยุทธ์การแบ่งข้อความ (Chunking) ขั้นสูง
วิทยาศาสตร์ของการแบ่งข้อความ
Chunking เป็นปัจจัยที่สำคัญที่สุดในการสร้างคุณภาพ RAG การแบ่งข้อความที่แย่นำไปสู่การสูญเสีย context ในขณะที่การแบ่งข้อความที่เหมาะสมที่สุดสามารถปรับปรุงความแม่นยำในการดึงข้อมูลได้ 40%+
┌──────────────────────────────────────────────────────────────────────────────┐
│ การเปรียบเทียบกลยุทธ์การแบ่งข้อความ │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ เอกสาร: "บริษัทก่อตั้งขึ้นในปี 2018 รายได้เติบโต 300% ในปี 2024" │
│ │
│ ขนาดคงที่ (ไม่ดี): │
│ ┌─────────────────┬─────────────────┬─────────────────┐ │
│ │บริษัทก่อตั้งขึ้น │้ปี 2018 รายได้ │เติบโต 300% ใน │ │
│ └─────────────────┴─────────────────┴─────────────────┘ │
│ └─ "บริษัทก่อตั้งขึ้นปีไหน?" → Query ตรงกับ chunk กลางเท่านั้น │
│ แต่ chunk แบ่ง "ก่อตั้งขึ้นปี 2018" → สูญเสียข้อมูล! │
│ │
│ เชิงความหมาย (ดีกว่า): │
│ ┌──────────────────────────────────┬──────────────────────────────────┐ │
│ │บริษัทก่อตั้งขึ้นในปี 2018 │ รายได้เติบโต 300% ในปี 2024 │ │
│ └──────────────────────────────────┴──────────────────────────────────┘ │
│ │
│ แบบ recursive พร้อมซ้อนทับ (ดีที่สุด): │
│ ┌──────────────────────────┐ │
│ │บริษัทก่อตั้งขึ้นในปี 2018│ ← Chunk 1 │
│ │รายได้เติบโต 300% ในปี 2024│ ← Chunk 2 (ซ้อนทับ 25%) │
│ │ │ ← Chunk 3 │
│ └──────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
การใช้งานใน n8n:
// Chunking ขั้นสูงด้วยตรรกะแบบ LangChain
const advancedChunking = {
// กลยุทธ์ 1: Markdown-aware chunking
markdown: {
splitOn: ['# ', '## ', '### ', '\n\n', '\n'],
preserveCodeBlocks: true,
preserveTables: true,
chunkSize: 1000,
chunkOverlap: 200
},
// กลยุทธ์ 2: Semantic chunking โดยใช้ embeddings
semantic: {
// สร้าง embeddings สำหรับแต่ละประโยค
sentenceEmbeddings: true,
// จัดกลุ่มประโยคที่มี embeddings คล้ายกัน
similarityThreshold: 0.85,
minChunkSize: 100,
maxChunkSize: 500,
// รวมประโยคจนกว่าความคล้ายคลึงจะลดลง
bufferSize: 3 // ดูประโยคก่อน/หลัง
},
// กลยุทธ์ 3: Agentic chunking (GPT-5.5)
agentic: {
// ใช้ GPT-5.5 เพื่อกำหนดจุดแบ่งที่เหมาะสม
model: 'gpt-5.5',
prompt: `
วิเคราะห์เอกสารนี้และระบุจุดที่ดีที่สุดในการแบ่งเป็น chunks
แต่ละ chunk ควร:
- มี 300-500 token
- มีความคิดหรือหัวข้อที่สมบูรณ์
- ไม่แบ่งกลางประโยคหรือกลางย่อหน้า
- รักษา context ภายในแต่ละ chunk
ส่งคืนตำแหน่งการแบ่งเป็นหมายเลขบรรทัด
เอกสาร:
{{ $json.documentText }}
`,
// Parse response เพื่อรับขอบเขต chunk
parseResponse: (response) => {
const lines = response.split('\n');
return lines.filter(l => l.match(/^\d+$/)).map(Number);
}
},
// กลยุทธ์ 4: Parent-child chunking (สำหรับการรักษา context)
parentChild: {
// Parent chunks ขนาดใหญ่ (สำหรับการดึงข้อมูล)
parentChunkSize: 2000,
parentChunkOverlap: 400,
// Child chunks ขนาดเล็ก (สำหรับการจับคู่ที่แม่นยำ)
childChunkSize: 200,
childChunkOverlap: 50,
// เก็บทั้งสองและเชื่อมโยง
indexingStrategy: 'dual',
retrieval: 'child', // ค้นหาบน children
generation: 'parent' // สร้างจาก parents
},
// กลยุทธ์ 5: Sliding window สำหรับ code/documentation
slidingWindow: {
windowSize: 10, // บรรทัด
stride: 3, // ซ้อนทับ
contextLines: 2, // บรรทัดก่อน/หลัง
// ผลลัพธ์: บรรทัด 1-10, 4-13, 7-16, etc.
}
};
การใช้งาน Hybrid Chunking:
// n8n Function node สำหรับ hybrid chunking
const hybridChunking = ($input) => {
const documents = $input.first().json.documents;
const chunks = [];
for (const doc of documents) {
const content = doc.content;
// ตรวจจับประเภทเอกสาร
const isMarkdown = doc.fileType === 'md' || doc.fileType === 'markdown';
const isCode = /\.(js|ts|py|java|cpp|go|rs)$/.test(doc.fileName);
const isStructured = doc.fileType === 'json' || doc.fileType === 'csv';
let docChunks;
if (isMarkdown) {
// ใช้ header-aware splitting
docChunks = splitMarkdown(content, {
chunkSize: 1000,
overlap: 200
});
} else if (isCode) {
// ใช้ AST-aware splitting (รักษา functions/classes)
docChunks = splitCode(content, doc.fileType, {
preserveStructure: true
});
} else if (isStructured) {
// Row-based chunking สำหรับ structured data
docChunks = splitStructured(content, {
rowsPerChunk: 100,
includeHeader: true
});
} else {
// ค่าเริ่มต้น: recursive character
docChunks = splitRecursive(content, {
chunkSize: 512,
overlap: 128,
separators: ['\n\n', '\n', '. ', ' ']
});
}
// เพิ่ม metadata ให้แต่ละ chunk
docChunks.forEach((chunk, index) => {
chunks.push({
text: chunk.text,
metadata: {
...doc.metadata,
chunkIndex: index,
totalChunks: docChunks.length,
chunkStrategy: isMarkdown ? 'markdown' : isCode ? 'code' : 'recursive',
charCount: chunk.text.length,
tokenEstimate: chunk.text.length / 4 // ประมาณการ token คร่าวๆ
}
});
});
}
return [{ json: { chunks } }];
};
// Markdown-aware splitter
function splitMarkdown(text, options) {
const { chunkSize, overlap } = options;
const chunks = [];
const headers = text.match(/^#{1,6}\s.+$/gm) || [];
let currentChunk = '';
let currentSize = 0;
const lines = text.split('\n');
for (const line of lines) {
const isHeader = /^#{1,6}\s/.test(line);
const lineSize = line.length;
// เริ่ม chunk ใหม่ที่ headers ถ้า chunk ปัจจุบันมีเนื้อหามาก
if (isHeader && currentSize > chunkSize * 0.5) {
chunks.push({ text: currentChunk.trim() });
currentChunk = line;
currentSize = lineSize;
} else if (currentSize + lineSize > chunkSize) {
chunks.push({ text: currentChunk.trim() });
// รักษา overlap
const overlapText = currentChunk.slice(-overlap);
currentChunk = overlapText + '\n' + line;
currentSize = overlap + lineSize;
} else {
currentChunk += '\n' + line;
currentSize += lineSize;
}
}
if (currentChunk) {
chunks.push({ text: currentChunk.trim() });
}
return chunks;
}
การสร้าง RAG Pipeline แบบสมบูรณ์
เฟส 1: Document Ingestion Workflow
// n8n workflow แบบสมบูรณ์: เอกสาร → Vector Database
// ชื่อไฟล์: 44-rag-ingestion-workflow.json
{
"name": "RAG Document Ingestion Pipeline",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 24
}
]
}
},
"name": "Daily Sync Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [250, 300]
},
{
"parameters": {
"url": "https://api.company.com/documents",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "modified_since",
"value": "={{ $getExecutionData('last_sync') || '1970-01-01' }}"
}
]
}
},
"name": "Fetch New Documents",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [450, 300]
},
{
"parameters": {
"jsCode": "// ประมวลผลเอกสารและดึงข้อความ\nconst documents = items[0].json.data || [];\nconst processed = [];\n\nfor (const doc of documents) {\n // กำหนดวิธีการดึงข้อมูลตามประเภทไฟล์\n const extraction = {\n id: doc.id,\n title: doc.title,\n url: doc.url,\n type: doc.file_type,\n modified: doc.modified_at,\n category: doc.category\n };\n \n processed.push({ json: extraction });\n}\n\nreturn processed;"
},
"name": "Prepare Documents",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [650, 300]
},
{
"parameters": {
"mode": "json",
"jsonMode": "=JSON.parse($json.extractionConfig || '{}')"
},
"name": "Split Batch",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [850, 300]
},
{
"parameters": {
"url": "={{ $json.url }}"
},
"name": "Download Document",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [1050, 300]
},
{
"parameters": {
"dataPropertyName": "data",
"extraction": "pdfText",
"options": {
"keepPageNumbers": true,
"keepMetadata": true
}
},
"name": "Extract PDF Text",
"type": "n8n-nodes-base.extractFromPDF",
"typeVersion": 1,
"position": [1250, 200]
},
{
"parameters": {
"extraction": "text",
"options": {}
},
"name": "Extract DOCX Text",
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1,
"position": [1250, 400]
},
{
"parameters": {
"jsCode": "// ตรรกะการแบ่งข้อความขั้นสูง\nconst content = $input.first().json.text;\nconst metadata = $input.first().json.metadata;\n\n// การแบ่งข้อความแบบ recursive character\nconst chunkSize = 512;\nconst overlap = 128;\nconst separators = ['\\n\\n', '\\n', '. ', ' '];\n\nconst chunks = [];\nlet currentChunk = '';\nlet currentSize = 0;\n\nconst sentences = content.split(/(?<=[.!?])\\s+/);\n\nfor (const sentence of sentences) {\n const sentenceSize = sentence.length;\n \n if (currentSize + sentenceSize > chunkSize && currentChunk) {\n chunks.push({\n text: currentChunk.trim(),\n metadata: {\n ...metadata,\n chunk_index: chunks.length,\n char_count: currentSize\n }\n });\n \n // ใช้ overlap\n const overlapStart = Math.max(0, currentChunk.length - overlap);\n currentChunk = currentChunk.slice(overlapStart) + ' ' + sentence;\n currentSize = currentChunk.length;\n } else {\n currentChunk += (currentChunk ? ' ' : '') + sentence;\n currentSize += sentenceSize;\n }\n}\n\nif (currentChunk) {\n chunks.push({\n text: currentChunk.trim(),\n metadata: {\n ...metadata,\n chunk_index: chunks.length,\n char_count: currentSize\n }\n });\n}\n\nreturn chunks.map(c => ({ json: c }));"
},
"name": "Chunk Documents",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1450, 300]
},
{
"parameters": {
"options": {},
"prompt": "={{ $json.text }}",
"model": "text-embedding-3-large"
},
"name": "Generate Embeddings",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1,
"position": [1650, 300]
},
{
"parameters": {
"mode": "insert",
"options": {
"qdrantCollection": "company-knowledge-base"
},
"points": {
"id": "={{ $json.metadata.chunk_index + '-' + $json.metadata.doc_id }}",
"vector": "={{ $json.embedding }}",
"payload": {
"text": "={{ $json.text }}",
"metadata": "={{ $json.metadata }}"
}
}
},
"name": "Store in Qdrant",
"type": "n8n-nodes-base.vectorStoreQdrant",
"typeVersion": 1,
"position": [1850, 300]
},
{
"parameters": {
"jsCode": "// ติดตามการ index ที่สำเร็จ\nconst result = {\n document_id: $input.first().json.metadata.doc_id,\n chunks_indexed: $input.first().json.metadata.chunk_index + 1,\n indexed_at: new Date().toISOString()\n};\n\n// ส่งไปยัง monitoring/alerting\nreturn [{ json: result }];"
},
"name": "Track Indexing",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2050, 300]
}
],
"connections": {
"Daily Sync Trigger": {
"main": [[{"node": "Fetch New Documents", "type": "main", "index": 0}]]
},
"Fetch New Documents": {
"main": [[{"node": "Prepare Documents", "type": "main", "index": 0}]]
},
"Prepare Documents": {
"main": [[{"node": "Split Batch", "type": "main", "index": 0}]]
},
"Split Batch": {
"main": [[{"node": "Download Document", "type": "main", "index": 0}]]
},
"Download Document": {
"main": [
[{"node": "Extract PDF Text", "type": "main", "index": 0}],
[{"node": "Extract DOCX Text", "type": "main", "index": 0}]
]
},
"Extract PDF Text": {
"main": [[{"node": "Chunk Documents", "type": "main", "index": 0}]]
},
"Extract DOCX Text": {
"main": [[{"node": "Chunk Documents", "type": "main", "index": 0}]]
},
"Chunk Documents": {
"main": [[{"node": "Generate Embeddings", "type": "main", "index": 0}]]
},
"Generate Embeddings": {
"main": [[{"node": "Store in Qdrant", "type": "main", "index": 0}]]
},
"Store in Qdrant": {
"main": [[{"node": "Track Indexing", "type": "main", "index": 0}]]
}
}
}
เฟส 2: Query และ Retrieval Workflow
// n8n workflow แบบสมบูรณ์: คำถามผู้ใช้ → RAG คำตอบ
// ชื่อไฟล์: 44-rag-query-workflow.json
{
"name": "RAG Query and Response Pipeline",
"nodes": [
{
"parameters": {
"path": "rag-query",
"responseMode": "responseNode"
},
"name": "RAG API Endpoint",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"options": {},
"prompt": "={{ $json.query.body.query }}",
"model": "text-embedding-3-large"
},
"name": "Embed Query",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1,
"position": [450, 300]
},
{
"parameters": {
"mode": "retrieve",
"options": {
"qdrantCollection": "company-knowledge-base",
"topK": 10
},
"filter": {
"category": "={{ $json.query.body.category || undefined }}"
}
},
"name": "Retrieve from Qdrant",
"type": "n8n-nodes-base.vectorStoreQdrant",
"typeVersion": 1,
"position": [650, 300]
},
{
"parameters": {
"jsCode": "// Re-rank เอกสารที่ดึงมา\nconst docs = $input.all()[0].json;\nconst query = $getWorkflowStaticData('query');\n\n// คะแนนแบบง่าย BM25-style สำหรับ re-ranking\nconst queryTerms = query.toLowerCase().split('\\s+');\nconst scored = docs.map(doc => {\n const text = doc.metadata.text.toLowerCase();\n let score = doc.score; // ความคล้ายคลึง vector เดิม\n \n // Boost สำหรับ exact term matches\n for (const term of queryTerms) {\n const matches = (text.match(new RegExp(term, 'g')) || []).length;\n score += matches * 0.05;\n }\n \n // Boost สำหรับความใหม่\n const docDate = new Date(doc.metadata.metadata.modified || doc.metadata.metadata.created);\n const daysOld = (Date.now() - docDate) / (1000 * 60 * 60 * 24);\n score += Math.max(0, 0.1 - daysOld * 0.001);\n \n return { ...doc, rerankedScore: score };\n});\n\n// เรียงตาม re-ranked score และเอา top 5\nconst topDocs = scored\n .sort((a, b) => b.rerankedScore - a.rerankedScore)\n .slice(0, 5);\n\nreturn [{ json: { documents: topDocs, query } }];"
},
"name": "Re-rank Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [850, 300]
},
{
"parameters": {
"jsCode": "// สร้าง context สำหรับ LLM\nconst docs = $input.first().json.documents;\nconst query = $input.first().json.query;\n\n// จัดรูปแบบเอกสารพร้อมการระบุแหล่งที่มา\nconst context = docs.map((doc, i) => \`[${i + 1}] ${doc.metadata.metadata.title}\nSource: ${doc.metadata.metadata.source}\nContent: ${doc.metadata.text}\n---\`).join('\\n\\n');\n\nconst sources = docs.map(doc => ({\n title: doc.metadata.metadata.title,\n source: doc.metadata.metadata.source,\n score: Math.round(doc.rerankedScore * 100) / 100\n}));\n\nreturn [{\n json: {\n query,\n context,\n sources,\n documentCount: docs.length\n }\n}];"
},
"name": "Build Context",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1050, 300]
},
{
"parameters": {
"model": "gpt-5.5",
"options": {
"temperature": 0.3,
"maxTokens": 1500
},
"messages": {
"message": [
{
"role": "system",
"content": "คุณเป็นผู้ช่วยที่ตอบคำถามตาม context ที่ให้มา\\n\\nคำสั่ง:\\n1. ตอบโดยใช้เฉพาะข้อมูลใน context ที่ให้มา\\n2. หาก context ไม่มีคำตอบ ให้ระบุอย่างชัดเจน\\n3. อ้างอิงแหล่งที่มาด้วย [1], [2] ฯลฯ เสมอ\\n4. กระชับแต่ครบถ้วน\\n5. หากต้องสมมติ ให้ระบุอย่างชัดเจน"
},
{
"role": "user",
"content": "=Context:\\n{{ $json.context }}\\n\\nคำถาม: {{ $json.query }}\\n\\nให้คำตอบที่ครอบคลุมพร้อมการอ้างอิงแหล่งที่มา"
}
]
}
},
"name": "Generate Response",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1.8,
"position": [1250, 300]
},
{
"parameters": {
"jsCode": "// ประกอบคำตอบสุดท้าย\nconst llmResponse = $input.first().json.content;\nconst context = $getWorkflowStaticData('context');\n\nreturn [{\n json: {\n answer: llmResponse,\n sources: context.sources,\n tokens_used: $input.first().json.usage?.total_tokens || null,\n query_time_ms: Date.now() - ($getWorkflowStaticData('startTime') || Date.now()),\n retrieved_documents: context.documentCount\n }\n}];"
},
"name": "Format Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1450, 300]
},
{
"parameters": {
"respondWith": "json",
"json": "={{ JSON.stringify($json) }}"
},
"name": "Return Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [1650, 300]
}
],
"connections": {
"RAG API Endpoint": {
"main": [[{"node": "Embed Query", "type": "main", "index": 0}]]
},
"Embed Query": {
"main": [[{"node": "Retrieve from Qdrant", "type": "main", "index": 0}]]
},
"Retrieve from Qdrant": {
"main": [[{"node": "Re-rank Results", "type": "main", "index": 0}]]
},
"Re-rank Results": {
"main": [[{"node": "Build Context", "type": "main", "index": 0}]]
},
"Build Context": {
"main": [[{"node": "Generate Response", "type": "main", "index": 0}]]
},
"Generate Response": {
"main": [[{"node": "Format Response", "type": "main", "index": 0}]]
},
"Format Response": {
"main": [[{"node": "Return Response", "type": "main", "index": 0}]]
}
}
}
รูปแบบ RAG ขั้นสูง
รูปแบบที่ 1: Multi-Query Retrieval
เมื่อ query เดียวอาจพลาด context ที่สำคัญ ให้สร้างหลายรูปแบบ:
// การขยาย multi-query เพื่อการดึงข้อมูลที่ดีขึ้น
const multiQueryConfig = {
originalQuery: "นโยบายการคืนเงินของเราคืออะไร",
// สร้าง 3-5 รูปแบบโดยใช้ GPT-5.5
expansionPrompt: `
สร้าง 3 วิธีต่างกันที่บางคนอาจถามคำถามต่อไปนี้
แต่ละรูปแบบควรเข้าหาคำถามจากมุมมองที่แตกต่างกัน
ต้นฉบับ: {{ $json.query }}
ส่งคืนเป็น JSON array ของ strings
`,
generatedQueries: [
"นโยบายการคืนเงินของเราคืออะไร",
"ฉันจะได้รับเงินคืนได้อย่างไร",
"นโยบายการคืนสินค้าคืออะไร",
"ฉันขอคืนเงินได้ไหม",
"เงื่อนไขการคืนเงินคืออะไร"
],
// ดึงข้อมูลสำหรับแต่ละ query
retrievalStrategy: 'parallel',
// รวมผลลัพธ์ ลบซ้ำ จัดอันดับใหม่
mergeStrategy: {
deduplication: 'semantic', // ลบ chunks ที่ซ้ำกัน
ranking: 'reciprocal', // Reciprocal Rank Fusion
topK: 10
}
};
// Reciprocal Rank Fusion scoring
function reciprocalRankFusion(results) {
const k = 60; // RRF constant
const scores = new Map();
for (const [queryIndex, queryResults] of results.entries()) {
for (const [rank, doc] of queryResults.entries()) {
const docId = doc.metadata.chunk_id;
const currentScore = scores.get(docId) || 0;
// RRF score: 1 / (k + rank)
scores.set(docId, currentScore + 1 / (k + rank + 1));
}
}
// เรียงตาม fused score
return Array.from(scores.entries())
.sort((a, b) => b[1] - a[1])
.map(([id, score]) => ({ id, score }));
}
รูปแบบที่ 2: Hypothetical Document Embeddings (HyDE)
สร้างคำตอบที่เหมาะสมที่สุดก่อน แล้ว embed สำหรับการดึงข้อมูล:
// HyDE pattern implementation
const hydeConfig = {
// ขั้นตอนที่ 1: สร้างคำตอบสมมุติ (โดยไม่ดึงข้อมูล)
hypotheticalPrompt: `
จินตนาการว่าคุณมีสิทธิ์เข้าถึงเอกสารของบริษัททั้งหมด
เขียนคำตอบที่ละเอียดและเป็นข้อเท็จจริงสำหรับคำถามนี้
คำถาม: {{ $json.query }}
เขียนคำตอบราวกับว่าคุณกำลังอ้างอิงจากเอกสารโดยตรง
รวมรายละเอียดเฉพาะ วันที่ และการอ้างอิง
`,
// ใช้ GPT-5.5 สำหรับการสร้างเอกสารสมมุติ
generationModel: 'gpt-5.5',
temperature: 0.7, // สร้างสรรค์เล็กน้อย
maxTokens: 500,
// ขั้นตอนที่ 2: Embed คำตอบสมมุติ
embeddingModel: 'text-embedding-3-large',
// ขั้นตอนที่ 3: ดึงข้อมูลโดยใช้ embedding สมมุติ
// มักจะพบเอกสารที่ไม่ตรงกับ query ต้นฉบับ
};
// n8n workflow สำหรับ HyDE
const hydeWorkflow = [
{
node: "รับคำถาม",
type: "webhook"
},
{
node: "สร้างคำตอบสมมุติ",
type: "openAi",
config: {
model: "gpt-5.5",
prompt: hydeConfig.hypotheticalPrompt,
temperature: 0.7
}
},
{
node: "Embed คำตอบสมมุติ",
type: "embeddingsOpenAi",
input: "={{ $json.hypotheticalAnswer }}"
},
{
node: "ดึงเอกสาร",
type: "vectorStoreQdrant",
vector: "={{ $json.embedding }}",
topK: 10
},
{
node: "สร้างคำตอบสุดท้าย",
type: "openAi",
// ใช้เอกสารที่ดึงมา ACTUAL
context: "={{ $json.retrievedDocuments }}"
}
];
รูปแบบที่ 3: Self-Reflective RAG
ให้ระบบตรวจสอบคำตอบของตัวเองและทำซ้ำ:
// Self-reflective RAG พร้อมการตรวจสอบ
const reflectiveRag = {
maxIterations: 3,
verificationPrompt: `
ตรวจสอบว่าคำตอบนี้ได้รับการสนับสนุนโดยสมบูรณ์จาก context ที่ให้มา
คำตอบ: {{ $json.answer }}
Context: {{ $json.context }}
ตรวจสอบ:
1. Hallucinations (ข้อมูลที่ไม่มีใน context)
2. ข้อความอ้างอิงที่ไม่มีหลักฐานสนับสนุน
3. ข้อมูลที่เกี่ยวข้องที่ขาดหายไป
ส่งคืน JSON:
{
"isVerified": boolean,
"confidence": 0-1,
"issues": ["รายการปัญหา"],
"additionalQueries": ["คำถามเพื่อหาข้อมูลที่ขาด"]
}
`,
// หากการตรวจสอบล้มเหลว ให้ดึงข้อมูลเพิ่มเติม
iterationLogic: async (state) => {
const verification = await verifyAnswer(state.answer, state.context);
if (verification.isVerified || state.iteration >= reflectiveRag.maxIterations) {
return {
finalAnswer: state.answer,
verified: verification.isVerified,
iterations: state.iteration
};
}
// ดึงเอกสารเพิ่มเติม
const newDocs = await retrieveDocuments(verification.additionalQueries);
const newContext = mergeContexts(state.context, newDocs);
// สร้างคำตอบใหม่ด้วย context ที่ขยาย
const newAnswer = await generateAnswer(state.query, newContext);
return reflectiveRag.iterationLogic({
...state,
answer: newAnswer,
context: newContext,
iteration: state.iteration + 1
});
}
};
รูปแบบที่ 4: Hierarchical RAG
สำหรับ knowledge base ขนาดใหญ่ ให้ใช้ระบบดึงข้อมูลสองระดับ:
// Hierarchical retrieval สำหรับ knowledge bases องค์กร
const hierarchicalRag = {
// ระดับ 1: ดัชนีสรุป (เล็กกว่า เร็วกว่า)
summaryIndex: {
collection: 'document-summaries',
embeddingModel: 'text-embedding-3-small', // ถูกกว่า
chunkSize: 'document-level',
content: ' สรุปของเอกสารทั้งฉบับ'
},
// ระดับ 2: ดัชนีเนื้อหาเต็ม (ละเอียด)
detailIndex: {
collection: 'document-chunks',
embeddingModel: 'text-embedding-3-large', // คุณภาพสูงกว่า
chunkSize: 512,
content: 'เอกสาร chunks แบบเต็ม'
},
// กระแส query
queryProcess: [
// ขั้นตอนที่ 1: Query ดัชนีสรุปเพื่อหาเอกสารที่เกี่ยวข้อง
{
action: 'retrieve',
index: 'summaryIndex',
topK: 5,
result: 'relevantDocuments'
},
// ขั้นตอนที่ 2: กรองดัชนีรายละเอียดเป็นเอกสารเหล่านั้น
{
action: 'filter',
index: 'detailIndex',
filter: {
doc_id: { $in: '{{ $json.relevantDocuments.map(d => d.doc_id) }}' }
}
},
// ขั้นตอนที่ 3: ดึง chunks ละเอียดจากชุดที่กรองแล้ว
{
action: 'retrieve',
index: 'detailIndex',
topK: 10,
result: 'detailedChunks'
}
],
// ประสิทธิภาพ: เร็วขึ้น 5 เท่าบน KB ขนาดใหญ่
// ต้นทุน: ลดค่าใช้จ่าย embedding 60%
};
การปรับแต่งสำหรับ Production
กลยุทธ์การแคช
// การแคชหลายระดับสำหรับระบบ RAG
const cachingLayers = {
// ระดับที่ 1: แคช query embedding
embeddingCache: {
store: 'redis',
key: 'embedding:{{ md5($json.query) }}',
ttl: 86400, // 24 ชั่วโมง
hitRate: '35%' // Query ทั่วไป
},
// ระดับที่ 2: แคชผลลัพธ์การดึงข้อมูล
retrievalCache: {
store: 'redis',
key: 'retrieve:{{ md5($json.queryEmbedding) }}:{{ $json.filterHash }}',
ttl: 3600, // 1 ชั่วโมง
hitRate: '28%',
// ยกเลิกเมื่อมีการอัปเดตเอกสาร
tags: ['knowledge-base']
},
// ระดับที่ 3: แคชคำตอบที่สร้าง (สำหรับ query เดียวกัน)
responseCache: {
store: 'redis',
key: 'response:{{ md5($json.query) }}:{{ md5($json.context) }}',
ttl: 1800, // 30 นาที
hitRate: '15%',
// ไม่แคชหาก context เปลี่ยน
conditional: '!$json.contextChanged'
},
// Cache warming สำหรับคำถามยอดนิยม
warming: {
schedule: '0 2 * * *', // ตี 2 ทุกวัน
queries: [
'บริการของคุณมีอะไรบ้าง',
'ฉันจะติดต่อฝ่ายสนับสนุนได้อย่างไร',
'เวลาทำการของคุณคือเมื่อไหร่'
]
}
};
การประหยัดต้นทุนด้วย GPT-5.5
// RAG ที่ปรับแต่งต้นทุนด้วย GPT-5.5
const costOptimization = {
// GPT-5.5 มีประสิทธิภาพ token สูงกว่า 40%
tokenEfficiency: 0.6, // ลด 40%
// การเลือกโมเดลแบบ tiered
modelSelection: {
// Query ง่าย: GPT-5.5-mini (เร็วที่สุด ถูกที่สุด)
condition: '{{ $json.complexityScore < 0.3 }}',
model: 'gpt-5.5-mini',
cost: '$0.002 / 1K tokens',
// Query มาตรฐาน: GPT-5.5 (สมดุล)
condition: '{{ $json.complexityScore >= 0.3 && $json.complexityScore < 0.8 }}',
model: 'gpt-5.5',
cost: '$0.015 / 1K tokens',
// Query ซับซ้อน: GPT-5.5-reasoning (คุณภาพดีที่สุด)
condition: '{{ $json.complexityScore >= 0.8 }}',
model: 'gpt-5.5-reasoning',
cost: '$0.03 / 1K tokens'
},
// การวิเคราะห์ความซับซ้อน
complexityAnalysis: {
factors: [
{ name: 'queryLength', weight: 0.2 },
{ name: 'numEntities', weight: 0.3 },
{ name: 'reasoningRequired', weight: 0.5 }
]
},
// การประมวลผลเป็นชุดสำหรับการจัดทำดัชนี
batchConfig: {
embeddingBatchSize: 100, // สูงสุดสำหรับ OpenAI
upsertBatchSize: 50, // Vector DB optimal
parallelBatches: 5 // ประมวลผลพร้อมกัน
},
// การคาดการณ์ต้นทุนรายเดือนสำหรับ 100K query
costProjection: {
gpt4: '$4,500',
gpt5_4: '$3,200',
gpt5_5: '$1,920', // ประหยัด 40%
gpt5_5WithTiers: '$1,440' // ประหยัดรวม 68%
}
};
การติดตามและการสังเกตการณ์
// การติดตาม RAG อย่างครอบคลุม
const ragMonitoring = {
// การติดตาม latency
latencyMetrics: {
embedding: { p50: '<100ms', p99: '<500ms' },
retrieval: { p50: '<50ms', p99: '<200ms' },
generation: { p50: '<1s', p99: '<3s' },
e2e: { p50: '<1.5s', p99: '<4s' }
},
// ตัวชี้วัดคุณภาพ
qualityMetrics: {
retrieval: {
precision: '0.85', // % ของเอกสารที่ดึงมาซึ่งเกี่ยวข้อง
recall: '0.78', // % ของเอกสารที่เกี่ยวข้องซึ่งดึงมา
mrr: '0.82' // Mean Reciprocal Rank
},
generation: {
relevance: '4.3/5', // การประเมินของมนุษย์
faithfulness: '0.91', // % ที่ได้รับการสนับสนุนจาก context
citationAccuracy: '0.88'
}
},
// การติดตามข้อผิดพลาด
errorTracking: {
categories: [
'retrieval_empty', // ไม่พบเอกสาร
'context_too_long', // Context เกิน token limit
'generation_error', // LLM API error
'hallucination_detected'
],
alerting: {
threshold: 5, // แจ้งเตือนหลังจาก 5 ข้อผิดพลาดใน 5 นาที
channels: ['slack', 'pagerduty']
}
},
// การติดตาม feedback ของผู้ใช้
feedback: {
thumbsUpDown: true,
commentCapture: true,
correctionTracking: true,
// ปรับปรุงโมเดลอัตโนมัติจาก feedback
feedbackLoop: 'weekly-retrain'
}
};
// n8n monitoring workflow
const monitoringWorkflow = {
trigger: 'webhook',
nodes: [
{
name: 'Parse RAG Request',
extract: ['query', 'responseTime', 'tokenUsage', 'cacheHit']
},
{
name: 'ส่งไปยัง Prometheus',
type: 'httpRequest',
url: 'http://prometheus:9090/metrics',
body: `
rag_query_latency{{ query_type="{{ $json.type }}" }} {{ $json.responseTime }}
rag_token_usage{{ model="{{ $json.model }}" }} {{ $json.tokenUsage }}
rag_cache_hit{{ layer="{{ $json.cacheLayer }}" }} {{ $json.cacheHit ? 1 : 0 }}
`
},
{
name: 'แจ้งเตือนหากเกินเกณฑ์',
type: 'if',
condition: '{{ $json.responseTime > 4000 || $json.tokenUsage > 4000 }}'
},
{
name: 'ส่งการแจ้งเตือน',
type: 'slack',
message: 'RAG performance alert: Query ใช้เวลา {{ $json.responseTime }}ms'
}
]
};
กรณีการใช้งานจริง
กรณีการใช้งานที่ 1: Knowledge Base ฝ่ายสนับสนุนลูกค้า
// การใช้งาน RAG สำหรับฝ่ายสนับสนุนลูกค้า
const supportRag = {
knowledgeSources: [
{ type: 'zendesk', collections: ['articles', 'tickets'] },
{ type: 'confluence', spaces: ['support', 'product'] },
{ type: 'pdf', path: '/kb/product-guides' }
],
// การผสานรวมประวัติการสนทนา
contextManagement: {
// รักษา context การสนทนาข้าม turns
sessionStore: 'redis',
ttl: 3600, // 1 ชั่วโมง
// รวม context ก่อนหน้าในการดึงข้อมูล
queryExpansion: `
การสนทนาก่อนหน้า:\n{{ $json.conversationHistory }}\n\nคำถามปัจจุบัน: {{ $json.query }}
`,
// ติดตามสถานะแก้ไข/ไม่แก้ไข
resolutionTracking: true
},
// กฎการส่งต่อให้มนุษย์
escalation: {
triggers: [
{ condition: 'confidence < 0.7', action: 'suggest_human' },
{ condition: 'sentiment < -0.5', action: 'escalate_immediately' },
{ condition: 'intent == "billing_dispute"', action: 'escalate_immediately' }
]
},
// ตัวชี้วัดประสิทธิภาพ
metrics: {
deflectionRate: '67%', // % แก้ไขได้โดยไม่ต้องใช้มนุษย์
avgResponseTime: '1.2s', // End-to-end
csat: '4.4/5', // ความพึงพอใจของลูกค้า
costPerQuery: '$0.08' // เทียบกับ $4.50 สำหรับ agent มนุษย์
}
};
กรณีการใช้งานที่ 2: การสนับสนุนการขายด้วย RAG
// การขาย RAG สำหรับการสร้างข้อเสนอ
const salesRag = {
knowledgeSources: [
{ type: 'crm', data: 'opportunities,contacts,accounts' },
{ type: 'documents', path: '/sales/case-studies' },
{ type: 'documents', path: '/sales/proposal-templates' },
{ type: 'database', table: 'pricing_matrix' }
],
// การปรับแต่งแบบไดนามิก
personalization: {
// ดึง context ลูกค้าจาก CRM
clientData: '{{ $json.crmData }}',
// ปรับการดึงข้อมูลตามอุตสาหกรรมของลูกค้า
industryBoost: '{{ $json.crmData.industry }}',
// รวม case studies ที่เกี่ยวข้อง
caseStudyFilter: 'industry == "{{ $json.crmData.industry }}"'
},
// workflow การสร้างข้อเสนอ
proposalGeneration: {
steps: [
{ name: 'retrieveCompanyInfo', query: '{{ $json.clientName }} company overview' },
{ name: 'retrievePainPoints', query: '{{ $json.clientIndustry }} common challenges' },
{ name: 'retrieveSolutions', query: 'solutions for {{ $json.painPoints }}' },
{ name: 'retrieveCaseStudies', query: '{{ $json.clientIndustry }} case studies' },
{ name: 'generateProposal', model: 'gpt-5.5', template: 'formal_proposal' }
],
// การจัดรูปแบบ output
output: {
format: 'docx',
sections: ['executive_summary', 'solution', 'pricing', 'timeline', 'case_studies'],
branding: 'auto_apply'
}
},
// ประสิทธิภาพ
metrics: {
proposalGenerationTime: '3 นาที', // เทียบกับ 4 ชั่วโมงด้วยมือ
winRateImprovement: '+23%',
repProductivity: '+40%'
}
};
กรณีการใช้งานที่ 3: การวิเคราะห์เอกสารทางกฎหมาย
// การใช้งาน RAG ทางกฎหมายสำหรับการวิเคราะห์สัญญา
const legalRag = {
// การควบคุมการเข้าถึงอย่างเข้มงวด
accessControl: {
authentication: 'sso',
authorization: 'role-based',
auditLogging: true,
dataRetention: '7_years'
},
knowledgeSources: [
{ type: 'documents', path: '/contracts/active', access: 'attorney_only' },
{ type: 'documents', path: '/legal-precedents', access: 'all_legal' },
{ type: 'documents', path: '/regulatory', access: 'compliance_team' }
],
// ความต้องการการอ้างอิง
citation: {
required: true,
format: 'legal_citation',
includePageNumbers: true,
includeClauseNumbers: true,
linkToDocument: true
},
// การวิเคราะห์ความเสี่ยง
riskAnalysis: {
enabled: true,
categories: ['liability', 'termination', 'indemnification', 'ip_rights'],
highlightRiskClauses: true,
suggestAlternatives: true
},
// การเลือกโมเดล
model: 'gpt-5.5', // การให้เหตุผลที่ดีกว่าสำหรับข้อความทางกฎหมาย
temperature: 0.1, // ระมัดระวังสำหรับกฎหมาย
// การปฏิบัติตามกฎระเบียบ
compliance: {
barAssociation: 'approved',
clientConfidentiality: 'encrypted_at_rest_and_in_transit',
aiDisclosure: 'included_in_output'
}
};
รูปแบบการผสานรวม
n8n + Directus สำหรับการจัดการเนื้อหา
// Directus CMS integration สำหรับเนื้อหา RAG
const directusIntegration = {
// ซิงค์ Directus content กับ vector database
syncConfig: {
trigger: 'directus.hook',
events: ['items.create', 'items.update', 'items.delete'],
collections: ['articles', 'documentation', 'faqs'],
// แปลง Directus content
transform: {
// รวมหลาย fields
text: '{{ $json.content }}\n\n{{ $json.excerpt }}',
// ดึง metadata
metadata: {
title: '{{ $json.title }}',
slug: '{{ $json.slug }}',
category: '{{ $json.category.name }}',
tags: '{{ $json.tags.map(t => t.name) }}',
author: '{{ $json.user_created.first_name }}',
published: '{{ $json.date_published }}',
status: '{{ $json.status }}'
}
},
// กรองเฉพาะ content ที่เผยแพร่แล้ว
filter: 'status == "published"'
},
// Query Directus จาก RAG
queryIntegration: {
// เมื่อ RAG พบ chunk ที่เกี่ยวข้อง ดึงเนื้อหาเต็มจาก Directus
enrichment: {
endpoint: 'https://directus.company.com/items/articles/{{ $json.metadata.slug }}',
fields: ['content', 'related_articles', 'attachments'],
includeRelations: true
}
},
// อัปเดต Directus ด้วย RAG analytics
feedbackLoop: {
// ติดตามว่าเนื้อหาใดมีประโยชน์ที่สุด
queryLog: 'directus.rag_queries',
// อัปเดตความนิยมของบทความ
popularityMetric: {
collection: 'articles',
field: 'rag_retrieval_count',
increment: 1
}
}
};
n8n + Slack สำหรับความรู้ทีม
// Slack integration สำหรับความรู้ทีม
const slackIntegration = {
// จัดทำดัชนีการสนทนา Slack
indexing: {
channels: ['#knowledge-base', '#product-discussions', '#engineering'],
excludeBots: true,
excludeCommands: true,
// การรักษา context ของ thread
threadContext: {
includeParent: true,
includeReplies: true,
maxThreadDepth: 5
}
},
// Slack bot สำหรับ query
bot: {
trigger: '@knowledgebot',
// ตอบใน thread
responseMode: 'thread',
// รวมลิงก์แหล่งที่มา
includeSources: true,
// สรุปสำหรับ Slack
summarize: {
maxLength: 3000, // Slack message limit
includeHighlights: true
}
},
// เรียนรู้จาก reactions
feedback: {
thumbsUp: 'positive_feedback',
thumbsDown: 'negative_feedback',
// ปรับปรุงอัตโนมัติตาม reactions
retraining: 'weekly'
}
};
ความปลอดภัยและความเป็นส่วนตัว
การปกป้องข้อมูล
// Security configuration สำหรับระบบ RAG
const securityConfig = {
// Encryption ขณะเก็บ
encryption: {
vectors: 'aes-256-gcm',
metadata: 'aes-256-gcm',
backups: 'aes-256-gcm'
},
// Encryption ขณะส่ง
tls: {
version: '1.3',
certificates: 'letsencrypt',
hsts: true
},
// การควบคุมการเข้าถึง
rbac: {
roles: [
{ name: 'admin', permissions: ['read', 'write', 'delete', 'configure'] },
{ name: 'editor', permissions: ['read', 'write'] },
{ name: 'viewer', permissions: ['read'] }
],
// Row-level security บนเอกสาร
documentLevel: true
},
// Audit logging
audit: {
events: ['query', 'ingest', 'update', 'delete', 'access_denied'],
retention: '2_years',
tamperProof: true
},
// การจัดการ PII
pii: {
detection: 'automatic',
redaction: 'mask', // หรือ 'remove', 'hash'
entities: ['email', 'phone', 'ssn', 'credit_card', 'name'],
// ไม่จัดทำดัชนี PII ใน vectors
excludeFromEmbedding: true
},
// Data residency
residency: {
vectors: 'eu-west-1', // สอดคล้อง GDPR
backups: 'eu-central-1'
}
};
การทดสอบและการตรวจสอบความถูกต้อง
RAG Evaluation Framework
// RAG testing อย่างครอบคลุม
const ragEvaluation = {
// ชุดข้อมูลทดสอบ
datasets: {
// คำถามพร้อมคำตอบที่ทราบ
qaPairs: [
{
question: 'นโยบายการคืนเงินของเราคืออะไร',
expectedAnswer: 'เราเสนอการคืนเงินเต็มจำนวนภายใน 30 วัน',
expectedSources: ['policies/refund.pdf']
}
],
// Edge cases
edgeCases: [
{ question: 'asdfghjkl', expectedBehavior: 'graceful_fallback' },
{ question: '2+2 เท่ากับเท่าไหร่', expectedBehavior: 'no_hallucination' }
]
},
// ตัวชี้วัด
metrics: {
// Retrieval metrics
hitRate: {
@1: 0.75, // Top 1 เกี่ยวข้อง
@5: 0.90, // เกี่ยวข้องใน top 5
@10: 0.95 // เกี่ยวข้องใน top 10
},
// Generation metrics
bleu: 0.45,
rouge: 0.52,
faithfulness: 0.88,
answerRelevance: 0.91,
// Latency
p95Latency: '< 3 วินาที'
},
// การทดสอบอัตโนมัติใน n8n
testWorkflow: [
{
node: 'โหลดชุดข้อมูลทดสอบ',
type: 'readBinaryFile',
path: '/tests/rag-test-cases.json'
},
{
node: 'รันการทดสอบ Query',
type: 'httpRequest',
url: 'https://api.company.com/rag-query',
batchSize: 10
},
{
node: 'คำนวณตัวชี้วัด',
type: 'code',
code: `
const results = $input.all();
const metrics = calculateMetrics(results);
return [{ json: metrics }];
`
},
{
node: 'เปรียบเทียบกับเกณฑ์',
type: 'if',
condition: '{{ $json.hitRate@5 >= 0.90 }}'
},
{
node: 'รายงานผลลัพธ์',
type: 'slack',
message: 'RAG evaluation เสร็จสิ้น Hit rate @5: {{ $json.hitRate@5 }}'
}
]
};
บทสรุป
Retrieval-Augmented Generation เป็นความก้าวหน้าที่สำคัญที่สุดใน AI องค์กรตั้งแต่การแนะนำ Large Language Models ด้วยความสามารถในการให้เหตุผลที่ดีขึ้นของ GPT-5.5 รวมกับ vector database ที่มีสถาปัตยกรรมดีและกลยุทธ์การดึงข้อมูลที่ชาญฉลาด องค์กรสามารถสร้างระบบอัตโนมัติที่เน้นความรู้ที่มีความแม่นยำ ตรวจสอบได้ และคุ้มค่า
รูปแบบและการใช้งานที่ครอบคลุมในคู่มือนี้ - ตั้งแต่การนำเข้าเอกสารพื้นฐานไปจนถึงการดึงข้อมูล multi-query ขั้นสูง จากการปรับแต่งต้นทุนไปจนถึงการติดตาม production - ให้พื้นฐานที่ครอบคลุมสำหรับการสร้างระบบ RAG ที่ scale เมื่อ GPT-5.5 ยังคงเปิดตัวข้ามแพลตฟอร์มและเทคโนโลยี vector database เติบโต เราคาดว่า RAG จะกลายเป็นสถาปัตยกรรมมาตรฐานสำหรับแอปพลิเคชัน AI องค์กร
ข้อควรจำสำคัญ:
- Chunking สำคัญ: วิธีที่คุณแบ่งเอกสารมีผลกระทบต่อคุณภาพ RAG มากกว่าปัจจัยอื่นใด ลงทุนในกลยุทธ์การแบ่งข้อความที่ชาญฉลาดและรับรู้เนื้อหา
- Hybrid Search ชนะ: การรวม vector similarity กับ keyword matching และ re-ranking สม่ำเสมอเอาชนะการค้นหา semantic อย่างบริสุทธิ์ 15-30%
- GPT-5.5 เปลี่ยนเศรษฐศาสตร์: ด้วยการปรับปรุงประสิทธิภาพ token 40% และการให้เหตุผลที่ดีขึ้น GPT-5.5 ทำให้ RAG production คุ้มค่าและมีประสิทธิภาพกว่าที่เคย
- Observability เป็นสิ่งจำเป็น: ระบบ RAG production ต้องการการติดตามที่ครอบคลุมทั้งคุณภาพการดึงข้อมูลและคุณภาพการสร้างคำตอบ
- เริ่มง่ายๆ Scale อย่างชาญฉลาด: เริ่มต้นด้วยรูปแบบ RAG พื้นฐานและเพิ่มความซับซ้อน (multi-query, HyDE, self-reflection) เฉพาะเมื่อวิธีง่ายๆ ไม่เพียงพอ
ต่อไปทำอะไร?
- ใช้งาน ingestion pipeline จากส่วนที่ 2
- ตั้งค่า monitoring โดยใช้รูปแบบจากส่วนที่ 5
- ทดลองกับกลยุทธ์การแบ่งข้อความที่แตกต่างกันบนเอกสารของคุณเอง
- เข้าร่วมชุมชน n8n เพื่อแบ่งปันการใช้งาน RAG ของคุณ
อนาคตของ AI องค์กรไม่ได้อยู่ที่โมเดลที่รู้ทุกอย่าง - แต่อยู่ที่โมเดลที่รู้วิธีค้นหาและใช้ข้อมูลที่ถูกต้องในเวลาที่ถูกต้อง นั่นคือสิ่งที่ RAG มอบให้
ต้องการความช่วยเหลือในการใช้งาน RAG สำหรับธุรกิจของคุณ? ติดต่อ Tropical Media สำหรับคำปรึกษาจากผู้เชี่ยวชาญด้าน AI automation, n8n workflows และระบบที่เน้นความรู้
แหล่งข้อมูล
- Qdrant Documentation
- Pinecone RAG Guide
- OpenAI Embeddings API
- n8n Vector Store Nodes
- LangChain RAG Tutorial
- GPT-5.5 Release Notes
Tags
#RAG #VectorDatabase #n8n #GPT-5.5 #AI-Agent #Knowledge-Management #Qdrant #Pinecone #Automation #Retrieval-Augmented-Generation #Enterprise-AI #Machine-Learning #Workflow-Automation #Natural-Language-Processing #Semantic-Search
การประสานงาน AI Agent ระดับ Production: การขยายระบบ Multi-Agent ด้วยสถาปัตยกรรม Event-Driven
เชี่ยวชาญการประสานงาน AI Agent ระดับ Production ด้วยสถาปัตยกรรม Event-Driven, Message Queues และรูปแบบที่ขยายได้ เรียนรู้วิธีจัดการ AI Agent 100+ ใน n8n workflows, การจัดการข้อผิดพลาดที่ยืดหยุ่น, การปรับเพิ่มประสิทธิภาพด้านค่าใช้จ่าย และการสร้างระบบ Multi-Agent ที่ทนต่อความผิดพลาดด้วย Redis, RabbitMQ และ Temporal
การสร้าง n8n MCP Workflow กับ Claude: จากภาษาธรรมชาติสู่ระบบ Automation ระดับ Production
เรียนรู้วิธีใช้ n8n MCP Server ใหม่กับ Claude AI เพื่อสร้าง Workflow ที่สมบูรณ์จากคำอธิบายภาษาธรรมชาติ ค้นพบการเปลี่ยนแปลงครั้งสำคัญจากการกำหนดค่า Node แบบ manual สู่สถาปัตยกรรม Workflow ที่ได้รับการสนับสนุนจาก AI พร้อมตัวอย่างการใช้งานจริงกว่า 20 ตัวอย่างสำหรับการ automation ธุรกิจ การเชื่อมต่อระบบ และระบบ agentic