บทนำ: ทำไมการติดตาม Agent Actions ถึงสำคัญ

เมื่อพัฒนา AI Agent ด้วย LangChain การเห็นว่า Agent คิดอะไร ตัดสินใจอย่างไร และเรียกใช้ Tool ใดบ้าง ถือเป็นสิ่งจำเป็นอย่างยิ่งสำหรับการพัฒนาและแก้ไขปัญหา ในบทความนี้เราจะมาดูวิธีใช้ LangChain Callbacks อย่างมีประสิทธิภาพ พร้อมกรณีศึกษาจริงจากทีมพัฒนาที่ประสบความสำเร็จในการปรับปรุงระบบ

กรณีศึกษา: ทีมสตาร์ทอัพ AI ในกรุงเทพฯ

บริบทธุรกิจ

ทีมสตาร์ทอัพ AI แห่งหนึ่งในกรุงเทพฯ พัฒนาแชทบอทสำหรับบริการลูกค้าของธุรกิจอีคอมเมิร์ซ ระบบต้องจัดการคำถามหลากหลายรูปแบบ ตั้งแต่การตรวจสอบสถานะคำสั่งซื้อ การแนะนำสินค้า ไปจนถึงการจัดการคืนสินค้า

จุดเจ็บปวดของผู้ให้บริการเดิม

ทีมเดิมใช้ OpenAI API และพบปัญหาหลายประการ:

เหตุผลที่เลือก HolySheep AI

หลังจากทดสอบหลาย provider ทีมตัดสินใจเลือก HolySheep AI เนื่องจากปัจจัยหลักดังนี้:

ขั้นตอนการย้าย

1. การเปลี่ยน Base URL

ขั้นตอนแรกคือการเปลี่ยน base_url จาก OpenAI เป็น HolySheep ในไฟล์ configuration ของระบบ

2. การหมุนคีย์ API

ทีมสร้าง API key ใหม่จาก HolySheep Dashboard และทำการ rotate คีย์อย่างปลอดภัยโดยใช้ environment variables

3. Canary Deploy

ทีมเริ่มด้วยการ deploy ให้ 10% ของผู้ใช้ก่อน ติดตามผลลัพธ์และค่อยๆ เพิ่มสัดส่วนจนถึง 100% ภายใน 1 สัปดาห์

ตัวชี้วัด 30 วันหลังจากนั้น

พื้นฐาน LangChain Callbacks

LangChain Callbacks คือระบบที่ช่วยให้คุณ "สอดแนม" การทำงานของ Chain และ Agent ได้ตลอดเวลา คุณสามารถเห็นได้ว่า:

การติดตั้งและตั้งค่าเบื้องต้น

ก่อนอื่นให้ติดตั้ง LangChain และ dependencies ที่จำเป็น:

pip install langchain langchain-openai langchain-anthropic python-dotenv

จากนั้นสร้างไฟล์ .env เพื่อเก็บ API key อย่างปลอดภัย:

# .env file
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1

การสร้าง Custom Callback Handler

สำหรับการ logging ที่ละเอียด เราควรสร้าง Callback Handler ของตัวเองเพื่อให้ควบคุม output ได้ตามต้องการ:

import os
from datetime import datetime
from typing import Any, Dict, List, Union
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction, AgentFinish, LLMResult
from dotenv import load_dotenv

load_dotenv()

