【原创】使用Kotlin代码调用扣子智能体Agent Api完成对话功能
本文介绍了如何使用Kotlin和OKHttp调用扣子AI智能体的API接口。主要内容包括:1.创建服务令牌获取访问凭证;2.创建并发布智能体;3.通过三个接口完成调用流程(chat创建会话、retrieve查询状态、message/list获取结果)。重点讲解了API调用的完整流程、参数设置和状态检查机制,并提供了关键代码示例。作者指出官方文档将重要流程图放在"最佳实践"部分,
前言
我想要用代码中调用扣子的智能体帮我完成点事,我可不想每次都到页面上去调用查看结果,并想在代码中使用,可是要完成这个功能并不简单。
本篇使用Kotlin配合OKhttp进行调用,主要还是写起来爽。
免责声明:
写本篇博客时扣子版本为2025年7月18日,如果后面有更新,不能保证这篇博客中的内容还能正常使用。
创建令牌
进入扣子的控制台,找到扣子API,点击授权,在服务身份及凭证处创建一个令牌,不建议使用个人访问令牌,因为一个月就过期了,没人想每个月都更新一遍令牌吧。

创建智能体
这个就不用多说了,按照自己想法自己创建一个智能体就行了

由于我要的功能比较简单,只需要插件,都不需要工作流,因此我这边就不详细说明了,创建完成后记得要发布才行,不然会无法拿到bot_id,导致无法进行API调用。
注意!发布的时候需要勾选API,否则可能无法通过API调用

API调用
最重要的一步就是通过API调用接口了,扣子官方文档里其实有说调用接口的过程

一共涉及到3个接口,只需要按照这个流程图调用即可
调用chat接口
第一步调用chat接口,创建聊天,注意!这个聊天返回的数据中不包含任何聊天结果,其中返回体中的msg不是聊天结果数据,而且接口是否异常的数据,只有在code不等于0时即接口报错时msg才会有结果

