【OpenAI】API プロンプトトークン数(利用料金)をカウントする

通常のAPIリクエストではレスポンスボディに利用トークンのカウント数は含まれる。


"usage": {
   "prompt_tokens": 9,
   "completion_tokens": 12,
   "total_tokens": 21
 }

👉 API Reference - OpenAI API hatena-bookmark

しかし「Server-Sent Events(SSE)」では、それをレスポンスで返さない。



👉 【OpenAI】Kotlin OkHttp で Server-Sent Events (SSE) hatena-bookmark

従量制のAPIを利用している限り料金は気になりますよね。

プロンプトのトークンの数をアプリ側で独自にカウントすれば料金(利用トークン数から)は算定できるのでは?

 

🤖 JTokkit

Java のライブラリありますね。OpenAI公式でも紹介されているやつ。


👉 openai-cookbook/How_to_count_tokens_with_tiktoken.ipynb at main · openai/openai-cookbook · GitHub hatena-bookmark

豊富な Java ライブラリを使えるのは Kotlin の便利なところです。

👉 Counting Tokens for ChatML | JTokkit hatena-bookmark

とりあえずテストで動かしてみます。


dependencies {
  testImplementation 'com.knuddels:jtokkit:0.4.0'
}


@Test
fun test_jtokkit() {

  val messages = listOf(
    Message("user", "こんにちはと言ってください。"),
    Message("assistant", "こんにちは!")
  )

  val encoding = Encodings.newDefaultEncodingRegistry()
    .getEncodingForModel(ModelType.GPT_3_5_TURBO)

  val count = messages.sumOf { message ->

    // GPT_3_5_TURBO without name
    listOf(
      4, // per message
      encoding.countTokens(message.role),
      encoding.countTokens(message.content)
    ).sum()

  } + 3 // every reply is primed with <|start|>assistant<|message|>

  println(count)

}


@Serializable
data class Message(
  val role: String,
  val content: String
)

メッセージごと、リプライごとのカウント追加が間違ってるのか、なんなのか。

少しカウント数ずれるんだけども。

 

🤖 まとめ

てか、返せよ Usage。

従量制の有料サービスなんだから。

👉 How to get total_tokens from a stream of CompletionCreateRequests - API - OpenAI Developer Forum hatena-bookmark
👉 How do you get token count when streaming - API - OpenAI Developer Forum hatena-bookmark
👉 How to determine the token usage for a session when using stream:true? - API - OpenAI Developer Forum hatena-bookmark

まあ、Webページで確認すればいいけども。

👉 Usage - OpenAI API hatena-bookmark

大して使ってないからどうでもいいか。


【Jetpack Compose】ChatGPT のようなアニメーションの @Composable AnimationText

画面がなんとなく元気になります。

Jetpack Compose AnimationText like ChatGPT



 

💬 実装

LaunchedEffect() のラムダ内は CoroutineScope なので delay() でお好みのスピードで。

JaetpackCompose は、なかなかメモリーリークしないのがいいところ。

 

💬 まとめ

アプリで公開するとすれば、最低でも WEB の UI を超えた機能を実装しなければなりません。

先人たちが公開されている UI の機能を取り込んでいきましょう。


【Android】公式エミュレーターがしれっと軽かったので Goole Play Store を入れて使う方法📱

「エミュレーターは遅い」てのは昔の話ですか。

入れて見たら十分使える感じ。

Pixel6 の SDK 33 を入れました。

 

📱 Google Play Store を入れる

エミュレーターに同梱されている設定ファイルを書き換えます。

[Show on Disk] からエミュレーターのファイル群を開きます。

[config.ini] を開きます。

2カ所編集してを保存します。


PlayStore.enabled = false

  ↓

PlayStore.enabled = true


image.sysdir.1 = system-images/android-33/google_apis/x86_64/

  ↓

image.sysdir.1 = system-images/android-33/google_apis_playstore/x86_64/

エミュレーターを再起動すると、Google Play Store がインストールされています。

 

📱 まとめ

いつのまにかエミュレーターも進化してたのですね!

Google Play Store を入れれば、さらに便利に使えます。


【無料】Apple / Google パスワードマネージャーを起動できる ショートカットApp 🔐【iPhone/Mac】

あれこれ試行錯誤してみましたが、

「マルチプラットフォームの有料アプリでー」とか

「import や export 機能でー」とかいうても、

結局は、OSやブラウザに認証の機能が依存してる限り、

手動でのアカウントやパスワードの管理は、

そのベンダーの提供しているUIを使った方が便利です。

Mac ベースで生活している私としましては、

そんなショートカットAppが欲しいので、

とりあえず作っておきました。

当然、iPhone でも iCloud共有しながら使えます。


👉 Password Managers hatena-bookmark

使い方のイメージは、このショートカットを起動後、

Chrome でのWEBサービス自動ログインができない時
→ 「Apple」を選択して、アカウントID/パスワードを確認(コピー)する。

Safari でのWEBサービスログインができない時
→ 「Google」を選択して、アカウントID/パスワードを確認する。

iPhone/Mac アプリのログインができない時
→ 「Google」を選択して、アカウントID/パスワードを確認する。

Android アプリのログインができない時
→ 「Apple」を選択して、アカウントID/パスワードを確認する。

という感じです。

基本的に、

「アカウントID/パスワードの登録は利用しているそのUIに任せる。」

のが簡単で安心で、

自動入力時にも混乱しなくて良いと思います。

iCloud と Google の重複はお互いのバックアップにもなります。

👉 【便利】Mac パスワードマネージャー を メニューバーのショートカット や コマンドラインから開く方法 hatena-bookmark


ChatGPTアプリで表を出力させる - Markdown Text for Android JetpackCompose

ChatGPT は Markdown 出力することができますよね。

それを Jetpack Compose で表示させましょう。

ChatGPTアプリで表を出力させる - Markdown Text for Android JetpackCompose

すごく分かりやすいですね。



以下のライブラリを使いました。

👉 jeziellago/compose-markdown: Markdown Text for Android Jetpack Compose 📋. hatena-bookmark

利用記述はシンプルに作成されています。


@Composable  
fun ComplexExampleContent() {  
  MarkdownText(
    modifier = Modifier.padding(8.dp),
    markdown = markdown,
    textAlign = TextAlign.Center,
    fontSize = 12.sp,
    color = LocalContentColor.current,
    maxLines = 3,
    fontResource = R.font.montserrat_medium,
    style = MaterialTheme.typography.overline,
  )  
}

続いて、Markdown で Mermaid や Planet UML で図を出力もできそうです。

ちなみに、このライブラリは、さらに以下のライブラリたちに順に依存しています。

👉 Markwon/app-sample at master · noties/Markwon hatena-bookmark
👉 CommonMark hatena-bookmark