entidi2608 commited on
Commit
5760f5e
·
1 Parent(s): 77eeb1b

update api

Browse files
Files changed (4) hide show
  1. config.py +3 -1
  2. dependencies.py +21 -7
  3. rag_components.py +58 -2
  4. schemas/chat.py +1 -1
config.py CHANGED
@@ -56,4 +56,6 @@ APP_ENVIRONMENT = os.environ.get("APP_ENVIRONMENT")
56
  # CHECKPOINT_FILE = "processed_files.log"
57
 
58
  MONGODB_CLOUD_URI= os.environ.get("MONGODB_CLOUD_URI")
59
- DB_NAME= os.environ.get("DB_NAME")
 
 
 
56
  # CHECKPOINT_FILE = "processed_files.log"
57
 
58
  MONGODB_CLOUD_URI= os.environ.get("MONGODB_CLOUD_URI")
59
+ DB_NAME= os.environ.get("DB_NAME")
60
+
61
+ GOOGLE_API_KEYS=os.environ.get("GOOGLE_API_KEYS", "")
dependencies.py CHANGED
@@ -58,10 +58,10 @@ async def initialize_api_components(app_state: AppState):
58
  logger.error("🔸Lỗi kết nối tới MongoDB hoặc Weaviate.", mongo_db.users)
59
  raise HTTPException(status_code=500, detail="Lỗi kết nối tới database.")
60
 
61
- app_state.google_api_key = os.environ.get("GOOGLE_API_KEY")
62
- if not app_state.google_api_key:
63
- logger.error("🔸GG API Key không được cung cấp.")
64
- raise HTTPException(status_code=500, detail="Missing GG API Key")
65
 
66
  app_state.device = 'cuda' if torch.cuda.is_available() else 'cpu'
67
  logger.info(f"🔸Sử dụng thiết bị: {app_state.device}")
@@ -90,9 +90,23 @@ async def initialize_api_components(app_state: AppState):
90
  # 3. Tải LLM
91
  logger.info(f"🔸Đang tải LLM...")
92
 
93
- llm = rag_components.get_google_llm(app_state.google_api_key)
94
- app_state.llm = llm
95
- logger.info(f"🔸Tải LLM (Groq) thanh cong")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  if not app_state.llm:
98
  raise HTTPException(status_code=500, detail="Failed to load LLM")
 
58
  logger.error("🔸Lỗi kết nối tới MongoDB hoặc Weaviate.", mongo_db.users)
59
  raise HTTPException(status_code=500, detail="Lỗi kết nối tới database.")
60
 
61
+ # app_state.google_api_key = os.environ.get("GOOGLE_API_KEY")
62
+ # if not app_state.google_api_key:
63
+ # logger.error("🔸GG API Key không được cung cấp.")
64
+ # raise HTTPException(status_code=500, detail="Missing GG API Key")
65
 
66
  app_state.device = 'cuda' if torch.cuda.is_available() else 'cpu'
67
  logger.info(f"🔸Sử dụng thiết bị: {app_state.device}")
 
90
  # 3. Tải LLM
91
  logger.info(f"🔸Đang tải LLM...")
92
 
93
+ # llm = rag_components.get_google_llm(app_state.google_api_key)
94
+ # app_state.llm = llm
95
+ if not config.GOOGLE_API_KEYS:
96
+ logger.error("🚨 BIẾN MÔI TRƯỜNG 'GOOGLE_API_KEYS' CHƯA ĐƯỢC THIẾT LẬP TRÊN HUGGING FACE SPACES!")
97
+ # Tại đây, bạn có thể dừng chương trình hoặc xử lý lỗi
98
+ google_api_keys_list = []
99
+ else:
100
+ google_api_keys_list = [key.strip() for key in config.GOOGLE_API_KEYS.split(',') if key.strip()]
101
+ logger.info(f"✅ Đã tìm thấy và tải {len(google_api_keys_list)} API key từ secrets.")
102
+
103
+ if not google_api_keys_list:
104
+ logger.error("🚨 KHÔNG CÓ GOOGLE API KEYS NÀO ĐƯỢC CẤP PHÁT!")
105
+ raise HTTPException(status_code=500, detail="No Google API keys found")
106
+
107
+ app_state.llm = rag_components.create_llm_from_google_key_list(google_api_keys=google_api_keys_list)
108
+
109
+
110
 
111
  if not app_state.llm:
112
  raise HTTPException(status_code=500, detail="Failed to load LLM")
rag_components.py CHANGED
@@ -5,7 +5,7 @@ from langchain_core.prompts import ChatPromptTemplate
5
  from langchain_core.runnables import RunnableLambda, RunnablePassthrough
6
  from langchain_core.documents import Document
7
  import logging
8
- from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
9
  from typing import List,Any,Dict
10
  from langchain_weaviate.vectorstores import WeaviateVectorStore
11
  from langchain_google_genai import ChatGoogleGenerativeAI
@@ -13,6 +13,7 @@ from utils.process_data import filter_and_serialize_complex_metadata
13
  import weaviate
14
  import weaviate.classes.config as wvc_config
15
  from weaviate.exceptions import WeaviateQueryException
 
16
  import time
17
  import json
18
  import re
