การจัดการ context ในการสนทนาหลายรอบ (Multi-turn Conversation) เป็นหัวใจสำคัญในการสร้าง AI Agent ที่มีประสิทธิภาพ ในบทความนี้เราจะมาดูวิธีการจัดการ conversation history อย่างมืออาชีพ พร้อมโค้ดตัวอย่างที่ใช้งานได้จริง ราคาถูกกว่าถึง 85%+ เมื่อใช้ HolySheep AI
ตารางเปรียบเทียบบริการ Claude API
| บริการ | ราคา Claude Sonnet 4.5/MTok | ความหน่วง (Latency) | วิธีการชำระเงิน | เครดิตฟรี |
|---|---|---|---|---|
| HolySheep AI | $15 (อัตรา ¥1=$1) | <50ms | WeChat, Alipay | ✅ มีเมื่อลงทะเบียน |
| API อย่างเป็นทางการ (Anthropic) | $15 + ภาษี | 100-300ms | บัตรเครดิตระหว่างประเทศ | ❌ ไม่มี |
| บริการรีเลย์อื่นๆ | $15-25 | 200-500ms | หลากหลาย | ขึ้นอยู่กับผู้ให้บริการ |
ทำความเข้าใจ Context Window และ Token
Claude Sonnet 4.5 มี context window 200K tokens ซึ่งเพียงพอสำหรับการสนทนายาวมาก แต่การจัดการที่ไม่ดีจะทำให้ token หมดเร็วและค่าใช้จ่ายสูงขึ้น ในการใช้งานจริงเราควร:
- สร้าง System Prompt ที่ดี - กำหนดบทบาทและขอบเขตการทำงานของ AI
- จัดการ conversation history - เก็บเฉพาะข้อมูลที่จำเป็น
- ใช้ truncation อย่างชาญฉลาด - ตัดข้อมูลเก่าที่ไม่เกี่ยวข้อง
- บีบอัด context - รวมข้อความที่ยาวให้กระชับ
โครงสร้างพื้นฐานสำหรับ Multi-turn Conversation
ให้เราสร้าง Python class สำหรับจัดการ conversation history อย่างมีประสิทธิภาพ:
import anthropic
from dataclasses import dataclass, field
from typing import List, Optional
import json
@dataclass
class Message:
role: str # "user" หรือ "assistant"
content: str
timestamp: float = 0.0
class ClaudeConversationManager:
"""ตัวจัดการ conversation history อย่างมีประสิทธิภาพ"""
def __init__(
self,
system_prompt: str,
max_tokens: int = 200_000,
target_context_tokens: int = 180_000
):
self.client = anthropic.Anthropic(
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY" # ใช้ HolySheep ประหยัด 85%+
)
self.system_prompt = system_prompt
self.max_tokens = max_tokens
self.target_context_tokens = target_context_tokens
self.history: List[Message] = []
def add_user_message(self, content: str) -> None:
"""เพิ่มข้อความจากผู้ใช้"""
self.history.append(Message(role="user", content=content))
def add_assistant_message(self, content: str) -> None:
"""เพิ่มข้อความจาก assistant"""
self.history.append(Message(role="assistant", content=content))
def get_context_window(self) -> List[dict]:
"""สร้าง context window พร้อมจัดการความยาว"""
# ตรวจสอบและ truncate ถ้าจำเป็น
self._ensure_token_limit()
messages = []
for msg in self.history:
messages.append({
"role": msg.role,
"content": msg.content
})
return messages
def _ensure_token_limit(self) -> None:
"""ตรวจสอบและ truncate conversation ถ้าเกิน limit"""
# ประมาณการ tokens (1 token ≈ 4 characters โดยเฉลี่ย)
total_chars = sum(len(m.content) for m in self.history)
estimated_tokens = total_chars // 4
if estimated_tokens > self.target_context_tokens:
# ลบข้อความเก่าที่สุดจนกว่าจะพอดี
removed_count = 0
while (sum(len(m.content) for m in self.history) // 4) > self.target_context_tokens:
if len(self.history) > 2: # เก็บ system prompt + ข้อความล่าสุด
self.history.pop(0)
removed_count += 1
else:
break
print(f"Truncated {removed_count} messages from history")
def send_message(self, user_message: str) -> str:
"""ส่งข้อความและรับ response"""
self.add_user_message(user_message)
response = self.client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
system=self.system_prompt,
messages=self.get_context_window()
)
assistant_response = response.content[0].text
self.add_assistant_message(assistant_response)
return assistant_response
กลยุทธ์ Context Summarization ขั้นสูง
สำหรับ conversation ที่ยาวมาก การ summarize context เก่าจะช่วยประหยัด token และเพิ่มความแม่นยำ:
class SummarizingConversationManager(ClaudeConversationManager):
"""Conversation manager พร้อม auto-summarization"""
def __init__(
self,
system_prompt: str,
max_tokens: int = 200_000,
summary_threshold: int = 150_000,
summary_trigger_tokens: int = 100_000
):
super().__init__(system_prompt, max_tokens)
self.summary_trigger_tokens = summary_trigger_tokens
self.summary_threshold = summary_threshold
self.summary: Optional[str] = None
def _check_and_summarize(self) -> None:
"""ตรวจสอบและ summarize ถ้าจำเป็น"""
total_chars = sum(len(m.content) for m in self.history)
estimated_tokens = total_chars // 4
if estimated_tokens > self.summary_trigger_tokens and not self.summary:
# สร้าง summary จากข้อความเก่า
old_messages = self.history[:-4] # เก็บ 4 ข้อความล่าสุด
old_content = "\n".join([m.content for m in old_messages])
summary_prompt = f"""Please summarize this conversation concisely,
keeping all important facts, decisions, and context:
{old_content}
Provide a brief summary (under 500 words):"""
summary_response = self.client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="You are a summarization assistant. Provide concise summaries.",
messages=[{"role": "user", "content": summary_prompt}]
)
self.summary = summary_response.content[0].text
# เก็บ summary + ข้อความล่าสุด
self.history = self.history[-4:]
# เพิ่ม summary เป็น system context
self.system_prompt = f"{self.system_prompt}\n\n[Previous Conversation Summary]:\n{self.summary}"
print("Context summarized successfully")
def send_message(self, user_message: str) -> str:
"""ส่งข้อความพร้อม auto-summarize"""
self.add_user_message(user_message)
self._check_and_summarize()
response = self.client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
system=self.system_prompt,
messages=self.get_context_window()
)
assistant_response = response.content[0].text
self.add_assistant_message(assistant_response)
return assistant_response
วิธีใช้งาน
manager = SummarizingConversationManager(
system_prompt="คุณเป็น AI assistant ที่ช่วยตอบคำถามเกี่ยวกับการเขียนโปรแกรม",
summary_trigger_tokens=80_000 # summarize เมื่อ token เกิน 80K
)
สนทนาต่อเนื่อง - ระบบจะ auto-summarize เมื่อจำเป็น
response1 = manager.send_message("อธิบายเรื่อง Python decorators")
response2 = manager.send_message("ให้ตัวอย่างการใช้งานจริง")
response3 = manager.send_message("เปรียบเทียบกับ JavaScript decorators")
รูปแบบการจัดการ Context ตาม Use Case
แต่ละ use case ต้องการกลยุทธ์การจัดการ context ที่แตกต่างกัน:
- Customer Support Bot - เก็บ ticket ID และข้อมูลลูกค้า แต่ truncate history เก่า
- Code Review Assistant - เก็บ file structure และ recent changes ทั้งหมด
- Research Assistant - เก็บ sources และ citations ทั้งหมด + summarize findings
- Document Editor - เก็บ document state + recent edits + undo history
Context Management สำหรับ AI Agent
สำหรับการสร้าง AI Agent ที่ต้องทำงานหลายขั้นตอน การจัดการ context ที่ดีจะเพิ่มประสิทธิภาพอย่างมาก:
from enum import Enum
from typing import Dict, Any, Callable
import re
class ContextPriority(Enum):
HIGH = "high" # ข้อมูลสำคัญ - เก็บเสมอ
MEDIUM = "medium" # ข้อมูลปานกลาง - เก็บจน full
LOW = "low" # ข้อมูลทั่วไป - truncate ก่อน
class PriorityConversationManager:
"""จัดการ context ตาม priority level"""
def __init__(self, system_prompt: str):
self.client = anthropic.Anthropic(
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY"
)
self.system_prompt = system_prompt
self.messages: List[Dict[str, Any]] = []
self.persistent_context: List[Dict[str, Any]] = [] # HIGH priority
def add_message(
self,
role: str,
content: str,
priority: ContextPriority = ContextPriority.MEDIUM,
metadata: Dict = None
) -> None:
"""เพิ่มข้อความพร้อมระบุ priority"""
msg = {
"role": role,
"content": content,
"priority": priority.value,
"metadata": metadata or {}
}
if priority == ContextPriority.HIGH:
self.persistent_context.append(msg)
else:
self.messages.append(msg)
def get_context(self) -> List[dict]:
"""สร้าง context ที่เรียงตาม priority"""
context = []
# 1. System prompt
# 2. Persistent context (HIGH priority)
context.extend([{"role": m["role"], "content": m["content"]}
for m in self.persistent_context])
# 3. Recent MEDIUM/LOW messages (limited)
medium_low = [m for m in self.messages
if m["priority"] != ContextPriority.HIGH.value]
# 4. Truncate ถ้าเกิน limit
for msg in medium_low[-20:]: # เก็บ 20 ข้อความล่าสุด
context.append({"role": msg["role"], "content": msg["content"]})
return context
def set_persistent_info(self, key: str, value: str) -> None:
"""บันทึกข้อมูลสำคัญที่ต้องเก็บตลอด"""
self.persistent_context.append({
"role": "user",
"content": f"[PERSISTENT: {key}] = {value}",
"priority": ContextPriority.HIGH.value
})
ตัวอย่างการใช้งานสำหรับ Document Editor Agent
editor_manager = PriorityConversationManager(
system_prompt="""คุณเป็น AI Document Editor Agent
- ช่วยแก้ไขและปรับปรุงเอกสาร
- รักษาความสอดคล้องของ content ตลอด conversation
- จำ structure และ formatting ของเอกสาร"""
)
ตั้งค่าข้อมูลที่ต้องเก็บตลอด (HIGH priority)
editor_manager.set_persistent_info("document_title", "รายงานประจำปี 2026")
editor_manager.set_persistent_info("target_audience", "ผู้บริหารระดับสูง")
editor_manager.set_persistent_info("style_guide", "formal, ใช้ภาษาทางการ")
ข้อความปกติ (MEDIUM priority)
editor_manager.add_message("user", "ขอให้เขียนบทนำ 200 คำ", ContextPriority.MEDIUM)
editor_manager.add_message("assistant", "บทนำ: [text]")
editor_manager.add_message("user", "ปรับให้สั้นลงเหลือ 100 คำ", ContextPriority.MEDIUM)
เทคนิค Context Compression
การบีบอัด context ให้เล็กลงโดยยังคงข้อมูลสำคัญ:
- Information Density Extraction - ดึงเฉพาะ facts สำคัญ
- Entity Linking - เชื่อมโยง entities ที่เกี่ยวข้อง
- Template-based Compression - แปลงข้อความเป็น structured format
- Progressive Summarization - summarize ซ้ำหลายรอบจนกว่าจะกระชับ
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
1. Token Limit Exceeded Error
# ❌ วิธีผิด: ไม่ตรวจสอบ context size ก่อนส่ง
response = client.messages.create(
model="claude-sonnet-4-20250514",
messages=conversation_history # อาจเกิน limit
)
✅ วิธีถูก: ตรวจสอบและ truncate ก่อน
def safe_send(client, messages, max_tokens=180000):
# ประมาณ token count
total_chars = sum(len(m.get("content", "")) for m in messages)
if total_chars // 4 > max_tokens:
# เก็บ system + ข้อความล่าสุด
keep_messages = [messages[0]] + messages[-(len(messages)-1):]
while (sum(len(m.get("content", "")) for m in keep_messages) // 4) > max_tokens:
if len(keep_messages) > 2:
keep_messages.pop(1)
messages = keep_messages
return client.messages.create(
model="claude-sonnet-4-20250514",
messages=messages,
max_tokens=4096
)
2. Context Bleeding (ข้อมูลปนกันระหว่าง conversations)
# ❌ วิธีผิด: ใช้ shared history object
shared_history = []
Thread A
shared_history.append({"role": "user", "content": "ข้อมูลลูกค้า A"})
Thread B (อาจเห็นข้อมูลลูกค้า A)
shared_history.append({"role": "user", "content": "ข้อมูลลูกค้า B"})
✅ วิธีถูก: แยก conversation อย่างชัดเจน
class ConversationSession:
def __init__(self, session_id: str):
self.session_id = session_id
self.messages: List[dict] = [] # แยก instance
self._init_system_context()
def _init_system_context(self):
# ตั้งค่า context เฉพาะ session
self.messages.append({
"role": "system",
"content": f"Session: {self.session_id}"
})
สร้าง session แยกกัน
session_a = ConversationSession("customer_A_123")
session_b = ConversationSession("customer_B_456")
3. Inconsistent Context Due to Async Operations
# ❌ วิธีผิด: race condition ในการ update history
async def send_message(conversation, msg):
conversation.history.append(msg) # อาจ conflict
response = await client.messages.create(...)
conversation.history.append(response) # อาจไม่ทัน
✅ วิธีถูก: ใช้ lock หรือ queue
import asyncio
class ThreadSafeConversation:
def __init__(self):
self._lock = asyncio.Lock()
self.history: List[dict] = []
async def send_message(self, client, new_message: str):
async with self._lock:
# Add user message
self.history.append({"role": "user", "content": new_message})
# Send (ใช้ snapshot ของ history)
snapshot = self.history.copy()
response = await client.messages.create(
model="claude-sonnet-4-20250514",
messages=snapshot
)
async with self._lock:
self.history.append({
"role": "assistant",
"content": response.content[0].text
})
return response.content[0].text
4. Memory Leak จาก Unbounded History Growth
# ❌ วิธีผิด: ไม่มีการ cleanup
class BadConversation:
def __init__(self):
self.history = []
def add_message(self, msg):
self.history.append(msg) # โตเรื่อยๆ ไม่หยุด
✅ วิธีถูก: มี cleanup strategy ชัดเจน
class GoodConversation:
MAX_HISTORY = 100 # max messages
CLEANUP_THRESHOLD = 80 # cleanup เมื่อถึง 80
def __init__(self):
self.history = []
self.summarized_content = None
def add_message(self, msg):
self.history.append(msg)
if len(self.history) >= self.CLEANUP_THRESHOLD:
self._cleanup_old_messages()
def _cleanup_old_messages(self):
if len(self.history) >= self.MAX_HISTORY:
# Summarize ข้อความเก่า
old_messages = self.history[:-20]
self.summarized_content = self._summarize(old_messages)
# เก็บเฉพาะ 20 ข้อความล่าสุด + summary
self.history = [{"role": "system",
"content": f"[Earlier summary]: {self.summarized_content}"}] + self.history[-20:]
Best Practices สรุป
- กำหนด Max Context เสมอ - ตั้ง threshold สำหรับ truncation หรือ summarization
- แยก Persistent vs Transient Context - ข้อมูลสำคัญเก็บแยก
- ใช้ Priority System - กำหนด priority ให้ข้อความต่างๆ
- Monitor Token Usage - ติดตาม token consumption อย่างสม่ำเสมอ
- Implement Graceful Degradation - มีแผนสำรองเมื่อ context เต็ม
- Test with Edge Cases - ทดสอบ conversation ที่ยาวมากและสั้นมาก
การจัดการ context ที่ดีจะช่วยให้ Claude ตอบได้แม่นยำขึ้น ประหยัดค่าใช้จ่าย และรองรับ conversation ที่ยาวขึ้น ลองนำโค้ดเหล่านี้ไปประยุกต์ใช้กับโปรเจกต์ของคุณได้เลย!
👉 สมัคร HolySheep AI — รับเครดิตฟรีเมื่อลงทะเบียน