class DetailedLoggingHandler(BaseCallbackHandler):
    """Callback handler สำหรับ logging รายละเอียดของ agent actions"""
    
    def __init__(self):
        super().__init__()
        self.action_log = []
        self.token_count = 0
    
    def on_llm_start(
        self, serialized: Dict[str, Any], prompts: List[str], **kwargs
    ) -> None:
        """ถูกเรียกเมื่อ LLM เริ่มประมวลผล"""
        print(f"\n🔵 [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] LLM Start")
        print(f"   Prompt length: {len(prompts[0])} characters")
        self.action_log.append({
            "type": "llm_start",
            "timestamp": datetime.now().isoformat(),
            "prompt_length": len(prompts[0])
        })
    
    def on_llm_new_token(self, token: str, **kwargs) -> None:
        """ถูกเรียกเมื่อ LLM ส่ง token ใหม่"""
        self.token_count += 1
        print(f"   📝 Token {self.token_count}: {token[:50]}...")
    
    def on_llm_end(self, response: LLMResult, **kwargs) -> None:
        """ถูกเรียกเมื่อ LLM ประมวลผลเสร็จ"""
        print(f"\n🟢 [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] LLM End")
        generation = response.generations[0][0]
        print(f"   Response: {generation.text[:200]}...")
        self.action_log.append({
            "type": "llm_end",
            "timestamp": datetime.now().isoformat(),
            "response_preview": generation.text[:100]
        })
    
    def on_tool_start(
        self, serialized: Dict[str, Any], input_str: str, **kwargs
    ) -> None:
        """ถูกเรียกเมื่อ tool เริ่มทำงาน"""
        tool_name = serialized.get("name", "unknown")
        print(f"\n🟡 [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] Tool Start: {tool_name}")
        print(f"   Input: {input_str[:150]}...")
        self.action_log.append({
            "type": "tool_start",
            "timestamp": datetime.now().isoformat(),
            "tool": tool_name,
            "input": input_str
        })
    
    def on_tool_end(self, output: str, **kwargs) -> None:
        """ถูกเรียกเมื่อ tool ทำงานเสร็จ"""
        print(f"🟢 [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] Tool End")
        print(f"   Output: {output[:150]}...")
        self.action_log.append({
            "type": "tool_end",
            "timestamp": datetime.now().isoformat(),
            "output": output
        })
    
    def on_agent_action(self, action: AgentAction, **kwargs) -> None:
        """ถูกเรียกเมื่อ agent ตัดสินใจทำอะไร"""
        print(f"\n🔴 [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] Agent Action")
        print(f"   Tool: {action.tool}")
        print(f"   Tool Input: {action.tool_input}")
        self.action_log.append({
            "type": "agent_action",
            "timestamp": datetime.now().isoformat(),
            "tool": action.tool,
            "tool_input": action.tool_input
        })
    
    def on_agent_finish(self, finish: AgentFinish, **kwargs) -> None:
        """ถูกเรียกเมื่อ agent จบการทำงาน"""
        print(f"\n✅ [{datetime.now().strftime('%H:%M:%S.%f')[:-3]}] Agent Finish")
        print(f"   Final Output: {finish.return_values['output'][:200]}...")
        self.action_log.append({
            "type": "agent_finish",
            "timestamp": datetime.now().isoformat(),
            "output": finish.return_values['output']
        })
    
    def get_summary(self) -> Dict[str, Any]:
        """สรุปผลการทำงานทั้งหมด"""
        return {
            "total_actions": len(self.action_log),
            "actions_by_type": self._count_by_type(),
            "total_tokens": self.token_count
        }
    
    def _count_by_type(self) -> Dict[str, int]:
        """นับจำนวน actions แต่ละประเภท"""
        counts = {}
        for log in self.action_log:
            log_type = log["type"]
            counts[log_type] = counts.get(log_type, 0) + 1
        return counts

การใช้งานกับ Agent และ Tools

ต่อไปนี้คือตัวอย่างการสร้าง Agent พร้อมใช้งาน callback handler กับ HolySheep AI:

import os
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
from detailed_logging_handler import DetailedLoggingHandler

load_dotenv()

สร้าง LLM ด้วย HolySheep

