Amity123 commited on
Commit
848228d
·
verified ·
1 Parent(s): 52d1dce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -32
app.py CHANGED
@@ -3,10 +3,8 @@ import gradio as gr
3
  import numpy as np
4
  import re
5
 
6
- # 初始化 OpenAI 客戶端
7
- client = OpenAI(api_key="OPENAIAPIKEY")
8
 
9
- # ============ 1. 定義主要專業領域 ============ #
10
  PROFESSIONS = {
11
  "程式設計": "你是一位資深程式設計師,回答必須專業、詳細,附上程式範例與步驟。",
12
  "行銷": "你是一位行銷專家,回答必須專業、詳細,提供可執行行銷策略與步驟。",
@@ -16,27 +14,24 @@ PROFESSIONS = {
16
  "設計": "你是一位設計師,回答必須專業、詳細,提供設計步驟與案例。"
17
  }
18
 
19
- # ============ 2. Embedding 工具 (UTF-8 安全 + 防呆) ============ #
20
  def get_embedding(text, model="text-embedding-3-small"):
 
 
 
21
  try:
22
- if not isinstance(text, str):
23
- text = str(text)
24
- text = text.encode("utf-8", "ignore").decode("utf-8")
25
  emb = client.embeddings.create(input=text, model=model)
26
  return np.array(emb.data[0].embedding)
27
- except Exception as e:
28
- print(f"[Embedding 錯誤] {e}")
29
- return np.zeros(1536) # fallback 避免程式 crash
30
 
31
- profession_embeddings = {} # 延遲初始化
32
 
33
  def ensure_embeddings():
34
  global profession_embeddings
35
  if not profession_embeddings:
36
- for field in PROFESSIONS.keys():
37
- profession_embeddings[field] = get_embedding(field)
38
 
39
- # ============ 3. NLP 判斷職業 (自動比對) ============ #
40
  def detect_profession(user_input: str) -> str:
41
  ensure_embeddings()
42
  if not user_input.strip():
@@ -45,39 +40,26 @@ def detect_profession(user_input: str) -> str:
45
  detail_emb = get_embedding(user_input)
46
  scores = {}
47
  for field, emb in profession_embeddings.items():
48
- if np.linalg.norm(detail_emb) == 0 or np.linalg.norm(emb) == 0:
49
  scores[field] = -1
50
  else:
51
  scores[field] = np.dot(detail_emb, emb) / (np.linalg.norm(detail_emb) * np.linalg.norm(emb))
52
-
53
  best_field = max(scores, key=scores.get)
54
  return PROFESSIONS[best_field]
55
 
56
- # ============ 4. AI Agent 回答邏輯 ============ #
57
  def professional_agent(user_input, state):
58
- """
59
- state 結構:
60
- {
61
- "chat_history": [(user, assistant), ...],
62
- "profession_prompt": None or str
63
- }
64
- """
65
-
66
- # 如果尚未設定專業 → 自動偵測
67
  if state.get("profession_prompt") is None:
68
  profession_prompt = detect_profession(user_input)
69
  state["profession_prompt"] = profession_prompt
70
-
71
- # 嘗試把「問題部分」抽出來
72
  question = re.sub(r"我是.*?(,|,)", "", user_input)
73
  if not question.strip():
74
- answer = f"✅ 已設定你的專業領域請提出問題。"
75
  state["chat_history"].append((user_input, answer))
76
  return answer, state["chat_history"], state
77
  else:
78
- user_input = question # 問題部分直接交給模型
79
 
80
- # 正常對話
81
  messages = [{"role": "system", "content": state["profession_prompt"]}]
82
  for h in state["chat_history"]:
83
  messages.append({"role": "user", "content": h[0]})
@@ -94,13 +76,14 @@ def professional_agent(user_input, state):
94
  except Exception as e:
95
  answer = f"⚠️ 發生錯誤: {str(e)}"
96
 
 
97
  state["chat_history"].append((user_input, answer))
98
  if len(state["chat_history"]) > 10:
99
  state["chat_history"] = state["chat_history"][-10:]
100
 
101
  return answer, state["chat_history"], state
102
 
103
- # ============ 5. Gradio 介面 ============ #
104
  with gr.Blocks() as demo:
105
  gr.Markdown("## 🧑‍💼 全職業專業 AI 顧問 (NLP 智能判斷)")
106
  gr.Markdown("👉 第一次輸入時,可以同時輸入職業 + 問題,例如:`我是專業會計師,我想知道該如何進行台灣的稅務分析`")
 
3
  import numpy as np
4
  import re
5
 
6
+ client = OpenAI(api_key="你的OPENAI_API_KEY")
 
7
 
 
8
  PROFESSIONS = {
9
  "程式設計": "你是一位資深程式設計師,回答必須專業、詳細,附上程式範例與步驟。",
10
  "行銷": "你是一位行銷專家,回答必須專業、詳細,提供可執行行銷策略與步驟。",
 
14
  "設計": "你是一位設計師,回答必須專業、詳細,提供設計步驟與案例。"
15
  }
16
 
17
+ # Embedding 函數
18
  def get_embedding(text, model="text-embedding-3-small"):
19
+ if not isinstance(text, str):
20
+ text = str(text)
21
+ text = text.encode("utf-8", "ignore").decode("utf-8")
22
  try:
 
 
 
23
  emb = client.embeddings.create(input=text, model=model)
24
  return np.array(emb.data[0].embedding)
25
+ except:
26
+ return np.zeros(1536)
 
27
 
28
+ profession_embeddings = {}
29
 
30
  def ensure_embeddings():
31
  global profession_embeddings
32
  if not profession_embeddings:
33
+ profession_embeddings = {field: get_embedding(field) for field in PROFESSIONS.keys()}
 
34
 
 
35
  def detect_profession(user_input: str) -> str:
36
  ensure_embeddings()
37
  if not user_input.strip():
 
40
  detail_emb = get_embedding(user_input)
41
  scores = {}
42
  for field, emb in profession_embeddings.items():
43
+ if np.linalg.norm(detail_emb)==0 or np.linalg.norm(emb)==0:
44
  scores[field] = -1
45
  else:
46
  scores[field] = np.dot(detail_emb, emb) / (np.linalg.norm(detail_emb) * np.linalg.norm(emb))
 
47
  best_field = max(scores, key=scores.get)
48
  return PROFESSIONS[best_field]
49
 
50
+ # AI 回答
51
  def professional_agent(user_input, state):
 
 
 
 
 
 
 
 
 
52
  if state.get("profession_prompt") is None:
53
  profession_prompt = detect_profession(user_input)
54
  state["profession_prompt"] = profession_prompt
 
 
55
  question = re.sub(r"我是.*?(,|,)", "", user_input)
56
  if not question.strip():
57
+ answer = f"✅ 已設定你的專業領域請提出問題。"
58
  state["chat_history"].append((user_input, answer))
59
  return answer, state["chat_history"], state
60
  else:
61
+ user_input = question
62
 
 
63
  messages = [{"role": "system", "content": state["profession_prompt"]}]
64
  for h in state["chat_history"]:
65
  messages.append({"role": "user", "content": h[0]})
 
76
  except Exception as e:
77
  answer = f"⚠️ 發生錯誤: {str(e)}"
78
 
79
+ # 確保每一筆都是 (user, assistant) tuple
80
  state["chat_history"].append((user_input, answer))
81
  if len(state["chat_history"]) > 10:
82
  state["chat_history"] = state["chat_history"][-10:]
83
 
84
  return answer, state["chat_history"], state
85
 
86
+ # Gradio 介面
87
  with gr.Blocks() as demo:
88
  gr.Markdown("## 🧑‍💼 全職業專業 AI 顧問 (NLP 智能判斷)")
89
  gr.Markdown("👉 第一次輸入時,可以同時輸入職業 + 問題,例如:`我是專業會計師,我想知道該如何進行台灣的稅務分析`")