尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

当 AI Agent 调用工具时,用户 ID 从哪来?——Spring AI ToolContext 传值实战

当 AI Agent 调用工具时,用户 ID 从哪来?——Spring AI ToolContext 传值实战
📅 发布时间:2026/8/4 12:25:36

一个绕不开的问题

你在用 Spring AI 开发 Agent 应用,一切都很美好——模型能理解自然语言,能自主决定调用哪个工具、传什么参数,直到你遇到了这样一个场景:

@Tool(description="查询用户账户余额")StringgetBalance(StringaccountType){returnbankService.getBalance(userId,accountType);// ^^^^^^// 这个 userId 从哪来?}

用户 ID 不能让 LLM 填。它属于运行时上下文,是请求进来时应用层已经确定的信息,不应该、也不能让模型来"猜"。

类似的场景很多:

  • 用户 ID、租户 ID——多租户系统中的安全边界
  • 会话 ID——需要关联当前对话上下文
  • 权限 Token——工具需要携带鉴权信息访问外部 API
  • 请求来源、渠道标识——工具行为需要根据来源差异化

这类参数有一个共同特征:它们属于"确定的上下文",不是 LLM 应该生成的"推理参数"。如果把它们混入工具的输入参数让模型来填,轻则幻觉(模型编造一个 userId),重则越权(模型填了别人的 userId)。

Spring AI 提供了ToolContext机制来优雅地解决这个问题。


ToolContext 是什么

一句话概括:ToolContext 是一个由应用层注入、对 LLM 不可见的键值对容器,在工具执行时自动传递给工具方法。

它的核心设计思想:

┌──────────────┐ toolContext(Map) ┌──────────────┐ │ Application │ ──────────────────────────▶│ Tool │ │ (应用层) │ userId, tenantId, ... │ (工具方法) │ └──────────────┘ └──────────────┘ ┌──────────────┐ toolInput(参数) ┌──────────────┐ │ LLM │ ─────────────────────▶│ Tool │ │ (大语言模型) │ accountType, ... │ (工具方法) │ └──────────────┘ └──────────────┘
  • LLM 负责填充的:工具的业务参数(如accountType)——模型根据用户意图推理得出
  • 应用层负责注入的:上下文参数(如userId)——应用层在调用时确定,透传给工具

两条路径,互不干扰。LLM 完全感知不到 ToolContext 的存在,既不会在工具的 JSON Schema 中看到它,也不会试图为它生成值。


具体用法

Spring AI 提供了两种等价的工具定义方式,都支持 ToolContext:

方式一:@Tool注解式——在方法签名中声明 ToolContext

将ToolContext作为方法的最后一个参数,Spring AI 会自动注入:

classCustomerTools{@Tool(description="查询客户信息")CustomergetCustomerInfo(Longid,ToolContexttoolContext){// 从 ToolContext 中取出应用层注入的租户 IDStringtenantId=(String)toolContext.getContext().get("tenantId");returncustomerRepository.findById(id,tenantId);}@Tool(description="查询账户余额")StringgetBalance(StringaccountType,ToolContexttoolContext){StringuserId=(String)toolContext.getContext().get("userId");returnbankService.getBalance(userId,accountType);}}

注意:ToolContext参数对模型是隐藏的。模型只看到id和accountType,不会看到ToolContext。

方式二:BiFunction<T, ToolContext, R>编程式——函数式定义

等价地,用BiFunction定义工具逻辑,第二个参数就是ToolContext:

publicclassAccountInfoToolimplementsBiFunction<String,ToolContext,String>{@OverridepublicStringapply(Stringquery,ToolContexttoolContext){StringuserId=(String)toolContext.getContext().get("userId");StringtenantId=(String)toolContext.getContext().get("tenantId");if(userId==null){return"用户未登录,无法查询";}returnaccountService.query(userId,tenantId,query);}}// 构建 ToolCallbackToolCallbackaccountTool=FunctionToolCallback.builder("get_account_info",newAccountInfoTool()).description("查询当前用户的账户信息").inputType(String.class).build();

两种方式完全等价,选择哪种取决于你的编码风格:

  • 注解式更简洁,适合工具逻辑简单的场景
  • 编程式更灵活,适合需要复杂构造或复用的场景

在调用端注入 ToolContext

定义好工具后,在调用时注入上下文数据。根据入口不同,方式略有差异。

ChatClient 入口

Stringresponse=ChatClient

相关新闻

  • 2026金华木门十大品牌,你选对了吗
  • 2026外贸独立站建设公司盘点_外贸企业如何挑选靠谱的建站服务商 - 资讯报道
  • 2026年河北节水灌溉设备选购指南:从大水漫灌到精准智能的完全破局 - 优质企业观察收录

最新新闻

  • OpenClaw与Telegram集成:智能社群管理实践
  • 小白程序员也能掌握的AI新职业机遇:智能体开发与GEO优化指南
  • Github上的资源安装包怎么选
  • WhatsApp测试新功能:大型企业消息将自动归入独立文件夹
  • 分布式电源配电网可靠性评估的Matlab实现与优化
  • ESXi 6.x时间同步配置与NTP服务详解

日新闻

  • 5分钟快速搭建智能数字人:Live2D虚拟形象终极部署指南
  • 告别繁简字幕转换烦恼:这款开源工具让你一键搞定影视字幕处理 [特殊字符]
  • GPT-5.4传闻背后:大模型永久记忆与极限推理的技术演进与挑战

周新闻

  • 怀化母婴除甲醛公司测甲醛中心怎么选:康之居母婴除甲醛标准、流程、避坑指南 - 信誉隆金银铂奢回收
  • 三步打造你的终极音乐中心:foobox-cn网络电台功能完整指南
  • Lance湖仓格式:为多模态AI工作流设计的终极数据存储方案

月新闻

  • ClickHouse版本管理深度实战:4步构建零风险升级与回滚体系
  • Java 23 种设计模式:从踩坑到精通 | 番外:责任链模式 —— 物流审批流程实战
  • 华硕笔记本性能解放指南:G-Helper轻量级控制工具全面解析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号