diff --git a/src/plugins/ai/backend.rs b/src/plugins/ai/backend.rs index 3086dc6..7d2109a 100644 --- a/src/plugins/ai/backend.rs +++ b/src/plugins/ai/backend.rs @@ -125,26 +125,32 @@ impl AiBackend for LocalCliBackend { history: &[(String, String)], max_tokens: u16, ) -> Result { - // 构造 llama-cli 对话 prompt - // 格式参考 spike: llama-cli -m -p -n -t 2 -c 1024 --temp 0.7 + // 对齐 spike (2026-07-03) 验证的调用方式: + // llama-cli --single-turn --no-warmup -sys -p -n -t 2 -c 1024 --temp 0.7 + // + // 关键参数: + // --single-turn 单轮模式,生成完即退出(否则进交互模式等待 stdin,永远不退出) + // --no-warmup 跳过预热(减少延迟) + // -sys system prompt(角色人设) + // -p 用户输入(只传当前消息,历史通过 context 另传,V1 简化) + // + // 历史上下文 V1 简化处理:拼到 -p 里(小模型 ctx 1024 有限,只保留最近 2 轮) let mut prompt = String::new(); - prompt.push_str(&format!("system\n{persona}\n")); - for (role, content) in history { - prompt.push_str(role); - prompt.push('\n'); - prompt.push_str(content); - prompt.push('\n'); + for (role, content) in history.iter().rev().take(4) { + // 逆序取最近 2 轮(4 条消息),正序拼接 + prompt.insert_str(0, &format!("{content}\n")); } - prompt.push_str("user\n"); prompt.push_str(user_message); - prompt.push('\n'); - prompt.push_str("assistant\n"); let tokens = if max_tokens == 0 { 128 } else { max_tokens as u32 }; let output = Command::new(self.llama_cli()) + .arg("--single-turn") + .arg("--no-warmup") .arg("-m") .arg(model_path) + .arg("-sys") + .arg(persona) .arg("-p") .arg(&prompt) .arg("-n") @@ -160,7 +166,8 @@ impl AiBackend for LocalCliBackend { if !output.status.success() { bail!( - "llama-cli 失败: {}", + "llama-cli 失败 (exit={}): {}", + output.status, String::from_utf8_lossy(&output.stderr) ); }