LLM - Spring AI × Anthropic Skills

LLM - Spring AI × Anthropic Skills

文章目录

在这里插入图片描述

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 定义请求/响应模型

// DataAnalysisSkillRequest.javapublicrecordDataAnalysisSkillRequest(String analysisRequest,String constraints ){}// DataAnalysisSkillResponse.javapublicrecordDataAnalysisSkillResponse(String reportText ){}// CodeReviewSkillRequest.javapublicrecordCodeReviewSkillRequest(String diffOrFiles,String context ){}// CodeReviewSkillResponse.javapublicrecordCodeReviewSkillResponse(String reviewReport ){}

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

1.2 Tool 实现:调用 Python Skill 脚本

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

// DataAnalysisSkillTool.javapackagecom.example.ai.tools;importorg.springframework.stereotype.Service;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.nio.charset.StandardCharsets;@ServicepublicclassDataAnalysisSkillTool{// 假设你的 Skill 目录在服务器上的路径privatestaticfinalString SKILL_BASE_DIR ="/opt/skills/internal-data-analysis-skill";publicDataAnalysisSkillResponserun(DataAnalysisSkillRequest request){try{// 这里调用一个 Python wrapper,例如 scripts/run_analysis_skill.pyProcessBuilder pb =newProcessBuilder("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 =newStringBuilder();try(BufferedReader reader =newBufferedReader(newInputStreamReader(process.getInputStream(),StandardCharsets.UTF_8))){String line;while((line = reader.readLine())!=null){ output.append(line).append("\n");}}int exitCode = process.waitFor();if(exitCode !=0){returnnewDataAnalysisSkillResponse("分析脚本执行失败,退出码:"+ exitCode +",输出:\n"+ output );}returnnewDataAnalysisSkillResponse(output.toString());}catch(Exception e){returnnewDataAnalysisSkillResponse("执行内部数据分析 Skill 时出现异常:"+ e.getMessage());}}}

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


2. 把 Tool 注册成 Spring AI Function

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

// SkillsConfig.javapackagecom.example.ai.config;importcom.example.ai.tools.DataAnalysisSkillTool;importcom.example.ai.tools.CodeReviewSkillTool;importcom.example.ai.tools.dto.*;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.function.Function;@Configuration(proxyBeanMethods =false)publicclassSkillsConfig{@BeanpublicFunction<DataAnalysisSkillRequest,DataAnalysisSkillResponse>internalDataAnalysis(DataAnalysisSkillTool tool){return tool::run;// 函数名 internalDataAnalysis = Skill 名}@BeanpublicFunction<CodeReviewSkillRequest,CodeReviewSkillResponse>codeReviewAssistant(CodeReviewSkillTool tool){return tool::run;}}

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


3. ChatClient:让 Agent 自己选用 Skill

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

// DataAnalysisAgentService.javapackagecom.example.ai.agent;importcom.example.ai.tools.dto.DataAnalysisSkillRequest;importcom.example.ai.tools.dto.DataAnalysisSkillResponse;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.stereotype.Service;@ServicepublicclassDataAnalysisAgentService{privatefinalChatClient chatClient;publicDataAnalysisAgentService(ChatClient.Builder chatClientBuilder){this.chatClient = chatClientBuilder.build();}publicStringanalyze(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 接口

// DataAnalysisController.javapackagecom.example.ai.web;importcom.example.ai.agent.DataAnalysisAgentService;importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/api/analysis")publicclassDataAnalysisController{privatefinalDataAnalysisAgentService agentService;publicDataAnalysisController(DataAnalysisAgentService agentService){this.agentService = agentService;}@PostMappingpublicStringanalyze(@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 中定义的结构)。

伪代码示例:

# internal-data-analysis-skill/scripts/run_analysis_skill.pyimport argparse import textwrap # 这里导入或复用 run_query.py / clean_and_aggregate.py 中的逻辑defmain(): 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
在这里插入图片描述

Read more

初学二叉搜索树踩坑多?C++ 从原理到代码,搞定增删查全流程

初学二叉搜索树踩坑多?C++ 从原理到代码,搞定增删查全流程

