Files
agcore/examples/prompt_composer.rs
T
徐涛 5baa170508 docs: 更新 README feature 表 + 升级指南 + 示例注释 + roadmap 同步
- README 添加 feature 组合表 + 模块级 features 清单 + 升级指南
- 18 个 example 顶部添加 Required features 注释
- roadmap.md 和 roadmap-v0.3.2.md 同步 Phase 26-27 完成状态
- cargo fmt 全量格式化(修复预存格式问题,CI format job 可通过)
2026-07-19 08:18:04 +08:00

114 lines
4.0 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 —— 提示词模板与组合器离线示例。
//! Required features: cargo run --example prompt_composer --features "prompt,llm"
//!
//! 演示:
//! 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::{
PromptComposer, PromptTemplate, PromptTemplateRegistry, TemplateContext, validate_messages,
};
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(),
_ => String::new(),
}
}
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",
_ => "unknown",
};
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 完成");
}