LangChain Agent Troubleshooting แก้ปัญหา
LangChain เป็น open source framework สำหรับสร้าง applications ที่ใช้ Large Language Models (LLMs) โดย Agents เป็น feature สำคัญที่ให้ LLM ตัดสินใจว่าจะใช้ tools อะไร เพื่อตอบคำถามหรือทำงานที่ซับซ้อน แต่การพัฒนา LangChain Agents มักพบปัญหาหลายอย่าง เช่น agent loop ไม่จบ, tool เรียกผิด, output parsing error, memory overflow และ performance ช้า บทความนี้รวบรวมปัญหาที่พบบ่อยและวิธีแก้ไขอย่างเป็นระบบ
LangChain Agent Architecture
# agent_arch.py — LangChain Agent architecture
import json
class AgentArchitecture:
COMPONENTS = {
"llm": {
"name": "LLM (Language Model)",
"description": "สมองของ agent — ตัดสินใจว่าจะทำอะไรต่อ",
"options": "OpenAI GPT-4, Claude, Llama, Mistral, Ollama",
},
"tools": {
"name": "Tools",
"description": "เครื่องมือที่ agent เรียกใช้ — search, calculator, API calls",
"examples": "SerpAPI, Wikipedia, Python REPL, SQL Database, Custom tools",
},
"memory": {
"name": "Memory",
"description": "เก็บ conversation history สำหรับ context",
"types": "ConversationBufferMemory, ConversationSummaryMemory, VectorStoreMemory",
},
"prompt": {
"name": "Prompt Template",
"description": "คำสั่งที่บอก agent ว่าต้องทำอะไร format อย่างไร",
"types": "ReAct, OpenAI Functions, Structured Chat",
},
"output_parser": {
"name": "Output Parser",
"description": "แปลง LLM output เป็น structured action/response",
"common_error": "OutputParserException — LLM ไม่ return format ที่คาดหวัง",
},
}
AGENT_TYPES = {
"react": {"name": "ReAct Agent", "use": "General purpose, reasoning + acting"},
"openai_functions": {"name": "OpenAI Functions Agent", "use": "ใช้กับ OpenAI models, structured tool calls"},
"structured_chat": {"name": "Structured Chat Agent", "use": "Multi-input tools, complex schemas"},
"plan_execute": {"name": "Plan-and-Execute", "use": "Complex tasks ที่ต้อง planning ก่อน"},
}
def show_components(self):
print("=== Agent Components ===\n")
for key, comp in self.COMPONENTS.items():
print(f"[{comp['name']}]")
print(f" {comp['description']}")
print()
def show_types(self):
print("=== Agent Types ===")
for key, agent in self.AGENT_TYPES.items():
print(f" [{agent['name']}] {agent['use']}")
arch = AgentArchitecture()
arch.show_components()
arch.show_types()
ปัญหาที่พบบ่อยและวิธีแก้ไข
# common_issues.py — Common LangChain Agent issues
import json
class CommonIssues:
ISSUES = {
"infinite_loop": {
"name": "1. Agent Loop ไม่จบ (Infinite Loop)",
"symptom": "Agent เรียก tool ซ้ำๆ ไม่หยุด หรือคิดวนไปวนมา",
"causes": [
"Prompt ไม่ชัดเจน — agent ไม่รู้ว่าเมื่อไหร่ควรหยุด",
"Tool return ข้อมูลไม่เพียงพอ — agent ต้องเรียกซ้ำ",
"LLM model อ่อนเกินไป — ตัดสินใจไม่ได้",
],
"fixes": [
"ตั้ง max_iterations=10 (จำกัดรอบ)",
"ปรับ prompt ให้ชัดเจน: 'หยุดเมื่อได้คำตอบแล้ว'",
"ใช้ model ที่ดีกว่า (GPT-4 แทน GPT-3.5)",
"เพิ่ม early_stopping_method='force'",
],
},
"output_parse_error": {
"name": "2. OutputParserException",
"symptom": "Could not parse LLM output / Invalid format",
"causes": [
"LLM ไม่ return format ที่ parser คาดหวัง",
"LLM ตอบเป็นภาษาธรรมชาติแทน structured output",
"Token limit ถูกตัด output ไม่ครบ",
],
"fixes": [
"ใช้ handle_parsing_errors=True",
"ใช้ OutputFixingParser wrap parser เดิม",
"เปลี่ยนเป็น OpenAI Functions agent (structured output)",
"เพิ่ม max_tokens ให้เพียงพอ",
],
},
"wrong_tool": {
"name": "3. Agent เรียก Tool ผิด",
"symptom": "Agent ใช้ wrong tool สำหรับ task, หรือไม่ใช้ tool เลย",
"causes": [
"Tool description ไม่ชัดเจน",
"มี tools คล้ายกันมากเกินไป",
"Prompt ไม่ guide agent ดีพอ",
],
"fixes": [
"เขียน tool description ให้ชัดเจน: 'ใช้เมื่อ..., อย่าใช้เมื่อ...'",
"ลดจำนวน tools (ไม่เกิน 5-7 tools)",
"เพิ่ม examples ใน prompt",
"ใช้ tool_choice='required' บังคับใช้ tool",
],
},
"memory_overflow": {
"name": "4. Memory/Context Overflow",
"symptom": "Token limit exceeded, context too long",
"causes": [
"Conversation history ยาวเกินไป",
"Tool output ยาวมาก",
"ไม่มี summarization",
],
"fixes": [
"ใช้ ConversationSummaryMemory แทน BufferMemory",
"ตั้ง max_token_limit ใน memory",
"Truncate tool output ก่อนส่งกลับ agent",
"ใช้ ConversationBufferWindowMemory(k=5) เก็บแค่ 5 รอบล่าสุด",
],
},
"slow_performance": {
"name": "5. Performance ช้า",
"symptom": "Agent ใช้เวลานานกว่าจะตอบ (30s+)",
"causes": [
"เรียก LLM หลายรอบเกินไป",
"Tool execution ช้า (API calls)",
"Model ใหญ่เกินไป",
],
"fixes": [
"ใช้ streaming=True สำหรับ UX ที่ดีขึ้น",
"Cache LLM responses (SQLiteCache, RedisCache)",
"ใช้ async tools สำหรับ parallel execution",
"ลด max_iterations",
],
},
}
def show_issues(self):
print("=== Common Issues & Fixes ===\n")
for key, issue in self.ISSUES.items():
print(f"[{issue['name']}]")
print(f" Symptom: {issue['symptom']}")
print(f" Top fix: {issue['fixes'][0]}")
print()
issues = CommonIssues()
issues.show_issues()
Debugging Techniques
# debugging.py — LangChain debugging techniques
import json
class DebuggingTechniques:
VERBOSE_MODE = """
# debug_agent.py — Enable verbose debugging
from langchain.agents import AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain.globals import set_verbose, set_debug
# Method 1: Verbose mode (แสดง agent thoughts)
set_verbose(True)
# Method 2: Debug mode (แสดงทุก LLM call)
set_debug(True)
# Method 3: LangSmith tracing (recommended for production)
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-langsmith-key"
os.environ["LANGCHAIN_PROJECT"] = "my-agent-debug"
# Method 4: Custom callbacks
from langchain.callbacks import StdOutCallbackHandler
class DebugCallback(StdOutCallbackHandler):
def on_agent_action(self, action, **kwargs):
print(f"\\n[ACTION] Tool: {action.tool}")
print(f"[INPUT] {action.tool_input}")
def on_tool_end(self, output, **kwargs):
print(f"[OUTPUT] {str(output)[:200]}...")
def on_agent_finish(self, finish, **kwargs):
print(f"\\n[FINISH] {finish.return_values}")
# Use callback
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
callbacks=[DebugCallback()],
max_iterations=10,
handle_parsing_errors=True,
)
"""
ERROR_HANDLING = """
# error_handling.py — Robust error handling
from langchain.agents import AgentExecutor
# 1. Handle parsing errors gracefully
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
handle_parsing_errors=True, # Auto-retry on parse errors
max_iterations=10, # Prevent infinite loops
early_stopping_method="force", # Force stop after max
return_intermediate_steps=True, # Debug: see all steps
)
# 2. Custom error handler
def custom_error_handler(error):
return f"An error occurred: {str(error)}. Please try a different approach."
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
handle_parsing_errors=custom_error_handler,
)
# 3. Try-except wrapper
def safe_agent_run(query, max_retries=3):
for attempt in range(max_retries):
try:
result = agent_executor.invoke({"input": query})
return result
except Exception as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt == max_retries - 1:
return {"output": f"Failed after {max_retries} attempts: {e}"}
"""
def show_verbose(self):
print("=== Verbose Debugging ===")
print(self.VERBOSE_MODE[:500])
def show_error_handling(self):
print(f"\n=== Error Handling ===")
print(self.ERROR_HANDLING[:500])
debug = DebuggingTechniques()
debug.show_verbose()
debug.show_error_handling()
Best Practices
# best_practices.py — LangChain Agent best practices
import json
class BestPractices:
PRACTICES = {
"tools": {
"name": "Tool Design",
"tips": [
"เขียน description ชัดเจน: 'ใช้เมื่อต้องการ... input คือ... output คือ...'",
"จำกัด tools ไม่เกิน 5-7 ตัว (มากกว่า = agent สับสน)",
"Validate tool input ก่อน execute",
"Truncate tool output ถ้ายาวเกิน (max 1000 chars)",
"ใช้ Pydantic model สำหรับ tool input schema",
],
},
"prompt": {
"name": "Prompt Engineering",
"tips": [
"ระบุ role ชัดเจน: 'คุณเป็น assistant ที่...'",
"เพิ่ม few-shot examples สำหรับ tool usage",
"บอกเมื่อไหร่ควรหยุด: 'เมื่อได้คำตอบแล้ว ให้ตอบทันที'",
"ห้ามสิ่งที่ไม่ต้องการ: 'อย่าเดา ถ้าไม่รู้ให้บอกว่าไม่รู้'",
],
},
"performance": {
"name": "Performance",
"tips": [
"ใช้ streaming สำหรับ UX ที่ดี",
"Cache LLM responses (SQLiteCache สำหรับ dev)",
"ใช้ async สำหรับ parallel tool execution",
"เลือก model size ให้เหมาะ: GPT-3.5 สำหรับง่ายๆ, GPT-4 สำหรับซับซ้อน",
],
},
"testing": {
"name": "Testing",
"tips": [
"เขียน unit tests สำหรับแต่ละ tool",
"ทดสอบ edge cases: empty input, very long input, invalid format",
"ใช้ LangSmith สำหรับ evaluation และ tracing",
"Benchmark: วัด latency, token usage, accuracy",
],
},
}
WORKING_AGENT = """
# working_agent.py — Well-structured agent example
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.tools import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. Define tools with clear descriptions
@tool
def search_knowledge_base(query: str) -> str:
'''Search internal knowledge base for information.
Use this when you need to find specific information about our products or policies.
Input: search query string
Output: relevant information or "not found"
'''
# Implement search logic
return f"Found: relevant info for '{query}'"
@tool
def calculate(expression: str) -> str:
'''Calculate a mathematical expression.
Use this for any math calculations.
Input: math expression like "2 + 2" or "100 * 1.07"
Output: calculation result
'''
try:
return str(eval(expression))
except Exception as e:
return f"Error: {e}"
# 2. Create agent with good prompt
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant. Use tools when needed. "
"When you have the answer, respond directly."),
MessagesPlaceholder("chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad"),
])
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
agent = create_openai_functions_agent(llm, [search_knowledge_base, calculate], prompt)
# 3. Create executor with safety guards
executor = AgentExecutor(
agent=agent,
tools=[search_knowledge_base, calculate],
verbose=True,
max_iterations=5,
handle_parsing_errors=True,
)
result = executor.invoke({"input": "What is our refund policy?"})
print(result["output"])
"""
def show_practices(self):
print("=== Best Practices ===\n")
for key, p in self.PRACTICES.items():
print(f"[{p['name']}]")
for tip in p["tips"][:3]:
print(f" • {tip}")
print()
def show_working(self):
print("=== Working Agent Example ===")
print(self.WORKING_AGENT[:600])
bp = BestPractices()
bp.show_practices()
bp.show_working()
LangSmith & Monitoring
# monitoring.py — LangSmith and agent monitoring
import json
import random
class AgentMonitoring:
LANGSMITH = {
"name": "LangSmith",
"description": "Platform สำหรับ debug, test, evaluate และ monitor LLM applications",
"features": ["Trace visualization", "Token usage tracking", "Latency analysis", "Evaluation datasets", "Prompt playground"],
"setup": "pip install langsmith + set LANGCHAIN_TRACING_V2=true",
}
METRICS = {
"latency": "เวลาตั้งแต่ส่ง query ถึงได้ response (target: < 5s)",
"token_usage": "จำนวน tokens ที่ใช้ต่อ query (ลดค่าใช้จ่าย)",
"iterations": "จำนวนรอบที่ agent ใช้ (target: < 5)",
"success_rate": "เปอร์เซ็นต์ที่ agent ตอบถูกต้อง",
"tool_accuracy": "เปอร์เซ็นต์ที่ agent เลือก tool ถูกต้อง",
"error_rate": "เปอร์เซ็นต์ที่เกิด error (parse, timeout, etc.)",
}
def show_langsmith(self):
print("=== LangSmith ===")
ls = self.LANGSMITH
print(f" {ls['description']}")
print(f" Features: {', '.join(ls['features'][:3])}")
print(f" Setup: {ls['setup']}")
def show_metrics(self):
print(f"\n=== Key Metrics ===")
for name, desc in self.METRICS.items():
print(f" [{name}] {desc}")
def agent_dashboard(self):
print(f"\n=== Agent Dashboard (Last 24h) ===")
metrics = {
"Total queries": random.randint(100, 1000),
"Avg latency": f"{random.uniform(1, 5):.1f}s",
"Avg tokens/query": random.randint(500, 3000),
"Avg iterations": f"{random.uniform(1.5, 4):.1f}",
"Success rate": f"{random.uniform(85, 98):.1f}%",
"Error rate": f"{random.uniform(0.5, 5):.1f}%",
"Cost": f"",
}
for m, v in metrics.items():
print(f" {m}: {v}")
mon = AgentMonitoring()
mon.show_langsmith()
mon.show_metrics()
mon.agent_dashboard()
FAQ - คำถามที่พบบ่อย
Q: Agent loop ไม่หยุดทำอย่างไร?
A: 1. ตั้ง max_iterations=10 (สำคัญที่สุด) 2. ใช้ early_stopping_method="force" 3. ปรับ prompt ให้ชัด: "เมื่อได้คำตอบแล้วให้ตอบทันที" 4. ใช้ model ที่ดีกว่า (GPT-4 แทน GPT-3.5) 5. ลดจำนวน tools ให้น้อยลง
Q: OutputParserException แก้อย่างไร?
A: ง่ายที่สุด: handle_parsing_errors=True (auto-retry) ดีกว่า: ใช้ OpenAI Functions agent (structured output, ไม่ต้อง parse) Advanced: ใช้ OutputFixingParser ครอบ parser เดิม ตรวจสอบ: max_tokens เพียงพอหรือไม่ (output ถูกตัด = parse fail)
Q: LangChain กับ LlamaIndex ต่างกัน?
A: LangChain: general purpose framework, agents, chains, tools, memory ครบ LlamaIndex: เน้น RAG (Retrieval-Augmented Generation), data indexing, query engine ใช้ LangChain: complex agents, multi-tool workflows, chatbots ใช้ LlamaIndex: document Q&A, knowledge base, search ใช้ทั้งคู่ได้: LlamaIndex สำหรับ RAG tool + LangChain สำหรับ agent orchestration
Q: Agent ช้ามากทำอย่างไร?
A: 1. ใช้ streaming=True (user เห็น response ทันที) 2. Cache: ใช้ SQLiteCache หรือ RedisCache สำหรับ repeated queries 3. Model: ใช้ gpt-4o-mini แทน gpt-4 สำหรับ simple tasks 4. Async: ใช้ ainvoke() สำหรับ parallel tool execution 5. ลด iterations: max_iterations=5 + เขียน prompt ให้ดี
