GPT3模型已经开放了通过API访问生成文本的功能,这样可以把GPT3类型的自然语言预训练大模型的能力集成进自己的应用系统中,提供自然语言AI处理的能力,比如客服与咨询等,如果在训练语料中加入专业领域的语料,比如大量的行业法律法规与案例或场景处理等,可以把行业客服与咨询机器人的水平直接从智障一级提升到智能一级,应用前景还是很广的,因此同类技术的在研平台可以参考。这个技术框架下,AI是智障还是智能,取决于它训练的语料,在这一点上,母语科技公司还是有非常大的优势的。
GPT3模型官方目前提供了Python与Node.js两种API SDK,开源社区提供了R、Java、C#等各种语言的API SDK,具体可以参阅OpenAI的官方文档。Node.js用于在浏览器网页中直接通过Javascript来调用,本篇用Python API,通过R语言的Shiny APP来封装对它的调用。参考的是OpenAI Playground上的chat例子。
需要注意测是GPT3与ChatGPT是两个不同的大模型,虽然它们的技术框架与基础相同,但训练的语料与优化的方向不同,GPT3面向多领域在预测准确性上进行优化,ChatGPT面向聊天进行优化,OpenAI官方说ChatGPT的API很快也会开放提供。
最近在开两会,不能访问OpenAI API的服务端口了,所以这个APP只是在笔记本上演示的开发版本。云端Linux服务器上虽然也部署了,不过暂时是用不了的。
下面看看它具体的实现。
1、ChatGPT.py。Python API访问OpenAI API的脚本,在Shiny APP中调用。
import openai
# 郑重提示:纯粹技术研究,请在法律法规范围内谨慎受控使用,勿用于违法用途,责任自负。
# Setup proxy for accessing OpenAI API server through VPN on Linux if it is needed.
# Need to down grade urllib3 to older version when access through VPN.
# pip install urllib3==1.25.11
import os
os.environ['http_proxy']="http://127.0.0.1:7890"
os.environ['https_proxy']="http://127.0.0.1:7890"
openai.api_key = 'Your OpenAI Access Key'
start_sequence = "\nAI: "
restart_sequence = "\nHuman: "
def CallAPI(prompt, tokens):
response = openai.Completion.create(
model="text-davinci-003",
prompt=prompt,
temperature=0.9,
max_tokens=tokens,
top_p=1,
frequency_penalty=0,
presence_penalty=0.6,
stop=[" Human:", " AI:"]
)
return response["choices"][0]["text"]
使用之前要先按安装OpenAI API的Python接口软件包。
pip install openai
下面是Shiny APP的几个文件。
2、global.R。加载上面的Python脚本以提供对OpenAI API的访问。Linux服务器上要修改为脚本存放的相应路径。
library(reticulate)
library(stringr)
# Load OpenAI API
print(getwd())
path<- "C:/Users/Jean/Documents/Python Scripts/OpenAI/ChatGPT.py"
print(path)
source_python(path)
3、ui.R,定义了聊天机器人的UI界面。
fluidPage(
sidebarLayout(
# Sidebar
sidebarPanel(
# Application title
tags$h3("GPT-3 聊天机器人"),
sliderInput("tokens",
"最大输出单词数:",
min = 1000, max = 5000, value = 500),
checkboxInput("ifContext","是否包括上下文:", value = TRUE),
actionButton("clearContext", "清除上下文", class = "btn-cleear"),
# 1/6
# width = 2
),
# Main
mainPanel(
textAreaInput("context","对话记录",width="100%", rows =20, resize="vertical", value =""),
# 插入javascript,禁止自己修改 context textAreaInput
tags$script(HTML("
var context = document.getElementById('context');
context.readOnly = true;
")),
tags$h6(" "),
textAreaInput("prompt","输入:",width="100%", rows =2, resize="vertical", value =""),
actionButton("sendout", "提交", class = "btn-success"),
# 5/6
# width = 10
)
)
)
4、server.R,在Shiny Server端处理对OpenAI的调用,维持用户对话的上下文,放入session用户变量中。另外在问题和回答前加上对话双方身份提示的前缀。
function(input, output, session) {
tokens<- reactive({
input$tokens
})
ifContext<- reactive({
input$ifContext
})
prompt<- reactive({
paste("Human: ",input$prompt, sep='')
})
observeEvent(input$clearContext,{
session$userData$context<- ""
updateTextAreaInput(session, "context", value = session$userData$context)
})
observeEvent(input$sendout,{
if(ifContext() && ! is.null(session$userData$context)){
session$userData$context<- paste(session$userData$context,prompt(),sep="\n\n")
} else{
session$userData$context<- prompt()
}
# Show notification while querying.
id <- showNotification("正在询问GPT-3...", duration = NULL, closeButton = FALSE)
on.exit(removeNotification(id), add = TRUE)
response<- CallAPI(session$userData$context, tokens())
index<-str_locate(response,":")
response<-str_sub(response,index[1]+1,str_length(response))
response<-paste("AI:",response,sep='')
session$userData$context<- paste(session$userData$context, response, sep="\n")
updateTextAreaInput(session, "context", value = session$userData$context)
updateTextAreaInput(session, "prompt", value = "")
})
}
That's all, 一共不到100行代码,是不是很简单呢?
需要注意的是OpenAI API现在还没有提供维持对话上下文的API,所以对话上下文的实现实际上是把整个对话的上下文拼接成字符串,整个作为输入,后续的版本大概会提供维持上下文功能的API吧。
这个简单的例子也展示了R与Python如何像人的左手和右手一样,互相配合,共同完成一个让人印象深刻的任务,他们真的是可以互相成就的。Shiny 浏览器界面的好处是,大屏小屏通用,程序写一次就可以了,不禁让人回想起了互联网刚开始普及的年代,大家在浏览器网络聊天室里热聊的情景,20年过去,Cyber空间已经沧海桑田。