Python: 使用 Flask 與 OpenAI API 建立智能問答系統

加入好友
加入社群
Python: 使用 Flask 與 OpenAI API 建立智能問答系統 - 儲蓄保險王

 code:

import os
import json
from flask import Flask, request, jsonify, render_template
from openai import OpenAI
from typing import List, Dict
import sys
import io

# 將默認編碼設置為 UTF-8
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

# 設置目錄路徑和文件名
dirname = r"D:\user\Python\GPT\json"
basename_api_key = "api_key.json"
basename_database = "database.json"

path_api_key = os.path.join(dirname, basename_api_key)
path_database = os.path.join(dirname, basename_database)

# 獲取 API Key
def get_api_key(path_api_key=path_api_key):
    with open(path_api_key, "r", encoding="UTF-8") as f:
        data = json.load(f)
        api_key = data["api_key"]
        return api_key

api_key = get_api_key(path_api_key=path_api_key)

# 配置 OpenAI 客戶端
client = OpenAI(api_key=api_key)

# 加載 JSON 資料庫
def load_jsonDB(file_path=path_database):
    with open(file_path, "r", encoding="utf-8") as f:
        database = json.load(f)
    return database

# 初始化資料庫
database: List[Dict[str, str]] = load_jsonDB(file_path=path_database)

# 查詢 JSON 資料庫
def query_database(question: str) -> List[Dict[str, str]]:
    # 將問題拆分為關鍵詞並匹配資料庫內容中是否包含關鍵詞
    results = [dic for dic in database if any(word in dic["content"].lower() for word in question.lower().split())]
    return results

# 初始化 Flask 應用
app = Flask(__name__)

# GPT 問答接口
@app.route("/ask", methods=["POST"])
def ask_gpt():
    try:
        # 獲取用戶問題
        data = request.json  # 從用戶的 POST 請求中提取 JSON 數據
        user_question = data.get("question", "")

        # 查詢 JSON 資料庫
        db_results = query_database(user_question)

        # 構造 GPT 提示
        if db_results:
            # 如果資料庫有匹配結果
            gpt_prompt = f"資料庫查詢結果:{db_results}\n\n用戶問題:{user_question}\n\n請根據資料庫內容回答:"
        else:
            # 如果資料庫沒有匹配結果 GPT 自行回答
            gpt_prompt = f"用戶問題:{user_question}\n\n資料庫中沒有相關內容,請根據一般知識回答:"

        #  GPT 發送請求
        response = client.chat.completions.create(
            model="gpt-4-32k",
            messages=[
                {"role": "system", "content": "你是專業的問題回答助手請根據用戶的問題給出準確的回答。"},
                {"role": "user", "content": gpt_prompt},
            ],
        )
        print("response:\n",response)
        # 提取 GPT 的回答
        answer = response.choices[0].message.content
        print("GPT 回答:", answer)

        # 返回 JSON 格式的回答
        return jsonify({"answer": answer})

    except Exception as e:
        # 返回錯誤信息
        return jsonify({"error": str(e)}), 500

# 網頁接口
@app.route("/")
def index():
    return render_template("index.html")  # 加載 templates/index.html 文件

# 啟動 Flask 服務器
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

執行程式後:

Python: 使用 Flask 與 OpenAI API 建立智能問答系統 - 儲蓄保險王

http://127.0.0.1:5000/

Python: 使用 Flask 與 OpenAI API 建立智能問答系統 - 儲蓄保險王

在這篇文章中,我們將詳細介紹如何使用 Python 的 Flask 框架和 OpenAI API 建立一個智能問答系統。這個系統能夠根據用戶的問題查詢本地 JSON 資料庫,並結合 OpenAI 的 GPT 模型生成答案。我們會一步步引導您設置環境、編寫代碼,以及如何購買 OpenAI API Key,讓您快速上手開發這樣一個功能強大的應用。


