LLM - Spring AI × Anthropic Skills

文章目录

  • Pre
  • 概述
  • 整体思路概览
  • [1. 封装 Skill 的 Java DTO 与 Tool](#1. 封装 Skill 的 Java DTO 与 Tool)
    • [1.1 定义请求/响应模型](#1.1 定义请求/响应模型)
    • [1.2 Tool 实现:调用 Python Skill 脚本](#1.2 Tool 实现:调用 Python Skill 脚本)
  • [2. 把 Tool 注册成 Spring AI Function](#2. 把 Tool 注册成 Spring AI Function)
  • [3. ChatClient:让 Agent 自己选用 Skill](#3. ChatClient:让 Agent 自己选用 Skill)
    • [3.1 定义一个「数据分析 Agent」服务](#3.1 定义一个「数据分析 Agent」服务)
    • [3.2 控制器层简单暴露 HTTP 接口](#3.2 控制器层简单暴露 HTTP 接口)
  • [4. Python 侧:包装 Skill 为统一入口(可选但推荐)](#4. Python 侧:包装 Skill 为统一入口(可选但推荐))
  • [5. 同理挂载其它 Skill(如代码评审)](#5. 同理挂载其它 Skill(如代码评审))
  • 扩展阅读
    • [Function Calling / Tool Calling 核心能力](#Function Calling / Tool Calling 核心能力)
    • [Tool / MCP / 动态能力扩展](#Tool / MCP / 动态能力扩展)
    • [架构实践 / 综合教程](#架构实践 / 综合教程)
    • [Java × Python / 跨语言协作(Agent 常见落地形态)](#Java × Python / 跨语言协作(Agent 常见落地形态))
    • [Agent / Claude / 外部参照体系](#Agent / Claude / 外部参照体系)
    • 视频资源

Pre

LLM - Agent Skills 智能体新范式

LLM - Agent Skills 案例:PR 代码评审 Skill

LLM - Agent Skills 案例:内部数据分析

概述

可以把前面那两个 Skill(代码评审 / 内部数据分析)理解为「外部可执行能力」,再用 Spring AI 的 Function/Tool Calling 把它们挂到 Agent 上,让模型自己决定何时调用哪一个脚本,然后再基于脚本结果继续对话。

下面给一个端到端的集成示例,假设你用的是 Spring Boot + Spring AI + OpenAI/Mistral 等支持函数调用的模型。


整体思路概览

  • Skill 本身:仍然是文件夹 + SKILL.md + scripts/*.py,部署在应用服务器旁(或者挂载到容器)。
  • Spring AI 这边做三件事:
    • 用 Java 封装「运行某个 Skill 的脚本」为一个 Function/Tool(例如 runCodeReviewSkillrunDataAnalysisSkill)。
    • 在 Function 内部,通过 ProcessBuilder 调 Python 脚本,并把结果(评审报告 / 分析报告)作为字符串返回给模型。
    • ChatClient 中声明这些函数为可调用工具,让 LLM 自己选用。

下面示例以「内部数据分析 Skill」为主,同时顺带演示代码评审 Skill 的挂载方式。


1. 封装 Skill 的 Java DTO 与 Tool

1.1 定义请求/响应模型

java 复制代码
// DataAnalysisSkillRequest.java
public record DataAnalysisSkillRequest(
        String analysisRequest,
        String constraints
) { }

// DataAnalysisSkillResponse.java
public record DataAnalysisSkillResponse(
        String reportText
) { }

// CodeReviewSkillRequest.java
public record CodeReviewSkillRequest(
        String diffOrFiles,
        String context
) { }

// CodeReviewSkillResponse.java
public record CodeReviewSkillResponse(
        String reviewReport
) { }

Spring AI 会用这些类型自动生成函数的 JSON Schema,帮助 LLM 正确构造调用参数。

1.2 Tool 实现:调用 Python Skill 脚本

这里用「内部数据分析 Skill」举例,调用的是 run_query.py + clean_and_aggregate.py,然后再调用一个「汇总为报告」的小脚本,或者直接把 CSV 路径返回给 LLM 让它读内容(取决于你怎么暴露数据)。示例里用最简单的方式:把「分析意图」传给一个 Python wrapper 脚本,由它内部使用前面那两个脚本并生成最终报告文本。

java 复制代码
// DataAnalysisSkillTool.java
package com.example.ai.tools;

import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

@Service
public class DataAnalysisSkillTool {

    // 假设你的 Skill 目录在服务器上的路径
    private static final String SKILL_BASE_DIR = "/opt/skills/internal-data-analysis-skill";

    public DataAnalysisSkillResponse run(DataAnalysisSkillRequest request) {
        try {
            // 这里调用一个 Python wrapper,例如 scripts/run_analysis_skill.py
            ProcessBuilder pb = new ProcessBuilder(
                    "python",
                    SKILL_BASE_DIR + "/scripts/run_analysis_skill.py",
                    "--request", request.analysisRequest(),
                    "--constraints", request.constraints() == null ? "" : request.constraints()
            );
            pb.redirectErrorStream(true);
            Process process = pb.start();

            StringBuilder output = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line).append("\n");
                }
            }

            int exitCode = process.waitFor();
            if (exitCode != 0) {
                return new DataAnalysisSkillResponse(
                        "分析脚本执行失败,退出码:" + exitCode + ",输出:\n" + output
                );
            }

            return new DataAnalysisSkillResponse(output.toString());
        } catch (Exception e) {
            return new DataAnalysisSkillResponse("执行内部数据分析 Skill 时出现异常:" + e.getMessage());
        }
    }
}

代码评审 Skill 同理:调用 code-review-skill/scripts/... 并返回报告文本即可。


2. 把 Tool 注册成 Spring AI Function

Spring AI 推荐通过 @Bean Function<Req,Resp>@Tool 暴露工具,让 ChatClient / ChatModel 知道有哪些函数可用。

java 复制代码
// SkillsConfig.java
package com.example.ai.config;

import com.example.ai.tools.DataAnalysisSkillTool;
import com.example.ai.tools.CodeReviewSkillTool;
import com.example.ai.tools.dto.*;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.function.Function;

@Configuration(proxyBeanMethods = false)
public class SkillsConfig {

    @Bean
    public Function<DataAnalysisSkillRequest, DataAnalysisSkillResponse> internalDataAnalysis(DataAnalysisSkillTool tool) {
        return tool::run; // 函数名 internalDataAnalysis = Skill 名
    }

    @Bean
    public Function<CodeReviewSkillRequest, CodeReviewSkillResponse> codeReviewAssistant(CodeReviewSkillTool tool) {
        return tool::run;
    }
}

在 Spring AI 里,这两个 Bean 名(internalDataAnalysis / codeReviewAssistant)就是 LLM 能看到的工具名,你可以在 prompt 中让模型了解它们的用途,也可以只靠 JSON Schema 自动推断。


3. ChatClient:让 Agent 自己选用 Skill

3.1 定义一个「数据分析 Agent」服务

java 复制代码
// DataAnalysisAgentService.java
package com.example.ai.agent;

import com.example.ai.tools.dto.DataAnalysisSkillRequest;
import com.example.ai.tools.dto.DataAnalysisSkillResponse;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;

@Service
public class DataAnalysisAgentService {

    private final ChatClient chatClient;

    public DataAnalysisAgentService(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    public String analyze(String userQuestion, String constraints) {
        var sysPrompt = """
                你是公司内部的数据分析助手。
                你可以使用名为 internalDataAnalysis 的工具,它会基于数据仓库执行查询和分析,并返回一份结构化的中文报告草稿。
                当用户的问题涉及具体的数据指标、时间范围、渠道/地区对比时,应优先调用该工具,而不是凭空猜测。
                """;

        // 这里不直接 new DataAnalysisSkillRequest,而是让 LLM 自己构造参数并调用工具
        return chatClient
                .prompt()
                .system(sysPrompt)
                .user(userSpec -> userSpec
                        .text("用户问题:{q}\n约束条件(可为空):{c}")
                        .param("q", userQuestion)
                        .param("c", constraints == null ? "" : constraints)
                )
                // 关键:声明允许使用的函数名,Spring AI 会把函数 Schema 一起发给模型
                .functions("internalDataAnalysis")
                .call()
                .content(); // 最终答案:模型在工具结果基础上生成的回答
    }
}

模型流程示意:

  1. 收到用户问题 → 判断需要具体数据 → 选择调用 internalDataAnalysis
  2. 构造 DataAnalysisSkillRequest 的 JSON 入参。
  3. Spring AI 执行 Java Function → 调 Python Skill 脚本 → 拿到报告文本。
  4. Spring AI 把报告作为新一轮对话上下文喂回模型。
  5. 模型基于报告,生成最终面向业务同学的自然语言回答。

3.2 控制器层简单暴露 HTTP 接口

java 复制代码
// DataAnalysisController.java
package com.example.ai.web;

import com.example.ai.agent.DataAnalysisAgentService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/analysis")
public class DataAnalysisController {

    private final DataAnalysisAgentService agentService;

    public DataAnalysisController(DataAnalysisAgentService agentService) {
        this.agentService = agentService;
    }

    @PostMapping
    public String analyze(@RequestParam("question") String question,
                          @RequestParam(value = "constraints", required = false) String constraints) {
        return agentService.analyze(question, constraints);
    }
}

4. Python 侧:包装 Skill 为统一入口(可选但推荐)

上面的 Java Tool 调用了一个假想的 run_analysis_skill.py,它可以作为 Skill 的统一入口,内部再去调用 run_query.pyclean_and_aggregate.py,并基于结果拼出完整报告文本(按照你在 SKILL.md 中定义的结构)。

伪代码示例:

python 复制代码
# internal-data-analysis-skill/scripts/run_analysis_skill.py
import argparse
import textwrap
# 这里导入或复用 run_query.py / clean_and_aggregate.py 中的逻辑

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--request", required=True)
    parser.add_argument("--constraints", default="")
    args = parser.parse_args()

    # 1. 解析 request / constraints -> 决定查询模板
    # 2. 生成 SQL,调用 run_query.py 获得 result.csv
    # 3. 调用 clean_and_aggregate.py 做清洗与聚合
    # 4. 按 SKILL.md 中的报告结构拼出一份文本,print 到 stdout

    report = textwrap.dedent(f"""
    内部数据分析报告(示例)

    一、分析诉求
    - {args.request}
    - 约束条件:{args.constraints or "无"}

    二、关键指标(示例说明)
    - ...

    三、主要发现
    - ...

    四、风险与局限
    - ...

    五、后续建议
    - ...
    """).strip()

    print(report)


if __name__ == "__main__":
    main()

这样有三个好处:

  • Java 只关心「给脚本字符串 → 拿报告字符串」,无需理解 SQL 细节。
  • Skill 的演进主要在 Python + SKILL.md 里完成,不影响 Java 侧接口。
  • 以后如果换成 MCP / 远程服务,也可以保持 Java 侧函数签名不变,只调整内部实现。

5. 同理挂载其它 Skill(如代码评审)

代码评审 Skill 的集成方式完全相同,只是:

  • DTO 换成 CodeReviewSkillRequest/Response
  • Tool 内部调用的是 code-review-skill/scripts/...
  • Agent 的 system prompt 改成「你是代码评审助手,可以调用 codeReviewAssistant 工具......」。

Spring AI 会自动把两个工具的 Schema 一起发给模型,这样一个更通用的「工程生产力 Agent」就可以根据用户问题自动选择是「查数据」还是「审代码」了。

下一步可以一起细化两点:

  • 根据当前用的具体模型(OpenAI、Anthropic 代理、Mistral 等),调整 application.yml 中 Spring AI 的模型配置和函数调用选项。
  • 把「Skill 元数据(目录扫描) + MCP」结合起来,让 Spring AI 在运行时动态发现新的 Skill,而不仅仅是写死在配置中的两个函数。

扩展阅读

  1. Spring AI 官方主页
    https://spring.io/ai

  2. Spring AI 官方文档:Tools API
    https://docs.spring.io/spring-ai/reference/api/tools.html

  3. Spring AI GitHub 仓库
    https://github.com/spring-projects/spring-ai

  4. Spring AI 1.0 GA 官方发布(Azure 场景)
    https://techcommunity.microsoft.com/blog/appsonazureblog/spring-ai-1-0-ga-is-here---build-java-ai-apps-end-to-end-on-azure-today/4414763


Function Calling / Tool Calling 核心能力

  1. Function Calling in Java & Spring AI(Mistral)
    https://spring.io/blog/2024/03/06/function-calling-in-java-and-spring-ai-using-the-latest-mistral-ai-api

  2. Spring AI Function Calling 示例(HowToDoInJava)
    https://howtodoinjava.com/spring-ai/spring-ai-function-calling-example/

  3. Spring AI Function Calling 入门
    https://piotrminkowski.com/2025/01/30/getting-started-with-spring-ai-function-calling/

  4. Baeldung:Spring AI + Mistral Function Calling
    https://www.baeldung.com/spring-ai-mistral-api-function-calling

  5. Spring AI Chat Functions(OpenAI / 早期版本文档)
    https://www.spring-doc.cn/spring-ai/1.0.0-M4/api_chat_functions_openai-chat-functions.en.html


Tool / MCP / 动态能力扩展

  1. Spring AI + MCP:Dynamic Tool Updates
    https://spring.io/blog/2025/05/04/spring-ai-dynamic-tool-updates-with-mcp

  2. Spring AI GitHub Discussion:Tool / Function 设计讨论
    https://github.com/spring-projects/spring-ai/discussions/1082


架构实践 / 综合教程

  1. Building AI-Driven Applications with Spring AI
    https://javapro.io/2025/04/22/building-ai-driven-applications-with-spring-ai/

  2. Integrating Spring AI
    https://dimitri.codes/integrating-spring-ai/

  3. Spring AI 入门教程(InfoWorld)
    https://www.infoworld.com/article/4091447/spring-ai-tutorial-get-started-with-spring-ai.html

  4. Spring Boot + Spring AI 集成指南
    https://javatechonline.com/spring-ai-how-to-integrate-ai-with-spring-boot/


Java × Python / 跨语言协作(Agent 常见落地形态)

  1. Java 调用 Python 的几种方式(Baeldung)
    https://www.baeldung.com/java-working-with-python

  2. Java 调用 Python ML 服务的架构选择(StackOverflow)
    https://stackoverflow.com/questions/59492410/calling-python-machine-learning-service-from-java-as-an-os-process-or-micro-serv

  3. Java 与 Python 并行运行的实践讨论(Reddit)
    https://www.reddit.com/r/javahelp/comments/jwnygr/running_persistent_python_program_in_parallel_to/


Agent / Claude / 外部参照体系

  1. Anthropic:Agent Skills 官方工程文
    https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills

  2. Claude Code 作为数据分析 Agent 的实践
    https://pub.towardsai.net/claude-code-as-a-data-analyst-from-zero-to-first-report-0aa55539a19f

  3. 中文解读:Claude Agent Skills
    https://www.toutiao.com/article/7581769941976711718/


视频资源

  1. Spring AI 实战讲解(YouTube)
    https://www.youtube.com/watch?v=LJCnpsdhPlQ

  2. Spring AI / Function Calling 视频教程
    https://www.youtube.com/watch?v=qezHjW7oryE

相关推荐
AI精钢11 小时前
Claude Certification 出现了一道“官方文档级”错题:关于 Claude Code Skills 优先级的误导
java·开发语言·工程实践·claude code·ai coding·agent skills·技术认证
haiyangyiba12 小时前
学习Spring Ai的摸索实践
学习·spring ai
LucaJu1 天前
分布式智能体|A2A Agent实战
agent·智能体·spring ai·a2a·spring ai alibaba
gujunge2 天前
Spring with AI (6): 记忆保持——会话与长期记忆
ai·大模型·llm·openai·qwen·rag·spring ai·deepseek
种时光的人2 天前
Java+AI 无缝衔接:Spring AI 聊天模型入门到精通
java·人工智能·spring·ai·spring ai
ToTensor4 天前
从零开始,深入解析 OpenClaw 架构设计与实现细节
agent·agent skills·openclaw
光仔December4 天前
【从0学习Spring AI Alibaba】3、阿里云百炼平台API Key 申请指南
人工智能·ai大模型·spring ai·阿里云百炼·apikey申请
光仔December5 天前
【从0学习Spring AI Alibaba】2、Spring AI Alibaba版本选型及环境搭建
人工智能·大模型·saa·spring ai·ai alibaba
空城.依旧6 天前
找到了一个学习Spring AI的教程,感觉还不错,示例可以直接运行,学习Spring AI推荐
spring ai
超级无敌大好人7 天前
程序运行卡住排查
java·spring ai·qdrant