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で受ける設定を参考にさせていただきました