truglpk3 commited on
Commit
195b940
·
1 Parent(s): d324b6f

Streaming Chatbot

Browse files
chatbot/__pycache__/main.cpython-310.pyc CHANGED
Binary files a/chatbot/__pycache__/main.cpython-310.pyc and b/chatbot/__pycache__/main.cpython-310.pyc differ
 
chatbot/agents/graphs/__pycache__/food_similarity_graph.cpython-310.pyc CHANGED
Binary files a/chatbot/agents/graphs/__pycache__/food_similarity_graph.cpython-310.pyc and b/chatbot/agents/graphs/__pycache__/food_similarity_graph.cpython-310.pyc differ
 
chatbot/agents/nodes/app_functions/optimize_select.py CHANGED
@@ -60,19 +60,17 @@ def calculate_top_options(state: SwapState):
60
  try:
61
  loss, scale = calculate_score(item)
62
 
63
- # Chỉ lấy những món có sai số chấp nhận được
64
- if loss < 10.0:
65
- item_score = item.copy()
66
- item_score["optimization_loss"] = round(loss, 4)
67
- item_score["portion_scale"] = round(scale, 2)
68
 
69
- # Tính chỉ số hiển thị sau khi scale
70
- item_score["final_kcal"] = int(item["kcal"] * scale)
71
- item_score["final_protein"] = int(item["protein"] * scale)
72
- item_score["final_totalfat"] = int(item["totalfat"] * scale)
73
- item_score["final_carbs"] = int(item["carbs"] * scale)
74
 
75
- scored_candidates.append(item_score)
76
  except Exception as e:
77
  logger.warning(f"Lỗi khi xử lý món {item.get('name', 'N/A')}: {e}")
78
  continue
 
60
  try:
61
  loss, scale = calculate_score(item)
62
 
63
+ item_score = item.copy()
64
+ item_score["optimization_loss"] = round(loss, 4)
65
+ item_score["portion_scale"] = round(scale, 2)
 
 
66
 
67
+ # Tính chỉ số hiển thị sau khi scale
68
+ item_score["final_kcal"] = int(item["kcal"] * scale)
69
+ item_score["final_protein"] = int(item["protein"] * scale)
70
+ item_score["final_totalfat"] = int(item["totalfat"] * scale)
71
+ item_score["final_carbs"] = int(item["carbs"] * scale)
72
 
73
+ scored_candidates.append(item_score)
74
  except Exception as e:
75
  logger.warning(f"Lỗi khi xử lý món {item.get('name', 'N/A')}: {e}")
76
  continue
chatbot/agents/nodes/chatbot/classify_topic.py CHANGED
@@ -20,8 +20,10 @@ class Topic(BaseModel):
20
 
21
  def classify_topic(state: AgentState):
22
  print("---CLASSIFY TOPIC ---")
23
-
24
- classifier_llm = llm.with_structured_output(Topic)
 
 
25
 
26
  system_msg = """
27
  Bạn là bộ điều hướng thông minh.
@@ -45,15 +47,20 @@ def classify_topic(state: AgentState):
45
 
46
  prompt = ChatPromptTemplate.from_messages([
47
  ("system", system_msg),
48
- MessagesPlaceholder(variable_name="history"),
 
49
  ])
50
 
 
51
  chain = prompt | classifier_llm
52
 
53
  recent_messages = get_chat_history(state["messages"], max_tokens=500)
54
 
55
  try:
56
- topic_result = chain.invoke({"history": recent_messages})
 
 
 
57
  topic_name = topic_result.name
58
  except Exception as e:
59
  print(f"⚠️ Lỗi phân loại: {e}")
 
20
 
21
  def classify_topic(state: AgentState):
22
  print("---CLASSIFY TOPIC ---")
23
+ all_messages = state["messages"]
24
+
25
+ question = all_messages[-1].content
26
+ history_messages = all_messages[:-1]
27
 
28
  system_msg = """
29
  Bạn là bộ điều hướng thông minh.
 
47
 
48
  prompt = ChatPromptTemplate.from_messages([
49
  ("system", system_msg),
50
+ MessagesPlaceholder(variable_name="history"), # Bối cảnh chat
51
+ ("human", "{input}") # Câu hỏi MỚI CẦN PHÂN LOẠI
52
  ])
53
 
