让大模型“能动手”到底是救命还是作妖:你敢把执行权交给它吗?
🏆本文收录于《滚雪球学SpringBoot 3》:
https://blog.csdn.net/weixin_43970743/category_12795608.html,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。
本专栏致力打造最硬核 SpringBoot3 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot3教程导航帖】https://blog.csdn.net/weixin_43970743/article/details/151115907,你想学习的都被收集在内,快速投入学习!!两不误。
若还想学习更多,可直接前往《滚雪球学SpringBoot(全版本合集)》:https://blog.csdn.net/weixin_43970743/category_11599389.html,涵盖SpringBoot所有版本教学文章。
演示环境说明:
- 开发工具:IDEA 2021.3
- JDK版本: JDK 17(推荐使用 JDK 17 或更高版本,因为 Spring Boot 3.x 系列要求 Java 17,Spring Boot 3.5.4 基于 Spring Framework 6.x 和 Jakarta EE 9,它们都要求至少 JDK 17。)
- Spring Boot版本:3.5.4(于25年7月24日发布)
- Maven版本:3.8.2 (或更高)
- Gradle:(如果使用 Gradle 构建工具的话):推荐使用 Gradle 7.5 或更高版本,确保与 JDK 17 兼容。
- 操作系统:Windows 11
前言
我第一次把“函数调用”接进业务系统的时候,心情很复杂:一方面像给模型装上了手脚——它终于不只是“嘴强王者”;另一方面又有点发怵:**这玩意儿要是被提示注入忽悠了,岂不是能把我数据库当游乐场?**😅
所以这篇我按你的大纲来:讲清原理、给你 Spring Boot 3 的 Java 实现(天气 API / 数据库查询两套示例),最后认真聊安全边界,别让“执行力”变成“破坏力”。
先提醒一句:Spring AI 生态里“Function Calling”这套 API 在新版本里逐步向 Tool Calling(工具调用)迁移,底层概念一致:模型只会请求调用工具,真正执行发生在你应用侧。Spring AI 官方参考把这条链路讲得很清楚。
OpenAI 官方也强调:你给模型一组 tools(JSON schema 描述),模型会返回工具调用请求,你的应用执行并把结果回传。
1)让大模型具备“执行力”:到底发生了什么?
把它想象成一场“带脚本的对话”,分 6 步走(这 6 步非常关键,理解了你就不容易被玄学带跑偏):
- 你发起一次聊天请求,同时告诉模型:“你可以用这些工具(函数)。”(每个工具有名称、描述、入参 schema)
- 模型判断自己需要外部信息/动作(比如实时天气、查库),于是返回一个工具调用请求:工具名 + JSON 入参。
- 你的应用根据工具名找到对应的 Java 函数/方法。
- 你的应用执行真实逻辑(调用天气服务、跑 SQL、访问内部系统)。
- 你的应用把执行结果回传给模型(作为额外上下文)。
- 模型基于工具结果生成最终自然语言回答。
重点来了(别忽略!):
- 模型不会真的“直接访问你的数据库/网络”。它只是“提出调用请求”,执行权永远在你服务端。
- 所以你要把它当成一个“会写调用意图的实习生”:能干活,但必须上锁、加审批、留审计😄。
2)定义 Java Function 并注册为 Spring Bean(最常用、最稳的姿势)
Spring AI 的理念是:你把函数作为 Spring Bean 暴露出来,框架帮你做“工具描述 + 回调编排”的样板工作。旧的 FunctionCallback/Function Calling 文档也这么描述(虽然新版本更推荐 Tool Calling 命名)。
下面我用Tool Calling方式来写(更贴近新版本参考),但你会发现结构跟 Function Calling 几乎一模一样。
2.1 天气查询工具(外部 API / 你自己的 WeatherClient)
Step A:定义入参/出参 record(强烈建议这么做,清晰又可校验)
public record WeatherRequest(String location, String unit) {} // unit: "C" or "F"
public record WeatherResponse(double temp, String unit, String description) {}
Step B:实现工具(Function)并注册为 Bean
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ToolsConfig {
@Bean(name = "get_weather")
public Function<WeatherRequest, WeatherResponse> getWeatherTool(WeatherClient weatherClient) {
return req -> {
// 这里你可以调用真实天气 API,也可以先 mock
var data = weatherClient.query(req.location(), req.unit());
return new WeatherResponse(data.temp(), req.unit(), data.summary());
};
}
}
Spring AI 会把这个 Function 包装成可供模型调用的 ToolCallback(概念上就是“工具”),并在模型返回工具调用时自动回调执行。
3)模型自动回调:让 GPT 调用你的天气 API 或数据库查询方法
这里分两种常见形态:
- A:Function 作为 Tool(上面那种)
- B:直接把某个 Java 方法暴露为 Tool(更细粒度,也更“像写业务”)
3.1 用 ChatClient 发起请求,并“允许”使用哪些工具(关键:白名单!)
Spring AI 工具调用参考强调:你可以传 ToolCallback 对象,或者只传工具名,让框架运行时解析。
伪代码示例(表达意图为主,不纠结具体包名的小版本差异):
@RestController
public class AssistantController {
private final ChatClient chatClient;
public AssistantController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/ask")
public String ask(@RequestParam String q) {
return chatClient.prompt()
.user(q)
// 重点:只允许本次对话使用 get_weather 这个工具
.tools("get_weather")
.call()
.content();
}
}
你看,这里真正的“权限开关”是你服务端控制的:你不把工具放进 tools 列表,它就算嘴上想调用,也没门。
3.2 数据库查询工具:让模型“查数据”,但别让它“随便查”
先说我的底线:不要给模型一个“通用 SQL 执行器”(比如入参是 sql: "select * from ...")。这相当于把方向盘交给一个会背交通规则但没驾照的人🚗💥。
正确做法:定义“业务化”的查询工具(参数化、可控字段)
入参/出参:
public record UserLookupRequest(Long userId) {}
public record UserLookupResponse(Long userId, String name, String status) {}
工具实现:
@Bean(name = "get_user_by_id")
public Function<UserLookupRequest, UserLookupResponse> getUserByIdTool(UserRepository repo) {
return req -> repo.findById(req.userId())
.map(u -> new UserLookupResponse(u.getId(), u.getName(), u.getStatus()))
.orElseThrow(() -> new IllegalArgumentException("User not found"));
}
调用:
return chatClient.prompt()
.system("你是客服助手。需要用户信息时可以调用 get_user_by_id,但不得暴露敏感字段。")
.user("帮我查一下用户 123 的状态,并用一句话解释。")
.tools("get_user_by_id")
.call()
.content();
这样模型即使想“扩展查询范围”,也只能在你定义的输入 schema 里活动。工具调用的输入 schema/工具定义就是你的“围栏”。
4)安全性思考:限制 AI 的执行权限(这块不做,迟早要还债🙂)
下面这部分我写得稍微“啰嗦”点,因为它真的是上线分水岭。
4.1 工具白名单:每次请求只给“必要工具”
- 不要默认把所有工具都挂上(特别是“写操作”工具)。
- 同一个 ChatClient 可以按场景切不同 tools 列表。
经验话术:
“能不用工具就不用;要用也只用这一把扳手,别把整个工具箱扔给模型。”
4.2 只暴露“业务能力”,不要暴露“底层能力”
✅ 推荐:get_user_by_id(userId)、search_orders(status, from, to)
❌ 不推荐:execute_sql(sql)、http_fetch(url)(除非你做了极强的域名/路径限制)
原因很简单:工具调用就是“执行入口”。OpenAI/Spring AI 的机制决定了——模型可以提出调用请求,你的应用会执行。你暴露得越底层,越容易被提示注入绕开业务限制。
4.3 对入参做严格校验:schema + 运行时校验双保险
- schema(record 字段)只能限制形状
- 运行时还要限制:长度、枚举、范围、正则、名单
例如 location 只允许城市名,不允许塞 URL;userId 必须是正整数;分页大小必须有上限。
4.4 工具执行要“最小权限”
- 查库用只读账号(能读就别给写)
- 写操作必须额外鉴权(比如用户确认、管理员角色、二次校验)
- 对外 HTTP 调用限制目标域名(allowlist),防 SSRF
4.5 审计与可追溯:记录 tool_name + arguments + caller + result 摘要
你要能回答这三个问题:
- 谁触发的?2) 调了什么工具?3) 用了什么参数?
出了事能定位,才叫“可控执行力”。
4.6 提示注入防线:把模型当“不可信输入”
- 用户输入里如果出现“忽略系统指令、改用某工具、把数据库全导出”——你要靠工具白名单 + 参数校验挡住
- 系统提示里明确:什么能做、什么不能做、敏感信息不返回
- 重要动作要求人类确认(Human-in-the-loop)
🧧福利赠与你🧧
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G PDF编程电子书、简历模板、技术文章Markdown文档等海量资料。
ps:本文涉及所有源代码,均已上传至Gitee:
https://gitee.com/bugjun01/SpringBoot-demo开源,供同学们一对一参考 Gitee传送门https://gitee.com/bugjun01/SpringBoot-demo,同时,原创开源不易,欢迎给个star🌟,想体验下被🌟的感jio,非常感谢❗
🫵 Who am I?
我是 bug菌:
- 热活跃于 CSDN:
https://blog.csdn.net/weixin_43970743| 掘金:https://juejin.cn/user/695333581765240| InfoQ:https://www.infoq.cn/profile/4F581734D60B28/publish| 51CTO:https://blog.51cto.com/u_15700751| 华为云:https://bbs.huaweicloud.cn/community/usersnew/id_1582617489455371| 阿里云:https://developer.aliyun.com/profile/uolxikq5k3gke| 腾讯云:https://cloud.tencent.com/developer/user/10216480/articles等技术社区; - CSDN 博客之星 Top30、华为云多年度十佳博主&卓越贡献奖、掘金多年度人气作者 Top40;
- 掘金、InfoQ、51CTO 等平台签约及优质作者;
- 全网粉丝累计 30w+。
更多高质量技术内容及成长资料,可查看这个合集入口 👉 点击查看:https://bbs.csdn.net/topics/612438251 👈️
硬核技术公众号 「猿圈奇妙屋」https://bbs.csdn.net/topics/612438251 期待你的加入,一起进阶、一起打怪升级。
- End -
- 点赞
- 收藏
- 关注作者
评论(0)