目標:建立前端可上傳 PDF/CSV 或輸入文字問題,後端 n8n 呼叫 Gemini 2.5 Flash 生成摘要或答案,結果回傳至前端。
概念:
注意:請確保 Gemini 2.5 Flash API Key 可用,且 n8n Workflow 已 Activate
import gradio as gr
import requests
# 主函式:接收檔案與問題,呼叫 n8n Webhook
def analyze_file(file, question):
# 判斷是否有上傳檔案
if file:
# 注意:open(file.name, "rb") 必須關閉檔案,或使用 with
with open(file.name, "rb") as f:
files = {"file": f}
data = {"question": question}
# 呼叫 n8n Webhook,傳送檔案與問題
response = requests.post(
"http://localhost:5678/webhook/ai-analyzer",
data=data,
files=files
)
else:
# 無檔案時,僅傳送文字內容
response = requests.post(
"http://localhost:5678/webhook/ai-analyzer",
json={"question": question, "content": ""}
)
# 檢查回應狀態
if response.status_code == 200:
# 注意 JSON key 是否與 Function 節點輸出一致
return response.json().get("result", "Agent 沒回應")
else:
return f"Error: {response.text}"
# 建立 Gradio UI
iface = gr.Interface(
fn=analyze_file,
inputs=[
gr.File(label="上傳檔案(PDF / CSV)", file_types=[".pdf", ".csv"]),
gr.Textbox(label="想詢問的問題", placeholder="例如:幫我摘要報告重點")
],
outputs=gr.Textbox(label="AI 分析結果"),
title="LLM Agent 智慧文件分析",
description="上傳文件並輸入問題,AI Agent 自動產生摘要或答案"
)
# 啟動 Gradio
iface.launch()
註解提醒:
file.name
是檔案路徑,必須用 "rb"
開啟二進位檔result
)Webhook (/ai-analyzer)
↓
Function (解析檔案)
↓
Function (轉文字)
↓
HTTP Request (呼叫 Gemini 2.5 Flash)
↓
Function (整理 LLM 回應)
↓
Webhook Response (Last Node)
const { parse } = require('csv-parse/sync');
const pdf = require('pdf-parse');
// 檢查是否有檔案上傳
if (Object.keys($binary).length > 0) {
if ($binary.data.mimeType === 'application/pdf') {
// PDF 解析
return pdf($binary.data).then(data => [{json:{content:data.text}}]);
} else if ($binary.data.mimeType.includes('csv')) {
// CSV 解析
const records = parse($binary.data.toString(), {columns:true});
return [{json:{content: JSON.stringify(records)}}];
} else {
return [{json:{content:"Unsupported file"}}];
}
} else {
// 無檔案,使用前端傳入文字
return [{json:{content:$json["content"]}}];
}
註解提醒:
pdf-parse
套件csv-parse/sync
套件POST https://api.gemini.com/v1/llm
Headers:
Authorization: Bearer <YOUR_API_KEY>
Body (JSON):
{
"model": "gemini-2.5-flash",
"input": "請閱讀以下內容並回答問題: {{$json['question']}}\n內容: {{$json['content']}}",
"temperature": 0.7,
"max_tokens": 500
}
註解提醒:
model
一定要使用 "gemini-2.5-flash"
input
可以使用 n8n 表達式 {{$json[...]}}
return [{
json: {
result: $json["choices"] ? $json["choices"][0]["text"] : "LLM 沒回應"
}
}]
註解提醒:
choices[0].text
路徑正確curl 測試範例:
curl -X POST http://localhost:5678/webhook/ai-analyzer \
-F "file=@sample.pdf" \
-F "question=幫我摘要重點"
問題 | 可能原因 | 建議處理 |
---|---|---|
LLM 無回應 | API Key 錯誤或 Body JSON 不正確 | 檢查 Key 與輸入格式 |
PDF / CSV 解析錯誤 | 套件未安裝或 MIME type 不正確 | 安裝套件,確認 Node 設定 |
Webhook 空白 | Response Mode 未選 Last Node | 調整 Webhook Response Mode |
Gradio 顯示空白 | Function 節點回傳 JSON key 與前端不一致 | 確認回傳 key 為 "result" |