54
+ classifier_llm = llm.with_structured_output(Topic)
55
  chain = prompt | classifier_llm
56
 
57
  recent_messages = get_chat_history(state["messages"], max_tokens=500)
58
 
59
  try:
60
+ topic_result = chain.invoke({
61
+ "history": recent_messages, # Lịch sử chat (MessagesPlaceholder)
62
+ "input": question # Câu hỏi mới (HumanMessage)
63
+ })
64
  topic_name = topic_result.name
65
  except Exception as e:
66
  print(f"⚠️ Lỗi phân loại: {e}")
chatbot/agents/nodes/chatbot/general_chat.py CHANGED
@@ -1,19 +1,22 @@
1
  from chatbot.agents.states.state import AgentState
2
  from chatbot.models.llm_setup import llm
3
- from langchain.schema.messages import SystemMessage, HumanMessage
4
  from chatbot.utils.chat_history import get_chat_history
 
5
  import logging
6
 
7
  # --- Cấu hình logging ---
8
  logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
- def general_chat(state: AgentState):
12
  logger.info("---GENERAL CHAT---")
13
 
 
 
14
  history = get_chat_history(state["messages"], max_tokens=1000)
15
 
16
- system_text = """
17
  Bạn là một chuyên gia dinh dưỡng và ẩm thực AI.
18
  Hãy trả lời các câu hỏi về:
19
  - món ăn, thành phần, dinh dưỡng, calo, protein, chất béo, carb,
@@ -21,18 +24,22 @@ def general_chat(state: AgentState):
21
  - sức khỏe, lối sống, chế độ tập luyện liên quan đến ăn uống.
22
  - chức năng, điều khoản, chính sách của ứng dụng.
23
 
 
 
24
  Quy tắc:
25
  - Không trả lời các câu hỏi ngoài chủ đề này (hãy từ chối lịch sự).
26
  - Giải thích ngắn gọn, tự nhiên, rõ ràng.
27
  - Dựa vào lịch sử trò chuyện để trả lời mạch lạc nếu có câu hỏi nối tiếp.
28
  """
29
 
30
- messages_to_send = [SystemMessage(content=system_text)] + history
31
-
32
  try:
33
- response = llm.invoke(messages_to_send)
34
- logger.info(f"🤖 AI Response: {response.content}")
 
 
 
35
  return {"messages": [response]}
 
36
  except Exception as e:
37
- logger.info(f"⚠️ Lỗi General Chat: {e}")
38
- return {"messages": []}
 
1
  from chatbot.agents.states.state import AgentState
2
  from chatbot.models.llm_setup import llm
3
+ from langchain.schema.messages import SystemMessage, HumanMessage, AIMessage
4
  from chatbot.utils.chat_history import get_chat_history
5
+ from langchain_core.runnables import RunnableConfig
6
  import logging
7
 
8
  # --- Cấu hình logging ---
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ async def general_chat(state: AgentState, config: RunnableConfig):
13
  logger.info("---GENERAL CHAT---")
14
 
15
+ messages = state["messages"]
16
+ question = messages[-1].content
17
  history = get_chat_history(state["messages"], max_tokens=1000)
18
 
19
+ system_prompt = f"""
20
  Bạn là một chuyên gia dinh dưỡng và ẩm thực AI.
21
  Hãy trả lời các câu hỏi về:
22
  - món ăn, thành phần, dinh dưỡng, calo, protein, chất béo, carb,
 
24
  - sức khỏe, lối sống, chế độ tập luyện liên quan đến ăn uống.
25
  - chức năng, điều khoản, chính sách của ứng dụng.
26
 
27
+ Lịch sử hội thoại: {history}
28
+
29
  Quy tắc:
30
  - Không trả lời các câu hỏi ngoài chủ đề này (hãy từ chối lịch sự).
31
  - Giải thích ngắn gọn, tự nhiên, rõ ràng.
32
  - Dựa vào lịch sử trò chuyện để trả lời mạch lạc nếu có câu hỏi nối tiếp.
33
  """
34
 
 
 
35
  try:
36
+ response = await llm.ainvoke([
37
+ SystemMessage(content=system_prompt),
38
+ HumanMessage(content=question)
39
+ ], config=config)
40
+
41
  return {"messages": [response]}
42
+
43
  except Exception as e:
