Là một kỹ sư đã triển khai LangChain cho hơn 20 dự án AI production, tôi hiểu rằng callbacks là trái tim của hệ thống monitoring. Bài viết này sẽ hướng dẫn bạn từ cơ bản đến nâng cao về cách track events và logging trong LangChain với HolySheep AI — nền tảng tiết kiệm đến 85% chi phí API với độ trễ dưới 50ms.

Bảng So Sánh Chi Phí API 2026

Trước khi đi vào chi tiết kỹ thuật, hãy xem dữ liệu giá thực tế từ các nhà cung cấp hàng đầu:

ModelOutput ($/MTok)10M tokens/tháng ($)
GPT-4.1$8.00$80
Claude Sonnet 4.5$15.00$150
Gemini 2.5 Flash$2.50$25
DeepSeek V3.2$0.42$4.20

Với HolySheep AI, bạn có thể truy cập tất cả các model này qua một endpoint duy nhất. Tỷ giá ¥1 = $1 giúp doanh nghiệp Việt Nam tiết kiệm đáng kể khi thanh toán qua WeChat hoặc Alipay.

Callbacks Trong LangChain Là Gì?

Callbacks là cơ chế cho phép bạn "lắng nghe" các sự kiện trong chain của LangChain. Khi tôi bắt đầu với LangChain, việc không có visibility vào internal operations là một trong những thách thức lớn nhất. Callbacks giải quyết vấn đề này bằng cách cho phép bạn:

BaseCallbackHandler — Nền Tảng Của Mọi Callbacks

Trong kinh nghiệm thực chiến của tôi, việc tạo một custom handler tập trung giúp đơn giản hóa rất nhiều việc quản lý logging. Dưới đây là implementation hoàn chỉnh sử dụng HolySheep AI:

"""
LangChain Callback Handler cho HolySheep AI
Tác giả: HolySheep AI Technical Team
Version: 2.0.0
"""

import json
import time
from datetime import datetime
from typing import Any, Dict, List, Optional
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction, AgentFinish, LLMResult

class HolySheepCallbackHandler(BaseCallbackHandler):
    """
    Custom callback handler cho LangChain
    - Track token usage với chi phí cụ thể
    - Logging chi tiết từng event
    - Integration với monitoring systems
    """
    
    def __init__(self, model_name: str = "gpt-4.1"):
        super().__init__()
        self.model_name = model_name
        self.events: List[Dict[str, Any]] = []
        self.total_tokens = 0
        self.total_cost = 0.0
        self.start_time = None
        
        # HolySheep pricing 2026 (output price per MTok)
        self.pricing = {
            "gpt-4.1": 8.00,           # $8/MTok
            "claude-sonnet-4.5": 15.00, # $15/MTok
            "gemini-2.5-flash": 2.50,   # $2.50/MTok
            "deepseek-v3.2": 0.42,     # $0.42/MTok
        }
    
    def _calculate_cost(self, tokens: int) -> float:
        """Tính chi phí dựa trên số tokens"""
        price_per_token = self.pricing.get(self.model_name, 8.00) / 1_000_000
        return tokens * price_per_token
    
    def _log_event(self, event_type: str, data: Dict[str, Any]):
        """Log event với timestamp và metadata"""
        event = {
            "timestamp": datetime.now().isoformat(),
            "type": event_type,
            "model": self.model_name,
            "data": data
        }
        self.events.append(event)
        print(f"[HolySheep] {event_type}: {json.dumps(data, indent=2, ensure_ascii=False)}")
    
    def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs):
        """Called when LLM starts processing"""
        self.start_time = time.time()
        self._log_event("llm_start", {
            "serialized": serialized,
            "prompts_count": len(prompts),
            "first_prompt_length": len(prompts[0]) if prompts else 0
        })
    
    def on_llm_end(self, response: LLMResult, **kwargs):
        """Called when LLM finishes processing"""
        if self.start_time:
            latency_ms = (time.time() - self.start_time) * 1000
        
        # Extract token information from response
        for gen in response.generations:
            for generation in gen:
                if hasattr(generation, 'generation_info') and generation.generation_info:
                    token_info = generation.generation_info.get('token_usage', {})
                    
                    prompt_tokens = token_info.get('prompt_tokens', 0)
                    completion_tokens = token_info.get('completion_tokens', 0)
                    total_tokens = prompt_tokens + completion_tokens
                    cost = self._calculate_cost(total_tokens)
                    
                    self.total_tokens += total_tokens
                    self.total_cost += cost
                    
                    self._log_event("llm_end", {
                        "latency_ms": round(latency_ms, 2),
                        "prompt_tokens": prompt_tokens,
                        "completion_tokens": completion_tokens,
                        "total_tokens": total_tokens,
                        "cost_usd": round(cost, 6),
                        "total_cost_usd": round(self.total_cost, 6)
                    })
    
    def on_chain_start(self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs):
        """Called when chain starts"""
        self._log_event("chain_start", {
            "chain_name": serialized.get('name', 'unknown'),
            "input_keys": list(inputs.keys())
        })
    
    def on_chain_end(self, outputs: Dict[str, Any], **kwargs):
        """Called when chain ends"""
        self._log_event("chain_end", {
            "output_keys": list(outputs.keys())
        })
    
    def get_summary(self) -> Dict[str, Any]:
        """Trả về tổng kết sử dụng"""
        return {
            "total_events": len(self.events),
            "total_tokens": self.total_tokens,
            "total_cost_usd": round(self.total_cost, 6),
            "events": self.events
        }

