GPT4o でテキスト生成を試す

gpt 4o がでた。高速化 + 安価性 

[Hello GPT-4o](https://openai.com/index/hello-gpt-4o/)

以前 雑に書いたメモをもとに、それを記事に仕立て上げてもらう　ってことをやったので、これをつかってモデル比較してみる

[Notionのメモをもとに記事を作らせて投稿してみる - Qiita](https://qiita.com/kk__777/items/a4f924ee9a2a2a16aa53)

### やること

[https://kk--777.notion.site/Kotlin-Listener-3706188a8ee74ebeb8837c0e65c85960?pvs=4](https://www.notion.so/Kotlin-Listener-3706188a8ee74ebeb8837c0e65c85960?pvs=21)

- このメモを記事に仕立て上げてもらう。
- コストと 出力結果　を比較する

Gpt4-turboと3.5は処理時間も計測

gpt-4oは使っているOpenAI- Clientライブラリが対応してなかったので、PlayGroundを使用。

トークン数の比較もしたかったが、今回は割愛。

### gpt-3.5-turbo

- 処理時間: 38302.964291 ms
- <$0.01

日本語で　って伝えてるのに英語にしてくれた様子

プロンプトでは含めないように指示しているが、前後に余計な文章あり

```
与えられたファイルは、Kotlinコードに関する内容のようです。Markdown形式で書かれたメモであり、suspendCancellableCoroutine関数についての説明やサンプルコードが含まれています。

以下に、このメモをブログ記事に変換したものを提供します。

Understanding suspendCancellableCoroutine in Kotlin
In Kotlin, the suspendCancellableCoroutine function is used to return a result in a suspendable manner. Let's explore how this function works and its usage in asynchronous programming.

Syntax
The syntax of the suspendCancellableCoroutine function in Kotlin is as follows:

public suspend inline fun <T> suspendCancellableCoroutine(
    crossinline block: (CancellableContinuation<T>) -> Unit
)
What does suspendCancellableCoroutine do?
The suspendCancellableCoroutine function allows you to notify a listener and resume a coroutine to return a specific result when the notification is received.

Example Usage
Let's see an example of how suspendCancellableCoroutine can be used in Kotlin code:

return suspendCancellableCoroutine<String> { coroutine ->
    val listener = object : AnyListener {
        fun onSuccess() {
            coroutine.resume("success!")
        }
        fun onFailure(error) {
            coroutine.consume(error.toString())
        }
    }
    val target = SomeAsyncTask(listener)
    // Perform async task and notify the listener
}
In this example, when the onSuccess or onFailure callbacks are triggered in the asynchronous task, the suspendCancellableCoroutine function allows the coroutine to be resumed with the corresponding result.

By using suspendCancellableCoroutine, you can handle asynchronous operations in a structured and manageable way in Kotlin.

This blog post summarizes the use of suspendCancellableCoroutine in Kotlin for asynchronous programming. It showcases the power of Kotlin coroutines in handling suspending functions effectively.
```

### gpt-4-turbo

- 処理時間: 84581.445958 ms
- **$0.08**

前後の余計な出力はない

メモの後半の内容が欠落している（これはたぶんたまたま）

高い

```
KotlinのsuspendCancellableCoroutineの活用法
Kotlinでの非同期プログラミングは、suspendCancellableCoroutine関数によって大きく強化されます。この機能を利用すれば、非同期のcallbackが返された時に、スムーズに処理を再開することができます。今回は、suspendCancellableCoroutineの基本的な使い方と具体例を通じて、その使い方を解説します。

基本的な関数のシグネチャ
まず、suspendCancellableCoroutine関数のシグネチャは以下のようになります。

public suspend inline fun <T> suspendCancellableCoroutine(
    crossinline block: (CancellableContinuation<T>) -> Unit
)
効果的な利用例
非同期の処理でよく見られるのは、何かのイベントが発生した際に結果を受け取るパターンです。以下の例では、任意のリスナーが成功または失敗のcallbackを受け、適切にcoroutineを再開または例外処理を行います。

return suspendCancellableCoroutine<String> { coroutine ->
    val listener = object: AnyListener {
        fun onSuccess(){
            coroutine.resume("success!")
        }
        fun onFailure(error){
            coroutine.resumeWithException(Exception(error.toString()))
        }
    }
    // リスナーを何らかの処理に登録します
    val target = Connection.target(listener)
}
このコードスニペットでは、AnyListenerインターフェースを実装してリスナーを定義し、成功時にはresumeメソッドで正常な結果を、失敗時にはresumeWithExceptionでエラーをcoroutineに通知しています。targetはこのリスーナーを使って何らかの処理を実行するオブジェクトを想定しています。

まとめ
suspendCancellableCoroutineを使うことで、Kotlinの非同期処理の柔軟性が増し、適切なエラー処理や結果の返し方を実装できるようになります。コールバックベースのAPIとの連携もスムーズに行えるため、Kotlinでの開発がより効率的かつ直感的に行えるようになります。

この技術を用いることで、コードの明確性が向上し、バグの発生を減少させることが期待できます。是非とも、自身のプロジェクトに応用してみてください。
```

### gpt-4o

- **$0.05**

入力内容をできるだけ端折らずに出力している

使ったライブラリの都合で、処理時間が測れてないが、感覚かなり早い印象

出力が増えているのにコストがgpt-4-turboより控えめ

```
Kotlinの非同期処理：suspendCancellableCoroutine と callbackFlow の使い方
Kotlinコルーチンは、非同期プログラミングをより直感的かつ簡潔にするための強力なツールです。その中でも特に重要な2つの手法、suspendCancellableCoroutine と callbackFlow について解説します。これらの手法は、非同期結果をどう返すかに関するさまざまな場面で役立ちます。

suspendCancellableCoroutine で結果を返す
suspendCancellableCoroutine は、単一の非同期結果を待ち受けるための関数です。この関数を使うと、リスナーからの通知を受け取った際にコルーチンを再開 (resume) して特定のデータを返すことができます。

public suspend inline fun <T> suspendCancellableCoroutine(
    crossinline block: (CancellableContinuation<T>) -> Unit
)
使用例
以下のコードスニペットでは、suspendCancellableCoroutine を使って非同期結果を受け取り、それに応じて処理を行っています。

return suspendCancellableCoroutine<String> { coroutine ->
    val listener = object: AnyListener {
        fun onSuccess() {
            coroutine.resume("success!")
        }
        fun onFailure(error: Throwable) {
            coroutine.resumeWithException(error)
        }
    }
    val target = ConsumeListenerClass(listener)
    target.start()
}
このコードでは、成功時に "success!" という結果を返し、失敗時にはエラーをスローしています。重要なのは、coroutine.isCancelled によってキャンセル状態を確認し、リスナーを破棄することでメモリリークを防ぐことです。

特徴
単一の結果: 通常、一つの結果またはイベントを待つために使用されます。
シンプルなAPI呼び出し: APIが一つの成功/失敗の結果を返す場合に適しています。
直接的なコントロール: resume または resumeWithException を使用して、明示的にコルーチンの状態を制御できます。
適した用途
非同期APIからの単一の応答を待つ場合。
コールバックが一度だけ呼び出されることが保証される場合。
シンプルな非同期操作で、複雑なイベントストリームの処理が不要な場合。
callbackFlow で結果を返す
callbackFlow は、複数の非同期結果を処理する場合に使用される関数です。これにより、イベントのストリームや複数のデータポイントを扱うことができます。

fun <T> callbackFlow(block: suspend ProducerScope<T>.() -> Unit): Flow<T>
使用例
以下のコードスニペットは、非同期APIからのコールバックをフローとして扱う方法を示しています。

fun <T> flowFrom(api: CallbackBasedApi): Flow<T> = callbackFlow {
    val callback = object : Callback {
        override fun onNextValue(value: T) {
            trySendBlocking(value)
                .onFailure { throwable ->
                    // Downstream has been cancelled or failed, can log here
                }
        }

        override fun onApiError(cause: Throwable) {
            cancel(CancellationException("API Error", cause))
        }

        override fun onCompleted() = channel.close()
    }
    api.register(callback)
    awaitClose { api.unregister(callback) }
}
このコードでは、複数の結果やイベントを callbackFlow を介して受け取り、最終的に awaitClose によってコールバックの登録解除を行います。

特徴
複数のイベントの処理: イベントのストリームや複数のデータ点を扱うことができます。
バックプレッシャの管理: Flow のバックプレッシャ管理機能を利用できます。
リソースの自動管理: awaitClose ブロックを使用してリソースを自動的にクリーンアップすることができます。
適した用途
イベントリスナーからの複数のコールバックを受け取る場合。
長期間にわたるまたは継続的なデータストリームを処理する場合。
複数のコールバックイベント間の操作や変換を行いたい場合。
まとめ
非同期処理において、suspendCancellableCoroutine と callbackFlow は非常に強力なツールです。どちらを使うべきかは、待機する非同期結果が単一なのか、または複数なのかによります。例えば、一度きりの成功/失敗の結果を待つ場合は suspendCancellableCoroutine が適しており、複数のイベントやデータストリームを扱う場合は callbackFlow を使用すると良いでしょう。あなたのアプリケーションのニーズに最適な方法を選んでみてください。
```

### おわり

単純なテキスト処理と生成だけど、性能めっちゃ上がってそうーー