介绍:想让AI智能体像人一样"学以致用"?Spring AI Alibaba的Skills机制,通过"渐进式披露"让模型按需加载专业知识,既省Token又强能力。Skills是可复用的指令与上下文包,智能体在遇到相关任务时会自动发现并使用。核心设计:渐进式披露传统方式:把所有技能说明一股脑塞进系统提示->上下文臃肿、成本高
Skills方式分三步走:- 1.清单注入:系统提示中只注入技能列表(名称+简短描述+路径)- 2.按需加载:模型判断需要某技能时,调用read_skill(skill_name)加载完整SKILL.md- 3.资源访问:根据技能目录下的资源(脚本、参考文档等)执行具体操作
这种方式大幅降低了初始上下文长度,让模型能够"按需学习"。每个技能都是一个独立目录,必须包含SKILL.md:skills/├── pdf-extractor/│ ├── SKILL.md # 必需:技能定义文件│ ├── references/ # 可选:参考文档│ ├── examples/ # 可选:示例│ └── scripts/ # 可选:辅助脚本├── code-reviewer/│ └── SKILL.md└── data-analyzer/ └── SKILL.md
---name: pdf-extractordescription: 从PDF文档中提取文本、表格和关键信息。当用户需要处理PDF文件时使用此技能。---# PDF提取器技能## 功能说明- 提取PDF中的纯文本- 识别并提取表格数据- 获取文档元信息## 使用方法1. 提供PDF文件路径2. 指定需要提取的内容类型3. 获得结构化结果## 依赖工具- Python: PyPDF2库- Shell: pdftotext命令
- name:技能唯一标识(小写字母、数字、连字符,最长64字符)
- description:技能描述(会被注入系统提示,过长会被截断)
import com.alibaba.cloud.ai.graph.agent.ReactAgent;import com.alibaba.cloud.ai.graph.agent.hook.skills.SkillsAgentHook;import com.alibaba.cloud.ai.graph.skills.registry.filesystem.FileSystemSkillRegistry;// 1. 创建技能注册表(从项目目录加载)SkillRegistry registry = FileSystemSkillRegistry.builder() .projectSkillsDirectory(System.getProperty("user.dir") + "/skills") .build();// 2. 创建Skills HookSkillsAgentHook skillsHook = SkillsAgentHook.builder() .skillRegistry(registry) .build();// 3. 构建Agent并挂载HookReactAgent agent = ReactAgent.builder() .name("skills-agent") .model(chatModel) .saver(new MemorySaver()) .hooks(List.of(skillsHook)) .build();// 4. 使用agent.call("请介绍你有哪些技能");// 模型会先列出可用技能清单agent.call("请帮我从这份PDF中提取文本: /path/to/doc.pdf");// 模型会自动调用read_skill('pdf-extractor')加载完整技能说明
- userSkillsDirectory:用户级技能目录(默认~/saa/skills)
- projectSkillsDirectory:项目级技能目录(默认./skills)
SkillRegistry registry = ClasspathSkillRegistry.builder() .classpathPath("skills") // 从src/main/resources/skills加载 .basePath("/tmp/skills") // JAR内资源复制到的临时目录(可选) .build();SkillsAgentHook hook = SkillsAgentHook.builder() .skillRegistry(registry) .build();
真实场景中,技能往往需要执行脚本(Python/Shell)来完成具体任务。下面是一个完整的集成示例:import com.alibaba.cloud.ai.graph.agent.ReactAgent;import com.alibaba.cloud.ai.graph.agent.hook.skills.SkillsAgentHook;import com.alibaba.cloud.ai.graph.agent.hook.shelltool.ShellToolAgentHook;import com.alibaba.cloud.ai.graph.agent.tools.PythonTool;import com.alibaba.cloud.ai.graph.agent.tools.ShellTool2;import com.alibaba.cloud.ai.graph.skills.registry.classpath.ClasspathSkillRegistry;// 1. 技能注册表(从classpath加载)SkillRegistry registry = ClasspathSkillRegistry.builder() .classpathPath("skills") .build();// 2. Skills Hook:提供read_skill工具 + 技能列表注入SkillsAgentHook skillsHook = SkillsAgentHook.builder() .skillRegistry(registry) .build();// 3. Shell Hook:提供Shell命令执行能力ShellToolAgentHook shellHook = ShellToolAgentHook.builder() .shellTool2(ShellTool2.builder(System.getProperty("user.dir")).build()) .build();// 4. 构建AgentReactAgent agent = ReactAgent.builder() .name("skills-integration-agent") .model(chatModel) .saver(new MemorySaver()) .tools(PythonTool.createPythonToolCallback(PythonTool.DESCRIPTION)) .hooks(List.of(skillsHook, shellHook)) .enableLogging(true) .build();// 5. 调用示例String skillFilePath = "/path/to/skills/pdf-extractor/saa-roadmap.pdf";AssistantMessage response = agent.call("请从 " + skillFilePath + " 文件中提取关键信息。");
- 调用read_skill('pdf-extractor')加载完整技能说明
除了技能内容,你还可以让工具也跟随技能按需激活——只有当模型调用了read_skill后,该技能绑定的工具才会被注册。// 定义工具ToolCallback pdfTool = FunctionToolCallback.builder("extract_pdf", new PdfExtractor()) .description("提取PDF内容") .build();// 将工具绑定到技能Map<String, List<ToolCallback>> groupedTools = Map.of( "pdf-extractor", // 与SKILL.md中的name一致 List.of(pdfTool));SkillsAgentHook hook = SkillsAgentHook.builder() .skillRegistry(registry) .groupedTools(groupedTools) // 技能激活后才暴露工具 .build();
优势:避免模型过早接触不相关的工具,减少工具选择的困惑。SkillsAgentHook hook = SkillsAgentHook.builder() .skillRegistry(registry) .autoReload(true) // 每次Agent执行前重新加载技能 .build();
SystemPromptTemplate customTemplate = SystemPromptTemplate.builder() .template("## 可用技能\n{skills_list}\n\n## 加载方法\n{skills_load_instructions}") .build();SkillRegistry registry = FileSystemSkillRegistry.builder() .projectSkillsDirectory("./skills") .systemPromptTemplate(customTemplate) .build();
- {skills_load_instructions}:加载说明(如何使用read_skill)
SkillRegistry registry = FileSystemSkillRegistry.builder() .userSkillsDirectory("/home/user/saa/skills") // 通用技能 .projectSkillsDirectory("/app/project/skills") // 项目特定技能 .build();// 同名技能:项目级覆盖用户级
步骤六:在Graph/ChatClient中使用Skills除ReactAgent外,你也可以通过以下方式使用import org.springframework.ai.chat.client.ChatClient;import com.alibaba.cloud.ai.graph.advisors.SkillPromptAugmentAdvisor;// 创建AdvisorSkillPromptAugmentAdvisor skillAdvisor = SkillPromptAugmentAdvisor.builder() .projectSkillsDirectory("./skills") .build();// 集成到ChatClientChatClient chatClient = ChatClient.builder(chatModel) .defaultAdvisors(skillAdvisor) .build();// 调用时系统提示中会包含技能列表String response = chatClient.prompt() .user("请介绍你有哪些技能") .call() .content();
eg:这种方式下,模型无法按需加载完整SKILL.md,如需完整Skills体验(渐进式披露),请使用ReactAgent+SkillsAgentHook。本人正在打造技术交流群,欢迎志同道合的朋友一起探讨,一起努力,通过自己的努力,在技术岗位这条道路上走得更远。QQ群号:952912771 备注:技术交流 即可通过!加入技术群可以获取资料,含AI资料、Spring AI中文文档等,等你加入~想从AI小白成长为独当一面的开发者?这份Spring AI Alibaba系列文章合集,为你提供手把手、保姆级的学习路径,助你顺利拿下心仪offer。