44
+ print(f"Lỗi LLM: {e}")
45
+ return {"messages": [AIMessage(content="Xin lỗi, có lỗi xảy ra.")]}
chatbot/agents/nodes/chatbot/generate_final_response.py CHANGED
@@ -1,46 +1,99 @@
1
  from langchain_core.messages import AIMessage
2
  from chatbot.agents.states.state import AgentState
 
 
 
3
  import logging
4
 
5
  # --- Cấu hình logging ---
6
  logging.basicConfig(level=logging.INFO)
7
  logger = logging.getLogger(__name__)
8
 
9
- def generate_final_response(state: AgentState):
10
- logger.info("---NODE: FINAL RESPONSE---")
 
 
11
  menu = state.get("final_menu", [])
12
- reason = state.get("reason", "")
13
  profile = state.get("user_profile", {})
14
-
15
  if not menu:
16
  return {"messages": [AIMessage(content="Xin lỗi, tôi chưa thể tạo thực đơn lúc này.")]}
17
 
 
18
  meal_priority = {"sáng": 1, "trưa": 2, "tối": 3}
19
  sorted_menu = sorted(
20
  menu,
21
  key=lambda x: meal_priority.get(x.get('assigned_meal', '').lower(), 99)
22
  )
23
-
24
- output_text = "📋 **THỰC ĐƠN DINH DƯỠNG CÁ NHÂN HÓA**\n"
25
- output_text += f"🎯 Mục tiêu: {int(profile.get('targetcalories', 0))} Kcal | {int(profile.get('protein', 0))}g Protein\n\n"
26
-
27
- current_meal = None
28
 
29
- for dish in sorted_menu:
30
- meal_name = dish.get('assigned_meal', 'Khác').upper()
 
31
 
32
- if meal_name != current_meal:
33
- current_meal = meal_name
34
- output_text += f"🍽️ **BỮA {current_meal}**:\n"
 
 
 
 
 
 
 
 
 
35
 
36
  scale = dish.get('portion_scale', 1.0)
37
- scale_info = f" (x{scale} suất)" if scale != 1.0 else ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- output_text += f" • **{dish['name']}**{scale_info}\n"
40
- output_text += f" └─ {dish['final_kcal']} Kcal | {dish['final_protein']}g Đạm | {dish['final_totalfat']}g Béo | {dish['final_carbs']}g Bột\n"
 
 
 
 
41
 
42
- if reason:
43
- output_text += f"\n💡 **Góc nhìn chuyên gia:**\n{reason}"
44
 
45
- return {"messages": [AIMessage(content=output_text)]}
 
 
46
 
 
1
  from langchain_core.messages import AIMessage
2
  from chatbot.agents.states.state import AgentState
3
+ from chatbot.models.llm_setup import llm
4
+ from langchain_core.messages import SystemMessage, HumanMessage
5
+ from langchain_core.runnables import RunnableConfig
6
  import logging
7
 
8
  # --- Cấu hình logging ---
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ async def generate_final_response(state: AgentState, config: RunnableConfig):
13
+ print("---NODE: FINAL RESPONSE (FULL NUTRITION AI SUMMARY)---")
14
+
15
+ # 1. Lấy dữ liệu từ State
16
  menu = state.get("final_menu", [])
 
17
  profile = state.get("user_profile", {})
18
+
19
  if not menu:
20
  return {"messages": [AIMessage(content="Xin lỗi, tôi chưa thể tạo thực đơn lúc này.")]}
21
 
22
+ # 2. Chuẩn bị bối cảnh thực đơn chi tiết (Full Macros)
23
  meal_priority = {"sáng": 1, "trưa": 2, "tối": 3}
24
  sorted_menu = sorted(
25
  menu,
26
  key=lambda x: meal_priority.get(x.get('assigned_meal', '').lower(), 99)
27
  )
 
 
 
 
 
28
 
29
+ # Tính toán tổng dinh dưỡng thực tế của cả thực đơn để gửi cho AI nhận xét
30
+ actual_total = {"kcal": 0, "p": 0, "f": 0, "c": 0}
31
+ menu_context = ""
32
 
