use zai_rs::{
client::http::*,
model::{
async_chat::AsyncChatCompletion, async_chat_get::AsyncChatGetRequest,
chat_base_response::TaskStatus, *,
},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let enable_logging = std::env::var_os("RUST_LOG").is_some();
if enable_logging {
let _ = tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.try_init();
}
let key =
std::env::var("ZHIPU_API_KEY").expect("ZHIPU_API_KEY environment variable must be set");
tracing::trace!("=== 提交异步聊天任务 ===");
let messages = vec![
"你好,请介绍一下机器学习的基本概念",
"你能解释一下什么是深度学习吗?",
"请简单说明自然语言处理的应用场景",
];
let mut task_ids = vec![];
for message in messages {
let key_clone = key.clone();
let http_config = HttpClientConfigBuilder::default()
.logging(enable_logging)
.mask_sensitive_data(false)
.build();
let client = AsyncChatCompletion::new(GLM4_5 {}, TextMessage::user(message), key_clone)
.with_temperature(0.7)
.with_top_p(0.9)
.with_http_config(http_config);
match client.send().await {
Ok(body) => {
if let Some(task_id) = body.id() {
tracing::trace!("问题: {}", message);
tracing::trace!("任务ID: {}", task_id);
task_ids.push((message, task_id.to_string()));
}
},
Err(e) => {
tracing::trace!("提交失败: {}", e);
},
}
}
tracing::trace!("\n=== 获取异步聊天结果 ===");
use tokio::task::JoinSet;
let mut set: JoinSet<(&'static str, Result<String, String>)> = JoinSet::new();
for (message, task_id) in task_ids {
let key = key.clone();
set.spawn(async move {
let request = AsyncChatGetRequest::new(GLM4_5 {}, task_id, key);
loop {
match request.send().await {
Ok(body) => match body.task_status() {
Some(TaskStatus::Success) => {
let content = body
.choices()
.and_then(|choices| choices.first())
.and_then(|choice| choice.message.content())
.map(|v| match v {
serde_json::Value::String(s) => s.clone(),
other => other.to_string(),
})
.unwrap_or_default();
break (message, Ok(content));
},
Some(TaskStatus::Fail) => {
break (message, Err("任务失败".to_string()));
},
Some(TaskStatus::Processing) => {
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
},
None => break (message, Err("未知状态".to_string())),
},
Err(e) => break (message, Err(format!("获取结果失败: {e}"))),
}
}
});
}
while let Some(res) = set.join_next().await {
match res {
Ok((message, Ok(content))) => {
tracing::trace!("问题: {message}");
tracing::trace!("回复: {content}");
tracing::trace!("---");
},
Ok((message, Err(e))) => {
tracing::trace!("问题: {message}");
tracing::trace!("{e}");
tracing::trace!("---");
},
Err(e) => tracing::trace!("轮询任务异常: {e}"),
}
}
Ok(())
}