You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/hk/9-chat-project/README.md

11 KiB

聊天項目

這個聊天項目展示了如何使用 GitHub Models 構建一個聊天助手。

以下是完成後的項目樣子:

聊天應用

一些背景資訊,使用生成式 AI 構建聊天助手是一個學習 AI 的好方法。在這節課中,你將學會如何將生成式 AI 整合到網頁應用中,讓我們開始吧。

連接生成式 AI

在後端,我們使用 GitHub Models。這是一個很棒的服務可以免費使用 AI。前往它的 Playground獲取與你選擇的後端語言對應的代碼。以下是 GitHub Models Playground 的樣子:

GitHub Models AI Playground

如我們所說,選擇 "Code" 標籤和你選擇的運行時環境。

Playground 選擇

使用 Python

在這個例子中,我們選擇 Python這意味著我們會選擇以下代碼

"""Run this model in Python

> pip install openai
"""
import os
from openai import OpenAI

# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings. 
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
    base_url="https://models.github.ai/inference",
    api_key=os.environ["GITHUB_TOKEN"],
)

response = client.chat.completions.create(
    messages=[
        {
            "role": "system",
            "content": "",
        },
        {
            "role": "user",
            "content": "What is the capital of France?",
        }
    ],
    model="openai/gpt-4o-mini",
    temperature=1,
    max_tokens=4096,
    top_p=1
)

print(response.choices[0].message.content)

讓我們稍微清理一下這段代碼,使其可重用:

def call_llm(prompt: str, system_message: str):
    response = client.chat.completions.create(
        messages=[
            {
                "role": "system",
                "content": system_message,
            },
            {
                "role": "user",
                "content": prompt,
            }
        ],
        model="openai/gpt-4o-mini",
        temperature=1,
        max_tokens=4096,
        top_p=1
    )

    return response.choices[0].message.content

通過這個函數 call_llm,我們現在可以傳入一個提示和一個系統提示,函數最終會返回結果。

自定義 AI 助手

如果你想自定義 AI 助手的行為,可以像這樣填充系統提示:

call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")

通過 Web API 暴露

很好,我們已經完成了 AI 部分,現在來看看如何將其整合到 Web API 中。對於 Web API我們選擇使用 Flask但任何網絡框架都可以。以下是代碼

使用 Python

# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS

app = Flask(__name__)
CORS(app)   # *   example.com

@app.route("/", methods=["GET"])
def index():
    return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"


@app.route("/hello", methods=["POST"])
def hello():
    # get message from request body  { "message": "do this taks for me" }
    data = request.get_json()
    message = data.get("message", "")

    response = call_llm(message, "You are a helpful assistant.")
    return jsonify({
        "response": response
    })

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

在這裡,我們創建了一個 Flask API並定義了默認路由 "/" 和 "/chat"。後者是為了讓前端傳遞問題給後端。

要整合 llm.py,我們需要做以下幾件事:

  • 導入 call_llm 函數:

    from llm import call_llm
    from flask import Flask, request
    
  • 從 "/chat" 路由調用它:

    @app.route("/hello", methods=["POST"])
    def hello():
       # get message from request body  { "message": "do this taks for me" }
       data = request.get_json()
       message = data.get("message", "")
    
       response = call_llm(message, "You are a helpful assistant.")
       return jsonify({
          "response": response
       })
    

    在這裡,我們解析傳入的請求,從 JSON 主體中檢索 message 屬性。然後,我們通過以下調用來調用 LLM

    response = call_llm(message, "You are a helpful assistant")
    
    # return the response as JSON
    return jsonify({
       "response": response 
    })
    

很好,現在我們已經完成了所需的部分。

配置 Cors

我們需要提到的是,我們設置了類似 CORS跨域資源共享的東西。這意味著由於我們的後端和前端將在不同的端口運行我們需要允許前端調用後端。

使用 Python

api.py 中有一段代碼設置了這個功能:

from flask_cors import CORS

app = Flask(__name__)
CORS(app)   # *   example.com

目前,它被設置為允許 "*",即所有來源,這有點不安全,我們應該在進入生產環境時進行限制。

運行你的項目

要運行你的項目,你需要先啟動後端,然後啟動前端。

使用 Python

好的,我們有 llm.pyapi.py,如何讓它們與後端一起工作呢?我們需要做兩件事:

  • 安裝依賴項:

    cd backend
    python -m venv venv
    source ./venv/bin/activate
    
    pip install openai flask flask-cors openai
    
  • 啟動 API

    python api.py
    

    如果你在 Codespaces 中,請前往編輯器底部的 Ports右鍵點擊它選擇 "Port Visibility",然後選擇 "Public"。