目錄

  1. 系統功能概述
  2. 準備工作
    • 購買 OpenAI API Key
    • 安裝必要的工具與庫
  3. 程式碼詳細解說與註解
  4. 啟動與測試
  5. 結語

1. 系統功能概述

這個智能問答系統的主要功能包括:

  • 查詢本地 JSON 資料庫:當用戶輸入問題時,系統會先檢索本地 JSON 文件,嘗試找到和問題相關的內容。
  • 結合 GPT 模型生成答案:如果資料庫中有相關內容,系統會將這些內容作為上下文提示 GPT;如果資料庫中沒有匹配的內容,則直接讓 GPT 根據一般知識回答。
  • 簡單的 Web 網頁界面:用戶可以通過 Web 瀏覽器輸入問題並查看答案。

2. 準備工作

購買 OpenAI API Key

要使用 OpenAI 提供的 GPT 模型,我們需要獲取一個 API Key。以下是購買和獲取 API Key 的步驟:

  1. 註冊 OpenAI 帳戶
  2. 購買 API Key
  3. 生成 API Key
    • 點擊「API Keys」選項卡。
    • 點擊「Create new secret key」生成一個新的 API Key。
    • 複製該 Key(注意:這是一次性可見的,請妥善保存)。
  4. 保存 API Key
    將 API Key 保存到一個名為 api_key.json 的文件中,結構如下:
{
    "api_key": "your_openai_api_key_here"
}

安裝必要的工具與庫

在開發這個系統之前,請確保您已安裝以下工具和庫:

  1. 安裝 Python
    • 請確保您已安裝 Python 3.8 或更高版本,並將其添加到環境變量中。
  2. 安裝必要的庫
    • 使用以下命令安裝開發所需的庫:

pip install flask openai
若使用anaconda:
conda install anaconda::flask
conda install conda-forge::openai

設置目錄結構

  • 創建一個目錄結構如下:
GPT/
├── app.py          # 主程式
├── json/           # 資料庫與 API Key 文件存放
│   ├── api_key.json
│   ├── database.json
├── templates/      # 前端 HTML 文件存放
│   └── index.html

