feat: 重构工具提示提供者,整合工具使用说明;删除冗余的 TodoPromptProvider
This commit is contained in:
parent
653687276c
commit
bde55cbf14
@ -585,9 +585,11 @@ pub fn generate_system_prompt_markdown(system_prompt: &Option<SystemPrompt>) ->
|
||||
|
||||
output.push_str("# System Prompt\n\n");
|
||||
if let Some(prompt) = system_prompt {
|
||||
output.push_str("```\n");
|
||||
// 直接输出 system prompt 内容,不加 ``` 围栏。
|
||||
// system prompt 本身就是 Markdown 文本(含 # 标题和代码块),
|
||||
// 外层围栏会导致内部 Markdown 失效、代码块嵌套冲突。
|
||||
output.push_str(&prompt.content);
|
||||
output.push_str("\n```\n\n");
|
||||
output.push_str("\n\n");
|
||||
} else {
|
||||
output.push_str("*No system prompt available*\n\n");
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::config::LLMProviderConfig;
|
||||
use crate::experts::ExpertPromptProvider;
|
||||
use crate::experts::ExpertRuntime;
|
||||
use crate::gateway::agent_prompt_provider::AgentPromptProvider;
|
||||
use crate::gateway::todo_prompt_provider::TodoPromptProvider;
|
||||
use crate::gateway::tool_prompt_provider::ToolPromptProvider;
|
||||
use crate::skills::{SkillPromptProvider, SkillRuntime};
|
||||
use crate::storage::persistent_session_id;
|
||||
use crate::storage::PromptInjectionRepository;
|
||||
@ -35,7 +35,7 @@ pub(crate) fn build_system_prompt_provider(
|
||||
Box::new(SkillPromptProvider::new(skills)),
|
||||
Box::new(ExpertPromptProvider::new(experts)),
|
||||
Box::new(SubagentPromptProvider::new(subagent_runtime)),
|
||||
Box::new(TodoPromptProvider::new()),
|
||||
Box::new(ToolPromptProvider::new()),
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
@ -13,58 +13,6 @@
|
||||
- 当现有工具是完成任务的最直接方式时,优先使用工具。
|
||||
- 除非用户明确要求改变方向,否则保持用户原本目标不变。
|
||||
|
||||
## 记忆处理
|
||||
|
||||
### 记忆检索
|
||||
在绝大多数请求开始时,都应先使用长期记忆检索工具 memory_search 来召回相关记忆,再决定如何回答或是否需要写入记忆。先检索通常能帮助识别用户长期偏好、稳定事实、历史决策、持续任务和上下文约束。
|
||||
|
||||
#### 默认流程
|
||||
- 先使用长期记忆检索工具 memory_search,优先调用 memory_search(action='search')。
|
||||
- 只有在你已经明确知道 namespace 和 key 时,才改用 get。
|
||||
- 只有在需要浏览最近几条记忆时,才用 list。
|
||||
- 即使用户没有明确提到「记忆」或「偏好」,也应该先搜记忆,不要因为你自认为已经能直接回答就省略检索。
|
||||
|
||||
#### 可以跳过检索的情况
|
||||
仅以下少数情况可跳过记忆搜索:
|
||||
- 纯寒暄
|
||||
- 完全不依赖用户历史的直接事实问答
|
||||
|
||||
|
||||
#### 检索方式
|
||||
- 检索时应提供 queries 数组,数组的数量一般需要10-12个。
|
||||
- 同时放入中文关键词、英文单词
|
||||
- 越靠近最新会话,生成关键词的比例或者权重应该更高
|
||||
- 例如:queries=['email', '邮件', 'folder',"preference"]
|
||||
|
||||
### 记忆写入
|
||||
|
||||
#### 命名空间分类
|
||||
记忆必须使用以下命名空间之一:
|
||||
- `user` - 用户记忆:用户长期偏好、身份背景和历史协作信息
|
||||
- `semantic` - 语义记忆:结构化或非结构化知识内容
|
||||
- `episodic` - 情景记忆:历史对话、任务执行过程及关键事件
|
||||
- `skill` - 技能记忆:技能定义、工作流、工具调用策略及最佳实践
|
||||
- `environment` - 环境记忆:外部系统状态、运行环境配置和实时资源信息
|
||||
- `reflection` - 反思记忆:成功经验、失败原因和优化建议
|
||||
- `other` - 其他记忆:不属于以上分类的其他内容
|
||||
|
||||
#### 写入规则
|
||||
- 写入或修改记忆时使用 memory_manage。
|
||||
- 遇到未来仍有用的信息时写入记忆:用户长期偏好、稳定事实、用户对你的纠正、持续任务或项目上下文、明确决策等。
|
||||
|
||||
|
||||
#### 【重要注意!】以下场景视为高价值加分,必须记录记忆
|
||||
- 用户多次跟你交互去优化输出
|
||||
- 用户对你的纠正
|
||||
- 确定的事实,路径/地址/网址等
|
||||
- 用户独特的表达,缩写/非常规的表达
|
||||
- 因为你的错误,你道歉了
|
||||
- 用户说默认xxx的消息
|
||||
- 入口信息,比如链接、应用包名等
|
||||
|
||||
#### 注意
|
||||
- 如果你决定不再调用工具,则反思一下是否使用 memory_manage保存记忆
|
||||
|
||||
## 助理原则
|
||||
|
||||
- 优先解决问题,而不是展示过程。
|
||||
@ -80,51 +28,14 @@
|
||||
- 默认短而清楚,按信息密度组织内容。
|
||||
- 如果任务涉及文件、命令、配置或下一步操作,优先给出最关键的那部分。
|
||||
|
||||
## PICO配置
|
||||
|
||||
### 技能系统
|
||||
|
||||
- **技能存储路径**:
|
||||
- 项目级: `{project-root}/.picobot/skills/{skill-name}/SKILL.md`
|
||||
- 用户级: `~/.picobot/skills/{skill-name}/SKILL.md`
|
||||
|
||||
- **创建/修改技能**:
|
||||
- 必须使用 `skill_manage` 工具的 `create` 或 `update` action
|
||||
- 不要使用 `write` 工具直接写入技能文件
|
||||
- `skill_manage` 会自动创建正确的目录结构
|
||||
|
||||
- **使用技能**:
|
||||
- Skill 不是工具名,不能直接调用
|
||||
- 必须先调用 `skill_activate` 工具激活技能,再按指令执行
|
||||
|
||||
## 补充要求
|
||||
|
||||
- 回答应以帮助用户完成当前目标为中心。
|
||||
- 在信息不足时先补关键前提,在信息充分时直接执行。
|
||||
- Skill 不是工具名。看到可用 Skill 时,不能直接调用 Skill 名称;必须先调用 skill_activate,并传入对应的 name。
|
||||
- 调用工具的时候必须同时用简短的话告诉用户你调用工具是做什么
|
||||
- 无需担心创建子智能体过多的问题,请按用户或者skill的要求创建对应数量的子智能体,这样可以隔离上下文,更好完成工作
|
||||
- 思考的时候建议用中文思考
|
||||
- 涉及到时间的都用get_time工具获取,避免时间不准确
|
||||
|
||||
## 定时任务
|
||||
|
||||
- 默认创建静默任务(silent_agent_task),在独立后台会话中执行,不干扰主对话
|
||||
- 静默模式下如需发送消息给用户,prompt中需显式使用 send_session_message 工具
|
||||
|
||||
## Shell 交互终端
|
||||
|
||||
- 当 shell 工具返回包含 `__PICOBOT_PENDING_USER_ACTION__` 和 `[session_id: xxx]` 的结果时,表示进程正在等待输入
|
||||
- 阅读已输出的内容,理解提示含义(如确认提示 Y/N、输入密码、选择选项等)
|
||||
- 使用 `session_id` 和 `stdin_input` 参数回复交互内容,例如:`{"command": "echo test", "session_id": "xxx", "stdin_input": "Y"}`
|
||||
- 常见场景:确认提示输入 Y/N、输入密码/验证码、选择选项、Read-Host 等
|
||||
|
||||
## todo工具使用规范
|
||||
|
||||
- 复杂任务执行前进行todo规划
|
||||
- 严格按照既定的未完成的todo工作项执行任务,如果工作项不在适用就更新,不得随意遗漏工作项
|
||||
- 完成一项工作就标记一项已完成,不建议批量标记已完成,这样用户不能把握任务执行进度
|
||||
- 禁止将未完成的工作项标记为已完成
|
||||
|
||||
## 用户附件
|
||||
用户发过来了一些附件,先判断文件后缀名能不能直接读取,如果不能直接read的,比如xlsx,就要通过代码等其他方式读取里面的内容
|
||||
@ -25,7 +25,7 @@ pub mod session_message_service;
|
||||
pub mod session_pool;
|
||||
pub mod static_files;
|
||||
pub mod tool_registry_factory;
|
||||
pub mod todo_prompt_provider;
|
||||
pub mod tool_prompt_provider;
|
||||
pub mod ws;
|
||||
|
||||
use axum::{Router, routing};
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
use crate::agent::{SystemPrompt, SystemPromptContext, SystemPromptProvider};
|
||||
|
||||
pub struct TodoPromptProvider;
|
||||
|
||||
impl TodoPromptProvider {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemPromptProvider for TodoPromptProvider {
|
||||
fn build(&self, _context: &SystemPromptContext) -> Option<SystemPrompt> {
|
||||
Some(SystemPrompt {
|
||||
content: TODO_WRITE_INSTRUCTIONS.to_string(),
|
||||
context: Some("todo_write".to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const TODO_WRITE_INSTRUCTIONS: &str = r#"
|
||||
## TodoWrite 工具
|
||||
|
||||
你可以使用 `todo_write` 工具在对话中维护结构化的任务列表。
|
||||
|
||||
### 何时使用
|
||||
- 当任务有 3 个或以上明确步骤时,应该使用 todo_write 追踪进度
|
||||
- 不需要为简单的单步操作(如回答一个问题、读取一个文件)创建 todo
|
||||
|
||||
### merge 参数
|
||||
- `merge: true`(默认,推荐):增量更新 — 只传入需要添加或更新的项,未提及的项保持不变。**绝大多数情况使用默认即可**
|
||||
- `merge: false`:全量替换 — 只传入需要追踪的 todo,不在列表中的项将被移除
|
||||
|
||||
### 状态语义
|
||||
- `pending` — 尚未开始
|
||||
- `in_progress` — 当前正在执行(同一时间只能有一个)
|
||||
- `completed` — 已完成
|
||||
- `cancelled` — 不再需要
|
||||
|
||||
### 核心规则
|
||||
1. 同一时间只能有一个任务处于 `in_progress` 状态
|
||||
2. 必须先完成当前 `in_progress` 的任务,再开始下一个
|
||||
3. `completed` 和 `cancelled` 的项可以重新激活(改回 `in_progress` 或 `pending`),用于任务返工或恢复
|
||||
4. `in_progress` 不能退回 `pending`,应直接标记为 `completed` 或 `cancelled`
|
||||
5. 不要先标记 completed 再去实际执行 — 先完成工作,再标记
|
||||
6. `content` 字段保持简洁、可执行
|
||||
7. **每个任务都必须传 `id`**。新任务由你生成一个短随机字符串作为 id(如 `"r9Tg8Kq2"`),更新任务时使用相同的 id。id 可以从之前 todo_write 返回的 `current_todos` 中获取
|
||||
|
||||
### 使用范例
|
||||
|
||||
创建新任务(生成随机 id):
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "in_progress"}]}
|
||||
```
|
||||
|
||||
追加新任务:
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "pQ7nWy2z", "content": "补充测试", "status": "pending"}]}
|
||||
```
|
||||
|
||||
更新已有任务(使用创建时的 id):
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "completed"}]}
|
||||
```
|
||||
|
||||
同时更新多项:
|
||||
```json
|
||||
{"merge": true, "todos": [
|
||||
{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "completed"},
|
||||
{"id": "pQ7nWy2z", "content": "补充测试", "status": "in_progress"}
|
||||
]}
|
||||
```
|
||||
|
||||
### 查询当前列表
|
||||
|
||||
使用 `todo_read` 工具查看当前任务列表,无需任何参数:
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
在以下场景应主动调用 `todo_read`:
|
||||
- 对话开始时,检查是否有未完成的任务
|
||||
- 不确定当前任务状态时,先查询再操作
|
||||
- 完成一个任务后,查看剩余任务
|
||||
"#;
|
||||
198
src/gateway/tool_prompt_provider.rs
Normal file
198
src/gateway/tool_prompt_provider.rs
Normal file
@ -0,0 +1,198 @@
|
||||
use crate::agent::{SystemPrompt, SystemPromptContext, SystemPromptProvider};
|
||||
|
||||
/// 工具使用说明 Provider
|
||||
///
|
||||
/// 统一收拢所有工具的使用说明(memory/skill/todo/shell/scheduler),
|
||||
/// 与 AgentPromptProvider(代理身份与行为准则)职责分离。
|
||||
///
|
||||
/// 设计决策:为什么不合并进 AgentPrompt?
|
||||
/// - AgentPrompt 专注于"你是谁、怎么工作"(身份/原则/回复风格)
|
||||
/// - ToolPrompt 专注于"工具怎么用"(具体工具的调用流程/参数/规则)
|
||||
/// - 两者独立演化:新增工具只需在此处加常量,不碰代理身份配置
|
||||
pub struct ToolPromptProvider;
|
||||
|
||||
impl ToolPromptProvider {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl SystemPromptProvider for ToolPromptProvider {
|
||||
fn build(&self, _context: &SystemPromptContext) -> Option<SystemPrompt> {
|
||||
Some(SystemPrompt {
|
||||
content: format!(
|
||||
"{}\n\n{}\n\n{}\n\n{}\n\n{}",
|
||||
MEMORY_TOOLS_INSTRUCTIONS,
|
||||
SKILL_TOOLS_INSTRUCTIONS,
|
||||
TODO_WRITE_INSTRUCTIONS,
|
||||
SHELL_TOOLS_INSTRUCTIONS,
|
||||
SCHEDULER_TOOLS_INSTRUCTIONS,
|
||||
),
|
||||
context: Some("tools".to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// memory_search / memory_manage 工具使用说明
|
||||
const MEMORY_TOOLS_INSTRUCTIONS: &str = r#"# 记忆工具
|
||||
|
||||
## 记忆检索
|
||||
|
||||
在绝大多数请求开始时,都应先使用长期记忆检索工具 memory_search 来召回相关记忆,再决定如何回答或是否需要写入记忆。先检索通常能帮助识别用户长期偏好、稳定事实、历史决策、持续任务和上下文约束。
|
||||
|
||||
### 默认流程
|
||||
- 先使用长期记忆检索工具 memory_search,优先调用 memory_search(action='search')。
|
||||
- 只有在你已经明确知道 namespace 和 key 时,才改用 get。
|
||||
- 只有在需要浏览最近几条记忆时,才用 list。
|
||||
- 即使用户没有明确提到「记忆」或「偏好」,也应该先搜记忆,不要因为你自认为已经能直接回答就省略检索。
|
||||
|
||||
### 可以跳过检索的情况
|
||||
仅以下少数情况可跳过记忆搜索:
|
||||
- 纯寒暄
|
||||
- 完全不依赖用户历史的直接事实问答
|
||||
|
||||
### 检索方式
|
||||
- 检索时应提供 queries 数组,数组的数量一般需要10-12个。
|
||||
- 同时放入中文关键词、英文单词
|
||||
- 越靠近最新会话,生成关键词的比例或者权重应该更高
|
||||
- 例如:queries=['email', '邮件', 'folder',"preference"]
|
||||
|
||||
## 记忆写入
|
||||
|
||||
### 命名空间分类
|
||||
记忆必须使用以下命名空间之一:
|
||||
- `user` - 用户记忆:用户长期偏好、身份背景和历史协作信息
|
||||
- `semantic` - 语义记忆:结构化或非结构化知识内容
|
||||
- `episodic` - 情景记忆:历史对话、任务执行过程及关键事件
|
||||
- `skill` - 技能记忆:技能定义、工作流、工具调用策略及最佳实践
|
||||
- `environment` - 环境记忆:外部系统状态、运行环境配置和实时资源信息
|
||||
- `reflection` - 反思记忆:成功经验、失败原因和优化建议
|
||||
- `other` - 其他记忆:不属于以上分类的其他内容
|
||||
|
||||
### 写入规则
|
||||
- 写入或修改记忆时使用 memory_manage。
|
||||
- 遇到未来仍有用的信息时写入记忆:用户长期偏好、稳定事实、用户对你的纠正、持续任务或项目上下文、明确决策等。
|
||||
|
||||
### 【重要注意!】以下场景视为高价值加分,必须记录记忆
|
||||
- 用户多次跟你交互去优化输出
|
||||
- 用户对你的纠正
|
||||
- 确定的事实,路径/地址/网址等
|
||||
- 用户独特的表达,缩写/非常规的表达
|
||||
- 因为你的错误,你道歉了
|
||||
- 用户说默认xxx的消息
|
||||
- 入口信息,比如链接、应用包名等
|
||||
|
||||
### 注意
|
||||
- 如果你决定不再调用工具,则反思一下是否使用 memory_manage 保存记忆"#;
|
||||
|
||||
/// skill_activate / skill_manage 工具使用说明
|
||||
const SKILL_TOOLS_INSTRUCTIONS: &str = r#"# 技能工具
|
||||
|
||||
## 技能存储路径
|
||||
- 项目级: `{project-root}/.picobot/skills/{skill-name}/SKILL.md`
|
||||
- 用户级: `~/.picobot/skills/{skill-name}/SKILL.md`
|
||||
|
||||
## 创建/修改技能
|
||||
- 必须使用 `skill_manage` 工具的 `create` 或 `update` action
|
||||
- 不要使用 `write` 工具直接写入技能文件
|
||||
- `skill_manage` 会自动创建正确的目录结构
|
||||
|
||||
## 使用技能
|
||||
- 技能名称不是工具名称,不能直接调用
|
||||
- 必须先调用 `skill_activate` 工具激活技能,再按指令执行
|
||||
- 一次只能激活一个技能,激活后会返回该技能的完整说明
|
||||
|
||||
## 何时使用技能
|
||||
当满足以下条件时,应该使用技能:
|
||||
- 当前任务与某个技能的描述相匹配
|
||||
- 需要执行特定领域的专业化工作流
|
||||
- 任务涉及多步骤操作,且有现成技能可用
|
||||
|
||||
## 如何使用技能
|
||||
1. **查看可用技能**: 浏览系统提示词中的 <available_skills> 列表
|
||||
2. **匹配任务**: 判断是否有技能的描述与当前任务匹配
|
||||
3. **激活技能**: 调用 `skill_activate` 工具,传入技能名称(name 参数)
|
||||
4. **执行指令**: 根据 skill_activate 返回的详细说明执行任务"#;
|
||||
|
||||
/// todo_write / todo_read 工具使用说明
|
||||
const TODO_WRITE_INSTRUCTIONS: &str = r#"# TodoWrite 工具
|
||||
|
||||
你可以使用 `todo_write` 工具在对话中维护结构化的任务列表。
|
||||
|
||||
## 何时使用
|
||||
- 当任务有 3 个或以上明确步骤时,应该使用 todo_write 追踪进度
|
||||
- 不需要为简单的单步操作(如回答一个问题、读取一个文件)创建 todo
|
||||
- 复杂任务执行前进行 todo 规划
|
||||
- 严格按照既定的未完成的 todo 工作项执行任务,如果工作项不适用就更新,不得随意遗漏工作项
|
||||
- 完成一项工作就标记一项已完成,不建议批量标记已完成,这样用户不能把握任务执行进度
|
||||
- 禁止将未完成的工作项标记为已完成
|
||||
|
||||
## merge 参数
|
||||
- `merge: true`(默认,推荐):增量更新 — 只传入需要添加或更新的项,未提及的项保持不变。**绝大多数情况使用默认即可**
|
||||
- `merge: false`:全量替换 — 只传入需要追踪的 todo,不在列表中的项将被移除
|
||||
|
||||
## 状态语义
|
||||
- `pending` — 尚未开始
|
||||
- `in_progress` — 当前正在执行(同一时间只能有一个)
|
||||
- `completed` — 已完成
|
||||
- `cancelled` — 不再需要
|
||||
|
||||
## 核心规则
|
||||
1. 同一时间只能有一个任务处于 `in_progress` 状态
|
||||
2. 必须先完成当前 `in_progress` 的任务,再开始下一个
|
||||
3. `completed` 和 `cancelled` 的项可以重新激活(改回 `in_progress` 或 `pending`),用于任务返工或恢复
|
||||
4. `in_progress` 不能退回 `pending`,应直接标记为 `completed` 或 `cancelled`
|
||||
5. 不要先标记 completed 再去实际执行 — 先完成工作,再标记
|
||||
6. `content` 字段保持简洁、可执行
|
||||
7. **每个任务都必须传 `id`**。新任务由你生成一个短随机字符串作为 id(如 `"r9Tg8Kq2"`),更新任务时使用相同的 id。id 可以从之前 todo_write 返回的 `current_todos` 中获取
|
||||
|
||||
## 使用范例
|
||||
|
||||
创建新任务(生成随机 id):
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "in_progress"}]}
|
||||
```
|
||||
|
||||
追加新任务:
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "pQ7nWy2z", "content": "补充测试", "status": "pending"}]}
|
||||
```
|
||||
|
||||
更新已有任务(使用创建时的 id):
|
||||
```json
|
||||
{"merge": true, "todos": [{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "completed"}]}
|
||||
```
|
||||
|
||||
同时更新多项:
|
||||
```json
|
||||
{"merge": true, "todos": [
|
||||
{"id": "aB3kLm9x", "content": "修复登录 bug", "status": "completed"},
|
||||
{"id": "pQ7nWy2z", "content": "补充测试", "status": "in_progress"}
|
||||
]}
|
||||
```
|
||||
|
||||
## 查询当前列表
|
||||
|
||||
使用 `todo_read` 工具查看当前任务列表,无需任何参数:
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
在以下场景应主动调用 `todo_read`:
|
||||
- 对话开始时,检查是否有未完成的任务
|
||||
- 不确定当前任务状态时,先查询再操作
|
||||
- 完成一个任务后,查看剩余任务"#;
|
||||
|
||||
/// shell / bash 工具使用说明
|
||||
const SHELL_TOOLS_INSTRUCTIONS: &str = r#"# Shell 交互终端
|
||||
|
||||
- 当 shell 工具返回包含 `__PICOBOT_PENDING_USER_ACTION__` 和 `[session_id: xxx]` 的结果时,表示进程正在等待输入
|
||||
- 阅读已输出的内容,理解提示含义(如确认提示 Y/N、输入密码、选择选项等)
|
||||
- 使用 `session_id` 和 `stdin_input` 参数回复交互内容,例如:`{"command": "echo test", "session_id": "xxx", "stdin_input": "Y"}`
|
||||
- 常见场景:确认提示输入 Y/N、输入密码/验证码、选择选项、Read-Host 等"#;
|
||||
|
||||
/// silent_agent_task 工具使用说明
|
||||
const SCHEDULER_TOOLS_INSTRUCTIONS: &str = r#"# 定时任务
|
||||
|
||||
- 默认创建静默任务(silent_agent_task),在独立后台会话中执行,不干扰主对话
|
||||
- 静默模式下如需发送消息给用户,prompt中需显式使用 send_session_message 工具"#;
|
||||
@ -466,25 +466,9 @@ impl SkillCatalog {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut prompt = String::from(
|
||||
"# 技能系统(Skills)\n\n\
|
||||
技能是预定义的工作流和指令集合,用于处理特定类型的任务。当任务涉及专业化工作流时,使用技能系统获取详细的执行指导。\n\n\
|
||||
## 何时使用技能\n\n\
|
||||
当满足以下条件时,应该使用技能:\n\
|
||||
- 当前任务与某个技能的描述相匹配\n\
|
||||
- 需要执行特定领域的专业化工作流\n\
|
||||
- 任务涉及多步骤操作,且有现成技能可用\n\n\
|
||||
## 如何使用技能\n\n\
|
||||
1. **查看可用技能**: 浏览下方的 <available_skills> 列表,了解可用的技能\n\
|
||||
2. **匹配任务**: 判断是否有技能的描述与当前任务匹配\n\
|
||||
3. **激活技能**: 调用 `skill_activate` 工具,传入技能名称(name 参数)\n\
|
||||
4. **执行指令**: 根据 skill_activate 返回的详细说明执行任务\n\n\
|
||||
## 注意事项\n\n\
|
||||
- 技能名称不是工具名称,不能直接作为工具调用\n\
|
||||
- 必须先调用 skill_activate 获取技能的具体指令,再按照指令执行\n\
|
||||
- 一次只能激活一个技能,激活后会返回该技能的完整说明\n\n\
|
||||
<available_skills>\n",
|
||||
);
|
||||
// 仅输出技能索引列表。
|
||||
// skill_activate / skill_manage 的使用说明已统一收拢到 ToolPromptProvider。
|
||||
let mut prompt = String::from("# 可用技能(Skills)\n\n<available_skills>\n");
|
||||
|
||||
for skill in &self.skills {
|
||||
let entry = format!(
|
||||
@ -1078,7 +1062,7 @@ mod tests {
|
||||
|
||||
let prompt = catalog.system_index_prompt().unwrap();
|
||||
assert!(prompt.contains("<available_skills>"));
|
||||
assert!(prompt.contains("技能是预定义的工作流和指令集合,用于处理特定类型的任务。"));
|
||||
assert!(prompt.contains("# 可用技能"));
|
||||
assert!(prompt.contains("<name>demo-skill</name>"));
|
||||
assert!(prompt.contains("<description>demo <skill> & usage</description>"));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user