当前位置: 首页 > ds >正文

安卓接入通义千问AI的实现记录

官网:https://help.aliyun.com/zh/model-studio/use-qwen-by-calling-api#b1320a1664b9a

创建网络请求

  1. 创建一个BaseNetworkApi基类用于实现各种拦截器等。
abstract class BaseNetworkApi {fun <T> getApi(serviceClass: Class<T>, baseUrl: String): T {val retrofitBuilder = Retrofit.Builder().baseUrl(baseUrl).client(okHttpClient)return setRetrofitBuilder(retrofitBuilder).build().create(serviceClass)}/*** 实现重写父类的setHttpClientBuilder方法,* 在这里可以添加拦截器,可以对 OkHttpClient.Builder 做任意操作*/abstract fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder/*** 实现重写父类的setRetrofitBuilder方法,* 在这里可以对Retrofit.Builder做任意操作,比如添加GSON解析器,Protocol*/abstract fun setRetrofitBuilder(builder: Retrofit.Builder): Retrofit.Builder/*** 配置http*/private val okHttpClient: OkHttpClientget() {var builder = RetrofitUrlManager.getInstance().with(OkHttpClient.Builder())builder = setHttpClientBuilder(builder)return builder.build()}
}
  1. 完成BaseNetworkApi的具体实现类。
val aiService : AiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {AiApi.INSTANCE.getApi(AiService::class.java, AiService.getBaseUrl())
}class AiApi : BaseNetworkApi() {companion object {val INSTANCE: AiApi by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {AiApi()}}/*** 实现重写父类的setHttpClientBuilder方法,* 在这里可以添加拦截器,可以对 OkHttpClient.Builder 做任意操作*/override fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder {builder.apply {//设置缓存配置 缓存最大10Mcache(Cache(File(appContext.cacheDir, "cxk_cache"), 10 * 1024 * 1024))//添加Cookies自动持久化cookieJar(cookieJar)addInterceptor(AiInterceptor())//超时时间 连接、读、写connectTimeout(10, TimeUnit.SECONDS)readTimeout(120, TimeUnit.SECONDS)writeTimeout(30, TimeUnit.SECONDS)}return builder}/*** 实现重写父类的setRetrofitBuilder方法,* 在这里可以对Retrofit.Builder做任意操作,比如添加GSON解析器,protobuf等*/override fun setRetrofitBuilder(builder: Retrofit.Builder): Retrofit.Builder {return builder.apply {addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))}}val cookieJar: PersistentCookieJar by lazy {PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(appContext))}}
  1. 在AiInterceptor完成公共Header的添加。
class AiInterceptor : Interceptor {@Throws(IOException::class)override fun intercept(chain: Interceptor.Chain): Response {val builder = chain.request().newBuilder()builder.addHeader("Authorization", "Bearer sk-xxxxxxxxxxxxxxxxxxxx")builder.addHeader("Content-Type", "application/json").build()return chain.proceed(builder.build())}
}

此处的Key可在阿里云百炼自行申请。

  1. 通过第三方框架retrofit2完成网络请求注解。

interface AiService {companion object {fun getBaseUrl(): String {return "https://dashscope.aliyuncs.com"}}@POST("compatible-mode/v1/chat/completions")suspend fun askQuestion(@Body request: AiRequest): AiResponse<List<Choice>>
}@Keep
data class AiResponse<T>(val error: Error?, val choices: T) : BaseResponse<T>() {override fun isSucces() = error ==  nulloverride fun getResponseCode(): Int {return if (error == null) {200} else {400}}override fun getResponseData() = choicesoverride fun getResponseMsg(): String {return error?.message?: ""}
}data class Error(val message: String?, val type: String?, val param: String?, val code: String?)data class Message(var role: String?, var content: String?)data class Choice(var message: Message?,  var finish_reason: String?,  var index: Int?)data class AiRequest(var model: String?, var messages: List<Message>?, var stream :Boolean? = false)
@Keep
abstract class BaseResponse<T> {abstract fun isSucces(): Booleanabstract fun getResponseData(): Tabstract fun getResponseCode(): Intabstract fun getResponseMsg(): String}
  1. 在需要的地方直接调用即可,亦可编辑请求类对异常情况进行处理。
val message = Message("user", "你好")val messageList = ArrayList<Message>()messageList.add(message)val request1 = AiRequest("qwen-max", messageList)val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)scope.launch  {val response = aiService.askQuestion(request1)Log.d("AI-test", response.toString())}

在这里插入图片描述

  1. 实现效果如下。

在这里插入图片描述

  1. 遇到的问题

● 在请求时,报java.net.SocketTimeoutException: timeout

遇到的 java.net.SocketTimeoutException: timeout 是网络请求超时问题,在调用阿里通义千问API时很常见。以下是建议方案:

① 增加超时时间配置

            connectTimeout(10, TimeUnit.SECONDS)readTimeout(120, TimeUnit.SECONDS)writeTimeout(30, TimeUnit.SECONDS)

② 网络状态检查
③ 使用 qwen-turbo,响应速度最快

http://www.xdnf.cn/news/19050.html

相关文章:

  • 欧盟《人工智能法案》生效一年主要实施进展概览(二)
  • React 组件命名规范:为什么必须大写首字母蛊傲
  • 【Datawhale之Happy-LLM】Encoder-only模型篇 task05精华~
  • 计算神经科学数学建模编程深度前沿方向研究(下)
  • 医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(一)
  • 卷积神经网络CNN
  • Xposed框架实战指南:从原理到你的第一个模块
  • 面试之JVM
  • Java并发编程深度解析:从互斥锁到StampedLock的高性能锁优化之路
  • 计算机视觉:从 “看见” 到 “理解”,解锁机器感知世界的密码
  • 嵌入式(day34) http协议
  • 快速了解卷积神经网络
  • 【软考论文】论DevOps及其应用
  • C#由Dictionary不正确释放造成的内存泄漏问题与GC代系
  • 红黑树下探玄机:C++ mapmultimap 的幕后之旅
  • Java大厂面试实录:从Spring Boot到Kubernetes的全链路技术突围
  • 【数据结构】单链表详解
  • Linux系统网络管理学习.2
  • Wireshark捕获数据的四种层次
  • IUV5G专网排障(下)
  • git submodule的基本使用
  • 【软考论文】论领域驱动开发方法(DDD)的应用
  • 为什么的中小企业很难承受“大型系统”的成本
  • 基于 MediaPipe + Three.js 的实时姿态可视化前端
  • 论文阅读:CIKM 2024 Empowering Private Tutoring by Chaining Large Language Models
  • 【7】SQL 语句基础应用
  • 运算符(2)
  • AT_abc401_f [ABC401F] Add One Edge 3
  • 传统联邦 VS 联邦+大模型
  • 学习做动画4.回转运动