拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring AI Tool Calling:让模型调用业务接口

Spring AI Tool Calling:让模型调用业务接口 摘要大模型只能生成文本无法天然知道订单状态、库存数量、用户权限或企业内部系统数据。要让 AI 应用完成真实业务任务需要让模型提出结构化的工具调用请求由服务端完成参数校验、权限判断和业务执行再把工具结果交回模型生成最终回答。Spring AI 提供了 Tool Calling 抽象可以将 Java 方法、函数或ToolCallback暴露为模型可调用的工具。本文围绕“订单查询与售后客服”场景介绍如何设计工具契约、注册工具、执行调用、处理多轮工具链并重点讨论Tool Calling 与普通 Prompt 的区别Tool、MethodToolCallback和ToolCallback的使用方式工具参数的结构化描述和校验用户权限、租户隔离和高风险操作审批模型连续调用多个工具时的状态管理流式输出、超时、重试、幂等和审计如何避免让模型直接获得数据库或 Shell 权限。一、背景与问题1. 仅靠 Prompt 无法访问业务系统下面的 Prompt 只能让模型根据用户输入生成文字用户查询订单 O1001 当前状态。 模型我无法访问你的订单系统。如果把订单数据直接写进 Prompt又会出现数据过期、权限绕过和上下文泄露问题。更合理的流程是用户问题 ↓ 模型判断需要查询订单 ↓ 模型生成结构化工具调用 ↓ 服务端校验并执行订单查询 ↓ 工具结果返回模型 ↓ 模型生成用户可读答案2. Tool Calling 的基本结构工具调用包含四个角色角色作用工具名称标识要调用的业务能力参数 Schema描述参数名称、类型和约束服务端执行器校验权限并执行真实业务逻辑工具结果将执行结果返回给模型或前端模型只负责提出调用意图不能直接绕过服务端执行器访问数据库。3. 为什么不能把所有方法都暴露成工具暴露工具意味着模型可能在满足条件时请求调用。以下能力需要特别谨慎修改订单关闭工单发送邮件和短信删除文件修改权限执行退款访问生产数据库执行 Shell 命令。建议按风险分级只读查询 ↓ 草稿和预览 ↓ 用户确认 ↓ 执行写操作二、核心概念1. Function Calling 与 Tool CallingFunction Calling 侧重模型返回一个结构化函数名和参数Tool Calling 是更宽泛的能力工具可以是 Java 方法、HTTP API、数据库查询、搜索服务或人工审批流程。应用层可以统一成publicinterfaceBusinessTool{Stringname();ToolResultexecute(ToolContextcontext,JsonNodearguments);}2. Spring AI 的工具抽象Spring AI 支持通过Tool注解、ToolCallback、ToolCallbackProvider或Function等方式提供工具。工具定义最终会转换为模型能够理解的名称、描述和参数 Schema。业务服务通常使用ChatClient ↓ ToolCallback ↓ 业务方法 ↓ 业务结果3. 工具描述比方法名更重要工具描述会参与模型决策。下面的描述过于模糊ToolpublicObjectquery(Stringid){...}更好的描述应说明什么时候使用参数代表什么返回结果包含什么不应该用于什么是否只读是否需要用户确认。4. 工具调用不是权限模型即使模型决定调用queryOrder服务端仍然要校验当前用户 ↓ 是否属于当前租户 ↓ 是否拥有订单访问权限 ↓ 订单是否属于当前用户 ↓ 是否允许当前 Agent 使用该工具 ↓ 执行查询模型输出的参数、用户输入的订单号和客户端传入的租户 ID 都不能直接作为最终授权依据。三、工作原理1. 一次工具调用的完整流程1. 服务端向模型发送工具定义 2. 模型返回 tool_call 3. 应用解析工具名称和 JSON 参数 4. 校验工具是否在白名单 5. 校验参数格式和业务权限 6. 执行 Java 业务方法 7. 保存工具调用记录 8. 将工具结果加入对话消息 9. 再次调用模型 10. 返回最终答案2. 多工具调用一个问题可能需要多个工具用户我的订单什么时候到如果超过承诺日期能否申请补偿 ↓ 查询订单 ↓ 查询物流 ↓ 查询售后政策 ↓ 模型整合结果每个工具调用都应该有独立的toolCallId、状态、参数摘要和结果摘要。3. 工具调用状态REQUESTED ↓ VALIDATING ├─ REJECTED └─ APPROVED ↓ RUNNING ├─ COMPLETED ├─ FAILED ├─ TIMEOUT └─ CANCELLED4. 工具结果不等于最终答案工具结果可能是内部结构化数据{orderId:O1001,status:SHIPPED,internalRiskScore:0.81}最终返回给用户时不应该自动暴露internalRiskScore。工具执行结果需要经过输出策略或 DTO 转换。四、实战示例1. 定义只读订单工具importorg.springframework.ai.tool.annotation.Tool;importorg.springframework.stereotype.Component;ComponentpublicclassOrderTools{privatefinalOrderQueryServiceorderQueryService;publicOrderTools(OrderQueryServiceorderQueryService){this.orderQueryServiceorderQueryService;}Tool(description 查询当前用户有权访问的订单状态。 只用于订单查询不执行修改、取消或退款。 当用户没有提供明确订单号时不要猜测订单号。 )publicOrderSummaryqueryOrder(OrderToolContextcontext,StringorderId){returnorderQueryService.queryOwnedOrder(context.tenantId(),context.userId(),orderId);}}OrderToolContext不应该由模型填写应该由服务端从认证上下文生成publicrecordOrderToolContext(UUIDtenantId,UUIDuserId,StringrequestId){}2. 使用 ToolCallbackimportorg.springframework.ai.tool.ToolCallbacks;importorg.springframework.ai.tool.ToolCallback;ToolCallback[]callbacksToolCallbacks.from(orderTools);StringanswerchatClient.prompt().user(question).tools(callbacks).call().content();不同 Spring AI 版本中工具 API 的包名和方法名可能变化项目应以锁定版本的官方 Tool Calling 文档为准。3. 使用 ChatClient 注册工具ServicepublicclassCustomerAssistant{privatefinalChatClientchatClient;privatefinalToolCallback[]orderToolCallbacks;publicCustomerAssistant(ChatClient.Builderbuilder,OrderToolsorderTools){this.chatClientbuilder.build();this.orderToolCallbacksToolCallbacks.from(orderTools);}publicStringanswer(Stringquestion){returnchatClient.prompt().system( 你是企业客服助手。 查询订单时只能使用工具返回的事实。 工具调用失败时说明暂时无法查询 不要编造订单状态。 ).user(question).tools(orderToolCallbacks).call().content();}}4. 工具参数校验模型返回的 JSON 仍然是不可信输入publicrecordQueryOrderRequest(NotBlankPattern(regexp^[A-Z0-9-]{4,32}$)StringorderId){}在执行前还需要if(!orderIdBelongsToUser(context.tenantId(),context.userId(),request.orderId())){thrownewAccessDeniedException(order is not accessible);}5. 高风险工具增加确认退款工具不应该和查询工具一样自动执行publicrecordToolApproval(StringapprovalId,StringuserId,StringtoolName,StringargumentsHash,InstantexpiresAt){}流程模型提出退款请求 ↓ 服务端校验订单和退款金额 ↓ 返回 approval_required ↓ 用户确认具体订单和金额 ↓ 服务端校验 approvalId ↓ 执行退款确认必须绑定具体参数不能只确认“允许退款”这一抽象动作。6. 工具调用审计CREATETABLEai_tool_call(id BIGSERIALPRIMARYKEY,tenant_idBIGINTNOTNULL,conversation_idBIGINTNOTNULL,message_idBIGINTNOTNULL,tool_call_idVARCHAR(128)NOTNULL,tool_nameVARCHAR(128)NOTNULL,arguments_json JSONB,arguments_hashVARCHAR(128),statusVARCHAR(32)NOTNULL,result_summaryTEXT,error_codeVARCHAR(64),created_at TIMESTAMPTZNOTNULLDEFAULTCURRENT_TIMESTAMP,completed_at TIMESTAMPTZ);日志中不要保存完整密码、Token、银行卡号和未脱敏工具结果。7. 工具调用超时和取消returnMono.fromCallable(()-tool.execute(context,arguments)).subscribeOn(Schedulers.boundedElastic()).timeout(Duration.ofSeconds(5)).onErrorMap(TimeoutException.class,error-newToolTimeoutException(tool.name()));阻塞式数据库或 HTTP 客户端不能直接占用 WebFlux 事件线程。工具超时后要更新调用状态并阻止迟到结果覆盖已经失败或取消的任务。8. 限制工具调用次数publicrecordToolPolicy(intmaxCallsPerTurn,SetStringallowedTools,booleanrequireApprovalForWrites){}调用策略应限制单轮最大工具次数单个工具最大重试次数工具参数大小工具结果大小工具链最长深度单次任务总耗时。9. 流式 Tool Calling流式模型可能先返回工具调用片段再返回工具参数。不要在收到第一个片段时立即执行接收工具名称和参数片段 ↓ 持续拼接并验证 JSON ↓ 确认参数完整 ↓ 执行权限检查 ↓ 执行工具 ↓ 发送 tool_call 状态事件高风险工具还要暂停流等待用户确认。五、常见问题与实践建议1. 模型为什么不调用工具可能原因工具描述不清楚当前模型不支持工具调用工具没有注册到本次请求用户问题不需要工具参数 Schema 不完整模型被系统 Prompt 要求直接回答Provider 兼容层丢失了工具字段。排查时记录工具列表、模型能力、请求模式和模型原始 tool call但注意脱敏。2. 模型调用了错误工具可以通过缩小每次请求的工具集合改善工具名称和描述将只读和写入工具分开在系统 Prompt 中明确决策边界增加服务端意图和权限校验对高风险工具强制人工确认。不要只依赖 Prompt 让模型“永远不要调用某工具”。3. 工具结果太长工具结果过长会消耗上下文。应返回摘要或分页结果{items:[{id:O1001,status:SHIPPED}],nextCursor:...}模型需要详细数据时再通过下一次工具调用获取指定内容。4. 工具失败后是否重试查询类工具可以有限重试写操作必须使用幂等键避免重复执行tool_name tenant_id business_request_id写入业务系统前服务端先检查请求是否已经成功执行。5. 工具调用和事务怎么配合不要把长时间模型调用放在数据库事务中。推荐创建任务和消息 ↓ 提交事务 执行工具和模型 ↓ 保存结果 ↓ 短事务更新状态6. 是否可以让模型直接执行 SQL不建议让模型直接连接生产数据库。更安全的方式是暴露固定业务查询工具使用只读数据库账号限制表和字段限制查询耗时和返回行数做 SQL 审计对高敏感字段脱敏。六、进阶思考1. 工具目录和动态注册当工具数量增加后可以设计工具目录Tool Catalog ├─ tool metadata ├─ required scopes ├─ risk level ├─ timeout ├─ rate limit └─ approval policyAgent 根据当前用户和任务只获得一部分工具避免把全量工具描述发送给模型。2. Tool Calling 与 Agent 状态机多步任务可以用状态机管理UNDERSTAND ↓ PLAN ↓ CALL_TOOL ↓ CHECK_RESULT ├─ NEED_MORE_TOOL ├─ NEED_APPROVAL └─ ANSWER比起让模型无限循环调用工具状态机更容易设置预算、超时和人工接管。3. 工具结果可信度工具返回的内容也可能来自外部系统或用户可编辑字段。模型不能把所有工具结果都当成系统规则业务工具结果 事实数据 用户备注和网页文本 不可信内容 系统授权和策略 服务端规则4. 评估 Tool Calling测试集应包括应该调用哪个工具参数是否正确无权限时是否拒绝工具失败时是否正确处理需要确认的动作是否暂停是否出现重复调用是否在预算和次数限制内完成。指标包括工具选择准确率、参数准确率、成功率、平均调用次数和越权拒绝率。结论Spring AI Tool Calling 的核心不是给模型增加几个 Java 方法而是建立一条受控的业务执行链路模型提出结构化调用意图服务端验证参数和权限业务工具执行真实操作工具结果经过脱敏和摘要模型根据结果生成最终回答每次调用都可追踪、可取消、可审计。查询工具可以先从只读、低风险场景开始涉及修改、发送、删除和资金操作时必须增加幂等、审批和人工确认。模型能力可以帮助系统理解用户意图但最终业务权限必须由服务端掌握。参考资料Spring AI Tool CallingSpring AI ChatClientSpring AI Advisors
返回列表