開發前端

現在我們的 API 已經運行起來了,讓我們為此創建一個前端。這是一個最低限度的前端,我們將逐步改進它。在 frontend 文件夾中,創建以下內容:

backend/
frontend/
index.html
app.js
styles.css

讓我們從 index.html 開始:

<html>
    <head>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
      <form>
        <textarea id="messages"></textarea>
        <input id="input" type="text" />
        <button type="submit" id="sendBtn">Send</button>  
      </form>  
      <script src="app.js" />
    </body>
</html>    

以上是支持聊天窗口所需的最低限度,包含一個用於顯示消息的文本區域、一個輸入框用於輸入消息,以及一個按鈕用於將消息發送到後端。接下來讓我們看看 app.js 中的 JavaScript

app.js

// app.js

(function(){
  // 1. set up elements  
  const messages = document.getElementById("messages");
  const form = document.getElementById("form");
  const input = document.getElementById("input");

  const BASE_URL = "change this";
  const API_ENDPOINT = `${BASE_URL}/hello`;

  // 2. create a function that talks to our backend
  async function callApi(text) {
    const response = await fetch(API_ENDPOINT, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message: text })
    });
    let json = await response.json();
    return json.response;
  }

  // 3. add response to our textarea
  function appendMessage(text, role) {
    const el = document.createElement("div");
    el.className = `message ${role}`;
    el.innerHTML = text;
    messages.appendChild(el);
  }

  // 4. listen to submit events
  form.addEventListener("submit", async(e) => {
    e.preventDefault();
   // someone clicked the button in the form
   
   // get input
   const text = input.value.trim();

   appendMessage(text, "user")

   // reset it
   input.value = '';

   const reply = await callApi(text);

   // add to messages
   appendMessage(reply, "assistant");

  })
})();

讓我們逐段解析代碼:

    1. 在這裡,我們獲取所有稍後會在代碼中引用的元素。
    1. 在這部分,我們創建了一個函數,使用內建的 fetch 方法來調用後端。
    1. appendMessage 幫助添加響應以及用戶輸入的消息。
    1. 在這裡,我們監聽提交事件,讀取輸入字段,將用戶的消息放入文本區域,調用 API並將響應渲染到文本區域中。

接下來讓我們看看樣式設置,這裡你可以自由發揮,讓它看起來像你想要的樣子,但以下是一些建議:

styles.css

.message {
    background: #222;
    box-shadow: 0 0 0 10px orange;
    padding: 10px:
    margin: 5px;
}

.message.user {
    background: blue;
}

.message.assistant {
    background: grey;
} 

通過這三個類,你可以根據消息的來源(助手或用戶)來設置不同的樣式。如果你需要靈感,可以查看 solution/frontend/styles.css 文件夾。

更改 Base Url

有一件事我們還沒有設置,那就是 BASE_URL,這在後端啟動之前是未知的。設置方法如下:

  • 如果你在本地運行 API應設置為類似 http://localhost:5000
  • 如果在 Codespaces 中運行,應設置為類似 "[name]app.github.dev"。

作業

創建你自己的文件夾 project,內容如下:

project/
  frontend/
    index.html
    app.js
    styles.css
  backend/
    ...

複製上述指導中的內容,但可以根據你的喜好進行自定義。

解決方案

解決方案

額外挑戰

嘗試更改 AI 助手的個性。

對於 Python

當你在 api.py 中調用 call_llm 時,可以將第二個參數更改為你想要的內容,例如:

call_llm(message, "You are Captain Picard")

前端

同時更改 CSS 和文本,對 index.htmlstyles.css 進行修改。

總結

太棒了,你已經從零開始學會了如何使用 AI 創建一個個人助手。我們使用了 GitHub Models後端使用 Python前端使用 HTML、CSS 和 JavaScript。

使用 Codespaces 設置

  • 前往:Web Dev For Beginners repo

  • 從模板創建(確保你已登錄 GitHub在右上角

    從模板創建

  • 進入你的倉庫後,創建一個 Codespace

    創建 Codespace

    這將啟動一個你可以使用的環境。


免責聲明
本文件已使用人工智能翻譯服務 Co-op Translator 進行翻譯。雖然我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。原始語言的文件應被視為權威來源。對於重要信息,建議使用專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或錯誤解釋概不負責。