GenieChat:使用 Genie API 构建 LLM 驱动的安卓应用

GenieChat:使用 Genie API 构建 LLM 驱动的安卓应用

本文档为开发人员提供了一份全面的指南,介绍如何使用 Genie API 构建一个功能强大的安卓聊天应用。我们将详细讲解 GenieChat 项目的关键组件,从基本设置到流式响应和 Markdown 渲染等高级功能。

1. 项目概述

GenieChat 是一个安卓应用,演示了如何通过 Genie API 与大型语言模型(LLM)集成。它拥有简洁、现代的用户界面,并支持实时流式响应,提供了无缝的交互式用户体验。

主要功能:

  • 实时聊天界面:一个熟悉、直观的聊天界面,用于与 LLM 进行交流。

  • 流式 API 集成:高效处理流式响应,实现即时反馈。

  • 可自定义的 API 设置:轻松配置 API 地址和模型参数。

  • 动态模型管理:随时添加、重命名和切换不同的 LLM 模型。

  • Markdown 渲染:以层级结构显示格式化的回复,增强可读性。


2. 用户界面

用户界面由一个主聊天屏幕和一个设置屏幕组成。

2.1. 主聊天屏幕

主屏幕(activity_main.xml)旨在提供流畅的聊天体验。它包括:

  • 一个 Toolbar,用于导航和访问设置。

  • 一个 RecyclerView,用于显示对话历史。

  • 一个输入区域,包含一个用于输入消息的 EditText 和一个用于发送的 FloatingActionButton

img_v3_02ra_3b0cb017-0011-4ca6-b95e-86b45b12504g.png

2.2. 设置屏幕

设置屏幕(activity_settings.xmlroot_preferences.xml)允许用户自定义应用的行为。主要设置包括:

  • API 地址:指定您的本地 Genie API 服务器的 IP 地址和端口。

  • 模型管理:动态添加、选择、重命名和删除模型。

  • 模型参数:调整 TemperatureTop PTop K,以微调 LLM 的响应。

img_v3_02rh_1ec27fbc-36bb-41dc-99c7-de8b4bc4192g.webp

3. 核心组件

3.1. MainActivity.java

这是应用的核心,负责:

  • 初始化 UI 组件,包括 RecyclerView 和输入框。

  • 管理消息列表并相应地更新 UI。

  • 处理用户输入并将消息发送到 Genie API。

  • 处理来自 API 的流式响应。

发送消息

当用户发送消息时,会调用 sendMessage() 方法。该方法将用户的消息添加到聊天中,然后触发 callChatApi()

调用 Genie API

callChatApi() 方法会构建一个包含模型名称、消息和其他参数的 JSON 请求体。然后,它使用 OkHttpClient/v1/chat/completions 端点发送 POST 请求。

// MainActivity.java 中 callChatApi() 的关键代码片段

JsonObject jsonBody = new JsonObject();
jsonBody.addProperty("model", modelName);
jsonBody.addProperty("stream", true); // 流式响应的关键

// ... 添加消息和其他参数 ...

RequestBody body = RequestBody.create(requestBodyString, JSON);
Request request = new Request.Builder()
        .url(apiUrl)
        .post(body)
        .build();

client.newCall(request).enqueue(new Callback() { ... });

处理流式响应

为了处理流式响应,应用在请求中设置了 "stream": true。然后,onResponse 回调会逐行读取响应,解析每个 JSON 数据块以提取内容,并将其追加到聊天的最后一条消息中。

// MainActivity.java 中 onResponse 的关键代码片段

try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseBody.byteStream()))) {
    String line;
    while ((line = reader.readLine()) != null) {
        if (line.startsWith("data:")) {
            String jsonData = line.substring(5).trim();
            if ("[DONE]".equals(jsonData)) {
                break;
            }
            // ... 解析 jsonData 并将内容追加到消息中 ...
        }
    }
}

3.2. MessageAdapter.java

MessageAdapter 负责将消息数据绑定到 RecyclerView。它为每条消息加载 item_message.xml 布局,并根据消息是由用户还是 AI 发送来设置文本和背景。

Markdown 渲染

为了增强 AI 回复的显示效果,我们集成了 Markwon 库。这使得应用能够渲染 Markdown 格式的文本,从而以结构化的方式显示标题、列表、粗体/斜体文本等。

集成发生在 MessageViewHolder 中:

// MessageAdapter.java 中 MessageViewHolder 的关键代码片段

void bind(Message message) {
    if (message.isSentByUser()) {
        textViewMessage.setText(message.getText());
        // ... 设置用户消息样式 ...
    } else {
        markwon.setMarkdown(textViewMessage, message.getText());
        // ... 设置 AI 消息样式 ...
    }
}

为了使用 Markwon,我们在 app/build.gradle 中添加了以下依赖:

// 在 app/build.gradle 中

dependencies {
    // ... 其他依赖
    implementation "io.noties.markwon:core:4.6.2"
    implementation "io.noties.markwon:ext-strikethrough:4.6.2"
}

3.3. 设置

设置由 SettingsActivity.javaSettingsFragment.javaroot_preferences.xml 管理。

  • SettingsActivity.java:一个托管 SettingsFragment 的简单 Activity。

  • SettingsFragment.java:此 Fragment 动态管理可用模型的列表。它允许用户添加、重命名、删除和选择模型,并将列表存储在 SharedPreferences 中。

  • root_preferences.xml:定义设置屏幕的布局,包括 API 地址和模型参数的首选项。

img_v3_02rh_2ed3f6b5-c902-44d4-96da-313a82ca086g.webp

4. 如何使用

  1. 设置您的 Genie API 服务器:确保您的本地 Genie API 服务器正在运行。

  2. 配置 API 地址

    • 启动 GenieChat 应用。

    • 导航到设置屏幕。

    • 点击“API 地址”并输入您服务器的 IP 地址和端口(例如,127.0.0.1:8910)。

  3. 管理模型

    • 在设置中,您可以看到默认模型(qwen2.0_7b)。

    • 点击“添加新模型”以添加您拥有的其他模型。

    • 点击列表中的任何模型以选择、重命名或删除它。

  4. 开始聊天

    • 返回主屏幕。

    • 输入您的消息并发送。

5. 源码及预编译apk下载

GenieChat.zip

app-release-1029.apk