JasonFinley0821 commited on
Commit
f4d5e8a
·
1 Parent(s): e060de2

feat : 統一agents 回饋json 格式

Browse files
Files changed (2) hide show
  1. services/agents.py +28 -7
  2. services/linebot.py +41 -14
services/agents.py CHANGED
@@ -38,7 +38,7 @@ def generate_and_upload_image(prompt: str) -> str:
38
  prompt: 用於生成圖片的文字提示。
39
 
40
  Returns:
41
- 回傳生成圖片 URL。
42
  """
43
  try:
44
  # 呼叫 Google GenAI 模型生成內容
@@ -65,11 +65,21 @@ def generate_and_upload_image(prompt: str) -> str:
65
  # 從環境變數獲取 Hugging Face Space 的 URL (或你的伺服器 URL)
66
  # 並組合完整的圖片 URL
67
  image_url = os.path.join(os.getenv("HF_SPACE"), file_name) # Embed this Space
68
- return image_url
 
 
 
 
69
 
70
- return "圖片生成失敗。"
 
 
 
71
  except Exception as e:
72
- return f"圖片生成與上傳失敗: {e}"
 
 
 
73
 
74
  @tool
75
  def analyze_image_with_text(image_path: str, user_text: str) -> str:
@@ -81,12 +91,14 @@ def analyze_image_with_text(image_path: str, user_text: str) -> str:
81
  user_text: 針對圖片提出的文字問題。
82
 
83
  Returns:
84
- 模型針對圖片和文字提示給出的回應。
85
  """
86
  try:
87
  # 檢查圖片路徑是否存在
88
  if not os.path.exists(image_path):
89
- return "圖片路徑無效,無法進行分析。"
 
 
90
 
91
  # 使用 PIL 開啟圖片
92
  img_user = PIL.Image.open(image_path)
@@ -99,11 +111,20 @@ def analyze_image_with_text(image_path: str, user_text: str) -> str:
99
  out = response.text
100
  else:
101
  out = "Gemini沒答案!請換個說法!"
 
 
 
 
 
 
102
  except Exception as e:
103
  # 處理錯誤
104
  out = f"Gemini執行出錯: {e}"
 
 
 
 
105
 
106
- return out
107
 
108
  @tool
