cwadayi commited on
Commit
ef43cc9
·
verified ·
1 Parent(s): 5da9c98

Update ai_service.py

Browse files
Files changed (1) hide show
  1. ai_service.py +54 -20
ai_service.py CHANGED
@@ -1,12 +1,9 @@
1
- # ai_service.py (Definitive fix for the ImportError)
2
  import json
3
  from datetime import datetime
4
  import google.generativeai as genai
5
  from gradio_client import Client
6
 
7
- # [修正] 移除 'Part' 的 import,因為它導致了錯誤
8
- # from google.generativeai.types import Part
9
-
10
  # 從設定檔匯入金鑰和 URL
11
  from config import GEMINI_API_KEY, MCP_SERVER_URL
12
 
@@ -14,7 +11,9 @@ from config import GEMINI_API_KEY, MCP_SERVER_URL
14
  if GEMINI_API_KEY and "YOUR_GEMINI_API_KEY" not in GEMINI_API_KEY:
15
  genai.configure(api_key=GEMINI_API_KEY)
16
 
17
- # --- 2. 工具函式 (用於地震查詢) ---
 
 
18
  def call_mcp_earthquake_search(
19
  start_date: str,
20
  end_date: str,
@@ -51,21 +50,59 @@ def call_mcp_earthquake_search(
51
  print(f"呼叫 MCP 伺服器失敗: {e}")
52
  return f"工具執行失敗,錯誤訊息: {e}"
53
 
54
- # --- 3. 向 Gemini 定義工具 ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  earthquake_search_tool_declaration = {
56
  "name": "call_earthquake_search_tool",
57
  "description": "根據指定的條件(時間、地點、規模等)從台灣中央氣象署的資料庫中搜尋地震事件。預設搜尋台灣周邊地區。",
58
  "parameters": {
59
  "type": "OBJECT", "properties": {
60
- "start_date": {"type": "STRING", "description": "搜尋的開始日期 (格式 'YYYY-MM-DD')。模型應根據使用者問題推斷此日期,例如從『去年』或『2024年』推斷出 '2024-01-01'。"},
61
- "end_date": {"type": "STRING", "description": "搜尋的結束日期 (格式 'YYYY-MM-DD')。模型應根據使用者問題推斷此日期,例如從『昨天』或『2024年』推斷出 '2024-12-31'。"},
62
- "min_magnitude": {"type": "NUMBER", "description": "要搜尋的最小地震規模。如果使用者未指定,請使用預設值 4.5。"},
63
- "max_magnitude": {"type": "NUMBER", "description": "要搜尋的最大地震規模。預設為 8.0。"},
64
  }, "required": ["start_date", "end_date"]
65
  }
66
  }
67
 
68
- available_tools = {"call_earthquake_search_tool": call_mcp_earthquake_search}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  # --- 4. 建立 Gemini 模型 ---
71
  model = None
@@ -73,20 +110,19 @@ if GEMINI_API_KEY and "YOUR_GEMINI_API_KEY" not in GEMINI_API_KEY:
73
  try:
74
  system_instruction = (
75
  "You are a helpful AI assistant. You must answer in Traditional Chinese."
76
- "You have access to tools. When a tool returns data in JSON format, "
77
- "you must analyze the JSON data to fully answer the user's question. "
78
- "For example, if the user asks for the largest earthquake, use the search tool for the relevant date range "
79
- "and then find the entry with the highest magnitude from the JSON results before answering."
80
  )
 
81
  model = genai.GenerativeModel(
82
  model_name="gemini-1.5-flash",
83
- tools=[earthquake_search_tool_declaration],
84
  system_instruction=system_instruction
85
  )
86
  except Exception as e:
87
  print(f"建立 Gemini 模型失敗: {e}")
88
 
89
- # --- 5. 主要的 AI 文字生成函式 ---
90
  def generate_ai_text(user_prompt: str) -> str:
91
  if not model:
92
  return "🤖 AI (Gemini) 服務尚未設定 API 金鑰,或金鑰無效。"
@@ -110,7 +146,6 @@ def generate_ai_text(user_prompt: str) -> str:
110
  tool_result = tool_function(**dict(function_call.args))
111
  print("--- 將工具結果回傳給 Gemini ---")
112
 
113
- # [修正] 直接傳送包含 function_response 的字典,不再使用 Part 類別
114
  response = chat.send_message(
115
  {"function_response": {"name": function_call.name, "response": {"result": tool_result}}}
116
  )
@@ -119,5 +154,4 @@ def generate_ai_text(user_prompt: str) -> str:
119
  return response.text
120
  except Exception as e:
121
  print(f"與 Gemini AI 互動時發生錯誤: {e}")
122
- return f"🤖 AI 服務發生錯誤: {e}"
123
-
 
1
+ # ai_service.py (已整合 PWS 查詢工具)
2
  import json
3
  from datetime import datetime
4
  import google.generativeai as genai
5
  from gradio_client import Client
6
 
 
 
 
7
  # 從設定檔匯入金鑰和 URL
8
  from config import GEMINI_API_KEY, MCP_SERVER_URL
9
 
 
11
  if GEMINI_API_KEY and "YOUR_GEMINI_API_KEY" not in GEMINI_API_KEY:
12
  genai.configure(api_key=GEMINI_API_KEY)
13
 
14
+ # --- 2. 工具函式 (Tool Functions) ---
15
+
16
+ # [既有] 地震查詢工具函式
17
  def call_mcp_earthquake_search(
18
  start_date: str,
19
  end_date: str,
 
50
  print(f"呼叫 MCP 伺服器失敗: {e}")
51
  return f"工具執行失敗,錯誤訊息: {e}"
52
 
53
+ # [新增] PWS 查詢工具函式
54
+ def call_mcp_pws_search() -> str:
55
+ """從遠端伺服器查詢最新的 PWS (Public Weather Service) 發布情形。"""
56
+ try:
57
+ print(f"--- 正在呼叫遠端 PWS MCP 伺服器 (由 Gemini 觸發) ---")
58
+ # 連線到使用者指定的 Gradio 應用程式
59
+ client = Client("cwadayi/MCP-pws")
60
+ # 假設 Gradio API 不需要參數,直接呼叫 predict
61
+ result = client.predict(api_name="/predict")
62
+
63
+ # Gradio client 回傳的結果通常是元組 (tuple),取出第一個元素
64
+ if isinstance(result, tuple) and len(result) > 0:
65
+ report = result[0]
66
+ else:
67
+ report = str(result)
68
+
69
+ print(f"--- PWS MCP 伺服器成功回傳 ---")
70
+ return report
71
+ except Exception as e:
72
+ print(f"呼叫 PWS MCP 伺服器失敗: {e}")
73
+ return f"工具執行失敗,錯誤訊息: {e}"
74
+
75
+ # --- 3. 向 Gemini 定義工具 (Tool Declarations) ---
76
+
77
+ # [既有] 地震查詢工具定義
78
  earthquake_search_tool_declaration = {
79
  "name": "call_earthquake_search_tool",
80
  "description": "根據指定的條件(時間、地點、規模等)從台灣中央氣象署的資料庫中搜尋地震事件。預設搜尋台灣周邊地區。",
81
  "parameters": {
82
  "type": "OBJECT", "properties": {
83
+ "start_date": {"type": "STRING", "description": "搜尋的開始日期 (格式 'YYYY-MM-DD')。"},
84
+ "end_date": {"type": "STRING", "description": "搜尋的結束日期 (格式 'YYYY-MM-DD')。"},
85
+ "min_magnitude": {"type": "NUMBER", "description": "要搜尋的最小地震規模。"},
86
+ "max_magnitude": {"type": "NUMBER", "description": "要搜尋的最大地震規模。"},
87
  }, "required": ["start_date", "end_date"]
88
  }
89
  }
90
 
91
+ # [新增] PWS 查詢工具定義
92
+ pws_search_tool_declaration = {
93
+ "name": "call_mcp_pws_search",
94
+ "description": "查詢最新的 PWS (Public Weather Service) 公共天氣服務發布情形。",
95
+ "parameters": {
96
+ "type": "OBJECT",
97
+ "properties": {} # 此工具不需要參數
98
+ }
99
+ }
100
+
101
+ # [修改] 將所有可用的工具函式註冊在此
102
+ available_tools = {
103
+ "call_earthquake_search_tool": call_mcp_earthquake_search,
104
+ "call_mcp_pws_search": call_mcp_pws_search
105
+ }
106
 
107
  # --- 4. 建立 Gemini 模型 ---
108
  model = None
 
110
  try:
111
  system_instruction = (
112
  "You are a helpful AI assistant. You must answer in Traditional Chinese."
113
+ "You have access to tools. When a tool returns data, "
114
+ "you must analyze the data to fully answer the user's question."
 
 
115
  )
116
+ # [修改] 初始化模型時,提供所有工具的定義
117
  model = genai.GenerativeModel(
118
  model_name="gemini-1.5-flash",
119
+ tools=[earthquake_search_tool_declaration, pws_search_tool_declaration],
120
  system_instruction=system_instruction
121
  )
122
  except Exception as e:
123
  print(f"建立 Gemini 模型失敗: {e}")
124
 
125
+ # --- 5. 主要的 AI 文字生成函式 (此部分維持不變) ---
126
  def generate_ai_text(user_prompt: str) -> str:
127
  if not model:
128
  return "🤖 AI (Gemini) 服務尚未設定 API 金鑰,或金鑰無效。"
 
146
  tool_result = tool_function(**dict(function_call.args))
147
  print("--- 將工具結果回傳給 Gemini ---")
148
 
 
149
  response = chat.send_message(
150
  {"function_response": {"name": function_call.name, "response": {"result": tool_result}}}
151
  )
 
154
  return response.text
155
  except Exception as e:
156
  print(f"與 Gemini AI 互動時發生錯誤: {e}")
157
+ return f"🤖 AI 服務發生錯誤: {e}"