跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaAIjava

Spring AI Agent Skills 接入实战指南

Spring AI Agent Skills 允许开发者将模块化能力注入智能体。如何在 Spring AI 项目中配置 Maven 依赖与环境变量,定义了包含元数据和指令的 SKILL.md 文件结构。通过 SkillsTool 注册技能目录并结合 ChatClient 进行工具回调构建,实现了大模型对自定义技能的动态发现与调用。源码分析揭示了从文件扫描、元数据解析到函数执行的完整链路,帮助开发者理解底层机制并落地实践。

草莓泡芙发布于 2026/3/23更新于 2026/9/1057 浏览
Spring AI Agent Skills 接入实战指南

引言

Agent Skills 旨在将模块化、可复用的能力注入到智能体中。本文聚焦于如何在 Spring AI 环境下快速集成 Skills,并解析其背后的实现机制。

环境准备

Maven 依赖

官方文档建议 Spring AI 版本不低于 2.0.0-M2。以下是项目所需的依赖配置:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.2</version>
    <relativePath/>
</parent>
<properties>
    <java.version>21</java.version>
    <spring-ai.version>2.0.0-M2</spring-ai.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>
    <!-- 引入社区实现的 skills 工具 -->
    <dependency>
        <groupId>org.springaicommunity</groupId>
        <artifactId>spring-ai-agent-utils</artifactId>
        <version>0.4.2</version>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

注:实测 Spring Boot 3.5.10、JDK 17 配合 Spring AI 1.1.2 也能运行,具体视环境稳定性而定。

配置文件

server:
  port: 8080
spring:
  application:
    name: pocketmind-server
  ai:
    chat:
      client:
        observations:
          log-prompt: true
          log-completion: true
        openai:
          api-key: xxxx # 替换为你的 API Key
          base-url: xxxx # 替换为你的 Base URL,无需 /v1
        chat:
          options:
            model: deepseek-chat # 替换为你使用的模型名称

示例采用 OpenAI 兼容接口,若需适配 Anthropic 等其他厂商,请参照对应文档调整配置。

定义 Skill

在根目录下创建技能目录,结构如下:

my-skill/
├── SKILL.md       # 必需:指令 + 元数据
├── scripts/       # 可选:可执行代码
├── references/    # 可选:文档
└── assets/        # 可选:模板、资源

SKILL.md 文件必须包含 FrontMatter(元信息)和正文内容。FrontMatter 用于描述技能名称和用途,正文则是具体的 Prompt 指令。

---
name: code-reviewer
description: Reviews Java code for best practices, security issues, and Spring Framework conventions. Use when user asks to review, analyze, or audit code
---
# Code Reviewer
## Instructions
When reviewing code:
1. Check **for** security vulnerabilities (SQL injection, XSS, etc.)
2. Verify Spring Boot best practices (proper use of @Service, @Repository, etc.)
3. Look **for** potential null pointer exceptions
4. Suggest improvements **for** readability and maintainability
5. Provide specific line-by-line feedback with code examples

接入实现

Controller 配置

通过 SkillsTool 注册技能目录,并配合 ChatClient 使用。

import org.springaicommunity.agent.tools.FileSystemTools;
import org.springaicommunity.agent.tools.ShellTools;
import org.springaicommunity.agent.tools.SkillsTool;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

@RestController
@RequestMapping("/demo")
public class SkillController {
    private final ChatClient chatClient;

