import logging from typing import List, Dict from core.config import settings from .base_llm import BaseLLMProvider logger = logging.getLogger("LocalLLM") class LocalLLM(BaseLLMProvider): def __init__(self): try: from openai import OpenAI except ImportError: logger.error("LỖI: Thư viện openai chưa được cài đặt.") raise if not settings.local_llm_endpoint: raise ValueError("LOCAL_LLM_ENDPOINT chưa được cấu hình trong .env!") # llama.cpp server hỗ trợ API y hệt OpenAI # Ta cần cắt đuôi /chat/completions để ra base_url base_url = settings.local_llm_endpoint.replace("/chat/completions", "") self.client = OpenAI( api_key="sk-no-key-required", # Llama.cpp local không cần key base_url=base_url ) logger.info(f"Đã khởi tạo Local Llama.cpp Provider kết nối tới: {base_url}") def generate_response(self, prompt: str, context: str, history: List[Dict[str, str]] = None) -> str: system_prompt = f"""Bạn là trợ lý RAG nội bộ. Chỉ trả lời dựa trên NGỮ CẢNH dưới đây. Nếu không biết thì nói không biết. === NGỮ CẢNH === {context} """ messages = [{"role": "system", "content": system_prompt}] if history: for msg in history: messages.append({"role": msg.get("role", "user"), "content": msg.get("content", "")}) messages.append({"role": "user", "content": prompt}) try: response = self.client.chat.completions.create( model="local-model", # llama.cpp thường phớt lờ tên model messages=messages, temperature=0.1, max_tokens=1024 ) return response.choices[0].message.content except Exception as e: logger.error(f"Lỗi khi gọi Local LLM: {e}") return f"Xin lỗi, máy chủ AI nội bộ đang bận hoặc mất kết nối: {e}"