Mở Đầu: Câu Chuyện Thực Tế Từ Đỉnh Mùa Tuyển Sinh

Tôi vẫn nhớ rõ cách đây 2 năm, khi làm tư vấn tuyển sinh cho một trường đại học top 3 Trung Quốc, hệ thống chatbot cũ của họ sập lúc 23:47 — ngay giữa ca trực đêm của mùa tuyển sinh. Hơn 200 câu hỏi chờ đợi, đội ngũ tư vấn viên đã nghỉ hết, và tỷ lệ khách hàng bỏ đi lên tới 73%. Kể từ đó, tôi đã xây dựng hệ thống tư vấn tuyển sinh thông minh với HolySheep AI — kết hợp sức mạnh của Kimi cho FAQ phức tạp, Claude cho phản hồi cá nhân hóa, và cơ chế fallback tự động đa mô hình. Trong bài viết này, tôi sẽ chia sẻ toàn bộ kiến trúc, code, và bài học xương máu từ dự án thực tế — giúp bạn xây dựng hệ thống tư vấn tuyển sinh có thể xử lý 10,000+ concurrent users với độ trễ dưới 50ms.

Kiến Trúc Tổng Quan: Tại Sao Cần Multi-Model Fallback?

Trong hệ thống tư vấn tuyển sinh thực tế, chúng ta đối mặt với 3 loại câu hỏi hoàn toàn khác nhau:

Ba loại câu hỏi trong hệ thống tư vấn tuyển sinh

QUESTION_TYPES = { "FAQ_COMPLEX": { "description": "Hỏi đáp phức tạp, cần ngữ cảnh dài", "example": "Cho tôi biết sự khác biệt giữa ngành Khoa học Máy tính và Kỹ thuật Phần mềm ở ĐH Tsinghua?", "best_model": "kimi" # Dài context, chi phí thấp }, "PERSONALIZED": { "description": "Câu hỏi cá nhân hóa dựa trên profile", "example": "Em được 1450 điểm SAT, muốn apply ngành Economics ở Peking University, cơ hội như thế nào?", "best_model": "claude" # Personality, reasoning }, "FAST_FALLBACK": { "description": "Câu hỏi đơn giản, cần response nhanh", "example": "Hạn nộp hồ sơ是什么时候?", "best_model": "deepseek" # Siêu rẻ, siêu nhanh } }

Triển Khai Chi Tiết: Code Hoàn Chỉnh

Bước 1: Cấu Hình HolySheep API Client


import requests
import json
import time
from typing import Optional, Dict, Any, List
from dataclasses import dataclass
from enum import Enum

class ModelType(Enum):
    KIMI = "kimi"
    CLAUDE = "claude-sonnet"
    DEEPSEEK = "deepseek-chat"
    GEMINI = "gemini-2.0-flash"

@dataclass
class HolySheepConfig:
    base_url: str = "https://api.holysheep.ai/v1"
    api_key: str = "YOUR_HOLYSHEEP_API_KEY"  # Thay thế bằng API key của bạn
    timeout: int = 30
    max_retries: int = 3

class HolySheepClient:
    """Client cho HolySheep AI với multi-model fallback thông minh"""
    
    def __init__(self, config: Optional[HolySheepConfig] = None):
        self.config = config or HolySheepConfig()
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Bearer {self.config.api_key}",
            "Content-Type": "application/json"
        })
    
    def chat_completion(
        self,
        model: ModelType,
        messages: List[Dict[str, str]],
        temperature: float = 0.7,
        max_tokens: int = 2048
    ) -> Dict[str, Any]:
        """Gọi API chat completion với error handling"""
        
        endpoint = f"{self.config.base_url}/chat/completions"
        payload = {
            "model": model.value,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens
        }
        
        for attempt in range(self.config.max_retries):
            try:
                start_time = time.time()
                response = self.session.post(
                    endpoint,
                    json=payload,
                    timeout=self.config.timeout
                )
                latency = (time.time() - start_time) * 1000  # ms
                
                if response.status_code == 200:
                    return {
                        "success": True,
                        "data": response.json(),
                        "latency_ms": round(latency, 2),
                        "model": model.value
                    }
                elif response.status_code == 429:
                    # Rate limit - chờ và retry
                    wait_time = 2 ** attempt
                    time.sleep(wait_time)
                    continue
                elif response.status_code == 401:
                    return {
                        "success": False,
                        "error": "Invalid API key",
                        "code": 401
                    }
                else:
                    return {
                        "success": False,
                        "error": response.text,
                        "code": response.status_code
                    }
                    
            except requests.exceptions.Timeout:
                if attempt == self.config.max_retries - 1:
                    return {
                        "success": False,
                        "error": "Request timeout"
                    }
            except Exception as e:
                return {
                    "success": False,
                    "error": str(e)
                }
        
        return {"success": False, "error": "Max retries exceeded"}