33
+ for dish in sorted_menu:
34
+ # Lấy giá trị dinh dưỡng
35
+ k = dish.get('final_kcal', 0)
36
+ p = dish.get('final_protein', 0)
37
+ f = dish.get('final_totalfat', 0)
38
+ c = dish.get('final_carbs', 0)
39
+
40
+ # Cộng dồn tổng
41
+ actual_total["kcal"] += k
42
+ actual_total["p"] += p
43
+ actual_total["f"] += f
44
+ actual_total["c"] += c
45
 
46
  scale = dish.get('portion_scale', 1.0)
47
+ scale_text = f" (x{scale} suất)" if scale != 1.0 else ""
48
+
49
+ menu_context += (
50
+ f"- Bữa {dish.get('assigned_meal', '').upper()}: {dish['name']}{scale_text}\n"
51
+ f" + Năng lượng: {k} Kcal\n"
52
+ f" + Protein: {p}g | Lipid: {f}g | Carbs: {c}g\n\n"
53
+ )
54
+
55
+ # 3. Thiết lập System Prompt tập trung vào sự cân bằng chất
56
+ target_kcal = int(profile.get('targetcalories', 0))
57
+ target_p = int(profile.get('protein', 0))
58
+ # Ước tính mục tiêu F/C nếu app có lưu (giả định có trong profile)
59
+ target_f = int(profile.get('totalfat', 0))
60
+ target_c = int(profile.get('carbs', 0))
61
+
62
+ system_prompt = f"""
63
+ Bạn là một Chuyên gia Dinh dưỡng AI. Hãy trình bày thực đơn và phân tích sâu về các chỉ số dinh dưỡng.
64
+
65
+ DỮ LIỆU THỰC ĐƠN:
66
+ {menu_context}
67
+
68
+ TỔNG DINH DƯỠNG THỰC TẾ:
69
+ - Tổng: {actual_total['kcal']} Kcal | {actual_total['p']}g P | {actual_total['f']}g F | {actual_total['c']}g C
70
+
71
+ MỤC TIÊU CỦA NGƯỜI DÙNG:
72
+ - Mục tiêu: {target_kcal} Kcal | {target_p}g P | {target_f}g F | {target_c}g C
73
+
74
+ YÊU CẦU TRÌNH BÀY:
75
+ 1. Trình bày danh sách món ăn theo từng bữa (Sử dụng Markdown đẹp).
76
+ 2. Nhận xét chi tiết về 3 nhóm chất (Macros):
77
+ - Protein: Đủ để xây dựng cơ bắp chưa?
78
+ - Lipid (Chất béo): Có nằm trong ngưỡng lành mạnh không?
79
+ - Carbs (Bột đường): Có cung cấp đủ năng lượng cho hoạt động không?
80
+ 3. So sánh tổng thực tế với mục tiêu người dùng (Sai số bao nhiêu %).
81
+ 4. Đưa ra lời khuyên về cách phân bổ các chất này trong ngày.
82
+ 5. Tuyệt đối KHÔNG bịa đặt con số ngoài dữ liệu đã cho.
83
+ 6. Trả lời một cách ngắn gọn không dài dòng.
84
+ """
85
+ print(f"👉 Prompt: {system_prompt}")
86
 
87
+ # 4. Gọi LLM Stream
88
+ try:
89
+ response = await llm.ainvoke([
90
+ SystemMessage(content=system_prompt),
91
+ HumanMessage(content="Hãy phân tích thực đơn đầy đủ các chất giúp tôi.")
92
+ ], config=config)
93
 
94
+ return {"messages": [response]}
 
95
 
96
+ except Exception as e:
97
+ print(f"Lỗi LLM: {e}")
98
+ return {"messages": [AIMessage(content="Xin lỗi, có lỗi xảy ra.")]}
99
 
chatbot/agents/nodes/chatbot/policy.py CHANGED
@@ -2,13 +2,14 @@ from chatbot.agents.states.state import AgentState
2
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
3
  from chatbot.models.llm_setup import llm
4
  from chatbot.agents.tools.info_app_retriever import policy_retriever
 
5
  import logging
6
 
7
  # --- Cấu hình logging ---
8
  logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
- def policy(state: AgentState):
12
  logger.info("---POLICY---")
13
  messages = state["messages"]
14
  question = messages[-1].content if messages else state.question
@@ -42,12 +43,13 @@ QUY TẮC AN TOÀN:
42
  logger.info(f"Prompt gửi đến LLM cho chính sách: {system_prompt}")