@@ -310,7 +311,7 @@ def get_google_llm(google_api_key):
310
  model="gemini-2.5-flash-preview-05-20",
311
  google_api_key=google_api_key,
312
  temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
313
- safety_settings={ },
314
  )
315
 
316
  llm = create_chat_google()
@@ -321,6 +322,61 @@ def get_google_llm(google_api_key):
321
  logger.error(f"🔸Lỗi khi khởi tạo Google Generative AI LLM: {e}")
322
  return None
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
 
325
  # def create_qa_chain(
326
  # llm: Any,
 
5
  from langchain_core.runnables import RunnableLambda, RunnablePassthrough
6
  from langchain_core.documents import Document
7
  import logging
8
+ from langchain_core.output_parsers import StrOutputParser
9
  from typing import List,Any,Dict
10
  from langchain_weaviate.vectorstores import WeaviateVectorStore
11
  from langchain_google_genai import ChatGoogleGenerativeAI
 
13
  import weaviate
14
  import weaviate.classes.config as wvc_config
15
  from weaviate.exceptions import WeaviateQueryException
16
+ from google.api_core.exceptions import ResourceExhausted, PermissionDenied
17
  import time
18
  import json
19
  import re
 
311
  model="gemini-2.5-flash-preview-05-20",
312
  google_api_key=google_api_key,
313
  temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
314
+ safety_settings={},
315
  )
316
 
317
  llm = create_chat_google()
 
322
  logger.error(f"🔸Lỗi khi khởi tạo Google Generative AI LLM: {e}")
323
  return None
324
 
325
+ def create_llm_from_google_key_list(google_api_keys: List[str]):
326
+ """
327
+ Khởi tạo một LLM duy nhất có khả năng tự động fallback qua một danh sách
328
+ các API key của Google.
329
+
330
+ Khi một key hết hạn mức (lỗi ResourceExhausted), nó sẽ tự động thử key tiếp theo.
331
+
332
+ :param google_api_keys: Một list chứa các chuỗi API key của Google.
333
+ :return: Một đối tượng LLM của LangChain, hoặc None nếu có lỗi.
334
+ """
335
+ if not google_api_keys or not isinstance(google_api_keys, list):
336
+ logger.error("❌ Danh sách API key không hợp lệ hoặc bị rỗng.")
337
+ return None
338
+
339
+ logger.info(f"🔸 Đang khởi tạo chuỗi LLM từ {len(google_api_keys)} API key của Google...")
340
+
341
+ try:
342
+ # --- 1. Tạo một danh sách các instance LLM, mỗi cái với một key khác nhau ---
343
+ llm_instances = [
344
+ ChatGoogleGenerativeAI(
345
+ model="gemini-2.5-flash-preview-05-20",
346
+ google_api_key=key,
347
+ temperature=0.0, # Điều chỉnh nhiệt độ nếu cần, 0.1-0.3 thường tốt cho RAG
348
+ safety_settings={},
349
+ )
350
+ for key in google_api_keys
351
+ ]
352
+
353
+ # --- 2. Nếu chỉ có một key, không cần fallback ---
354
+ if len(llm_instances) == 1:
355
+ logger.info("✅ Chỉ có một API key được cung cấp. Không cấu hình fallback.")
356
+ return llm_instances[0]
357
+
358
+ # --- 3. Dùng LLM đầu tiên làm LLM chính, phần còn lại làm fallback ---
359
+ primary_llm = llm_instances[0]
360
+ fallback_llms = llm_instances[1:]
361
+
362
+ logger.info(f"▶️ LLM chính sẽ dùng key: '...{google_api_keys[0][-4:]}'")
363
+ for i, llm in enumerate(fallback_llms):
364
+ logger.info(f"↪️ Fallback {i+1} sẽ dùng key: '...{google_api_keys[i+1][-4:]}'")
365
+
366
+ # --- 4. Kết hợp chúng lại ---
367
+ llm_with_fallbacks = primary_llm.with_fallbacks(
368
+ fallbacks=fallback_llms,
369
+ exceptions_to_handle=(ResourceExhausted, PermissionDenied)
370
+ )
371
+
372
+ logger.info("✅ Đã tạo thành công chuỗi LLM với cơ chế fallback giữa các key Google!")
373
+ return llm_with_fallbacks
374
+
375
+ except Exception as e:
376
+ logger.error(f"❌ Lỗi nghiêm trọng khi tạo chuỗi LLM từ danh sách key: {e}", exc_info=True)
377
+ return None
378
+
379
+
380
 
381
  # def create_qa_chain(
382
  # llm: Any,
schemas/chat.py CHANGED
@@ -5,7 +5,7 @@ from datetime import datetime
5
  class AppState(BaseModel):
6
  embeddings: Optional[Any] = None
7
  vectorstore: Optional[Any] = None
8
- llm: Optional[Any] = None
9
  process_input_llm: Optional[Any] = None
10
  qa_chain: Optional[Any] = None
11
  device: str = "cpu"
 
5
  class AppState(BaseModel):
6
  embeddings: Optional[Any] = None
7
  vectorstore: Optional[Any] = None
8
+ # llm: Optional[Any] = None
9
  process_input_llm: Optional[Any] = None
10
  qa_chain: Optional[Any] = None
11
  device: str = "cpu"