index.html內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GPT 問答系統</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f9;
            color: #333;
        }
        .container {
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }
        h1 {
            text-align: center;
            color: #444;
        }
        textarea, input {
            width: 100%;
            margin-top: 10px;
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }
        button {
            margin-top: 20px;
            width: 100%;
            padding: 10px;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 16px;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        .response {
            margin-top: 20px;
            padding: 15px;
            background-color: #f8f9fa;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>GPT 問答系統</h1>
        <textarea id="question" rows="4" placeholder="請輸入您的問題..."></textarea>
        <button onclick="askGPT()">發送問題</button>
        <div id="response" class="response" style="display: none;"></div>
    </div>

    <script>
        async function askGPT() {
            const question = document.getElementById("question").value;
            const responseDiv = document.getElementById("response");

            if (!question.trim()) {
                responseDiv.style.display = "block";
                responseDiv.innerText = "請輸入問題!";
                return;
            }

            responseDiv.style.display = "none";
            responseDiv.innerText = "";

            try {
                const response = await fetch("/ask", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify({ question })
                });

                const data = await response.json();

                if (data.answer) {
                    responseDiv.style.display = "block";
                    responseDiv.innerText = "GPT 的回答:\n" + data.answer;
                } else if (data.error) {
                    responseDiv.style.display = "block";
                    responseDiv.innerText = "錯誤:\n" + data.error;
                }
            } catch (error) {
                responseDiv.style.display = "block";
                responseDiv.innerText = "請求失敗,請檢查伺服器是否正常運行。\n" + error;
            }
        }
    </script>
</body>
</html>

3. 程式碼詳細解說與註解

以下是完整程式碼的分段講解。

1. 引入必要的模組

import os
import json
from flask import Flask, request, jsonify, render_template
from openai import OpenAI
from typing import List, Dict
import sys
import io

osjson:用於處理文件操作以及 JSON 格式數據。
flask:用於建立 Web 應用。
openai:用於與 OpenAI API 交互。
typing:用於指定數據類型。
sysio:用於解決 Python 默認編碼問題。

設置 UTF-8 編碼

# 將默認編碼設置為 UTF-8
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
  • 解決 Python 在輸出中文時可能遇到的編碼問題。

3. 設置文件路徑

dirname = r"D:\user\Python\GPT\json"
basename_api_key = "api_key.json"
basename_database = "database.json"

path_api_key = os.path.join(dirname, basename_api_key)
path_database = os.path.join(dirname, basename_database)

指定存放 API Key 和資料庫文件的路徑。

獲取 API Key

def get_api_key(path_api_key=path_api_key):
    with open(path_api_key, "r", encoding="UTF-8") as f:
        data = json.load(f)
        api_key = data["api_key"]
        return api_key

api_key = get_api_key(path_api_key=path_api_key)
  • api_key.json 文件中讀取 API Key。

5. 配置 OpenAI 客戶端

client = OpenAI(api_key=api_key)

  • 使用獲取的 API Key 配置 OpenAI 客戶端。

6. 加載 JSON 資料庫

def load_jsonDB(file_path=path_database):
    with open(file_path, "r", encoding="utf-8") as f:
        database = json.load(f)
    return database

database: List[Dict[str, str]] = load_jsonDB(file_path=path_database)

將本地 JSON 資料庫加載到內存中。 資料庫文件結構示例:

[
{"content": "Flask 是一個 Python 的 Web 框架。"},
{"content": "GPT 是一種基於 Transformer 的大型語言模型。"},
{"content": "JSON Line 是一種每行為一個 JSON 對象的文件格式。"}
]

7. 查詢 JSON 資料庫

def query_database(question: str) -> List[Dict[str, str]]:
    results = [dic for dic in database if any(word in dic["content"].lower() for word in question.lower().split())]
    return results

根據用戶問題中的關鍵詞查詢資料庫,返回匹配的結果。


8. 啟動 Flask 應用

app = Flask(__name__)

  • 初始化 Flask 應用。

9. GPT 問答接口

@app.route("/ask", methods=["POST"])
def ask_gpt():
    try:
        data = request.json
        user_question = data.get("question", "")
        db_results = query_database(user_question)

        if db_results:
            gpt_prompt = f"資料庫查詢結果:{db_results}\n\n用戶問題:{user_question}\n\n請根據資料庫內容回答:"
        else:
            gpt_prompt = f"用戶問題:{user_question}\n\n資料庫中沒有相關內容,請根據一般知識回答:"

        response = client.chat.completions.create(
            model="gpt-4-32k",
            messages=[
                {"role": "system", "content": "你是專業的問題回答助手,請根據用戶的問題給出準確的回答。"},
                {"role": "user", "content": gpt_prompt},
            ],
        )
        answer = response.choices[0].message.content
        return jsonify({"answer": answer})

    except Exception as e:
        return jsonify({"error": str(e)}), 500
  • 該接口處理用戶問題,與 OpenAI API 交互生成答案。

10. 網頁接口

@app.route("/")
def index():
    return render_template("index.html")
  • 加載前端 HTML 文件,提供簡單的用戶界面。

11. 啟動服務器

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
  • 啟動 Flask 開發服務器。

4. 啟動與測試

  1. 啟動 Flask 應用:

python app.py

2. 打開瀏覽器訪問

http://localhost:5000

測試問答功能。


5. 結語

恭喜!您已成功搭建了一個基於 Flask 的智能問答系統,
並結合 OpenAI 的 GPT 模型處理用戶的問題。
如果您有更多功能需求
(如增加用戶身份驗證、支持多語言等),
可以基於此系統進一步擴展!

推薦hahow線上學習python: https://igrape.net/30afN

加入好友
加入社群
Python: 使用 Flask 與 OpenAI API 建立智能問答系統 - 儲蓄保險王

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡

You may also like...

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *