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

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:
iven
2026-04-06 13:11:49 +08:00
parent 9871c254be
commit c3ab7985d2

View File

@@ -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)