ys memos

Blog

RustでOpenAIのChatCompletionsをストリームで受けるmod 〜0.概要〜


rust

2023/08/31


本コードの動作確認は2023/05時点までしか行っていません。
当時動作していたコードをそのまま公開いたします。

現在のAPIでの動作確認はしていないこと、ご了承ください。

以前、OpenAIのChat Completionsを叩くアプリを作っていた。 しかし、いつしか熱が冷めて開発が止まっていたので、眠らせておくくらいならと思い、コードを公開する。

また、一つの記事にまとめたかったが、ボリュームが大きくなりすぎてしまったので、記事をいくつかに分割した。



一つのファイルにすると長くなってしまうので、いくつかのファイルに分割した。これらを一つのディレクトリ内に配置して使ってもらえたら動くだろう。


仮にsrc/内に以下のディレクトリ構造があるとする。

以下に記述していくコードを配置していくことで、Chatterを利用できる。

src/
└── chatter
    ├── error.rs
    ├── headers.rs
    ├── json.rs
    ├── message.rs
    ├── mod.rs
    ├── request_builder.rs
    ├── role.rs
    └── stream_data.rs

こんな具合で利用できるようなモジュールを作った。

実行時は以下のような環境変数をセットする。直接セットしてもいいし、.envに以下のように書き込んでもよい。

環境変数
OPENAI_API_KEY=xx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CLIアプリケーションのように利用できるイメージ。

main.rs
use std::io::{self, BufRead, Write};

use super::chatter::Chatter;

fn get_user_input() -> io::Result<String> {
    let stdin = io::stdin();
    let mut input = String::new();

    for line in stdin.lock().lines() {
        match line {
            Ok(line) => {
                input.push('\n');
                input.push_str(line.as_str());
            }
            Err(_) => break,
        }
    }
    Ok(input)
}

#[tokio::main]
pub async fn main() -> io::Result<()> {
    let mut chatter = Chatter::new();
    loop {
        println!("=================");
        println!("=== User ========");
        let user_input = get_user_input()?;
        chatter.push_user_message(user_input.into());
        println!("=================");
        println!("=== Assistant ===");
        if let Err(e) = chatter
            .send(|content| {
                print!("{content}");
                std::io::stdout().flush()?;
                Ok(())
            })
            .await
        {
            println!("{e:?}");
        }
        println!("");
        println!("================");
    }
}


Streamで受ける設定を参考にさせていただきました

関連タグを探す