use langchainrust::{
BM25Retriever, ChatPromptTemplate, ConversationBufferMemory, Document, Message, OpenAIChat,
OpenAIConfig, RAGPipelineBuilder, RagRunnable, Runnable, RunnableExt, RunnableWithMessageHistory,
StrOutputParser,
};
use std::collections::HashMap;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("OPENAI_API_KEY").expect("请设置 OPENAI_API_KEY 环境变量");
let base_url = std::env::var("OPENAI_BASE_URL")
.unwrap_or_else(|_| "https://api.openai.com/v1".to_string());
let model = std::env::var("TEST_CHAT_MODEL").unwrap_or_else(|_| "gpt-4o-mini".to_string());
let llm = OpenAIChat::new(OpenAIConfig {
api_key,
base_url,
model,
..Default::default()
});
let prompt = ChatPromptTemplate::from_messages([
Message::system("你是一个简洁的 Rust 助手,只输出结论,不要多余文字。"),
Message::human("{question}"),
]);
let qa_chain = prompt.pipe(llm.clone()).pipe(StrOutputParser::new());
let mut vars = HashMap::new();
vars.insert(
"question".to_string(),
"一句话说明什么是 Rust 语言".to_string(),
);
let answer = qa_chain.invoke(vars, None).await?;
println!("[1] 提示词+LLM+解析器\n {answer}\n");
let memory = ConversationBufferMemory::new().with_return_messages(true);
let chat_chain = RunnableWithMessageHistory::new(llm.clone(), memory)
.pipe(StrOutputParser::new());
let r1 = chat_chain.invoke("我叫小明,请记住我。".to_string(), None).await?;
let r2 = chat_chain.invoke("我叫什么名字?".to_string(), None).await?;
println!("[2] 记忆+LLM+解析器(多轮)\n 第一轮: {r1}\n 第二轮: {r2}\n");
let retriever = BM25Retriever::new();
retriever.add_documents_sync(vec![
Document::new("Rust 是一门系统编程语言,由 Mozilla 开发,注重安全和性能。")
.with_id("rust_intro"),
Document::new("Rust 的核心特性包括所有权系统、借用检查和零成本抽象。")
.with_id("rust_features"),
Document::new("LCEL(表达式语言)用 .pipe() 把提示词、模型、解析器串成一条链。")
.with_id("lcel_intro"),
]);
let pipeline = RAGPipelineBuilder::new()
.llm(llm)
.retriever(retriever)
.retrieve_k(2)
.build()?;
let rag_chain = RagRunnable::new(Arc::new(pipeline));
let answer = rag_chain
.invoke("Rust 有哪些核心特性?".to_string(), None)
.await?;
println!("[3] RAG 链\n {answer}\n");
println!("=== lcel_compose 全链完成 ✅ ===");
Ok(())
}