chat接口调用代码如下:
ChatBo是入参信息,我后面会给代码,secretKey就是令牌中的数据,conversation_id是上一次对话的对话id。由于这里的智能体调用是个耗时操作,因此我将整个过程都放在线程池中进行操作了
fun chat(chatBo: ChatBo, onSuccess: (resultVo: ChatResultVo) -> Unit, onFail: (e: Exception) -> Unit) {
retrieveRetryCount = 0
CozeThreadPool.threadPool.submit {
val requestJson = JSON.toJSONString(chatBo)
val toRequestBody = requestJson.toRequestBody("application/json".toMediaType())
var url = "https://api.coze.cn/v3/chat"
chatBo.conversationId?.also {
url = "https://api.coze.cn/v3/chat?conversation_id=$it"
}
val request = Request.Builder().url(url)
.header("Authorization", "Bearer $secretKey")
.header("Content-Type", "application/json")
.post(toRequestBody)
.build()
val call = okHttpClient.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
onFail(e)
}
override fun onResponse(call: Call, response: Response) {
try {
retrieve(response, onSuccess, onFail)
} catch (e: Exception) {
onFail(e)
}
}
})
}
}
ChatBo
这个就是我的入参信息,代码如下:
class ChatBo {
@JSONField(name = "additional_messages")
var additionalMessages = ArrayList<AdditionalMessage>()
@JSONField(name = "user_id")
var userId: String? = null
var stream = false
@JSONField(name = "bot_id")
var botId: String? = null
@JSONField(name = "auto_save_history")
var autoSaveHistory = true
var conversationId:String? = null
}
class AdditionalMessage {
var role = "user"
@JSONField(name = "content_type")
var contentType = "text"
@JSONField(name = "meta_data")
var metaData: HashMap<String, String>? = null
var type: String? = null
var content: String? = null
}
实际就是接口文档中的请求数据,其中要完成这个功能,autoSaveHistory必须为true,stream必须为false
additionalMessages必填,需要传入的对话内容在其中的content中。
userId必填,但是可以随便写。
botId就是你的智能体的id,可以在页面的URL中找到。
conversationId为上一次对话id,选填。
调用retrieve接口
这个接口用于查看对话信息,查看这个对话ai是否正在生成结果,代码如下:
其中conversationId和chatId能在上一个chat接口的返回值中拿到,用于查询这里的状态,主要就是判断返回值中的status是否为completed,如果是progress状态则需要再次请求,我这里偷懒直接使用递归调用了,限制调用10次,超出次数则直接报错,不再执行。
private fun retrieve(response: Response, onSuccess: (resultVo: ChatResultVo) -> Unit, onFail: (e: IOException) -> Unit) {
response.body?.string()?.let {
println(it)
val chatVo = JSON.parseObject(it, ChatVo::class.java)
if (chatVo.code != 0L) {
error("code not null, message is ${chatVo.msg}")
}
chatVo
}?.let {
it.data?.let {
val chatId = it.id ?: throw RuntimeException("chat_id is null")
val conversationId = it.conversationId ?: throw RuntimeException("conversation_id is null")
retrieveData(conversationId, chatId, onSuccess, onFail)
}
} ?: run {
error("chat_data is null")
}
}
private fun retrieveData(
conversationId: String,
chatId: String,
onSuccess: (resultVo: ChatResultVo) -> Unit,
onFail: (e: IOException) -> Unit
) {
val retrieveRequest = Request.Builder().url("https://api.coze.cn/v3/chat/retrieve?conversation_id=${conversationId}&chat_id=${chatId}")
.header("Authorization", "Bearer $secretKey")
.header("Content-Type", "application/json")
.get()
.build()
val retrieveCall = okHttpClient.newCall(retrieveRequest)
retrieveCall.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
onFail(e)
}
override fun onResponse(call: Call, response: Response) {
response.body?.string()?.let {
val retrieveVo = JSON.parseObject(it, RetrieveVo::class.java)
retrieveVo.code?.let {
if (it != 0L) {
error("code not null, message is ${retrieveVo.msg}")
}
}
retrieveVo.data?.let {
it.status?.let {
if (it == "completed") {
// INFO: Zhouwx: 2025/7/18 如果是已完成的,则进入下一步,否则继续请求,直到已完成为止
listMessage(conversationId, chatId, onSuccess, onFail)
} else {
Thread.sleep(2000)
retrieveRetryCount++
if (retrieveRetryCount > 10) {
error("retrieve_retry_count > 10")
} else {
retrieveData(conversationId, chatId, onSuccess, onFail)
}
}
}
}
} ?: run {
error("retrieve data is null")
}
}
})
}
调用message list接口
这是本篇博客的最后一步了,在这一步可以使用ai返回的结果了
代码如下:
private fun listMessage(conversationId: String, chatId: String, onSuccess: (messageList: ChatResultVo) -> Unit, onFail: (e: IOException) -> Unit) {
val listMessageRequest = Request.Builder().url("https://api.coze.cn/v3/chat/message/list?conversation_id=${conversationId}&chat_id=${chatId}")
.header("Authorization", "Bearer $secretKey")
.header("Content-Type", "application/json")
.get()
.build()
val listMessageCall = okHttpClient.newCall(listMessageRequest)
listMessageCall.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
onFail(e)
}
override fun onResponse(call: Call, response: Response) {
response.body?.string()?.let {
val listMessageVo = JSON.parseObject(it, MessageListVo::class.java)
listMessageVo.data?.let {
val chatResultVo = ChatResultVo()
chatResultVo.conversationId = conversationId
chatResultVo.messageList = it
chatResultVo.detail = listMessageVo
onSuccess(chatResultVo)
}
}
}
})
}
}
要说明一下,这里的ChatResultVo有点复杂,其中包含了多个内容,甚至包含了考虑过程信息,取data[0]中的content即可,就是智能体返回的结果数据。
结语
一开始对着这堆API研究了半天,就是不出数据,没想到官方把流程图等信息放在最佳实践里了,这个调用流程才迎刃而解,我也是服了,具体完整代码我在下方开源了,大家可以看一下,只是一个demo而已,写得有点潦草,请多包涵!
项目地址:
更多推荐



所有评论(0)