- 作者:老汪软件技巧
- 发表时间:2024-09-06 07:02
- 浏览量:
前言
ChatGPT问世已经两年了, 因为有些功能确实好用,如询问编程问题,生成创意广告文案/总结文章,文生图,文生视频,图形问题识别等,所以ChatGPT类的AI问答工具,如雨后春笋般冒出来。这么多人都做出来这个功能,说明AI问答类的技术壁垒应该不高,笔者也跃跃欲试,想开发一个极简版的AI对话功能。说干就干,到底选哪个大模型了实现AI对话功能呢? 自己平时用的最多的大模型是通义千问,因为它回答编程问题,比百度,字节,科大讯飞的大模型更精准,那就选它吧。现在我们进入今天的正题
第一步 获取API-Key和开通模型服务注册登录阿里云:前往阿里云官网,注册并使用你的账号登录阿里云(Tips: 如果你觉得注册麻烦,可以使用支付宝账号扫描登录).
创建API密钥:进入主页面之后,在顶部的菜单搜索栏, 输入百炼,点击搜索出来的大模型服务平台百炼
进入大模型服务平台百炼后接着点击管理控制台
点击查看我的API-KEY,创建一个API密钥,这个密钥用于调用大模型接口时的身份验证和计费
接着点击创建API KEY按钮,进入创建API KEY弹窗页面
描述不是必填项,可以不填,直接点击确定即可
可以看到,API KEY已经创建好了。
要想使用大模型,光有API KEY不行,还得开通模型服务。
开通模型服务时默认是开通所有。模型有好多种类型:如文本生成,图像生成,语音合成与识别,视频合成,向量(将文本、图像、语音转换成一组数字,适用于音视频分类、图像分类、图文检索等),特定行业(适用于法律咨询、案例分析和法规解读等)。
模型既有阿里自研的:如支持通用文本生成模型、、、超长文档模型以及视觉理解(图生文)模型。也支持开源版本的通用文本生成模型、、。也有第三方的:如、、、等第三方模型。
点开《模型管理服务协议》,协议内容比较长,重点看一下有关收费的条款。点击同意模型协议。
模型更详细的收费信息在模型广场==>某种模型==>查看详情中查找,一般都有免费的额度用于新模型的练手学习。
开通模型服务时又弹出提示要进行实名认证,用支付宝进行实名认证
到此,调用大模型的前置工作都已经准备好了,现在我们来编写调用程序。
第二步 编写调用代码
1.安装openai
pnpm add openai
千问大模型支持使用openAI的API调用自身。在使用 OpenAI 的 API 时,可以通过传递各种参数来控制生成内容的方式和行为。以下是常见的 OpenAI API 参数及其含义:
名称含义示例
apiKey
API 密钥,用于身份验证和授权访问 OpenAI 服务
apiKey: "YOUR_API_KEY"
baseURL
自定义 API 的基础 URL,通常用于指定 OpenAI 服务的访问点
baseURL:
temperature
控制生成的输出的随机性。值范围为 0 到 1。较低的值(如 0.2)会使输出更确定和保守,而较高的值(如 0.8)会增加生成内容的多样性。
temperature: 0.7
maxTokens
控制生成内容的最大长度,以 token 数量为单位(一个 token 约为一个词的一部分)
maxTokens: 150
topP
核采样策略的参数。值范围为 0 到 1。它与 temperature 类似,控制生成内容的多样性,但通过限制累积概率的方式来选择输出。
topP: 0.9
指定要生成多少个独立的响应
n: 1
stop
一个或多个字符串,用于指定生成应在何处停止。这些字符串会标识输出的截断点。
stop: ["\n", "###"]
presencePenalty
控制生成输出中是否引入新主题的倾向。较高的值会鼓励生成新的主题。
presencePenalty: 0.6
frequencyPenalty
控制模型生成输出时避免重复相同内容的倾向。较高的值会减少重复。
frequencyPenalty: 0.5
logitBias
用于调整特定 token 在生成中的出现概率。可以通过将某些 token 的概率降低来减少其出现频率。
logitBias: {"50256": -100}
配置 API Key 到环境变量
API Key不能以明文外泄到代码中,通常都是通过环境变量来访问。
# 用你的 API Key代替引号中的内容,引号要保留
export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
#使环境变量生效
source ~/.bashrc
# 检查环境变量是否生效
echo $DASHSCOPE_API_KEY
调用大模型 API
创建一个index.js文件,添加如下代码:
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
});
async function main() {
const completion = await openai.chat.completions.create({
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "你是谁?" },
],
model: "qwen-max",
});
console.log(completion.choices[0]["message"]["content"]);
}
main();
在package.json中指明使用esModule语法导入依赖包
{
"type": "module",
"dependencies": {
"openai": "^4.57.1"
}
}
运行结果如下: 可以看到,返回正确。
第三步 改造成Web版
为了能从环境变量中读取API KEY,我们需要创建一个node项目。这里选择创建一个基于vite构建工具的node项目。
pnpm create vite
项目package.json的内容如下,要将上一步的openai添加到运行时依赖包中。
{
"name": "ali-chat",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"openai": "^4.57.1"
},
"devDependencies": {
"vite": "^5.4.1"
}
}
创建好项目之后, 安装依赖,为了能在网页端访问到API KEY环境变量,需要在vite.config.js中进行定义,此外,在本地请求通义千问的api时,浏览器会提示会跨域,需要添加一条代理转发配置。
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
server: {
host: "0.0.0.0",
hmr: true,
proxy: {
"/compatible-mode/v1": {
target: "https://dashscope.aliyuncs.com",
changeOrigin: true,
secure: false,
},
},
},
define: {
"process.env": {
DASHSCOPE_API_KEY: process.env.DASHSCOPE_API_KEY,
},
},
});
创建一个简单的 HTML 页面,上方是对话内容显示区域,下方是对话内容输入区和发送按钮
html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>通义千问聊天AItitle>
<style>
.chat-content {
margin: 10px 0;
}
.user-input {
display: block;
margin: 20px 0;
}
style>
head>
<body>
<div id="chat-box">
div>
<textarea class="user-input" id="user-input" rows="4" cols="50" placeholder="请输入您的问题"> textarea>
<button id="send-button">发送button>
<script type="module" src="./src/chat.js">script>
body>
html>
接着编写对话功能,首先配置OpenAI基础参数, 与服务端调用配置相比,要多加一个参数dangerouslyAllowBrowser: true,不然控制台会产生告警。要想实现持续的对话,每次响应的要做为下一次请求中的 messages 的一部分,从而维持对话的上下文。在 messages 数组中设置第一条消息的 role 为 "system" 而非 "assistant" 是为了设定对话的上下文和基调,而不是直接提供助手的回复。"system" 消息用于设定助手的行为、风格、规则或限制。system 消息可以在对话开始时提供指导,使助手能够更好地理解用户的意图和上下文,通过这样做,可以影响助手在接下来的对话中如何生成回复,从而更好地匹配用户的预期。点击发送按钮事件回调和更新内容区域的功能比较简单,一看就懂,这里不再赘述。chat.js的完整内容如下:
// 引入 OpenAI 的 API 客户端库
import OpenAI from "openai";
// 绑定发送按钮事件
document.getElementById("send-button").addEventListener("click", () => {
const userInput = document.getElementById("user-input").value;
if (userInput.trim()) {
sendMessage(userInput);
document.getElementById("user-input").value = ""; // 清空输入框
}
});
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
dangerouslyAllowBrowser: true, // 允许在浏览器中使用 API
baseURL: "http://localhost:5173/compatible-mode/v1",
});
// 存储对话的上下文
let messages = [{ role: "system", content: "You are a helpful assistant." }];
// 处理发送消息
async function sendMessage(userInput) {
// 将用户的消息添加到对话上下文中
messages.push({ role: "user", content: userInput });
try {
// 调用 OpenAI 的 chat completion 接口
const response = await openai.chat.completions.create({
model: "qwen-max", // 使用的模型
messages: messages,
});
// 获取助手的回复
const assistantMessage = response.choices[0].message.content;
// 将助手的回复添加到对话上下文中
messages.push({ role: "assistant", content: assistantMessage });
// 更新对话显示区域
updateChatBox(userInput, assistantMessage);
} catch (error) {
console.error("Error during API call:", error);
}
}
// 更新对话显示区域
function updateChatBox(userMessage, assistantMessage) {
const chatBox = document.getElementById("chat-box");
// 添加用户消息
const userDiv = document.createElement("div");
userDiv.classList.add("chat-content");
userDiv.textContent = `用户: ${userMessage}`;
chatBox.appendChild(userDiv);
// 添加助手消息
const assistantDiv = document.createElement("div");
userDiv.classList.add("chat-content");
assistantDiv.textContent = `助手: ${assistantMessage}`;
chatBox.appendChild(assistantDiv);
// 滚动到最新的消息
chatBox.scrollTop = chatBox.scrollHeight;
}
AI对话功能开发完了, 现在我们调试一下,看看效果。执行yarn dev,启动界面
输入问题,这是问答效果,界面比较简陋,但核心功能已经有了。至此我们已经实现了web版的AI对话功能。
最后
简易Web版的AI问答功能开发出来了, 可是如果按token收费,调用成本偏高。要想真正商用的话,可能采用国外/国内开源的大模型,在本地部署一个大模型服务更佳。如何在本地部署一个大模型,这是另一个有探索价值的课题。下一篇我们就讲讲如何在本地部署大模型。