llm = ChatOpenAI( openai_api_key=os.getenv("HOLYSHEEP_API_KEY"), openai_api_base=os.getenv("HOLYSHEEP_BASE_URL"), model="gpt-4.1", # หรือเลือก model อื่นตามต้องการ temperature=0.7, streaming=True # เปิด streaming เพื่อดู token ทีละตัว )

สร้าง callback handler

logging_handler = DetailedLoggingHandler()

โหลด tools พื้นฐาน

tools = load_tools(["serpapi", "python_repl"], llm=llm)

สร้าง agent พร้อม callbacks

agent = initialize_agent( tools=tools, llm=llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=False, # ปิด verbose ของ LangChain เพราะใช้ callback เราแทน callbacks=[logging_handler] # ส่ง callback handler เข้าไป )

ทดสอบ agent

print("=" * 60) print("เริ่มทดสอบ Agent") print("=" * 60) response = agent.run( "ค้นหาข้อมูลราคา Bitcoin ล่าสุด แล้วคำนวณว่าถ้าซื้อ 0.5 BTC " "ต้องจ่ายกี่บาทไทย (สมมติ 1 BTC = 2,500,000 บาท)" ) print("\n" + "=" * 60) print("สรุปผลการทำงาน") print("=" * 60) summary = logging_handler.get_summary() print(f"จำนวน actions ทั้งหมด: {summary['total_actions']}") print(f"รายละเอียด: {summary['actions_by_type']}") print(f"จำนวน tokens ที่ stream: {summary['total_tokens']}")

การ Debug ด้วย Console Output

สำหรับการ debug แบบง่ายๆ โดยไม่ต้องสร้าง custom handler คุณสามารถใช้ StdOutCallbackHandler ที่มากับ LangChain:

from langchain.callbacks import StdOutCallbackHandler
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
import os
from dotenv import load_dotenv

load_dotenv()

ใช้ StdOutCallbackHandler สำหรับ debug ทั่วไป

std_out_handler = StdOutCallbackHandler()

สร้าง simple chain

llm = ChatOpenAI( openai_api_key=os.getenv("HOLYSHEEP_API_KEY"), openai_api_base=os.getenv("HOLYSHEEP_BASE_URL"), model="deepseek-v3.2", # ใช้ DeepSeek ซึ่งราคาถูกมาก $0.42/MTok ) prompt = PromptTemplate( input_variables=["topic"], template="อธิบายเกี่ยวกับ {topic} ให้เข้าใจง่ายใน 3 ประโยค" ) chain = LLMChain(llm=llm, prompt=prompt, callbacks=[std_out_handler])

รัน chain

result = chain.run("การทำงานของ LangChain callbacks") print(f"\n✅ Final Result: {result}")

การ Debug ด้วย LangSmith

สำหรับการ debug แบบมืออาชีพ LangSmith เป็นเครื่องมือที่ยอดเยี่ยม แม้จะมีค่าใช้จ่ายเพิ่มเติม แต่ช่วยให้เห็น traces ทั้งหมดได้:

import os
from langchain_openai import ChatOpenAI
from langchain.callbacks.tracers import LangSmithTracer
from langchain.schema import HumanMessage
from dotenv import load_dotenv

load_dotenv()

ตั้งค่า LangSmith

os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com" os.environ["LANGCHAIN_API_KEY"] = "your-langsmith-api-key"

สร้าง tracer

tracer = LangSmithTracer( project_name="holy-sheep-debugging", example_id="example-001" ) llm = ChatOpenAI( openai_api_key=os.getenv("HOLYSHEEP_API_KEY"), openai_api_base=os.getenv("HOLYSHEEP_BASE_URL"), model="claude-sonnet-4.5", callbacks=[tracer] ) messages = [HumanMessage(content="ทดสอบการ debug กับ LangSmith")] response = llm.predict_messages(messages) print(f"Response: {response.content}")

การเปรียบเทียบราคาและความเร็วของ Models ต่างๆ

เมื่อใช้ HolySheep คุณสามารถเลือก model ที่เหมาะสมกับงานได้ โดยพิจารณาจากราคาและความเร็ว:

Model ราคา (2026/MTok) เหมาะกับงาน
GPT-4.1 $8.00 งานที่ต้องการความแม่นยำสูง
Claude Sonnet 4.5 $15.00 งานเขียนโค้ด, การวิเคราะห์
Gemini 2.5 Flash $2.50 งานทั่วไป, ความเร็วสูง
DeepSeek V3.2 $0.42 งานที่ต้องการประหยัดต้นทุน

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

1. ImportError: cannot import name 'ChatOpenAI' from 'langchain_openai'

สาเหตุ: Package langchain-openai ยังไม่ได้ติดตั้ง หรือติดตั้งเวอร์ชันที่ไม่ถูกต้อง

วิธีแก้ไข:

# ติดตั้งเวอร์ชันล่าสุด
pip install --upgrade langchain-openai

หรือติดตั้งทั้งหมดใหม่

pip uninstall langchain-openai langchain -y pip install langchain langchain-openai

2. AuthenticationError: Invalid API Key

สาเหตุ: API key ไม่ถูกต้อง หรือไม่ได้ถูกโหลดจาก .env file

วิธีแก้ไข:

import os
from dotenv import load_dotenv

โหลด .env ก่อนใช้งาน

load_dotenv()

ตรวจสอบว่า API key ถูกโหลดหรือไม่

api_key = os.getenv("HOLYSHEEP_API_KEY") if not api_key: raise ValueError("HOLYSHEEP_API_KEY not found in environment variables")

ตรวจสอบว่าค่าถูกต้อง

print(f"API Key loaded: {api_key[:8]}...")

สร้าง LLM

llm = ChatOpenAI( openai_api_key=api_key, openai_api_base=os.getenv("HOLYSHEEP_BASE_URL"), model="gpt-4.1" )

3. AttributeError: 'NoneType' object has no attribute 'generations'

สาเหตุ: Callback ถูกเรียกก่อนที่ LLM จะประมวลผลเสร็จ หรือ response เป็น None

วิธีแก้ไข:

from typing import Any, Dict, List, Optional
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import LLMResult

class SafeLoggingHandler(BaseCallbackHandler):
    """Callback handler ที่ปลอดภัยต่อการ handle None values"""
    
    def on_llm_end(self, response: Optional[LLMResult], **kwargs) -> None:
        """ตรวจสอบ response ก่อนเข้าถึง"""
        if response is None:
            print("⚠️ LLM response is None - possible API error")
            return
        
        # ตรวจสอบว่า generations มีข้อมูลหรือไม่
        if not response.generations or not response.generations[0]:
            print("⚠️ No generations in response")
            return
        
        try:
            generation = response.generations[0][0]
            print(f"✅ Response: {generation.text[:100]}...")
        except (IndexError, AttributeError) as e:
            print(f"⚠️ Error accessing generation: {e}")
    
    def on_llm_error(
        self, error: Exception, *, run_id: Any, parent_run_id: Any | None = None, **kwargs
    ) -> None:
        """จับ error ที่เกิดขึ้นระหว่าง LLM ทำงาน"""
        print(f"❌ LLM Error occurred: {type(error).__name__}: {str(error)}")
        # บันทึก error สำหรับการ debug
        import traceback
        traceback.print_exc()

4. ConnectionError: HTTPSConnectionPool - Max retries exceeded

สาเหตุ: เครือข่ายไม่เสถียร หรือ proxy settings ไม่ถูกต้อง

วิธีแก้ไข:

import os
import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter

ตั้งค่า retry strategy

retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], ) adapter = HTTPAdapter(max_retries=retry_strategy)

ตรวจสอบการเชื่อมต่อก่อน

def check_connection(): try: response = requests.get( "https://api.holysheep.ai/v1/models", timeout=10 ) print(f"✅ Connection OK - Status: {response.status_code}") return True except requests.exceptions.RequestException as e: print(f"❌ Connection failed: {e}") return False

ทดสอบการเชื่อมต่อ

if check_connection(): # ดำเนินการต่อ from langchain_openai import ChatOpenAI llm = ChatOpenAI( openai_api_key=os.getenv("HOLYSHEEP_API_KEY"), openai_api_base=os.getenv("HOLYSHEEP_BASE_URL"), model="gpt-4.1", max_retries=3 # เพิ่ม retries สำหรับ LLM calls ) else: print("⚠️ กรุณาตรวจสอบการเชื่อมต่ออินเทอร์เน็ต")

สรุป

การใช้ LangChain Callbacks อย่างมีประสิทธิภาพช่วยให้คุณสามารถ:

กรณีศึกษาจากทีมสตาร์ทอัพในกรุงเทพฯ แสดงให้เห็นว่