refactor(skills): progressive skill loading — avoid duplicate injection
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
When SkillIndexMiddleware is active, build_system_prompt_with_skills no longer injects the full categorized skill list. Instead it only adds usage instructions, while the middleware handles the lightweight index. This reduces ~2000 tokens per request for the 75-skill system.
This commit is contained in:
@@ -229,35 +229,54 @@ impl Kernel {
|
||||
.map(|p| p.clone())
|
||||
.unwrap_or_else(|| "You are a helpful AI assistant.".to_string());
|
||||
|
||||
// Inject skill metadata only (progressive loading pattern from DeerFlow).
|
||||
// Full skill content is loaded on-demand via `load_skill_content` tool.
|
||||
// Progressive skill loading (DeerFlow pattern):
|
||||
// If the SkillIndexMiddleware is registered in the middleware chain,
|
||||
// it will inject a lightweight index at priority 200.
|
||||
// We still inject a basic instruction block here for when middleware is not active.
|
||||
//
|
||||
// When middleware IS active, avoid duplicate injection by only keeping
|
||||
// the skill-use instructions (not the full list).
|
||||
let skill_index_active = {
|
||||
use zclaw_runtime::tool::SkillExecutor;
|
||||
!self.skill_executor.list_skill_index().is_empty()
|
||||
};
|
||||
|
||||
if !skills.is_empty() {
|
||||
prompt.push_str("\n\n## Available Skills\n\n");
|
||||
prompt.push_str("You have access to specialized skills. Analyze user intent and autonomously call `execute_skill` with the appropriate skill_id.\n\n");
|
||||
if skill_index_active {
|
||||
// Middleware will inject the index — only add usage instructions
|
||||
prompt.push_str("\n\n## Skills\n\n");
|
||||
prompt.push_str("You have access to specialized skills listed in the skill index above. ");
|
||||
prompt.push_str("Analyze user intent and autonomously call `skill_load` to inspect a skill, ");
|
||||
prompt.push_str("then `execute_skill` with the appropriate skill_id.\n\n");
|
||||
prompt.push_str("- **IMPORTANT**: Autonomously decide when to use skills based on user intent.\n");
|
||||
prompt.push_str("- Do not wait for explicit skill names — recognize the need and act.\n");
|
||||
prompt.push_str("- If unsure about a skill, call `skill_load` first to understand its parameters.\n");
|
||||
} else {
|
||||
// No middleware — inject full skill list as fallback
|
||||
prompt.push_str("\n\n## Available Skills\n\n");
|
||||
prompt.push_str("You have access to specialized skills. Analyze user intent and autonomously call `execute_skill` with the appropriate skill_id.\n\n");
|
||||
|
||||
// Group skills by category based on their ID patterns
|
||||
let categories = self.categorize_skills(&skills);
|
||||
|
||||
for (category, category_skills) in categories {
|
||||
prompt.push_str(&format!("### {}\n", category));
|
||||
for skill in category_skills {
|
||||
prompt.push_str(&format!(
|
||||
"- **{}**: {}",
|
||||
skill.id.as_str(),
|
||||
skill.description
|
||||
));
|
||||
let categories = self.categorize_skills(&skills);
|
||||
for (category, category_skills) in categories {
|
||||
prompt.push_str(&format!("### {}\n", category));
|
||||
for skill in category_skills {
|
||||
prompt.push_str(&format!(
|
||||
"- **{}**: {}",
|
||||
skill.id.as_str(),
|
||||
skill.description
|
||||
));
|
||||
prompt.push('\n');
|
||||
}
|
||||
prompt.push('\n');
|
||||
}
|
||||
prompt.push('\n');
|
||||
}
|
||||
|
||||
prompt.push_str("### When to use skills:\n");
|
||||
prompt.push_str("- **IMPORTANT**: You should autonomously decide when to use skills based on your understanding of the user's intent.\n");
|
||||
prompt.push_str("- Do not wait for explicit skill names - recognize the need and act.\n");
|
||||
prompt.push_str("- Match user's request to the most appropriate skill's domain.\n");
|
||||
prompt.push_str("- If multiple skills could apply, choose the most specialized one.\n\n");
|
||||
prompt.push_str("### Example:\n");
|
||||
prompt.push_str("User: \"分析腾讯财报\" → Intent: Financial analysis → Call: execute_skill(\"finance-tracker\", {...})\n");
|
||||
prompt.push_str("### When to use skills:\n");
|
||||
prompt.push_str("- **IMPORTANT**: You should autonomously decide when to use skills based on your understanding of the user's intent.\n");
|
||||
prompt.push_str("- Do not wait for explicit skill names - recognize the need and act.\n");
|
||||
prompt.push_str("- Match user's request to the most appropriate skill's domain.\n\n");
|
||||
prompt.push_str("### Example:\n");
|
||||
prompt.push_str("User: \"分析腾讯财报\" → Intent: Financial analysis → Call: execute_skill(\"finance-tracker\", {...})\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-agent delegation instructions (Ultra mode only)
|
||||
|
||||
Reference in New Issue
Block a user