# LLM 環境建置與開發
## LLM 簡介 (大型語言模型)
LLM(Large Language Model,大型語言模型)是一種基於深度學習技術的自然語言處理模型,它通過分析大量文本資料進行訓練,能夠理解和生成人類語言。
## 目前主流別人已做好的 LLM
### GPT 系列(由 OpenAI 開發)
* GPT-3.5(支持 ChatGPT)
* GPT-4(更強大的多模態模型)
* GPT-4o (OpenAI 最新的語言模型)`
### Claude 系列
* Claude 3 Opus
* Claude 3.5 Sonnet
* Claude 3.7 Sonnet
### Gemini 系列(由 Google 開發)
* Gemini Ultra
* Gemini Pro
* Gemini Nano
### Llama 系列(由 Meta 開發的開源模型)
* Llama 2
* Llama 3
## 用別人訓練好的 LLM

通過 OpenAI API,開發者可以將 GPT 等 LLM 整合到自己的應用中,試著去做:
1. 客製化 AI 解決方案
2. 增強用戶體驗:提供智能交互和個性化服務
3. 自動化流程:減少人工處理,提高效率
4. 創新應用:開發全新的 AI 賦能產品和服務
## 建立 Node + express 環境
1. 建立 Node.js 後端環境
2. 整合 OpenAI API 實現自然語言處理
3. Function Calling 技術處理結構化資料
## 建立環境流程
1. 建立 Node 環境 (`npm init`)
2. 申請 OpenAI API 金鑰 ([官網](https://openai.com/))
3. 安裝 NPM 套件
```
npm init -y
npm install axios dotenv express openai
npm install --save-dev nodemon
```
## Function calling 介紹 ([文件](https://platform.openai.com/docs/guides/function-calling?api-mode=responses))、response API([文件](https://platform.openai.com/docs/api-reference/responses/create))
## 純 BMI 範例

## input 跟 output 累積結果

```=javascript
const express = require("express");
const OpenAI = require("openai");
require("dotenv").config();
// 初始化 Express 應用程式
const app = express();
const PORT = process.env.PORT || 3000;
// 中間件設定
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 初始化 OpenAI
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
/**
* 計算 BMI
* @param {number} height - 身高(公分)
* @param {number} weight - 體重(公斤)
* @returns {Object} - BMI 值
*/
function calculateBMI(height, weight) {
const heightInMeters = height / 100;
const bmi = weight / (heightInMeters * heightInMeters);
const roundedBMI = parseFloat(bmi.toFixed(2));
let category;
if (bmi < 18.5) category = "體重過輕";
else if (bmi < 24) category = "正常體重";
else if (bmi < 27) category = "過重";
else if (bmi < 30) category = "輕度肥胖";
else if (bmi < 35) category = "中度肥胖";
else category = "重度肥胖";
return { bmi: roundedBMI, category: category };
}
/**
* 處理 AI 查詢
* @param {string} query - 客戶的查詢
* @returns {Promise<Object>} - 包含回答和相關數據
*/
async function processAIQuery(query) {
try {
// 定義可用的
const tools = [
{
type: "function",
name: "calculate_bmi",
description: "計算用戶的身體質量指數(BMI)",
parameters: {
type: "object",
properties: {
height: {
type: "number",
description: "用戶的身高(公分),例如 170",
},
weight: {
type: "number",
description: "用戶的體重(公斤),例如 65",
},
},
required: ["height", "weight"],
additionalProperties: false,
},
},
];
// 準備輸入
const input = [{ role: "user", content: query }];
console.log(`處理查詢: "${query}"`);
// 第一次 AI 回應
const response = await openai.responses.create({
model: "gpt-4o",
instructions: `你是一個助手,可以回答 BMI 計算的問題。
當用戶詢問 BMI 相關問題時,呼叫 calculate_bmi 。
使用繁體中文回答,簡潔友善。`,
input,
tools,
tool_choice: "auto",
});
// 檢查是否有被呼叫
if (response.output && response.output.length > 0) {
// 檢查是否是 BMI 計算
const bmiCall = response.output.find(
(call) => call.name === "calculate_bmi"
);
if (bmiCall) {
// 計算 BMI
const args = JSON.parse(bmiCall.arguments);
const bmiResult = calculateBMI(args.height, args.weight);
// 將結果傳回 AI
input.push(bmiCall);
input.push({
type: "function_call_output",
call_id: bmiCall.call_id,
output: JSON.stringify(bmiResult),
});
// 獲取最終回答
const finalResponse = await openai.responses.create({
model: "gpt-4o",
instructions: "根據 BMI 數據回答問題,提供健康建議,提供純文字。",
input,
});
return finalResponse.output_text;
}
}
// 如果沒有呼叫,直接返回 AI 回答
return response.output_text;
} catch (error) {
console.error("處理查詢出錯:", error);
throw error;
}
}
// API 端點
app.post("/chat", async (req, res) => {
try {
const { message } = req.body;
if (!message) {
return res.status(400).json({ error: "請提供訊息內容" });
}
const answer = await processAIQuery(message);
if (!answer) {
return res.status(500).json({ error: "無法生成回答" });
}
res.json({ response: answer });
} catch (error) {
console.error("API 錯誤:", error);
res.status(500).json({ error: error.message || "處理查詢時發生錯誤" });
}
});
// 啟動伺服器
app.listen(PORT, () => {
console.log(`伺服器運行在 http://localhost:${PORT}`);
});
```
## 範例二:BMI 檢查跟今天吃什麼餐廳
多增加一個 tools,讓 AI 自行判斷要呼叫哪個函式
範例 Code:
```=javascript
const express = require("express");
const OpenAI = require("openai");
require("dotenv").config();
// 初始化 Express 應用程式
const app = express();
const PORT = process.env.PORT || 3000;
// 中間件設定
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 初始化 OpenAI
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
/**
* 計算 BMI
* @param {number} height - 身高(公分)
* @param {number} weight - 體重(公斤)
* @returns {Object} - BMI 值
*/
function calculateBMI(height, weight) {
const heightInMeters = height / 100;
const bmi = weight / (heightInMeters * heightInMeters);
const roundedBMI = parseFloat(bmi.toFixed(2));
let category;
if (bmi < 18.5) category = "體重過輕";
else if (bmi < 24) category = "正常體重";
else if (bmi < 27) category = "過重";
else if (bmi < 30) category = "輕度肥胖";
else if (bmi < 35) category = "中度肥胖";
else category = "重度肥胖";
return { bmi: roundedBMI, category: category };
}
/**
*
* @returns {Object} - 推薦的餐廳列表
*/
function recommendFood() {
const restaurants = [
"鼎泰豐",
"添好運點心專門店",
"乾杯燒肉",
"藏壽司",
"涓豆腐",
"金子半之助",
"屋馬燒肉",
"貳樓餐廳",
"樂福餐廳",
];
// 隨機選擇3家餐廳
const shuffled = restaurants.sort(() => 0.5 - Math.random());
const selected = shuffled.slice(0, 3);
return { recommendations: selected };
}
/**
* 處理 AI 查詢
* @param {string} query - 客戶的查詢
* @returns {Promise<Object>} - 包含回答和相關數據
*/
async function processAIQuery(query) {
try {
// 定義可用的
const tools = [
{
type: "function",
name: "calculate_bmi",
description: "計算用戶的身體質量指數(BMI)",
parameters: {
type: "object",
properties: {
height: {
type: "number",
description: "用戶的身高(公分),例如 170",
},
weight: {
type: "number",
description: "用戶的體重(公斤),例如 65",
},
},
required: ["height", "weight"],
additionalProperties: false,
},
},
{
type: "function",
name: "recommend_food",
description: "隨機推薦幾家餐廳",
parameters: {
type: "object",
properties: {},
additionalProperties: false,
},
},
];
// 準備輸入
const input = [{ role: "user", content: query }];
console.log(`處理查詢: "${query}"`);
// 第一次 AI 回應
const response = await openai.responses.create({
model: "gpt-4o",
instructions: `你是一個助手,可以回答 BMI 計算和餐廳推薦的問題。
當用戶詢問 BMI 相關問題時,呼叫 calculate_bmi 。
當用戶詢問餐廳推薦時,呼叫 recommend_food 。
使用繁體中文回答,簡潔友善。`,
input,
tools,
tool_choice: "auto",
});
// 檢查是否有被呼叫
if (response.output && response.output.length > 0) {
// 檢查是否是 BMI 計算
const bmiCall = response.output.find(
(call) => call.name === "calculate_bmi"
);
if (bmiCall) {
// 計算 BMI
const args = JSON.parse(bmiCall.arguments);
const bmiResult = calculateBMI(args.height, args.weight);
// 將結果傳回 AI
input.push(bmiCall);
input.push({
type: "function_call_output",
call_id: bmiCall.call_id,
output: JSON.stringify(bmiResult),
});
// 獲取最終回答
const finalResponse = await openai.responses.create({
model: "gpt-4o",
instructions: "根據 BMI 數據回答問題,提供健康建議,提供純文字。",
input,
});
return finalResponse.output_text;
}
// 檢查是否是餐廳推薦
const foodCall = response.output.find(
(call) => call.name === "recommend_food"
);
if (foodCall) {
// 獲取餐廳推薦
const foodResult = recommendFood();
// 將結果傳回 AI
input.push(foodCall);
input.push({
type: "function_call_output",
call_id: foodCall.call_id,
output: JSON.stringify(foodResult),
});
// 獲取最終回答
const finalResponse = await openai.responses.create({
model: "gpt-4o",
instructions: "根據餐廳列表回答問題,介紹餐廳特色。",
input,
});
return finalResponse.output_text;
}
}
// 如果沒有呼叫,直接返回 AI 回答
return response.output_text;
} catch (error) {
console.error("處理查詢出錯:", error);
throw error;
}
}
// API 端點
app.post("/chat", async (req, res) => {
try {
const { message } = req.body;
if (!message) {
return res.status(400).json({ error: "請提供訊息內容" });
}
const answer = await processAIQuery(message);
if (!answer) {
return res.status(500).json({ error: "無法生成回答" });
}
res.json({ response: answer });
} catch (error) {
console.error("API 錯誤:", error);
res.status(500).json({ error: error.message || "處理查詢時發生錯誤" });
}
});
// 啟動伺服器
app.listen(PORT, () => {
console.log(`伺服器運行在 http://localhost:${PORT}`);
});
```

## 第二堂課程,介接天氣 API 做整合