Khởi tạo client

client = HolySheepClient() print("HolySheep Client initialized successfully!")

Bước 2: Hệ Thống Intelligent Router và Fallback Chain


import re
from typing import Tuple

class AdmissionQuestionRouter:
    """Router thông minh phân loại câu hỏi và chọn model phù hợp"""
    
    def __init__(self, client: HolySheepClient):
        self.client = client
        # Priority: model ưu tiên, fallback chain
        self.fallback_chains = {
            ModelType.KIMI: [ModelType.DEEPSEEK, ModelType.GEMINI],
            ModelType.CLAUDE: [ModelType.KIMI, ModelType.DEEPSEEK],
            ModelType.DEEPSEEK: [ModelType.GEMINI, ModelType.KIMI]
        }
    
    def classify_question(self, question: str) -> Tuple[str, str]:
        """Phân loại câu hỏi và trả về (loại, model đề xuất)"""
        
        question_lower = question.lower()
        
        # Pattern cho FAQ phức tạp (cần Kimi)
        faq_patterns = [
            r"khác nhau.*giữa",
            r"so sánh.*với",
            r"tại sao.*chọn",
            r"điểm khác biệt",
            r"học phí.*năm",
            r"sinh viên.*như thế nào"
        ]
        
        # Pattern cho câu hỏi cá nhân hóa (cần Claude)
        personalized_patterns = [
            r"tôi được.*điểm",
            r"em.*điểm.*sat|gre|toefl",
            r"profile.*của tôi",
            r"cơ hội.*như thế nào",
            r"nên chọn.*hay",
            r"con tôi.*muốn"
        ]
        
        # Pattern cho câu hỏi nhanh (DeepSeek)
        fast_patterns = [
            r"khi nào",
            r"ở đâu",
            r"bao giờ",
            r"thời hạn",
            r"hạn chót",
            r"là gì"
        ]
        
        # Kiểm tra độ dài câu hỏi
        word_count = len(question.split())
        
        for pattern in personalized_patterns:
            if re.search(pattern, question_lower):
                return ("personalized", "claude")
        
        for pattern in faq_patterns:
            if re.search(pattern, question_lower) or word_count > 25:
                return ("faq_complex", "kimi")
        
        for pattern in fast_patterns:
            if re.search(pattern, question_lower) and word_count < 15:
                return ("fast_query", "deepseek")
        
        # Default: dựa vào độ dài
        if word_count > 30:
            return ("faq_complex", "kimi")
        elif word_count > 15:
            return ("general", "claude")
        else:
            return ("fast_query", "deepseek")
    
    def call_with_fallback(
        self,
        question: str,
        context: Optional[List[Dict]] = None,
        preferred_model: Optional[ModelType] = None
    ) -> Dict[str, Any]:
        """Gọi model với fallback chain tự động"""
        
        # Xác định model ưu tiên
        if preferred_model:
            question_type, primary_model = "forced", preferred_model
        else:
            question_type, model_name = self.classify_question(question)
            primary_model = ModelType(model_name) if isinstance(model_name, str) else model_name
        
        # Xây dựng messages
        messages = []
        if context:
            messages.extend(context)
        messages.append({"role": "user", "content": question})
        
        # Thử primary model trước
        fallback_chain = self.fallback_chains.get(primary_model, [])
        all_models = [primary_model] + fallback_chain
        
        errors = []
        for model in all_models:
            result = self.client.chat_completion(
                model=model,
                messages=messages,
                temperature=0.7 if model != ModelType.DEEPSEEK else 0.5
            )
            
            if result["success"]:
                return {
                    **result,
                    "question_type": question_type,
                    "model_used": result["model"],
                    "latency_ms": result["latency_ms"]
                }
            else:
                errors.append({
                    "model": model.value,
                    "error": result["error"]
                })
        
        # Tất cả đều thất bại
        return {
            "success": False,
            "errors": errors,
            "message": "Tất cả các model đều không khả dụng. Vui lòng thử lại sau."
        }