🎬 个人主页:Vect个人主页 🎬 GitHub:Vect的代码仓库 🔥 个人专栏: 《数据结构与算法》《C++学习之旅》《计算机基础》 ⛺️Per aspera ad astra. 文章目录 * 1. 二叉搜索树相关概念 * 2. 二叉搜索树的操作 * 2.1. 查找节点 * 2.2. 插入节点 * 2.3. 删除节点 * 3. 二叉搜索树的实现 * 4. 二叉搜索树的应用 * 4.1. K模型 * 4.2. KV模型 1. 二叉搜索树相关概念 如下图所示,二叉搜索树(binary search tree)满足下列条件: 1. 对于根节点,左子树中所有节点的值<根节点的值&

By Ne0inhk
gflags+spdlog实战:C++命令行参数与高性能日志的极致搭配行动指南

gflags+spdlog实战:C++命令行参数与高性能日志的极致搭配行动指南

文章目录 * 本篇摘要 * 一.gflags 介绍及简单使用 * 简单介绍 * 安装过程 * gflags简单使用 * `google::ParseCommandLineFlags` 介绍: * 使用方式 * 1·直接使用默认的参数 * 2·使用命令行参数 * 3·使用配置文件输入 * 使用参考 * 二.Spdlog组件介绍及简单使用 * 简单介绍 * 安装过程 * spdlog 简单使用 * 基于spdlog使用的二次封装(默认同步日志器) * 基于spdlog总结 * 总结文本查询小技巧 * 三.gtest介绍使用 * 四.本篇小结 本篇摘要 本文介绍gflags命令行参数解析库(轻量高效、类型安全)与spdlog高性能日志库(同步/异步、多平台),涵盖安装、基础使用及二次封装等帮助C++项目灵活配置与高效日志管理。 一.gflags 介绍及简单使用 简单介绍 Google 开源的命令行参数解析库,

By Ne0inhk
Microsoft Visual C++ 运行库安装教程(2025 最新版全版本修复指南)

Microsoft Visual C++ 运行库安装教程(2025 最新版全版本修复指南)

前言 在使用大型软件、开发工程项目或玩 3A 游戏时,很多人都遇到过这样的报错: “缺少 msvcp140.dll” “无法继续执行代码,因为系统找不到 vcruntime140_1.dll” “程序无法启动,因为计算机中丢失了 MSVCR100.dll” 这些提示看似复杂,其实本质是 Microsoft Visual C++ 运行库(VC++ Redistributable)缺失或损坏 所致。 本文将带来 2025 年最新版 Microsoft Visual C++ 运行库安装教程,无论你是游戏玩家、开发者还是普通用户,都能找到最合适的解决方案。内容涵盖: * 一键修复方法(适合新手,快速解决 DLL 报错) * 手动下载安装方案(适合专业或开发用途) * 常见 DLL 报错与完整修复思路 * 系统维护与预防技巧

By Ne0inhk
C++11新特性(下)----《Hello C++ Wrold!》(26)--(C/C++)

C++11新特性(下)----《Hello C++ Wrold!》(26)--(C/C++)

文章目录 * 前言 * lambda表达式 * 可变参数模板 * 展开参数包的方法 * 应用 * 包装器 * fiction包装器 * bind函数 * 作业部分 前言 在 C++11 标准带来的诸多革命性特性中,“简化代码编写” 与 “统一可调用对象管理” 是两大核心目标。lambda 表达式解决了传统仿函数 “定义繁琐、复用性低” 的痛点,让局部场景下的自定义逻辑(如排序规则、回调函数)能以更简洁的匿名函数形式实现;可变参数模板则打破了模板参数数量固定的限制,为 STL 容器(如emplace_back)和通用函数设计提供了灵活的参数处理能力;而 function 包装器与 bind 函数,则进一步整合了函数指针、仿函数、lambda 等不同类型的可调用对象,实现了统一管理与参数适配,甚至让可调用对象存储到容器中成为可能。 这些特性并非孤立存在 ——lambda 的底层依赖仿函数实现,可变参数模板为emplace系列接口提供了技术支撑,

By Ne0inhk