Khởi tạo handler

handler = HolySheepCallbackHandler(model_name="deepseek-v3.2") print(f"Handler initialized for model: {handler.model_name}") print(f"Pricing: ${handler.pricing[handler.model_name]}/MTok")

Tích Hợp Với HolySheep API

Điều quan trọng là tất cả code mẫu trong bài viết này sử dụng HolySheep AI với base_url chuẩn. Dưới đây là cách setup ChatOpenAI với HolySheep endpoint:

"""
LangChain + HolySheep AI Integration
base_url: https://api.holysheep.ai/v1
Supports: GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash, DeepSeek V3.2
"""

import os
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from your_callback_module import HolySheepCallbackHandler

=== CẤU HÌNH HOLYSHEEP ===

API Key từ HolySheep AI Dashboard

os.environ["HOLYSHEEP_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY"

Model selection - so sánh chi phí:

- GPT-4.1: $8/MTok → 10M tokens = $80

- Claude Sonnet 4.5: $15/MTok → 10M tokens = $150

- Gemini 2.5 Flash: $2.50/MTok → 10M tokens = $25

- DeepSeek V3.2: $0.42/MTok → 10M tokens = $4.20 ⭐ BEST VALUE

MODEL_CONFIG = { "model": "deepseek-v3.2", # Tiết kiệm 95% so với Claude "temperature": 0.7, "max_tokens": 2000, "request_timeout": 60, "max_retries": 3, "streaming": True }

=== KHỞI TẠO LLM VỚI HOLYSHEEP ===

llm = ChatOpenAI( **MODEL_CONFIG, api_key=os.environ["HOLYSHEEP_API_KEY"], base_url="https://api.holysheep.ai/v1" # ✅ HolySheep endpoint )

=== KHỞI TẠO CALLBACK HANDLER ===

callback_handler = HolySheepCallbackHandler(model_name=MODEL_CONFIG["model"])

=== TẠO CHAIN VỚI CALLBACKS ===

prompt = PromptTemplate( input_variables=["topic"], template="Giải thích {topic} theo cách đơn giản nhất, phù hợp với người mới bắt đầu." ) chain = LLMChain( llm=llm, prompt=prompt, callbacks=[callback_handler] # ✅ Attach callback )

=== CHẠY CHAIN VÀ XEM RESULTS ===

print("=" * 60) print("🔄 Running LangChain với HolySheep AI Callbacks") print("=" * 60) result = chain.run( topic="LangChain callbacks và event tracking", callbacks=[callback_handler] ) print("\n" + "=" * 60) print("📊 SUMMARY") print("=" * 60) summary = callback_handler.get_summary() print(f"Total Events: {summary['total_events']}") print(f"Total Tokens: {summary['total_tokens']:,}") print(f"Total Cost: ${summary['total_cost_usd']:.6f}")

=== SO SÁNH CHI PHÍ ===

print("\n📈 Cost Comparison (10M tokens/month):") models = ["gpt-4.1", "claude-sonnet-4.5", "gemini-2.5-flash", "deepseek-v3.2"] for model in models: cost_10m = (1_000_000 / 1_000_000) * 10 * 8.00 if model == "gpt-4.1" else \ (1_000_000 / 1_000_000) * 10 * 15.00 if model == "claude-sonnet-4.5" else \ (1_000_000 / 1_000_000) * 10 * 2.50 if model == "gemini-2.5-flash" else \ (1_000_000 / 1_000_000) * 10 * 0.42 print(f" {model}: ${cost_10m:.2f}/tháng")

Advanced Callback Patterns

Trong production, tôi thường sử dụng nhiều callback handlers kết hợp. Dưới đây là pattern nâng cao với async support và real-time metrics:

"""
Advanced LangChain Callbacks - Multi-Handler Pattern
Author: HolySheep AI Technical Team
Features: Async support, Real-time metrics, Cost optimization
"""

import asyncio
import json
from typing import AsyncIterator
from datetime import datetime
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import LLMResult
from collections import defaultdict
import time

class MetricsCollector(BaseCallbackHandler):
    """
    Async callback handler cho real-time metrics collection
    - Tính toán chi phí theo thời gian thực
    - Tracking latency distribution
    - Performance monitoring
    """
    
    def __init__(self):
        self.metrics = defaultdict(list)
        self.cost_tracker = defaultdict(float)
        self.latency_tracker = []
        self.request_count = 0
        self.error_count = 0
        
        # HolySheep 2026 Pricing
        self.pricing_per_1k = {
            "deepseek-v3.2": 0.00042,      # $0.42/MTok = $0.00042/1K tokens
            "gemini-2.5-flash": 0.00250,   # $2.50/MTok
            "gpt-4.1": 0.00800,            # $8.00/MTok
            "claude-sonnet-4.5": 0.01500,  # $15.00/MTok
        }
    
    def on_llm_start(self, serialized, prompts, **kwargs):
        self.metrics["llm_starts"].append({
            "timestamp": datetime.now().isoformat(),
            "model": serialized.get("name", "unknown")
        })
    
    def on_llm_end(self, response: LLMResult, **kwargs):
        self.request_count += 1
        start_time = time.time()
        
        for generation_group in response.generations:
            for generation in generation_group:
                if hasattr(generation, 'generation_info') and generation.generation_info:
                    token_usage = generation.generation_info.get('token_usage', {})
                    model = response.llm_output.get('model_name', 'unknown') if response.llm_output else 'unknown'
                    
                    total_tokens = token_usage.get('total_tokens', 0)
                    prompt_tokens = token_usage.get('prompt_tokens', 0)
                    completion_tokens = token_usage.get('completion_tokens', 0)
                    
                    # Calculate cost
                    price_per_token = self.pricing_per_1k.get(model, 0.008) / 1000
                    cost = total_tokens * price_per_token
                    
                    self.cost_tracker[model] += cost
                    
                    self.metrics["tokens"].append({
                        "total": total_tokens,
                        "prompt": prompt_tokens,
                        "completion": completion_tokens,
                        "cost_usd": cost
                    })
        
        latency = (time.time() - start_time) * 1000
        self.latency_tracker.append(latency)
    
    def on_llm_error(self, error, **kwargs):
        self.error_count += 1
        self.metrics["errors"].append({
            "timestamp": datetime.now().isoformat(),
            "error": str(error)
        })
    
    def get_metrics(self) -> dict:
        """Tính toán metrics tổng hợp"""
        total_tokens = sum(m["total"] for m in self.metrics["tokens"])
        total_cost = sum(self.cost_tracker.values())
        
        avg_latency = sum(self.latency_tracker) / len(self.latency_tracker) if self.latency_tracker else 0
        p95_latency = sorted(self.latency_tracker)[int(len(self.latency_tracker) * 0.95)] if self.latency_tracker else 0
        
        return {
            "request_count": self.request_count,
            "error_count": self.error_count,
            "total_tokens": total_tokens,
            "total_cost_usd": round(total_cost, 6),
            "cost_by_model": dict(self.cost_tracker),
            "latency": {
                "avg_ms": round(avg_latency, 2),
                "p95_ms": round(p95_latency, 2),
                "min_ms": round(min(self.latency_tracker), 2) if self.latency_tracker else 0,
                "max_ms": round(max(self.latency_tracker), 2) if self.latency_tracker else 0
            },
            "cost_projection_10m_tokens": {
                model: round(cost / total_tokens * 10_000_000, 2) if total_tokens > 0 else 0
                for model, cost in self.cost_tracker.items()
            }
        }

class StreamingCostOptimizer(BaseCallbackHandler):
    """
    Streaming callback với token counting theo thời gian thực
    Giúp tối ưu chi phí streaming
    """
    
    def __init__(self):
        self.current_tokens = 0
        self.stream_start_time = None
        self.chunks = []
    
    def on_llm_start(self, serialized, prompts, **kwargs):
        self.stream_start_time = time.time()
        print(f"[Streaming] Starting LLM call...")
    
    def on_llm_new_token(self, token: str, **kwargs):
        """Called for each streaming token"""
        self.current_tokens += 1
        self.chunks.append(token)
        
        # Print streaming output (limit to prevent spam)
        if len(self.chunks) % 50 == 0:
            print(f"[Streaming] Tokens received: {self.current_tokens}")
    
    def on_llm_end(self, response: LLMResult, **kwargs):
        if self.stream_start_time:
            total_time = time.time() - self.stream_start_time
            tokens_per_second = self.current_tokens / total_time if total_time > 0 else 0
            
            print(f"\n[Streaming] Complete!")
            print(f"  Total tokens: {self.current_tokens}")
            print(f"  Time: {total_time:.2f}s")
            print(f"  Speed: {tokens_per_second:.2f} tokens/s")
            
            # Cost với DeepSeek V3.2 ($0.42/MTok)
            cost = self.current_tokens * (0.42 / 1_000_000)
            print(f"  Cost (DeepSeek V3.2): ${cost:.6f}")

=== DEMO USAGE ===

async def demo_advanced_callbacks(): """Demo với multiple callbacks""" from langchain_openai import ChatOpenAI from langchain.chains import LLMChain from langchain.prompts import PromptTemplate import os os.environ["OPENAI_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY" # Initialize LLM với HolySheep llm = ChatOpenAI( model="deepseek-v3.2", api_key=os.environ["OPENAI_API_KEY"], base_url="https://api.holysheep.ai/v1", streaming=True ) # Multiple callbacks metrics_handler = MetricsCollector() streaming_handler = StreamingCostOptimizer() chain = LLMChain( llm=llm, prompt=PromptTemplate.from_template("Viết một đoạn văn ngắn về: {topic}"), callbacks=[metrics_handler, streaming_handler] ) # Run result = await chain.arun(topic="HolySheep AI - Tiết kiệm 85% chi phí API") # Get metrics print("\n" + "=" * 60) print("📊 ADVANCED METRICS SUMMARY") print("=" * 60) metrics = metrics_handler.get_metrics() print(json.dumps(metrics, indent=2, ensure_ascii=False)) return metrics

Chạy demo

if __name__ == "__main__": asyncio.run(demo_advanced_callbacks())

Streaming Callback Với Token Counting

Streaming là tính năng quan trọng để giảm perceived latency. Callback handler theo dõi từng token nhận được, giúp bạn đánh giá chi phí và tốc độ thực tế:

"""
Streaming Callback với Real-time Token Counting
Optimized cho HolySheep AI với <50ms latency
"""

from typing import Optional, Iterator
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import LLMResult
import time

class StreamingTokenCounter(BaseCallbackHandler):
    """
    Callback đếm tokens trong streaming mode
    - Real-time token counting
    - Chi phí tính theo từng token
    - Độ trễ theo dõi
    """
    
    def __init__(self, model: str = "deepseek-v3.2"):
        self.model = model
        self.tokens = 0
        self.chars = 0
        self.start_time = None
        self.first_token_time = None
        
        # HolySheep 2026 pricing
        self.cost_per_token = {
            "deepseek-v3.2": 0.42 / 1_000_000,      # $0.42/MTok
            "gemini-2.5-flash": 2.50 / 1_000_000,
            "gpt-4.1": 8.00 / 1_000_000,
        }
    
    def on_llm_start(self, serialized, prompts, **kwargs):
        self.start_time = time.time()
        self.first_token_time = None
        print(f"[TokenCounter] Model: {self.model}")
        print(f"[TokenCounter] Waiting for response...")
    
    def on_llm_new_token(self, token: str, **kwargs):
        if self.first_token_time is None:
            self.first_token_time = time.time()
            time_to_first_token = (self.first_token_time - self.start_time) * 1000
            print(f"[TokenCounter] First token received in {time_to_first_token:.2f}ms")
        
        self.tokens += 1
        self.chars += len(token)
    
    def on_llm_end(self, response: LLMResult, **kwargs):
        total_time = time.time() - self.start_time
        cost = self.tokens * self.cost_per_token.get(self.model, 0.42 / 1_000_000)
        
        print(f"\n[TokenCounter] === STREAMING COMPLETE ===")
        print(f"  Total tokens: {self.tokens}")
        print(f"  Total characters: {self.chars}")
        print(f"  Total time: {total_time:.2f}s")
        print(f"  Tokens/second: {self.tokens / total_time:.2f}")
        print(f"  Model: {self.model}")
        print(f"  Cost: ${cost:.8f}")
        print(f"  ====================================")

Sử dụng với HolySheep

from langchain_openai import ChatOpenAI import os os.environ["OPENAI_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY" llm = ChatOpenAI( model="deepseek-v3.2", api_key=os.environ["OPENAI_API_KEY"], base_url="https://api.holysheep.ai/v1", streaming=True, callbacks=[StreamingTokenCounter(model="deepseek-v3.2")] )

Test streaming

for chunk in llm.stream("Explain why DeepSeek V3.2 is cost-effective for production:"): print(chunk.content, end="", flush=True)

Lỗi Thường Gặp và Cách Khắc Phục

Qua kinh nghiệm triển khai LangChain callbacks cho nhiều dự án, tôi đã gặp và xử lý nhiều lỗi phổ biến. Dưới đây là 5 trường hợp điển hình nhất:

1. Lỗi "No module named 'langchain'" hoặc Import Errors

Nguyên nhân: Phiên bản LangChain không tương thích hoặc package chưa được cài đặt đúng cách.

# ❌ CÁCH SAI - Cài đặt không đầy đủ
pip install langchain

✅ CÁCH ĐÚNG - Cài đặt đầy đủ với tất cả dependencies

pip install --upgrade langchain langchain-openai langchain-community pip install langchain-core langchain-experimental

Hoặc sử dụng requirements.txt:

langchain>=0.1.0

langchain-openai>=0.0.5

langchain-community>=0.0.10

openai>=1.0.0

Kiểm tra version

import langchain print(f"LangChain version: {langchain.__version__}")

2. Lỗi "Invalid API Key" hoặc Authentication Failed

Nguyên nhân: API key không đúng hoặc base_url bị sai. Lưu ý quan trọng: KHÔNG sử dụng api.openai.com hoặc api.anthropic.com khi dùng HolySheep.

# ❌ CÁCH SAI - Sử dụng sai base_url
llm = ChatOpenAI(
    model="gpt-4.1",
    api_key="YOUR_HOLYSHEEP_API_KEY",
    base_url="https://api.openai.com/v1"  # ❌ SAI!
)

✅ CÁCH ĐÚNG - Sử dụng HolySheep AI endpoint

import os

Đảm bảo biến môi trường được set đúng

os.environ["OPENAI_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY" llm = ChatOpenAI( model="deepseek-v3.2", # Hoặc "gpt-4.1", "claude-sonnet-4.5", "gemini-2.5-flash" api_key=os.environ.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY"), base_url="https://api.holysheep.ai/v1" # ✅ ĐÚNG! )

Verify connection

try: response = llm.invoke("Test connection") print("✅ Connection successful!") except Exception as e: print(f"❌ Connection failed: {e}") # Kiểm tra lại API key tại: https://www.holysheep.ai/register

3. Lỗi "Callback handler not being called" hoặc Events Not Tracked

Nguyên nhân: Callback được truyền sai vị trí hoặc không được gắn vào đúng chain.

from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from your_callback_module import HolySheepCallbackHandler

Khởi tạo handler

callback_handler = HolySheepCallbackHandler(model_name="deepseek-v3.2")

❌ CÁCH SAI - Callback không được truyền đúng cách

chain = LLMChain( llm=llm, prompt=prompt ) result = chain.run("query") # ❌ Không có callback!

❌ CÁCH SAI 2 - Chỉ truyền callback khi run

result = chain.run("query", callbacks=[callback_handler]) # ❌ Vẫn có thể miss events

✅ CÁCH ĐÚNG - Gắn callback ngay khi khởi tạo chain

chain = LLMChain( llm=llm, prompt=prompt, callbacks=[callback_handler] # ✅ Gắn callback vào chain )

Truyền thêm khi run để đảm bảo

result = chain.run( "query", callbacks=[callback_handler] # ✅ Callback được đảm bảo )

Verify events

print(f"Events tracked: {len(callback_handler.events)}") print(f"Total tokens: {callback_handler.total_tokens}")

Nếu vẫn không có events, kiểm tra:

1. Handler có inherit từ BaseCallbackHandler không

2. Methods có đúng signature không (serialized, prompts, **kwargs)

assert hasattr(callback_handler, 'on_llm_start'), "Missing on_llm_start method" assert hasattr(callback_handler, 'on_llm_end'), "Missing on_llm_end method"

4. Lỗi "Streaming callback not working" hoặc Token Count = 0

Nguyên nhơn: Model không support streaming hoặc streaming mode chưa được bật.

from langchain_openai import ChatOpenAI

❌ CÁCH SAI - Không bật streaming

llm = ChatOpenAI( model="deepseek-v3.2", api_key="YOUR_HOLYSHEEP_API_KEY", base_url="https://api.holysheep.ai/v1", # streaming=False # Mặc định là False! )

❌ CÁCH SAI 2 - Callback không có on_llm_new_token

class BrokenCallback: def on_llm_start(self, *args, **kwargs): print("Started") def on_llm_end(self, *args, **kwargs): print("Ended") # Thiếu on_llm_new_token!

✅ CÁCH ĐÚNG - Bật streaming và implement đúng method

class WorkingStreamingCallback(BaseCallbackHandler): def on_llm_new_token(self, token: str, **kwargs): """Method BẮT BUỘC phải có cho streaming""" print(f"Token: {token}", end="", flush=True) def on_llm_start(self, *args, **kwargs): print("Starting...") def on_llm_end(self, *args, **kwargs): print("\nDone!")

Initialize với streaming=True

llm = ChatOpenAI( model="deepseek-v3.2", api_key="YOUR_HOLYSHEEP_API_KEY", base_url="https://api.holysheep.ai/v1", streaming=True # ✅ BẬT STREAMING )

Sử dụng stream() thay vì invoke()

for chunk in llm.stream("Count from 1 to 5:"): print(chunk.content, end="", flush=True)

5. Lỗi "Cost calculation incorrect" hoặc Token Usage = None

Nguyên nhân: Response không chứa token usage information hoặc cách trích xuất không đúng.

# ❌ CÁCH SAI - Không kiểm tra token usage structure
def on_llm_end(self, response, **kwargs):
    # Giả định token_usage luôn tồn tại
    tokens = response.generations[0][0].generation_info['token_usage']['total_tokens']
    # ❌ Sẽ crash nếu generation_info = None

✅ CÁCH ĐÚNG - Safe extraction với fallback

def on_llm_end(self, response: LLMResult, **kwargs): total_tokens = 0 cost = 0.0 try: # Method 1: Từ generation_info for generation_group in response.generations: for generation in generation_group: if hasattr(generation, 'generation_info') and generation.generation_info: token_info = generation.generation_info.get('token_usage', {}) total_tokens = token_info.get('total_tokens', 0) break # Method 2: Từ llm_output (OpenAI format) if total_tokens == 0 and hasattr(response, 'llm_output'): if response.llm_output and 'token_usage' in response.llm_output: total_tokens = response.llm_output['token_usage'].get('total_tokens', 0) # Method 3: Estimate từ text length (fallback) if total_tokens == 0: # Ước tính: ~4 characters per token cho tiếng Anh text = response.generations[0][0].text if response.generations else "" total_tokens = len(text) // 4 print(f"[Warning] Using estimated tokens: {total_tokens}") # Tính cost v