Demo usage

router = AdmissionQuestionRouter(client) test_questions = [ "Cho tôi biết sự khác nhau giữa ngành Khoa học Máy tính và Kỹ thuật Phần mềm?", "Em được 1450 điểm SAT, muốn apply ngành Economics, cơ hội như thế nào?", "Hạn nộp hồ sơ khi nào?" ] for q in test_questions: qtype, model = router.classify_question(q) print(f"Câu hỏi: {q[:50]}... → Type: {qtype}, Model: {model}")

Bước 3: RAG System Với HolySheep Embeddings


import hashlib
from typing import List, Optional

class AdmissionRAGSystem:
    """Hệ thống RAG cho tư vấn tuyển sinh với HolySheep"""
    
    def __init__(self, client: HolySheepClient):
        self.client = client
        self.vector_store = {}  # In production, dùng Pinecone/Weaviate
        self.document_store = {}
    
    def generate_embedding(self, text: str) -> List[float]:
        """Tạo embedding với HolySheep"""
        # Lưu ý: HolySheep sử dụng model embedding tương thích OpenAI
        endpoint = f"{self.client.config.base_url}/embeddings"
        payload = {
            "model": "text-embedding-3-small",  # Hoặc text-embedding-3-large
            "input": text
        }
        
        response = self.client.session.post(
            endpoint,
            json=payload,
            timeout=self.client.config.timeout
        )
        
        if response.status_code == 200:
            data = response.json()
            return data["data"][0]["embedding"]
        else:
            raise Exception(f"Embedding error: {response.text}")
    
    def cosine_similarity(self, a: List[float], b: List[float]) -> float:
        """Tính cosine similarity"""
        dot_product = sum(x * y for x, y in zip(a, b))
        norm_a = sum(x * x for x in a) ** 0.5
        norm_b = sum(x * x for x in b) ** 0.5
        return dot_product / (norm_a * norm_b) if norm_a and norm_b else 0
    
    def index_documents(self, documents: List[Dict[str, str]]):
        """Index documents cho RAG"""
        for doc in documents:
            doc_id = hashlib.md5(doc["content"].encode()).hexdigest()
            
            # Generate embedding
            embedding = self.generate_embedding(doc["content"])
            
            # Store
            self.vector_store[doc_id] = embedding
            self.document_store[doc_id] = {
                "content": doc["content"],
                "metadata": doc.get("metadata", {}),
                "source": doc.get("source", "unknown")
            }
            
            print(f"Indexed: {doc_id[:8]}... - {doc['metadata'].get('title', 'Untitled')}")
        
        print(f"\nTổng cộng: {len(documents)} documents đã được index")
    
    def retrieve_relevant(
        self,
        query: str,
        top_k: int = 5,
        similarity_threshold: float = 0.7
    ) -> List[Dict[str, Any]]:
        """Truy xuất documents liên quan"""
        
        # Generate query embedding
        query_embedding = self.generate_embedding(query)
        
        # Tính similarity và sort
        similarities = []
        for doc_id, doc_embedding in self.vector_store.items():
            sim = self.cosine_similarity(query_embedding, doc_embedding)
            if sim >= similarity_threshold:
                similarities.append({
                    "doc_id": doc_id,
                    "similarity": round(sim, 4),
                    "content": self.document_store[doc_id]["content"],
                    "metadata": self.document_store[doc_id]["metadata"]
                })
        
        # Sort by similarity và return top_k
        similarities.sort(key=lambda x: x["similarity"], reverse=True)
        return similarities[:top_k]
    
    def build_rag_context(
        self,
        query: str,
        use_context: bool = True
    ) -> List[Dict[str, str]]:
        """Xây dựng context từ RAG cho LLM"""
        
        if not use_context:
            return [{"role": "system", "content": self._get_system_prompt()}]
        
        # Retrieve relevant documents
        relevant_docs = self.retrieve_relevant(query, top_k=3)
        
        # Build context
        context_parts = ["Bạn là trợ lý tư vấn tuyển sinh. Dựa trên thông tin sau:\n"]
        
        for i, doc in enumerate(relevant_docs, 1):
            source = doc["metadata"].get("source", "Tài liệu")
            context_parts.append(f"\n[{i}] Nguồn: {source}")
            context_parts.append(f"Nội dung: {doc['content']}")
            context_parts.append(f"Độ chính xác: {doc['similarity']*100:.1f}%\n")
        
        context = "\n".join(context_parts)
        context += "\n\n" + self._get_system_prompt()
        
        return [
            {"role": "system", "content": context}
        ]
    
    def _get_system_prompt(self) -> str:
        return """Bạn là trợ lý tư vấn tuyển sinh chuyên nghiệp.
- Trả lời bằng tiếng Việt, thân thiện và chính xác
- Nếu không chắc chắn, hãy nói rõ và gợi ý liên hệ tư vấn viên
- Cung cấp thông tin cập nhật theo mùa tuyển sinh hiện tại
- Đưa ra lời khuyên cá nhân hóa dựa trên profile của người hỏi"""

