VocabVerse谐音梗功能开发--第九周

本周我的主要工作是结合DeepSeek API进行单词谐音梗功能的开发,选取单词后由DeepSeek生成响应单词的谐音梗,协助用户记忆。

一、DeepSeek API的调用

1. HTTP 客户端配置:创建了一个 OkHttpClient 实例,配置了连接超时:60秒,读取超时:60秒

private val client = OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .readTimeout(60, TimeUnit.SECONDS)
    .build()

2. 创建核心方法:streamResponse。 使用 callbackFlow 构建器创建一个冷流(cold flow),当收集者开始收集时才会执行。在 IO 调度器上下文中构建了HTTP请求,并且创建了 EventSource 工厂,初始化了一个 StringBuilder 用于累积最终响应。

val payload = JSONObject().apply {
            put("model", model)
            put("messages", JSONArray().apply {
                put(JSONObject().apply {
                    put("role", "user")
                    put("content", prompt)
                })
            })
            put("temperature", 0.7)
            put("max_tokens", 1024)
            put("stream", true)
        }

        val request = withContext(Dispatchers.IO) {
            Request.Builder()
                .url(url)
                .header("Authorization", "Bearer $apiKey")
                .header("Content-Type", "application/json")
                .post(payload.toString().toRequestBody())
                .build()
        }

        val eventSourceFactory = EventSources.createFactory(client)

        val finalResponse = StringBuilder()  // 存储最终回复

3. 定义了一个匿名类实现 EventSourceListener,用于处理接收到的服务器发送事件、请求失败情况和连接关闭事件。

val eventSourceListener = object : EventSourceListener() {
            override fun onEvent(
                eventSource: EventSource,
                id: String?,
                type: String?,
                data: String
            ) {
                val trimmedData = data.trim()
                Log.d("DeepSeekDebug", "收到完整数据: $trimmedData")

                if (trimmedData == "[DONE]") {
                    // 请求结束时打印最终结果
                    Log.d("DeepSeekDebug", "请求完成,最终回复: $finalResponse")
                    close()
                    return
                }

                try {
                    val jsonObject = JSONObject(trimmedData)
                    val choices = jsonObject.getJSONArray("choices")
                    if (choices.length() > 0) {
                        val delta = choices.getJSONObject(0).getJSONObject("delta")
                        if (delta.has("content")) {
                            val content = delta.getString("content")
//                            finalResponse.append(content)  // 追加内容
                            trySend(content)  // 发送部分内容
                        }
                    }
                } catch (e: Exception) {
                    trySend("\n[解析错误] ${e.message}")
                }
            }

            override fun onFailure(
                eventSource: EventSource,
                t: Throwable?,
                response: Response?
            ) {
                trySend("\n[API请求错误] ${t?.message}")
                close(t)
            }

            override fun onClosed(eventSource: EventSource) {
                close()
            }
        }

 二、架构设计与实现

1. 功能流程图如下:

 2. 通过 prompt tuning(加入定向描述)约束模型输出格式 :

onClick = {
                    if (selectedWords.value.isNotEmpty()) {
                        val prompt = if (selectedWords.value.size == 1) {
                            "角色:你是一个幽默的语言大师,能够根据用户提供的英文单词,输出谐音梗,中英结合 \n" +
                                    "\n" +
                                    "要求 \n" +
                                    "1. 描述要详细、准确,充分展现单词意思。 \n" +
                                    "2. 语言生动、有趣,富有表现力。 \n" +
                                    "3. 输出中英文结合! \n" +
                                    "\n" +
                                    "限制 \n" +
                                    "1.不添加无关内容。你只需要回答谐音梗就行了,其他的东西一个字也不要说\n " +
                                    "如果你准备好了,请回答:\n"+
                                    "${selectedWords.value.first()}"
                        }
                        else {
                            "角色:你是一个幽默的语言大师,能够根据用户提供的英文单词,输出谐音梗,中英结合 \n" +
                                    "\n" +
                                    "要求 \n" +
                                    "1. 描述要详细、准确,充分展现单词意思。 \n" +
                                    "2. 语言生动、有趣,富有表现力。 \n" +
                                    "3. 输出中英文结合! \n" +
                                    "\n" +
                                    "限制 \n" +
                                    "1.不添加无关内容。你只需要回答故事就行了,其他的东西一个字也不要说\n " +
                                    "如果你准备好了,请回答"+
                                    "${selectedWords.value.joinToString("、")}"

                        }
                        viewModel.sendPrompt(prompt)

                        selectedWords.value = emptySet() // 查询后清空选择
                    }
                },
                modifier = Modifier.weight(1f).padding(start = 4.dp),
                enabled = selectedWords.value.isNotEmpty() && !viewModel.uiState.isLoading
            ) {
                Text("查询")
            }
        }

3.最终实现效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cherlin_zy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值