为什么选择 Spring AI:DC3 如何让大模型操控你的工厂
2025 年,大语言模型(LLM)不再只是聊天机器人,它们正在成为运维操作员。GPT-4o、Claude 4、DeepSeek、Qwen — 这些模型已经能够读取传感器数据、推理设备状态,并判断是否需要开启某个阀门。唯一的缺失环节,是"模型理解"与"模型执行" 之间的桥梁。这座桥梁就是 Spring AI,也是 IoT DC3 选择它作为 Agentic Center 基座的根本原因。
问题所在:AI 想行动,平台说不行
传统 IoT 平台将数据和指令视为两个独立的世界。数据从设备北上流向仪表盘,指令从操作员南下流向设备。 这两个方向很少在单次 API 调用中交汇,更不用说在单句自然语言中完成。
来看一个真实场景:操作员发现 3 号锅炉温度异常。在传统平台中,工作流如下:
- 导航到仪表盘,找到 3 号锅炉,记下温度。
- 切换到历史页面,查询过去 2 小时的温度数据。
- 大脑中评估:这是趋势还是脉冲?
- 导航到指令页面,选择"风机转速",输入新值。
- 提交,等待确认,验证温度开始下降。
五个上下文切换,跨越三个页面。每次切换耗时 15–30 秒。乘以 200 台设备,运维摩擦就变成了瓶颈。
而在 DC3 的 Agentic Center 中,操作员只需输入一句话:
"3 号锅炉温度在上升。检查过去 2 小时的数据,如果持续上升超过 30 分钟,将排风机降到 60%。"
模型将这句话拆解为工具调用序列,执行读取和有条件写入,并在单轮对话中回报结果—— 这不是 Demo,而是运行在 DC3 的 Spring AI 工具调用基础设施上的生产级能力。
为什么是 Spring AI,而非 LangChain 或自研
团队在选定 Spring AI 之前,评估了三种方案:
| 方案 | 优势 | 劣势 | 结论 |
|---|---|---|---|
| LangChain (Python) | 生态庞大,原型开发快 | Python/JVM 互操作开销、独立部署、安全边界模糊 | 对 JVM 原生平台过于沉重 |
| 自研 @Tool 框架 | 完全掌控,零依赖 | 数月工程投入,长期维护负担,无社区支撑 | 重复造轮子 |
| Spring AI | 原生 JVM、Spring Boot 深度集成、OpenAI 兼容、类型安全的工具定义 | 生态较新(2024+) | ✅ 最佳选择 |
Spring AI 在三个决定性维度上胜出:
1. 原生 JVM,无需 Python 桥接
DC3 是纯 Java 21 / Spring Boot 4 平台。每个服务都在 JVM 上运行。为引入 AI 而加入 Python 运行时, 意味着额外的容器、额外的部署、以及两个语言运行时之间脆弱的网络桥接。
Spring AI 运行在进程内——ChatClient 是一个 Spring Bean,工具调用是普通的 Java 方法调用, 认证上下文通过与其他任何请求相同的 Spring Security 过滤器链流转。
// DC3 工具类中的一个真实方法(节选自 PointValueTool)——纯 Java、类型安全、租户感知
public Mono<AgenticToolResult<FacadePointValueBO>> getLatestPointValueReactive(
Long deviceId, Long pointId, ToolContext toolContext) {
return Mono.defer(() -> {
Long tenantId = AgenticToolContextUtil.requireTenantId(toolContext);
if (deviceId == null || pointId == null) {
return Mono.just(AgenticToolResult.invalid("Device ID and point ID are required."));
}
return pointValueFacade.lastValue(tenantId, deviceId, pointId)
.map(value -> AgenticToolResult.ok("Latest point value loaded", value));
});
}这段方法经 ReactiveAgenticToolRegistry 以工具名 getLatestPointValue 注册成编程式 ToolDefinition,模型调用的就是它。 无需跨语言的序列化,无需独立的认证流程——从工具方法到平台 Facade 是普通 Java 调用(Facade 之后按配置走本地或 gRPC 到对应中心),租户隔离在方法级别执行。
2. OpenAI 兼容,Anthropic 原生
智能中心对外暴露 OpenAI Chat Completions 协议,可以与任何暴露 OpenAI 兼容端点的模型提供商配合:OpenAI (GPT-4o, GPT-5)、DeepSeek、 Qwen、Groq、Together AI、Ollama (本地模型)、vLLM —— 列表还在不断增长。Claude 不必绕道兼容代理: AgenticModelProviderTypeEnum.ANTHROPIC(provider_type=1)经 spring-ai-anthropic 与官方 SDK 直连 Anthropic API (ChatClientFactory 直接构建 AnthropicChatModel)。
对运维人员来说,选择权在自己手上:先用云端模型方便上手,再切换到自托管模型保证数据主权, 或者采用混合方案,敏感查询留在本地。Agentic Center 的 dc3_model_provider 表支持配置多个提供商, 并可按会话切换。
3. 类型安全的工具定义,编译期校验
在基于 Python 的工具调用框架中,工具定义通常是 JSON Schema 或带字符串描述的装饰器。 参数名的拼写错误就是运行时错误。而在 Spring AI 中,@Tool 和 @ToolParam 注解由 Java 编译器验证。 如果你修改了方法签名中的参数名但忘了更新注解,IDE 会在编译之前就标记出来。
当你拥有 12 个工具类、68 个工具以及一个贡献者团队时,这一点至关重要。 编程式注册的工具定义(name / description / JSON Schema)集中在 ReactiveAgenticToolRegistry 一处,同样享受编译期检查。 编译器成为了 Python 工具调用框架无法提供的安全网。
架构全景:一条聊天消息如何变成设备指令
以下是 DC3 中一次典型 AI 辅助操作的完整路径,端到端:
四个要素使这个架构达到生产级别:
每层租户隔离。 任何工具执行之前,
requireTenantId(toolContext)提取调用方的租户 ID。 每次数据库查询、每个缓存键、每次 Facade 调用都携带该租户 ID。即使模型错误地猜测了另一租户 的设备 ID,查询也是返回空结果——而非返回错误数据。写入指令需要人工确认。 模型可以提议写入,但无法直接执行写入。
PointValueTool.writePointValue()生成一个待确认的Action,10 分钟有效期。 只有人工POST /api/v3/agentic/action/confirm(action_id为 query 参数,或同等的 UI 按钮点击)才能释放它。这不是建议—— 而是在服务层强制执行,不仅限于 UI 层。会话可跨重启持久化。 每一轮——用户消息、工具调用、工具结果、助手回复—— 都落入
dc3_message表。即使 Agentic Center 重启,消息存储(ReactiveMessageStore.loadHistory) 会回放最近 30 条消息(约合 15 轮对话,historyWindowSize可配置),对话接着聊,不用从头再来。这对跨小时的诊断会话至关重要。模型永远看不到其他租户的数据。 租户 ID 由网关注入(来自 JWT),而非由模型指定。 即使提示词说"显示所有设备",工具的 SQL 查询中带有
WHERE tenant_id = ?, 绑定到网关注入的值。模型无法绕过——不存在跨租户查询的 API。
内建工具面:12 个工具类、68 个工具
Agentic Center 出厂自带 12 个工具类,覆盖平台每个领域对象。每个工具方法包装已有的服务层方法—— 不存在重复的业务逻辑。全部工具都在 ReactiveAgenticToolRegistry 一处编程式注册(2026.10 收敛后不再有 @Tool 反射通道, 两条模型链路共享同一份工具面)。唯一的写工具 writePointValue 走两阶段确认(见 Agentic 中心)。
| 工具类 | 领域 | 关键方法 |
|---|---|---|
TenantTool | 租户 | getCurrentTenantInfo() |
UserTool | 用户 | getCurrentUserProfile() |
SystemTool | 系统 | getSystemHealth(), getDeviceStatuses(), getDriverStatuses() |
DeviceTool | 设备 | lookupDeviceById(), searchDevices(), getDeviceLatestPointValues() |
DriverTool | 驱动 | lookupDriverById(), searchDrivers() |
ProfileTool | 模板 | lookupProfileById(), searchProfiles(), listProfilesByDeviceId() |
PointTool | 位号 | lookupPointById(), searchPoints(), listPointsByDevice() |
PointValueTool | 位号值 | getLatestPointValue(), getPointValueHistory(), readPointValue(), writePointValue() |
CommandTool | 命令 | lookupCommandById(), searchCommands(), listCommandsByDeviceId() |
EventTool | 事件 | lookupEventById(), searchEvents(), listEventsByDeviceId() |
InsightTool | 洞察 | getAlertStats(), getTodayStats(), analyticsQueryHistory() 等 25 个 |
HistoryTool | 历史 | searchCommandHistories(), searchEventHistories() |
工具方法刻意使用与 REST/gRPC 层不同的命名规范。REST 端点遵循项目的 getXxx/listXxx 约定; 工具方法使用 lookupXxx/searchXxx。这种分离让模型能够区分"按 ID 获取一个" (lookupDeviceById) 和"分页搜索"(searchDevices),这对模型选择正确的工具至关重要。
为什么这对工业 IoT 意义深远
工业场景是 AI 辅助运维的完美用武之地:
高认知负荷。 一名工厂操作员需要同时监控数十个屏幕、数百个数据点,必须在数秒内响应异常。 模型可以同时观察所有这一切。
结构化、边界明确的动作。 与开放式的创意任务不同,工业运维有清晰的边界: 读取传感器、检查阈值、调整执行器。这些完美映射到工具调用模式。
可审计性不可妥协。 DC3 中的每一次 AI 辅助操作都被记录到
dc3_message和dc3_action表中。谁问了什么、模型决定了什么、调用了哪些工具、结果是什么、 谁确认了写操作——全部可审计。多供应商现实。 工厂中可能存在 Siemens、Rockwell、Mitsubishi 等十几种品牌的设备。 DC3 的 36 个协议驱动将这种异构性抽象为统一的设备模型,AI 工具查询的就是这个统一模型—— 模型无需知道 Modbus 寄存器映射或 OPC UA 节点 ID。
路线图:下一步走向何方
今天的 Agentic Center 处理的是描述性和诊断性操作:"温度是多少""为什么在上升""给我看趋势"。 下一个前沿是建议性操作:
异常到动作管道。 模型在数据流中检测到异常,通过工具调用诊断根因, 并在操作员打开仪表盘之前提出纠正措施。
定时健康报告。 每天早上 7 点,Agentic Center 生成一份自然语言交接报告: 昨晚哪些设备离线、哪些位号趋势异常、建议哪些维护动作。
多模型路由。 将简单查询路由到快速廉价的模型 (GPT-4o mini); 将复杂诊断路由到推理模型 (GPT-5 或 Claude); 将敏感的本地查询路由到本地 Ollama 实例。
dc3_model_provider表和按会话的模型选择 已支持这一点——路由逻辑是下一层。MCP ↔ Agentic 桥接。 MCP 外部 Agent 接入已经上线:网关
POST /mcp的 OAuth 2.1 + JSON-RPC 2.0 端点让外部 AI Agent 调用平台工具面(见 AI Agent / MCP 集成)。待做的是把这条 MCP 工具面与 Agentic 对话链路桥接起来,让一次会话可以中途从自动化 Agent 转到人类操作员手上。
下一步: 查看 Agentic Center 获取完整工具参考和配置指南。 查看 AI Agent / MCP 接入外部 Agent。 查看 快速开始 让你的第一台设备上线。