Demo: Index sample admission documents

rag_system = AdmissionRAGSystem(client) sample_docs = [ { "content": "Đại học Tsinghua - Ngành Khoa học Máy tính: Điểm chuẩn 2025 là 680/800 SAT, yêu cầu TOELF 100 hoặc IELTS 7.0. Học phí 30,000 CNY/năm. Cơ hội việc làm sau tốt nghiệp: 95% trong vòng 6 tháng.", "metadata": {"title": "Tsinghua CS Requirements", "source": "Official Website"}, "source": "https://admission.tsinghua.edu.cn" }, { "content": "Đại học Peking University - Ngành Economics: Điểm chuẩn SAT 1450+, TOELF 105+, có ưu tiên học sinh có достижения trong Olympic. Học phí 35,000 CNY/năm. Chương trình liên kết với Harvard và MIT.", "metadata": {"title": "PKU Economics Program", "source": "Official Website"}, "source": "https://admission.pku.edu.cn" } ] rag_system.index_documents(sample_docs)

Test retrieval

results = rag_system.retrieve_relevant("Yêu cầu đầu vào ngành Computer Science ở đại học Trung Quốc?") print("\nKết quả retrieval:") for r in results: print(f"- [{r['similarity']*100:.1f}%] {r['content'][:80]}...")

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

Trong quá trình triển khai hệ thống tư vấn tuyển sinh, tôi đã gặp nhiều lỗi phức tạp. Dưới đây là 5 trường hợp điển hình nhất kèm solution chi tiết.

Lỗi 1: "Connection timeout khi gọi Kimi với context dài"

Nguyên nhân: Khi context vượt quá 32K tokens, request timeout mặc định 30s không đủ cho model xử lý. Giải pháp:

Vấn đề: Timeout khi xử lý context dài

Giải pháp: Tăng timeout và sử dụng streaming