109
  def deblur_image_from_url(
 
38
  prompt: 用於生成圖片的文字提示。
39
 
40
  Returns:
41
+ 一個 JSON 格式的字串,包含圖片 URL 和描述,或錯誤訊息
42
  """
43
  try:
44
  # 呼叫 Google GenAI 模型生成內容
 
65
  # 從環境變數獲取 Hugging Face Space 的 URL (或你的伺服器 URL)
66
  # 並組合完整的圖片 URL
67
  image_url = os.path.join(os.getenv("HF_SPACE"), file_name) # Embed this Space
68
+ # 統一回傳 JSON 成功格式
69
+ return json.dumps({
70
+ "image_url": image_url,
71
+ "text_result": f"圖片已成功生成並上傳。這是根據提示 '{prompt[:50]}...' 生成的圖片。"
72
+ })
73
 
74
+ # 處理圖片生成失敗但 API 未報錯的情況
75
+ return json.dumps({
76
+ "error": "圖片生成失敗。API 回應中未包含圖片數據,請嘗試修改提示詞。"
77
+ })
78
  except Exception as e:
79
+ error_msg = f"圖片生成與上傳失敗: {e}"
80
+ return json.dumps({
81
+ "error": error_msg
82
+ })
83
 
84
  @tool
85
  def analyze_image_with_text(image_path: str, user_text: str) -> str:
 
91
  user_text: 針對圖片提出的文字問題。
92
 
93
  Returns:
94
+ 一個 JSON 格式的字串,包含模型回應或錯誤訊息
95
  """
96
  try:
97
  # 檢查圖片路徑是否存在
98
  if not os.path.exists(image_path):
99
+ return json.dumps({
100
+ "error": "圖片路徑無效,無法進行分析。"
101
+ })
102
 
103
  # 使用 PIL 開啟圖片
104
  img_user = PIL.Image.open(image_path)
 
111
  out = response.text
112
  else:
113
  out = "Gemini沒答案!請換個說法!"
114
+
115
+ # 統一回傳 JSON 成功格式 (只有文字結果)
116
+ return json.dumps({
117
+ "text_result": out
118
+ })
119
+
120
  except Exception as e:
121
  # 處理錯誤
122
  out = f"Gemini執行出錯: {e}"
123
+ # 統一回傳 JSON 錯誤格式
124
+ return json.dumps({
125
+ "error": out
126
+ })
127
 
 
128
 
129
  @tool
130
  def deblur_image_from_url(
services/linebot.py CHANGED
@@ -12,7 +12,7 @@ from linebot.models import ( # 匯入 Line Bot 的各種訊息模型
12
  ImageMessage,
13
  FollowEvent
14
  )
15
-
16
  from agents import agent_executor
17
 
18
  load_dotenv()
@@ -138,26 +138,53 @@ def handle_message(event):
138
  try:
139
  # 運行 LangChain 代理人
140
  response = agent_executor.invoke(agent_input)
141
- # 獲取代理人最終的輸出
142
- out = response["output"]
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
- # 檢查輸出中是否包含 'https' (判斷是否為生成的圖片 URL)
145
- if 'https' in out:
146
- # 解析 URL (這裡的解析方式比較簡易,可能需要更穩健的正規表達式)
147
- img_tmp = 'https'+out.split('https')[1]
148
- image_url = img_tmp.split('png')[0]+'png'
149
 
150
- # 使用 push_message 同時推送文字和圖片
151
- line_bot_api.push_message(
152
- event.source.user_id,
 
 
153
  [
154
- TextSendMessage(text="✨ 這是我為你生成的圖片喔~"),
155
  ImageSendMessage(original_content_url=image_url, preview_image_url=image_url)
156
  ]
157
  )
 
 
 
 
 
 
158
  else:
159
- # 如果輸出不是 URL,則直接回覆文字
160
- line_bot_api.reply_message(event.reply_token, TextSendMessage(text=out))
 
 
 
 
 
 
 
 
161
  except Exception as e:
162
  # 處理代理人執行時的錯誤
163
  print(f"代理人執行出錯: {e}")
 
12
  ImageMessage,
13
  FollowEvent
14
  )
15
+ import json
16
  from agents import agent_executor
17
 
18
  load_dotenv()
 
138
  try:
139
  # 運行 LangChain 代理人
140
  response = agent_executor.invoke(agent_input)
141
+ # Agent 的輸出是 JSON 字串 (無論成功或失敗)
142
+ out_str = response["output"]
143
+ # 2. 嘗試解析 JSON 輸出
144
+ result = json.loads(out_str)
145
+
146
+ if "error" in result:
147
+ # 3A. 處理錯誤情況 (例如:圖片下載失敗、API 錯誤)
148
+ error_msg = result["error"]
149
+ reply_text = f"🚫 圖片工具執行失敗:\n{error_msg}"
150
+ line_bot_api.reply_message(event.reply_token, TextSendMessage(text=reply_text))
151
+ elif "image_url" in result:
152
+ # 3B. 處理成功情況 (帶有圖片 URL,例如:圖片生成或去模糊工具)
153
+ image_url = result["image_url"]
154
+ text_result = result.get("text_result", "圖片處理完成。")
155
 
156
+ # Line 要求圖片 URL 必須是 HTTPS
157
+ # 由於 HF_SPACE 預設是 https,這裡做一個保險轉換
158
+ if image_url.startswith("http://"):
159
+ image_url = image_url.replace("http://", "https://")
 
160
 
161
+ # 使用 reply_message (或 push_message) 同時推送文字和圖片
162
+ # 註:reply_message 只能回覆一次。若要一次發送多個訊息,需要使用 list
163
+ # 這裡假設 text_result 是主要回覆,圖片作為輔助。
164
+ line_bot_api.reply_message(
165
+ event.reply_token,
166
  [
167
+ TextSendMessage(text=f"✨ {text_result}"),
168
  ImageSendMessage(original_content_url=image_url, preview_image_url=image_url)
169
  ]
170
  )
171
+
172
+ elif "text_result" in result:
173
+ # 3C. 處理純文字結果 (例如:多模態分析工具)
174
+ text_result = result["text_result"]
175
+ line_bot_api.reply_message(event.reply_token, TextSendMessage(text=text_result))
176
+
177
  else:
178
+ # 3D. 處理意外的 JSON 結構
179
+ line_bot_api.reply_message(
180
+ event.reply_token,
181
+ TextSendMessage(text="代理人回覆格式無法識別,請聯繫管理員。")
182
+ )
183
+ except json.JSONDecodeError:
184
+ # 4. 處理 Agent 返回了無法解析的純文字 (非 JSON)
185
+ # 這通常發生在 Agent 決定不使用工具,直接回覆純文字,或者推理過程出錯。
186
+ line_bot_api.reply_message(event.reply_token, TextSendMessage(text=out_str))
187
+
188
  except Exception as e:
189
  # 處理代理人執行時的錯誤
190
  print(f"代理人執行出錯: {e}")