43
 
44
  try:
45
- response = llm.invoke([
46
  SystemMessage(content=system_prompt),
47
  HumanMessage(content=question)
48
- ])
49
 
50
  return {"messages": [response]}
51
 
52
  except Exception as e:
53
- return {"messages": [AIMessage(content="Lỗi khi tạo câu trả lời.")]}
 
 
2
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
3
  from chatbot.models.llm_setup import llm
4
  from chatbot.agents.tools.info_app_retriever import policy_retriever
5
+ from langchain_core.runnables import RunnableConfig
6
  import logging
7
 
8
  # --- Cấu hình logging ---
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ async def policy(state: AgentState, config: RunnableConfig):
13
  logger.info("---POLICY---")
14
  messages = state["messages"]
15
  question = messages[-1].content if messages else state.question
 
43
  logger.info(f"Prompt gửi đến LLM cho chính sách: {system_prompt}")
44
 
45
  try:
46
+ response = await llm.ainvoke([
47
  SystemMessage(content=system_prompt),
48
  HumanMessage(content=question)
49
+ ], config=config)
50
 
51
  return {"messages": [response]}
52
 
53
  except Exception as e:
54
+ print(f"Lỗi LLM: {e}")
55
+ return {"messages": [AIMessage(content="Xin lỗi, có lỗi xảy ra.")]}
chatbot/agents/nodes/chatbot/select_food.py CHANGED
@@ -1,13 +1,14 @@
1
  from chatbot.agents.states.state import AgentState
2
  from chatbot.models.llm_setup import llm
3
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
 
4
  import logging
5
 
6
  # --- Cấu hình logging ---
7
  logging.basicConfig(level=logging.INFO)
8
  logger = logging.getLogger(__name__)
9
 
10
- def select_food(state: AgentState):
11
  print("---NODE: ANALYZE & ANSWER---")
12
 
13
  suggested_meals = state["suggested_meals"]
@@ -44,17 +45,15 @@ def select_food(state: AgentState):
44
 
45
  Lưu ý: Chỉ sử dụng thông tin từ danh sách cung cấp, không bịa đặt số liệu.
46
  """
47
-
48
  try:
49
- response = llm.invoke([
50
  SystemMessage(content=system_prompt),
51
  HumanMessage(content=user_message)
52
- ])
53
-
54
- logger.info("💬 AI Response:", response.content)
55
 
56
  return {"messages": [response]}
57
 
58
  except Exception as e:
59
- logger.info(f"⚠️ Lỗi sinh câu trả lời: {e}")
60
- return {"messages": [AIMessage(content="Đã xảy ra lỗi khi phân tích dữ liệu món ăn.")]}
 
1
  from chatbot.agents.states.state import AgentState
2
  from chatbot.models.llm_setup import llm
3
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
4
+ from langchain_core.runnables import RunnableConfig
5
  import logging
6
 
7
  # --- Cấu hình logging ---
8
  logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
+ async def select_food(state: AgentState, config: RunnableConfig):
12
  print("---NODE: ANALYZE & ANSWER---")
13
 
14
  suggested_meals = state["suggested_meals"]
 
45
 
46
  Lưu ý: Chỉ sử dụng thông tin từ danh sách cung cấp, không bịa đặt số liệu.
47
  """
48
+
49
  try:
50
+ response = await llm.ainvoke([
51
  SystemMessage(content=system_prompt),
52
  HumanMessage(content=user_message)
53
+ ], config=config)
 
 
54
 
55
  return {"messages": [response]}
56
 
57
  except Exception as e:
58
+ print(f"Lỗi LLM: {e}")
59
+ return {"messages": [AIMessage(content="Xin lỗi, lỗi xảy ra.")]}
chatbot/agents/nodes/chatbot/select_food_plan.py CHANGED
@@ -1,13 +1,14 @@
1
  from chatbot.agents.states.state import AgentState
2
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
3
  from chatbot.models.llm_setup import llm
 
4
  import logging
5
 
6
  # --- Cấu hình logging ---
7
  logging.basicConfig(level=logging.INFO)
8
  logger = logging.getLogger(__name__)
9
 
10
- def select_food_plan(state: AgentState):
11
  logger.info("---SELECT FOOD PLAN---")
12
 
13
  user_profile = state.get("user_profile", {})