class OptimizedHolySheepClient(HolySheepClient): """Client tối ưu cho long-context requests""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Tăng timeout cho long context self.long_context_timeout = 120 # 2 phút self.stream_timeout = 60 # 1 phút def chat_completion_streaming( self, model: ModelType, messages: List[Dict[str, str]], max_tokens: int = 4096 ) -> Dict[str, Any]: """Sử dụng streaming để xử lý long context hiệu quả hơn""" endpoint = f"{self.config.base_url}/chat/completions" payload = { "model": model.value, "messages": messages, "max_tokens": max_tokens, "stream": True # Bật streaming } try: response = self.session.post( endpoint, json=payload, timeout=self.long_context_timeout, stream=True ) if response.status_code != 200: return {"success": False, "error": response.text} # Xử lý streaming response full_content = "" start_time = time.time() for line in response.iter_lines(): if line: data = json.loads(line.decode('utf-8').replace('data: ', '')) if data.get('choices')[0].get('delta', {}).get('content'): full_content += data['choices'][0]['delta']['content'] latency = (time.time() - start_time) * 1000 return { "success": True, "data": { "choices": [{ "message": {"content": full_content} }] }, "latency_ms": round(latency, 2), "model": model.value, "streaming": True } except Exception as e: return {"success": False, "error": str(e)}

Sử dụng

optimized_client = OptimizedHolySheepClient() result = optimized_client.chat_completion_streaming( model=ModelType.KIMI, messages=[{"role": "user", "content": "Phân tích chi tiết về 10 trường đại học top Trung Quốc"}] ) print(f"Streaming response: {result['latency_ms']}ms")

Lỗi 2: "Rate limit khi đồng thời 100+ users"

Nguyên nhân: HolySheep có rate limit theo tier. Free tier giới hạn requests/minute. Giải pháp:

import asyncio
from collections import defaultdict
from datetime import datetime, timedelta

class RateLimitedClient:
    """Client với rate limiting thông minh"""
    
    def __init__(self, client: HolySheepClient):
        self.client = client
        # Rate limits theo tier
        self.rate_limits = {
            "free": {"requests_per_minute": 60, "tokens_per_minute": 60000},
            "pro": {"requests_per_minute": 500, "tokens_per_minute": 500000}
        }
        self.request_timestamps = defaultdict(list)
        self.current_tier = "free"  # Hoặc detect từ API response
    
    def _check_rate_limit(self) -> bool:
        """Kiểm tra rate limit"""
        now = datetime.now()
        cutoff = now - timedelta(minutes=1)
        
        # Lọc timestamps trong 1 phút qua
        recent_requests = [
            ts for ts in self.request_timestamps["all"]
            if ts > cutoff
        ]
        
        limit = self.rate_limits[self.current_tier]["requests_per_minute"]
        
        if len(recent_requests) >= limit:
            return False
        
        self.request_timestamps["all"].append(now)
        return True
    
    def _wait_for_rate_limit(self):
        """Chờ cho đến khi rate limit reset"""
        now = datetime.now()
        cutoff = now - timedelta(minutes=1)
        
        if self.request_timestamps["all"]:
            oldest_in_window = min(
                ts for ts in self.request_timestamps["all"]
                if ts > cutoff
            )
            wait_seconds = 60 - (now - oldest_in_window).total_seconds()
            
            if wait_seconds > 0:
                print(f"Rate limit reached. Waiting {wait_seconds:.1f}s...")
                time.sleep(wait_seconds)
    
    async def async_chat_completion(
        self,
        model: ModelType,
        messages: List[Dict[str, str]],
        priority: int = 0  # 0=low, 1=normal, 2=high
    ) -> Dict[str, Any]:
        """Async request với queue management"""
        
        while True:
            if self._check_rate_limit():
                # Rate limit OK, thực hiện request
                return await asyncio.to_thread(
                    self.client.chat_completion,
                    model, messages
                )
            else:
                if priority == 2:  # High priority - interrupt
                    continue
                else:
                    self._wait_for_rate_limit()

Sử dụng với asyncio

async def handle_concurrent_users(): client = RateLimitedClient(HolySheepClient()) tasks = [] for i in range(100): question = f"Câu hỏi thứ {i} về tuyển sinh" priority = 2 if i < 10 else 0 # 10 user đầu = high priority tasks.append(client.async_chat_completion( model=ModelType.DEEPSEEK, messages=[{"role": "user", "content": question}], priority=priority )) results = await asyncio.gather(*tasks) successful = sum(1 for r in results if r.get("success")) print(f"Hoàn thành: {successful}/100 requests") asyncio.run(handle_concurrent_users())

Lỗi 3: "Context window overflow với cuộc hội thoại dài"

Nguyên nhân: Cuộc hội thoại dài liên tục làm tràn context window của model. Giải pháp:

class ConversationManager:
    """Quản lý cuộc hội thoại với context window thông minh"""
    
    def __init__(
        self,
        client: HolySheepClient,
        max_context_tokens: int = 128000,
        compression_threshold: float = 0.8
    ):
        self.client = client
        self.max_context_tokens = max_context_tokens
        self.compression_threshold = compression_threshold
        self.conversations = {}
        self.token_counts = {}
    
    def _estimate_tokens(self, text: str) -> int:
        """Ước tính số tokens (quick estimate)"""
        # ~4 characters per token for Chinese, ~3 for English
        return len(text) // 3
    
    def _compress_context(
        self,
        messages: List[Dict[str, str]],
        preserve_last_n: int = 3
    ) -> List[Dict[str, str]]:
        """Nén context bằng cách tóm tắt messages cũ"""
        
        # Giữ lại messages gần đây
        recent = messages[-preserve_last_n:] if len(messages) > preserve_last_n else messages
        
        # Tóm tắt messages cũ
        old_messages = messages[:-preserve_last_n] if len(messages) > preserve_last_n else []
        
        if not old_messages:
            return messages
        
        # Gọi model để tóm tắt
        summary_prompt = """Tóm tắt cuộc hội thoại sau thành 200 tokens, giữ lại:
