Files
agcore/examples/conversation_memory_demo.rs
T
徐涛 2d0d5c1592 feat(examples): 新增 Phase B 7 个离线可运行示例
新增 7 个示例覆盖全 Phase 公共 API(不依赖 API key 即可运行):
- agent_session_demo:AgentBuilder → AgentSession → SessionMemory
- custom_tool:BaseTool 注册 + invoke/invoke_all + 权限检查
- prompt_composer:PromptTemplate + PromptComposer + validate_messages
- task_agent_demo:JsonPlanParser + Step 状态机 + 错误路径
- conversation_memory_demo:滑动窗口 + 多角色 + 隔离
- knowledge_search_demo:KnowledgeStore + 关键词检索 + 停用词过滤
- streaming_events_demo:submit_stream 事件消费 + 队列耗尽错误路径
2026-07-03 15:50:51 +08:00

143 lines
4.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! conversation_memory_demo —— 对话记忆滑动窗口与隔离。
//!
//! 演示:
//! 1. `ConversationMemoryConfig` 构造(SlidingWindow / Full 策略)
//! 2. `add_message` 写入多角色消息(Message IR
//! 3. 滑动窗口自动淘汰旧消息
//! 4. Full 策略保留全部
//! 5. `get_history` / `len` / `clear`
//! 6. 跨 session 数据隔离(共用 MemoryStore
//!
//! 运行:`cargo run --example conversation_memory_demo`
use std::sync::Arc;
use agcore::llm::types::message::Message;
use agcore::memory::{ConversationMemory, ConversationMemoryConfig, InMemoryStore, MemoryStrategy};
fn message_text(msg: &Message) -> &str {
match msg {
Message::User { content }
| Message::System { content }
| Message::Assistant { content }
| Message::ToolResult { content, .. } => content
.iter()
.filter_map(|b| match b {
agcore::llm::types::message::ContentBlock::Text { text } => Some(text.as_str()),
_ => None,
})
.next()
.unwrap_or(""),
Message::UserImage { .. } => "[image]",
}
}
#[tokio::main]
async fn main() {
// 1. 滑动窗口策略:写入 5 条但只保留最近 3 条
println!("=== SlidingWindow 策略(max_turns=3===");
let store = Arc::new(InMemoryStore::new());
let config = ConversationMemoryConfig {
strategy: MemoryStrategy::SlidingWindow,
max_turns: 3,
compact_config: None,
};
let mut memory = ConversationMemory::new(store, "session-1", config);
for i in 0..5 {
memory
.add_message(Message::user_text(format!("消息 {i}")))
.await
.expect("写入失败");
}
println!("写入 5 条 → len = {} (期望 3)", memory.len());
let history = memory.get_history();
for (i, msg) in history.iter().enumerate() {
println!(" [{}] {}", i, message_text(msg));
}
assert_eq!(memory.len(), 3);
assert_eq!(message_text(&history[0]), "消息 2", "最旧应是消息 2");
assert_eq!(message_text(&history[2]), "消息 4", "最新应是消息 4");
// 2. Full 策略:保留全部
println!("\n=== Full 策略(max_turns=3===");
let store2 = Arc::new(InMemoryStore::new());
let config2 = ConversationMemoryConfig {
strategy: MemoryStrategy::Full,
max_turns: 3,
compact_config: None,
};
let mut memory2 = ConversationMemory::new(store2, "session-2", config2);
for i in 0..5 {
memory2
.add_message(Message::user_text(format!("Full {i}")))
.await
.unwrap();
}
println!("写入 5 条 → len = {} (期望 5)", memory2.len());
assert_eq!(memory2.len(), 5);
// 3. 多角色混合 + clear
println!("\n=== 多角色写入 + clear ===");
let store3 = Arc::new(InMemoryStore::new());
let mut memory3 = ConversationMemory::new(
store3,
"session-3",
ConversationMemoryConfig::default(),
);
memory3
.add_message(Message::user_text("你好"))
.await
.unwrap();
memory3
.add_message(Message::assistant("你好!有什么可以帮你的吗?"))
.await
.unwrap();
memory3
.add_message(Message::user_text("今天天气怎么样?"))
.await
.unwrap();
memory3
.add_message(Message::assistant("我无法查询实时天气,但你可以查看天气应用。"))
.await
.unwrap();
println!(
"写入 4 条多角色消息 → len = {}, 最后一条: {:?}",
memory3.len(),
message_text(memory3.get_history().last().unwrap())
);
assert_eq!(memory3.len(), 4);
memory3.clear().await.unwrap();
println!(
"clear 后 → len = {}, is_empty = {}",
memory3.len(),
memory3.is_empty()
);
assert!(memory3.is_empty());
// 4. Session 隔离
println!("\n=== Session 隔离(共用 InMemoryStore===");
let store4 = Arc::new(InMemoryStore::new());
let mut a = ConversationMemory::new(
store4.clone(),
"s-a",
ConversationMemoryConfig::default(),
);
let mut b = ConversationMemory::new(
store4.clone(),
"s-b",
ConversationMemoryConfig::default(),
);
a.add_message(Message::user_text("A 的消息")).await.unwrap();
b.add_message(Message::user_text("B 的消息")).await.unwrap();
println!(
"A.len = {}, B.len = {} (期望 1/1,互不污染)",
a.len(),
b.len()
);
assert_eq!(a.len(), 1);
assert_eq!(b.len(), 1);
println!("\n✓ conversation_memory_demo 完成");
}