skills - 按需动态加载(和渐进式加载区别)
2026年1月31日 上午9:52:28
很多人会将 Solon AI Skill 的加载机制(“按需动态加载”)与 Claude Agent Skills 的“渐进式加载”做对比。虽然目标都是为了优化上下文,但其 底层原理 和 适用环境 有着本质不同:
1、渐进式加载 vs. 按需动态加载
| 维度 | Claude Agent Skills (渐进式) | Solon AI Skills (按需动态) |
|---|---|---|
| 交付物 | 工具 + Markdown 文档 | 框架 + Java 代码 (Class) |
| 加载逻辑 | 内容分层披露。模型通过阅读 SKILL.md 的摘要决定是否加载全文。 | 逻辑准入拦截。框架通过执行 isSupported 代码决定是否激活功能。 |
| 核心瓶颈 | 解决“说明书”太长,Token 消耗大的问题。 | 解决“逻辑复杂”,环境多变(权限、环境依赖)的问题。 |
| 生效方式 | 主要是文本层面的“可见性”切换。 | 主要是程序层面的“功能热插拔”。 |
| 优势场景 | 静态的、文档密集型的辅助工具。 | 动态的、工程化的生产力系统。 |
Claude 的方式是让 AI “看文档”来决定要不要继续看;而 Solon AI 是让程序“跑代码”来决定要不要给 AI 用。
2、“按需动态加载”过程的两个阶段
- 第一阶段,配置挂载 (Configuring)
将 Skill 放入“待选池”。此时 AI 不感知该技能,不消耗 Token。
// a. 静态构建时添加(全局生效的候选技能)
ChatModel agent = ChatModel.of("https://api.moark.com/v1/chat/completions")
.apiKey("***")
.model("Qwen3-32B")
.role("财务数据分析师")
.instruction("你负责分析订单与退款数据。金额单位均为元。")
.defaultSkillAdd(sqlSkill) // 注入 SQL 技能
.build();
// b. 请求时动态添加(仅本次请求生效的候选技能)
agent.prompt("去年消费最高的 VIP 客户是谁?")
.options(o->{
o.skillAdd(sqlSkill);
})
- 第二阶段,请求时“按需激活” (Activating)
当调用 .call() 或 .stream() 时,引擎进入 prepare 阶段。此时,系统会实时轮询待选池。
// 引擎内部 prepare 处理逻辑简化示意
private SystemMessage prepare() {
// a. 拼接角色与指令
StringBuilder systemMessage = new StringBuilder();
if (Assert.isNotEmpty(options.role())) {
systemMessage.append("## 你的角色\n").append(options.role()).append("\n\n");
}
if (Assert.isNotEmpty(options.instruction())) {
systemMessage.append("## 执行指令\n").append(options.instruction());
}
// b. 动态激活技能(核心环节)
// SkillUtil 会遍历候选技能,仅当 isSupported 为 true 时,
// 才会调用 getInstruction 和 getTools 并注入上下文。
SkillUtil.activeSkills(options, originalPrompt, systemMessage);
if (systemMessage.length() > 0) {
return ChatMessage.ofSystem(systemMessage.toString());
} else {
return null;
}
}