Rust 使用 lazy_static 和 reqwest 实现简单的 AI 对话功能
这段代码演示了如何使用 Rust 的 lazy_static 库和 reqwest 库实现一个简单的 AI 对话功能。
代码说明:
- 使用
lazy_static库定义了一个静态变量HISTORY_STR,用于保存用户输入历史记录。 - 使用
reqwest库发送 HTTP POST 请求到 AI API 获取响应。 - 代码中使用了
Mutex来保证HISTORY_STR的线程安全。 - 通过循环不断获取用户输入并发送到 AI API,然后将 AI 响应输出到控制台。
代码中存在的错误:
代码中尝试使用 HISTORY_STR.push_str(&input_buf) 直接修改 HISTORY_STR 的值,但是 HISTORY_STR 是一个 Mutex<String> 类型,它没有 push_str 方法。
解决方法:
需要先获取 HISTORY_STR 的 MutexGuard 对象,然后使用 push_str 方法修改它的值。
修改后的代码:
extern crate lazy_static;
use std::{io, collections::HashMap};
use lazy_static::lazy_static;
// use std::fmt::format;
// use std::io::BufRead;
use reqwest::header::HeaderMap;
use std::sync::Mutex;
// use serde::{Deserialize, Deserializer};
// use serde_derive::Deserialize;
// use std::error::Error;
// use serde::de::Visitor;
// use serde_json::{Map, Value};
#[macro_use]
lazy_static::lazy_static! {
static ref HISTORY_STR: Mutex<String> = Mutex::new(String::new());
}
#[tokio::main]
async fn main() {
loop {
match send_post().await {
Ok(res) => {
let completions: Vec<&str> = res
//分割字符串切片向量 其中每个元素都包含了completion值的json 对象 字符串
.split('{"type":"success","completion":"')
.skip(1)
//提取completion 值
.map(|s| s.split('"}"').next().expect("map error on loop."))
.collect();
//join 合并字符串
let merged = completions.join("");
println!("AI-> {}", merged);
}
Err(e) => { eprintln!("{:?}", e) }
}
}
}
//获取用户键盘输入
async fn get_user_input() -> String {
let mut input_buf = String::new();
let _input = io::stdin().read_line(&mut input_buf).expect("fail to get user input.");
unsafe {
let mut history_str = HISTORY_STR.lock().unwrap();
history_str.push_str(&input_buf);
}
input_buf
}
async fn send_post() -> Result<String, reqwest::Error> {
let client = reqwest::Client::new();
//post 请求头
let mut header = HeaderMap::new();
header.insert("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
Chrome/110.0.0.0 Safari/537.36".parse().expect("unsolve the userAgent header value."),
);
header.insert("referer", "https//www.covery.com".parse().expect("unsolve the referer value."));
header.insert("sec-ch-ua", "sec-ch-ua".parse().expect("ms"));
// post 请求体
let mut data = HashMap::new();
//用户输入
print!("Please enter your input:");
let input_buf = get_user_input().await;
data.insert("prompt", input_buf);
Ok(client.post("https://free-api.cveoy.com/v3/completions")
.headers(header)
.json(&data)
.send()
.await?
.text()
.await?
)
}
注意:
- 代码中使用
unsafe关键字是因为在多线程环境下访问MutexGuard对象是不安全的,需要手动保证线程安全。 - 代码中直接使用了
unwrap方法来获取到MutexGuard对象,在实际应用中,你可能需要使用更加复杂的方式来处理错误情况。
代码示例:
Please enter your input:Hello, world!
AI-> Hello, world! How can I help you?
Please enter your input:What is the weather like today?
AI-> I'm sorry, I don't have access to real-time information, such as weather forecasts.
原文地址: https://www.cveoy.top/t/topic/lBSK 著作权归作者所有。请勿转载和采集!