😈快速上手接入文心一言API

故事背景

前几天上线了自己的 web 终端项目 – https://www.weirdo-terminal.com/

由于后端是通过微信云托管部署的, 导致上线版本无法使用 chatGPT 服务, 啊 – 这样我也就放弃部署了


正好今天, 有位同志在我项目下提了一个问题

image-20231214221743543

我瞬间懵逼, 啊? 我咋没想到, 到官网看了看调用方法, 和 gpt 是差不多的。

那话不多说, 如何快速通过 Node.js 调用文心一言 API , 接下来你就知道咯~~

API 的调用流程如下图所示。

image-20231214221956120

  1. 创建一个千帆应用。根据实际需求创建千帆应用,创建成功后,获取AppID、API Key、Secret Key 等信息。
  2. API 授权。对应用的 AppID 进行授权。
  3. 获取接口访问凭证 access_token 。根据第1步获取的 API Key 和 Secret Key ,调用获取access_token接口获取 access_token ,通过 access_token 鉴权调用者身份。
  4. 调用API接口。例如调用ERNIE-Bot相关接口,详见API列表

登录

登录百度智能云千帆控制台。

注册并登录百度智能云千帆控制台

创建应用

创建千帆应用

进入控制台创建应用

image-20231214222138267

获取 key

创建应用后,获取AppID、API Key、Secret Key。

image-20231214222213748

上图则是我的 api key 和 secret key

得到 Access Token

这两个值的作用是用来获取 Access Token,Access Token 是调用文心 API 的必需参数。Access Token 是通过将 API Key 和 Secret Key 作为参数请求一个独立的接口得到。本文用 axios 作为 Node 端的网络请求库,下面的函数用来请求接口,拿到 token:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import axios from 'axios';

const API_KEY = '<API Key>';
const SECRET_KEY = '<Secret Key>';
const ACCESS_TOKEN_URL = 'https://aip.baidubce.com/oauth/2.0/token';

// 获取 access token
async function fetchAccessToken() {
const accessTokenRes = await axios.post(ACCESS_TOKEN_URL, null, {
params: {
'grant_type': 'client_credentials',
'client_id': API_KEY,
'client_secret': SECRET_KEY,
},
});
return accessTokenRes.data.access_token;
}

及时更新token

Access Token 的有效期是 30 天,需要及时更新,在一个需要持久运行的 Node 应用里,最好把 Access Token 和它对应的生成时间成对记录,以便在 token 过期之前及时更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 全局存储一个 access token -> 过期时间对象
let accessToken = {
expiredTime: 0,
value: '',
};

async function getAccessToken() {
if (accessToken.value && Date.now() < accessToken.expiredTime) {
return accessToken.value;
}
const token = await fetchAccessToken();
accessToken = {
expiredTime: Date.now() + 29 * 86400 * 1000, // 29 days
value: token,
};
return token;
}

接下来便是重头戏了, 调用文心一言的服务

调用 ERNIT-Bot API

千帆平台上有多个模型的 API 可以调用,不同 API 用到的参数比较类似,这里用最基本的 ERNIT-Bot API 来做示例。

Access Token 和对话信息是唯二的必填参数,前者以 query 的形式传入,后者则是作为 POST 请求体。

下面是一个简单的调用示例:

1
2
3
4
5
6
7
8
9
const CHAT_URL = 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions';

async function ask(question) {
const messages = [{ role: 'user', content: question }]
const token = await getAccessToken()
const res = await axios.post(CHAT_URL, { messages }, { params: { access_token: token } })
const { data } = res
return data
}

测试一下

1
2
3
4
5
6
7
async function main() {
const question = '我是最帅的!'
const res = await ask(question)
console.log(res)
}

main();

image-20231214223522188

可以看到,返回的内容里不仅包括回答的文本,还包括占用 token 数(与计费相关)、回答是否有被截断的等信息。

实现多轮对话

OpenAI API 多轮对话是通过维护一个固定 conversation id 的形式实现的,文心 API 则有所不同,要实现多轮对话,需要在调用接口时携带上之前所有的提问和回答。比如最开始我们提问了「把我接下来说的话都翻译成英文」,文心回答「好的,我会尽力把您接下来想要表达的内容翻译成英文。请随时告诉我您想要说的话。」,那么我们再一次提问的时候,message 参数就需要是:

1
2
3
4
5
[
{ role: 'user', content: '把我接下来说的话都翻译成英文' },
{ role: 'assistant', content: '好的,我会尽力把您接下来想要表达的内容翻译成英文。请随时告诉我您想要说的话。' },
{ role: 'user', content: '你好,我是一名程序员。' }
]

这里是通过每次加入一条前端传入的对话历史和当前请求的信息, 这样就能成功实现记忆功能

1
2
3
4
5
6
7
8
async function ask(memory, message) {
const token = await getAccessToken()
const messages = memory
messages.push({ role: 'user', content: message })
const res = await axios.post(CHAT_URL, { messages }, { params: { access_token: token } })
const { data } = res
return data.result
}

下面是前端的请求函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export const getBotOutput = async (message: string) => {
if (!message) return null
let botStore = useBotStore()
let { memory } = botStore
let res: any = await myAxios.post('/bot/get', { message, memory })
res = res.data
// 虽然后端也有添加消息记录的代码, 但是我们前端没有啊, 所以还是要加入
// 你可能会问 : 为什么不先加入一次记录, 然后拿到最新的memory发起请求呢? 这样可以少传一个message参数。
// 回答 : 测试过, 不行 ------- hhhh
botStore.addRecord({ role: 'user', content: message })
botStore.addRecord({ role: 'assistant', content: res })
return res
}

这个 res 就是我们获取的值了. 通过模板将回复的内容渲染到页面中即可。

image-20231214224540269

这样便能请求到文心一言服务啦~~

这是我的项目地址 ~~ https://github.com/2WeirDo/weirdo_terminal ~~ 感兴趣的朋友们欢迎star哦~ ⭐⭐⭐


😈快速上手接入文心一言API
http://example.com/2023/12/14/Node.js 接入文心一言 API/
作者
weirdo
发布于
2023年12月14日
更新于
2023年12月14日
许可协议