@@ -49,14 +50,13 @@ def select_food_plan(state: AgentState):
49
  """
50
 
51
  try:
52
- response = llm.invoke([
53
  SystemMessage(content=system_prompt),
54
  HumanMessage(content=user_message)
55
- ])
56
 
57
- print("💬 AI Response:", response.content)
58
  return {"messages": [response]}
59
 
60
  except Exception as e:
61
- print(f"⚠️ Lỗi sinh câu trả lời: {e}")
62
- return {"messages": [AIMessage(content="Xin lỗi, đã có lỗi xảy ra khi xử lý thông tin món ăn.")]}
 
1
  from chatbot.agents.states.state import AgentState
2
  from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
3
  from chatbot.models.llm_setup import llm
4
+ from langchain_core.runnables import RunnableConfig
5
  import logging
6
 
7
  # --- Cấu hình logging ---
8
  logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
+ async def select_food_plan(state: AgentState, config: RunnableConfig):
12
  logger.info("---SELECT FOOD PLAN---")
13
 
14
  user_profile = state.get("user_profile", {})
 
50
  """
51
 
52
  try:
53
+ response = await llm.ainvoke([
54
  SystemMessage(content=system_prompt),
55
  HumanMessage(content=user_message)
56
+ ], config=config)
57
 
 
58
  return {"messages": [response]}
59
 
60
  except Exception as e:
61
+ print(f"Lỗi LLM: {e}")
62
+ return {"messages": [AIMessage(content="Xin lỗi, có lỗi xảy ra.")]}
chatbot/main.py CHANGED
@@ -11,16 +11,14 @@ app = FastAPI(
11
  version="1.0.0",
12
  )
13
 
14
- # Cho phép CORS để kết nối frontend
15
  app.add_middleware(
16
  CORSMiddleware,
17
- allow_origins=["*"], # ⚠️ đổi sau nếu cần bảo mật
18
  allow_credentials=True,
19
  allow_methods=["*"],
20
  allow_headers=["*"],
21
  )
22
 
23
- # Đăng ký route
24
  app.include_router(chat_router)
25
  app.include_router(meal_plan_router)
26
  app.include_router(food_replace_router)
 
11
  version="1.0.0",
12
  )
13
 
 
14
  app.add_middleware(
15
  CORSMiddleware,
16
+ allow_origins=["*"],
17
  allow_credentials=True,
18
  allow_methods=["*"],
19
  allow_headers=["*"],
20
  )
21
 
 
22
  app.include_router(chat_router)
23
  app.include_router(meal_plan_router)
24
  app.include_router(food_replace_router)
chatbot/models/__pycache__/llm_setup.cpython-310.pyc CHANGED
Binary files a/chatbot/models/__pycache__/llm_setup.cpython-310.pyc and b/chatbot/models/__pycache__/llm_setup.cpython-310.pyc differ
 
chatbot/models/llm_setup.py CHANGED
@@ -1,4 +1,5 @@
1
  from langchain_deepseek import ChatDeepSeek
 
2
  from chatbot.config import DEEPSEEK_API_KEY
3
 
4
  if not DEEPSEEK_API_KEY:
@@ -12,6 +13,14 @@ llm = ChatDeepSeek(
12
  max_retries=2,
13
  )
14
 
 
 
 
 
 
 
 
 
15
  def get_llm(model_name: str = "deepseek-chat", temperature: float = 0.3):
16
  return ChatDeepSeek(
17
  model=model_name,
 
1
  from langchain_deepseek import ChatDeepSeek
2
+ from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
3
  from chatbot.config import DEEPSEEK_API_KEY
4
 
5
  if not DEEPSEEK_API_KEY:
 
13
  max_retries=2,
14
  )
15
 
16
+ llm_stream = ChatDeepSeek(
17
+ model="deepseek-chat",
18
+ temperature=0.3,
19
+ max_tokens=2048,
20
+ streaming=True,
21
+ callbacks=[StreamingStdOutCallbackHandler()],
22
+ )
23
+
24
  def get_llm(model_name: str = "deepseek-chat", temperature: float = 0.3):
