Files
agcore/examples/prompt_composer.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

108 lines
3.8 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.
//! prompt_composer —— 提示词模板与组合器离线示例。
//!
//! 演示:
//! 1. `PromptTemplate::compile` + `render` 变量插值(`{{var}}` 语法)
//! 2. 缺失变量返回 `PromptError`
//! 3. `PromptTemplateRegistry` 注册 + 按名渲染
//! 4. `PromptComposer` 构造多角色消息序列
//! 5. `validate_messages` 校验消息序列合法性
//!
//! 运行:`cargo run --example prompt_composer`
use agcore::llm::types::message::{ContentBlock, Message};
use agcore::prompt::{
validate_messages, PromptComposer, PromptTemplate, PromptTemplateRegistry, TemplateContext,
};
fn message_text(msg: &Message) -> String {
match msg {
Message::System { content }
| Message::User { content }
| Message::Assistant { content }
| Message::ToolResult { content, .. } => content
.iter()
.filter_map(|b| match b {
ContentBlock::Text { text } => Some(text.as_str()),
_ => None,
})
.collect(),
Message::UserImage { .. } => "[image]".into(),
}
}
fn main() {
// 1. PromptTemplate::compile + render —— 直接构造模板
println!("=== PromptTemplate::compile + render ===");
let tpl = PromptTemplate::compile(
"今日 {{location}} 天气:{{condition}},温度 {{temperature}}",
)
.expect("编译失败");
let mut ctx = TemplateContext::new();
ctx.insert("location", "北京");
ctx.insert("condition", "");
ctx.insert("temperature", "25°C");
let rendered = tpl.render(&ctx).expect("渲染失败");
println!("渲染结果: {rendered}");
// 2. 缺失变量 → PromptError
println!("\n=== 缺失变量 ===");
match tpl.render(&TemplateContext::new()) {
Ok(_) => println!("意外成功"),
Err(e) => println!("按预期报错: {e}"),
}
// 3. PromptTemplateRegistry —— 按名注册 + 渲染(支持 #if 条件)
println!("\n=== PromptTemplateRegistry ===");
let mut registry = PromptTemplateRegistry::new();
registry
.register("weather", "今日 {{location}}{{condition}}")
.expect("注册失败");
registry
.register("greet", "你好 {{name}}{{#if formal}} 见到您很荣幸。{{/if}}")
.expect("注册失败");
let mut ctx = TemplateContext::new();
ctx.insert("name", "Alice");
println!(
"greet (formal=false): {}",
registry.render("greet", &ctx).unwrap()
);
ctx.insert("formal", true);
println!(
"greet (formal=true): {}",
registry.render("greet", &ctx).unwrap()
);
// 4. PromptComposer —— 构造多角色消息序列
println!("\n=== PromptComposer ===");
let messages = PromptComposer::new()
.system("你是一个天气助手")
.user("今天天气怎么样?")
.assistant("请告诉我城市名。")
.user(rendered)
.build();
println!("消息数: {}", messages.len());
for (i, m) in messages.iter().enumerate() {
let role = match m {
Message::System { .. } => "system",
Message::User { .. } | Message::UserImage { .. } => "user",
Message::Assistant { .. } => "assistant",
Message::ToolResult { .. } => "tool",
};
println!("[{i}] {role}: {}", message_text(m));
}
// 5. validate_messages —— 消息序列合法性校验
println!("\n=== validate_messages ===");
match validate_messages(&messages) {
Ok(()) => println!("消息序列合法 ✓"),
Err(e) => println!("消息序列非法: {e}"),
}
let empty: Vec<Message> = Vec::new();
match validate_messages(&empty) {
Ok(()) => println!("空消息合法"),
Err(e) => println!("空消息按预期报错: {e}"),
}
println!("\n✓ prompt_composer 完成");
}