    public SkillController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder
                .defaultToolCallbacks(SkillsTool.builder()
                        .addSkillsDirectory(".claude/skills")
                        // 也可以使用下面这个
                        //.addSkillsResource(resourceLoader.getResource("classpath:.claude/skills"))
                        .build())
                .defaultTools(FileSystemTools.builder().build())
                .defaultTools(ShellTools.builder().build())
                .defaultToolContext(Map.of("foo", "bar")) // 添加工具上下文,防止构建报错
                .build();
    }

    /**
     * 测试 skill 流程
     */
    @PostMapping("/skill")
    public String chat(@RequestBody String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

这里的关键在于 ChatClient.Builder 的构建过程。defaultToolCallbacks 负责加载已组装好的工具包(含逻辑与 Schema),defaultTools 注册系统级工具以支持动态发现,而 defaultToolContext 则提供了必要的上下文参数,避免框架初始化时的潜在错误。请求链路通过 .user() 加载提示词,由框架内部处理 LLM 调用,最后通过 .content() 获取结果。

源码解析

目录设置

SkillsTool 的 Builder 模式支持添加多个技能路径。

public static class Builder {
    private List<Skill> skills = new ArrayList<>();
    private String toolDescriptionTemplate = TOOL_DESCRIPTION_TEMPLATE;

    protected Builder() {}

    public Builder addSkillsResources(List<Resource> skillsRootPaths) { ... }
    public Builder addSkillsDirectory(String skillsRootDirectory) { ... }
    // ...
}

toolDescriptionTemplate 用于定义技能描述的展示格式。

加载元数据

加载器会递归查找指定文件夹下的 SKILL.md 文件。

private static List<Skill> skills(String rootDirectory) throws IOException {
    Path rootPath = Paths.get(rootDirectory);
    if (!Files.exists(rootPath)) { ... }
    List<Skill> skillFiles = new ArrayList<>();
    try (Stream<Path> paths = Files.walk(rootPath)) {
        paths.filter(Files::isRegularFile)
             .filter(path -> path.getFileName().toString().equals("SKILL.md"))
             .forEach(path -> {
                 try {
                     String markdown = Files.readString(path, StandardCharsets.UTF_8);
                     MarkdownParser parser = new MarkdownParser(markdown);
                     skillFiles.add(new Skill(path, parser.getFrontMatter(), parser.getContent()));
                 } catch (IOException e) { ... }
             });
    }
    return skillFiles;
}

解析过程分为两部分:FrontMatter 提取技能名称和描述,Content 提取具体的 Prompt 指令。

工具调用

当 AI 决定调用特定技能时,触发 SkillsFunction。

public static class SkillsFunction implements Function<SkillsInput, String> {
    private Map<String, Skill> skillsMap;
    // ...
    @Override
    public String apply(SkillsInput input) {
        Skill skill = this.skillsMap.get(input.command());
        if (skill != null) {
            var skillBaseDirectory = skill.path().getParent().toString();
            return "Base directory for this skill: %s\n\n%s".formatted(skillBaseDirectory, skill.content());
        }
        return "Skill not found: " + input.command();
    }
}

返回的内容包含基础路径和技能正文,AI 据此读取操作指南或脚本。至此,基于 SKILL.md 的技能调用机制便完整实现了。

目录

  1. 引言
  2. 环境准备
  3. Maven 依赖
  4. 配置文件
  5. 定义 Skill
  6. Code Reviewer
  7. Instructions
  8. 接入实现
  9. Controller 配置
  10. 源码解析
  11. 目录设置
  12. 加载元数据
  13. 工具调用

更多推荐文章

查看全部
  • 基于 ESP32-S3 的 AI 人脸追踪机器人实现
  • YOLO26-Pose 零样本姿态估计:从原理到机器人应用
  • OpenClaw 对接飞书实现多机器人自动群聊配置指南
  • 用 DRF 搞定企业 API:从视图到监控的实战经验
  • Coze 工作流:智能体自动化任务执行与分类解析
  • 基于 Leaflet 和天地图的长沙市免费运动场所 WebGIS 可视化
  • 基于官方 API 搭建 QQ 群聊机器人实战指南
  • GitHub Copilot AI 编程助手使用指南:安装与进阶技巧
  • Neo4j 插件 APOC 安装及配置指南
  • 垂直行业定制 Llama-Guard 3 守卫模型微调实战
  • C++ 继承机制全面解析
  • Nginx 实现域名跳转的几种方式
  • 逻辑回归算法详解:原理、代码与可视化
  • Python、NumPy、Pandas 与 Matplotlib 版本兼容指南
  • C++ STL list 容器详解:使用与模拟实现
  • ToDesk AI 桌面助手 ToClaw:零门槛体验 OpenClaw 自动化能力
  • macOS 平台 notepad--文本编辑器高效配置指南
  • 鸿蒙 PC 应用开发:挪移布局与缩进布局
  • 无人机路径规划算法详解:原理与实战应用
  • Seedance 2.0 实操教程:从入门到 AI 导演模式

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online