1. Thông tin quan trọng đã trao đổi
2. Các quyết định đã đạt được
3. Bối cảnh cần thiết để tiếp tục

Cuộc hội thoại:
"""
        old_content = "\n".join([f"{m['role']}: {m['content']}" for m in old_messages])
        
        result = self.client.chat_completion(
            model=ModelType.KIMI,  # Rẻ và dài context
            messages=[{"role": "user", "content": summary_prompt + old_content}],
            max_tokens=300
        )
        
        if result["success"]:
            summary = result["data"]["choices"][0]["message"]["content"]
            return [
                {"role": "system", "content": f"[Tóm tắt cuộc trò chuyện trước đó]\n{summary}"},
                {"role": "user", "content": "[Tiếp tục cuộc trò chuyện]"}
            ] + recent
        
        return recent
    
    def add_message(
        self,
        session_id: str,
        role: str,
        content: str
    ) -> List[Dict[str, str]]:
        """Thêm message và tự động quản lý context"""
        
        if session_id not in self.conversations:
            self.conversations[session_id] = []
        
        messages = self.conversations[session_id]
        messages.append({"role": role, "content": content})
        
        # Kiểm tra context window
        total_tokens = sum(
            self._estimate_tokens(m["content"])
            for m in messages
        )
        
        if total_tokens > self.max_context_tokens * self.compression_threshold:
            messages = self._compress_context(messages)
            self.conversations[session_id] = messages
        
        return messages
    
    def get_context(self, session_id: str) -> List[Dict[str, str]]:
        """Lấy context hiện tại"""
        return self.conversations.get(session_id, [])

Sử dụng

conv_manager = ConversationManager(client) session_id = "user_123_session_abc"

Thêm nhiều messages

for i in range(50): conv_manager.add_message( session_id, "user", f"Câu hỏi thứ {i}: Em muốn biết về ngành {i % 10}" ) context = conv_manager.get_context(session_id) print(f"Context có {len(context)} messages sau khi nén")

Lỗi 4: "JSON parsing error khi Claude trả response"

Nguyên nhân: Claude đôi khi trả markdown code block thay vì clean JSON. Giải pháp:

import re

def clean_llm_response(response: str) -> str:
    """Clean response từ LLM, loại bỏ markdown formatting"""
    
    # Loại bỏ ```json blocks
    if response.strip().startswith("```"):
        response = re.sub(r'^```(?:json)?\s*', '', response.strip())
        response = re.sub(r'\s*```$', '', response)
    
    # Loại bỏ ``` blocks khác
    response = re.sub(r'``[\s\S]*?``', '', response)
    
    # Loại bỏ **bold** markers
    response = re.sub(r'\*\*(.*?)\*\*', r'\1', response)
    
    # Loại bỏ *italic* markers
    response = re.sub(r'\*(.*?)\*', r'\1', response)
    
    return response.strip()

def safe_json_parse(response: str) -> Optional[Dict]:
    """Parse JSON an toàn với fallback"""
    
    cleaned = clean_llm_response(response)
    
    try:
        return json.loads(cleaned)
    except json.JSONDecodeError:
        pass
    
    # Thử loại bỏ trailing commas
    cleaned_fix = re.sub(r',(\s*[}\]])', r'\1', cleaned)
    try:
        return json.loads(cleaned_fix)
    except json.JSONDecodeError:
        pass
    
    # Thử tìm JSON trong response
    json_match = re.search(r'\{[\s\S]*\}', cleaned)
    if json_match:
        try:
            return json.loads(json_match.group())
        except json.JSONDecodeError:
            pass
    
    return None

Test

test_responses = [ '``json\n{"status": "success", "data": [1,2,3]}\n``', '**Bold text** {"result": "parsed"}', '{"incomplete": true, "trailing": "comma",}', 'Some text before {"valid": true} and after' ] for resp in test_responses: result = safe_json_parse(resp) print(f"Input: {resp[:50]}... → Parsed: {result}")

Lỗi 5: "Model trả thông tin sai về admission requirements"

Nguyên nhân: LLM hallucinate thông tin admission không có