使用OkHttp流式请求OpenAI API(GPT API)接口
·
前言
因为 GPT 流式请求的出色交互体验,我们打算做一个开源基础应用,方便开发者快速集成项目。
本应用集成 ChatGPT API,使用模型为 gpt-3.5-turbo,项目代码为 Kotlin 语言开发的安卓应用。
人机交互的趋势已经到来,本应用框架也希望能帮助更多开发者快速集成 ChatGPT 体验到人机交互的乐趣!
正文
我们根据流式请求 Chat API 开源一个安卓项目,可方便开发者快速上手使用 开源地址
直接上核心代码,由 kotlin 编写
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.JsonObject
import okhttp3.*
import org.yameida.asrassistant.config.Config
import org.yameida.asrassistant.model.Message
import org.yameida.asrassistant.model.StreamAiAnswer
import java.io.BufferedReader
import java.io.IOException
import java.lang.Exception
object HttpUtil {
/**
* ChatGPT
*/
fun chat(send: String, callback: CallBack) {
val url = "https://api.openai.com/v1/chat/completions"
val apiKey = "Bearer ${Config.apiKey}"
val jsonObject = JsonObject()
jsonObject.addProperty("model", "gpt-3.5-turbo")
val body = RequestBody.create(MediaType.parse("application/json"), "{\n" +
" \"model\": \"gpt-3.5-turbo\",\n" +
" \"stream\": true,\n" +
" \"messages\": [{\"role\": \"user\", \"content\": \"$send!\"}]\n" +
"}")
val request: Request = Request.Builder().url(url).method("POST", body)
.addHeader("Authorization", apiKey)
.build()
OkHttpUtil.okHttpClient.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
ToastUtils.showLong("网络请求出错 请检查网络")
}
override fun onResponse(call: Call, response: Response) {
try {
val responseBody = response.body()
if (responseBody != null) {
val bufferedReader = BufferedReader(responseBody.charStream())
var line = bufferedReader.readLine()
var index = 0
val sb = StringBuilder()
while (line != null) {
val msg = convert(line, "1", index++)
if (msg != null) {
sb.append(msg.content)
callback.onCallBack(sb.toString(), false)
}
line = bufferedReader.readLine()
}
callback.onCallBack(sb.toString(), true)
}
} catch (e: Exception) {
e.printStackTrace()
ToastUtils.showLong("网络请求出错 请检查配置")
}
}
})
}
fun convert(answer: String, questionId: String, index: Int): Message? {
val msg = Message()
msg.content = ""
msg.messageType = "normal"
msg.id = questionId
if ("data: [DONE]" != answer) {
val beanStr = answer.replaceFirst("data: ", "", false)
val aiAnswer = GsonUtils.fromJson(beanStr, StreamAiAnswer::class.java) ?: return null
val choices = aiAnswer.choices
if (choices.isEmpty()) {
return null
}
val stringBuffer = StringBuffer()
for (choice in choices) {
if (choice.finish_reason != "stop") {
if (choice.delta.content != null) {
stringBuffer.append(choice.delta.content)
} else {
return null
}
}
}
msg.content = stringBuffer.toString()
if (index == 0) {
if (msg.content == "\n\n") {
LogUtils.e("发现开头有两次换行,移除两次换行")
return null
}
}
} else {
msg.type = "stop"
}
msg.index = index
return msg
}
interface CallBack {
fun onCallBack(result: String, isLast: Boolean)
}
}
// 使用方法
HttpUtil.chat(result, object : HttpUtil.CallBack {
override fun onCallBack(result: String, isLast: Boolean) {
runOnUiThread {
//更新数据或UI
updateData()
}
}
})
总结
至此,你应该已经完成了Chat机器人智能问答对接,一个智能QA机器人就实现了,后续我会继续进行AI能力的扩展,如多模态等。喜欢本文可以给开源项目一个 star~有问题可以留言或私信我。
更多推荐
已为社区贡献8条内容
所有评论(0)