3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ComposeAI: マルチプラットフォーム対応ChatGPT類似アプリ、でもどうやって?その技術を大公開!

Posted at

はじめに

皆さん、ごきげんよう!れぶです!

今回の記事では、ChatGPTと類似したComposeAIというオープンソースアプリの解説をしていきます。

ぶっちゃけこのアプリを参考にすることで、ChatGPTのようなアプリをAndroidとiOS両方で作れてしまいます。なので、この記事ではComposeAIアプリの参考資料として技術的な概要を整理していきます

約7分以内で読めます。それでは、参りましょう!!

この記事の対象者

以下二つに当てはまる方に特に読んで頂きたいです。

  • ChatGPTのようなチャットボットアプリを、AndroidとiOS両方で同時に作りたい方
  • KotlinKMMに一通り精通してる方

Githubリポジトリ

設計概要

  • 対応OS

    • Android
    • iOS
  • 言語

    • Kotlin
  • アーキテクチャ

    • UI Layer/Data Layer
  • 使用技術

    • UI:Compose Multiplatform
    • ロジック:KMM
    • デザイン:Material 3
    • OpenAI APIクライアント:openai-kotlin
    • ナビゲーション:Voyager
    • DI:Koin
    • SQLiteデータベース:SQLDelight
    • キーと値のデータ保持:Multiplatform Settings
    • 画像表示:Im​​ageLoader
    • リソース生成:Libre
    • ログ:Napier
    • BuildConfig:BuildKonfig
    • Firebase:Analytics/Crashlytics
    • 広告:AdMob
  • 機能

    • オンボーディング画面の表示
    • プロンプトの入力
    • プロンプトに対する回答の生成
    • プロンプトに対する回答のコピー
    • プロンプトに対する回答のシェア
    • スレッドのタイトルの表示
    • スレッドの追加・選択・更新
    • Firebase連携
    • コインによる広告収益
  • 画面

    • オンボーディング
    • チャット
    • スレッド管理ドロワー

フォルダ構造

今回はロジックやUIが共通化されているshared/scrフォルダ内(一部省く)に絞って説明します。

commonMain

スクリーンショット 2023-07-01 18.08.20.png

commonMain/kotlin

フォルダ(ファイル)名 主な内容
analytics Firebase Analytics関連の処理やデータを定義
data ・アプリ内で扱うローカルとリモートのデータ関連
・DB操作/API通信処理を行うRepositoryを定義
di Koinライブラリによるモジュール定義
expect expectを付与したメソッドやプロパティを定義
extendedspans 表示するテキストの特定の部分における描画や動作方法を定義
markdown 出力結果をマークダウン形式で表現するためのデータや表示方法を定義
model アプリで扱うデータ構造を定義
ui オンボーディング画面/チャット画面を構成するUI(Composable関数)を定義
util expectを付与したユーティリティメソッドを定義
App.kt アプリのメインエントリーポイントとなるUI(Composable関数)を定義
AppScreenModel.kt ・画面(App.kt)の状態を管理
・ユーザーの選択に基づいて適切な画面を表示

commonMain/sqldelight

  • SQLDelightライブラリ関連
  • チャットとチャットメッセージのデータを操作するSQLを定義

androidMain/kotlin

スクリーンショット 2023-07-01 18.08.52.png

  • Android固有の実装を記述
  • commonMain/kotlin/のフォルダと対応
  • main.android.kt
    • commonMain/kotlin/App.ktで定義したComposable関数を呼び出し
    • システムUIの初期設定

iosMain/kotlin

スクリーンショット 2023-07-01 18.09.40.png

  • iOS固有の実装を記述
  • commonMain/kotlin/のフォルダと対応
  • main.ios.kt
    • commonMain/kotlin/App.ktで定義したComposable関数を呼び出し
    • ComposeUIViewControllerでUIKitやSwiftUI製のUIをComposeに変換
  • NapierProxy.kt
    • iOS専用のNapierを使用したログ設定

API処理

openai-kotlinを使用してAPIを叩くことで、AIモデルによる文章生成等を可能にしています。その応答結果をSQLDelightによってDB管理するのが、このチャットボットアプリの基本構造になっています。

例えば、以下のメソッドは指定されたチャット(スレッド)に対して適切なタイトルを生成します。openAI.chatCompletion(request)でAPIに対してチャットの完了リクエストを送信します。これにより、AIモデルからの応答が得られます。

shared/src/commonMain/kotlin/data/repository/ChatMessageRepository.kt
suspend fun generateTitleFromChat(
        chatId: String,
    ): Result<String> = suspendRunCatching(defaultDispatcher) {
        val instruction = ChatMessage(
            role = ChatRole.System,
            content = "What would be a short and relevant title for this chat? You must strictly answer with only the title, no other text is allowed.",
        )

        val messages = chatMessageQueries.getChatMessagesWithChatId(chatId)
            .executeAsList()
            .map(ChatMessageEntity::asModel)

        val request = ChatCompletionRequest(
            model = ModelId("gpt-3.5-turbo"),
            messages = messages + instruction,
        )

        val response = openAI.chatCompletion(request)
        response.choices.first().message?.content ?: "?"
    }

また、以下の処理はユーザーが入力したメッセージをAPIに送信し、それに対するAIモデルからの応答を取得して、逐次データベースに保存しています。chatCompletions()を呼び出すことで、Flow型のデータを受け取ることができます。

shared/src/commonMain/kotlin/data/repository/ChatMessageRepository.kt
// Create request to OpenAI
val request = ChatCompletionRequest(
    model = ModelId("gpt-3.5-turbo"),
    messages = messagesToSend,
)

// Get assistant response
var assistantMessage = ""

Try {
    // Sending request to OpenAI
    openAI.chatCompletions(request).collect { chunk ->
        chunk.choices.first().delta?.content?.let {
            assistantMessage += it
            chatMessageQueries.updateChatMessageContent(
                id = assistantMessageId,
                content = assistantMessage,
            )
        }
    }
    ...
}

おわりに

今回はComposeAIというChatGPT類似アプリに関して、技術的な概要を設計・フォルダ構成・API処理の観点からまとめていきました。

今回紹介したアプリの設計やコードを参考にすることで、ChatGPTのようなアプリをAndroidとiOS両方に対応して作れます。また、KotlinによるOpenAI APIの扱い方も参考になるかと思います。

この記事がAndroid開発者/iOS開発者にとって少しでも役立つと嬉しいです。ありがとうございました。

参考サイト

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?