25
  return ChatDeepSeek(
26
  model=model_name,
chatbot/routes/__pycache__/chat_router.cpython-310.pyc CHANGED
Binary files a/chatbot/routes/__pycache__/chat_router.cpython-310.pyc and b/chatbot/routes/__pycache__/chat_router.cpython-310.pyc differ
 
chatbot/routes/__pycache__/food_replace_route.cpython-310.pyc CHANGED
Binary files a/chatbot/routes/__pycache__/food_replace_route.cpython-310.pyc and b/chatbot/routes/__pycache__/food_replace_route.cpython-310.pyc differ
 
chatbot/routes/chat_router.py CHANGED
@@ -1,14 +1,17 @@
1
- from fastapi import APIRouter, HTTPException
 
2
  from pydantic import BaseModel
3
  from langchain_core.messages import HumanMessage
4
  from chatbot.agents.graphs.chatbot_graph import workflow_chatbot
5
  import logging
 
 
6
 
7
  # --- Cấu hình logging ---
8
  logging.basicConfig(level=logging.INFO)
9
  logger = logging.getLogger(__name__)
10
 
11
- # --- Định nghĩa request body ---
12
  class ChatRequest(BaseModel):
13
  user_id: str
14
  thread_id: str
@@ -22,32 +25,36 @@ router = APIRouter(
22
 
23
  try:
24
  chatbot_app = workflow_chatbot()
 
25
  except Exception as e:
26
  logger.error(f"❌ Failed to compile Chatbot Graph: {e}")
27
  raise e
28
 
29
- # --- Route xử lý chat ---
30
- @router.post("/")
31
- def chat(request: ChatRequest):
32
- try:
33
- logger.info(f"Nhận được tin nhắn chat từ user: {request.user_id}")
34
- config = {"configurable": {"thread_id": request.thread_id}}
35
-
36
- initial_state = {
37
- "user_id": request.user_id,
38
- "messages": [HumanMessage(content=request.message)]
39
- }
40
-
41
- final_state = chatbot_app.invoke(initial_state, config=config)
42
 
43
- messages = final_state.get("messages", [])
44
- if messages and len(messages) > 0:
45
- response_content = messages[-1].content
46
- else:
47
- response_content = "Không có kết quả trả về."
48
-
49
- return {"response": response_content}
50
-
51
- except Exception as e:
52
- logger.error(f"Lỗi chatbot: {e}", exc_info=True)
53
- raise HTTPException(status_code=500, detail=f"Lỗi chatbot: {str(e)}")
 
 
 
 
1
+ from fastapi import APIRouter
2
+ from fastapi.responses import StreamingResponse
3
  from pydantic import BaseModel
4
  from langchain_core.messages import HumanMessage
5
  from chatbot.agents.graphs.chatbot_graph import workflow_chatbot
6
  import logging
7
+ import json
8
+ from chatbot.models.llm_setup import llm_stream
9
 
10
  # --- Cấu hình logging ---
11
  logging.basicConfig(level=logging.INFO)
12
  logger = logging.getLogger(__name__)
13
 
14
+ # # --- Định nghĩa request body ---
15
  class ChatRequest(BaseModel):
16
  user_id: str
17
  thread_id: str
 
25
 
26
  try:
27
  chatbot_app = workflow_chatbot()
28
+ logger.info("✅ Chatbot Graph compiled successfully!")
29
  except Exception as e:
30
  logger.error(f"❌ Failed to compile Chatbot Graph: {e}")
31
  raise e
32
 
33
+ async def generate_chat_response(initial_state, config):
34
+ async for event in chatbot_app.astream_events(
35
+ initial_state,
36
+ config=config,
37
+ version="v2"
38
+ ):
39
+ if event["event"] == "on_chat_model_stream":
40
+
41
+ data = event.get("data", {})
42
+ chunk = data.get("chunk")
43
+
44
+ if chunk and hasattr(chunk, "content") and chunk.content:
45
+ yield chunk.content
46
 
47
+ @router.post("/")
48
+ async def chat(request: ChatRequest):
49
+ logger.info(f"Nhận được tin nhắn chat từ user: {request.user_id}")
50
+ config = {"configurable": {"thread_id": request.thread_id}}
51
+
52
+ initial_state = {
53
+ "user_id": request.user_id,
54
+ "messages": [HumanMessage(content=request.message)]
55
+ }
56
+
57
+ return StreamingResponse(
58
+ generate_chat_response(initial_state, config),
59
+ media_type="text/plain"
60
+ )