Skip to content

基础 Agent

跑起来一个 Agent 之后(见快速开始),这篇讲日常最常用的几个模式。

系统提示词

系统提示词设定 Agent 的行为,每次请求都会拼在 prompt 的最前面。

rust
let agent = Agent::make(config).await?
    .preamble("你是一个用俳句回答问题的助手。");

提示词长度没有硬性限制,但注意它会占 token 预算。

聊天模板

不同模型用不同的 prompt 格式。Ambi 内置了 9 种模板:

模板适用模型
ChatmlOpenAI、Qwen、很多微调模型
Llama3Llama 3 / 3.1 系列
DeepseekDeepSeek V2/V3、R1
QwenQwen 2 / 2.5
GemmaGoogle Gemma
Phi3Microsoft Phi-3 / Phi-4
MistralMistral / Mixtral
ZephyrHuggingFace Zephyr
Llama2旧的 Llama 2
rust
use ambi::ChatTemplateType;

let agent = Agent::make(config).await?
    .template(ChatTemplateType::Deepseek);

默认是 Chatml。如果模型需要自定义格式,可以手动构造 ChatTemplate 结构体。

多轮对话

Agent 把历史存在 AgentState 里。每次 chat() 都会追加用户消息和助手回复,下一轮自动带上上下文。

rust
let state = AgentState::new_shared("session-001");

runner.chat(&agent, &state, "我叫小明。").await?;
// 下一轮它记得"小明"
runner.chat(&agent, &state, "我叫什么名字?").await?;
// -> "你叫小明"

session_id

每个 AgentState 都带有一个唯一的 session_id,为高并发环境下的分布式追踪和 KV Cache 槽位分配提供支持:

rust
let state = AgentState::new_shared("user-42-conversation-3");

动态上下文

易变数据(RAG 结果、时间戳、环境变量)通过 AgentState 注入,不会污染静态的 system_prompt

rust
state.write().await.set_dynamic_context("相关文档:...");
state.write().await.append_dynamic_context("用户语言:zh-CN");
state.write().await.clear_dynamic_context(); // 过期后重置

清空历史

想重新开始的时候:

rust
let mut state_lock = state.write().await;
ChatRunner::clear_history(&agent, &mut state_lock);

这会同时清空对话消息和引擎内部上下文(本地模型会清 KV Cache)。

ChatHistory 查询方法

rust
let hist = &state.read().await.chat_history;

// 搜索包含关键词的消息
let results = hist.search_by_keyword("天气");

// 获取最近一条用户消息
if let Some(msg) = hist.last_user_message() {
    // ...
}

// 获取最近一条助手回复
if let Some(msg) = hist.last_assistant_message() {
    // ...
}

克隆友好

Agent 的所有内部字段都用 Arc 包装,克隆只是引用计数 +1。可以一个 Agent 蓝图跑几百个对话:

rust
let agent = Agent::make(config).await?.preamble("你是一个助手。");
let state = AgentState::new_shared("多轮对话");
let runner = ChatRunner::default();

for _ in 0..100 {
    let agent = agent.clone();
    let state_clone = Arc::clone(&state);
    tokio::spawn(async move {
        let _ = runner.chat(&agent, &state_clone, "你好").await;
    });
}

错误处理

所有公开 API 都返回 Result<T, AmbiError>。错误枚举包括:

  • EngineError —— 模型初始化或推理失败
  • AgentError —— 逻辑错误(如工具名重复)
  • ToolError —— 工具执行超时或失败
  • ContextError —— prompt 格式化问题
  • PipelineError —— 流中断
  • MaxIterationsReached —— ReAct 循环超限
rust
let agent = Agent::make(config).await?.preamble("你是一个助手。");
let state = AgentState::new_shared("错误处理");
let runner = ChatRunner::default();

match runner.chat(&agent, &state, "你好").await {
    Ok(reply) => println!("{}", reply),
    Err(AmbiError::ToolError(msg)) => eprintln!("工具执行失败:{}", msg),
    Err(e) => eprintln!("其他错误:{}", e),
}

基于 Apache-2.0 协议开源