作者:互联网 时间: 2026-06-30 09:01:08
Phase 2 的 DeviceAgent 把 5 个工具全注册在一个 Agent 上:

复制代码AiServices.builder(IndustrialAssistant.class)
.chatModel(chatModel)
.tools(alarmTool, dataTool, diagnosisTool, knowledgeBaseTool, workOrderTool)
.build();
三个问题逐渐暴露:
queryDeviceAlarms 而不是 queryDeviceHistory 复制代码用户消息 → IntentClassifier(LLM + 关键词兜底)
↓
┌──────┼──────┬──────────┬──────────┐
↓ ↓ ↓ ↓ ↓
Alarm Data Diagnosis Knowledge General
Expert Expert Expert Expert Expert
核心思路:先分类,再分发。每个 Expert 只带 1-2 个工具和专精的系统消息。
复制代码@Component
public class IntentClassifier { public Intent classify(String message) {
// 1. 先用 LLM 分类(~50 token 的轻量调用)
Intent intent = classifyByLlm(message);
// 2. LLM 失败时退化到关键词匹配
if (intent == null) {
intent = classifyByKeyword(message);
}
return intent;
} private Intent classifyByLlm(String message) {
String prompt = "将以下消息分类为:ALARM/DATA/DIAGNOSIS/KNOWLEDGE/GENERALn消息:" + message;
String result = chatModel.chat(prompt).trim().toUpperCase();
// 从返回文本中匹配枚举值
for (Intent i : Intent.values()) {
if (result.contains(i.name())) return i;
}
return null; // LLM 返回无效 → 交给关键词
} private Intent classifyByKeyword(String message) {
if (Pattern.matches(".*诊断|故障|排查|工单.*", message)) return Intent.DIAGNOSIS;
if (Pattern.matches(".*告警|报警|警告.*", message)) return Intent.ALARM;
if (Pattern.matches(".*温度|振动|压力|数据|趋势.*", message)) return Intent.DATA;
if (Pattern.matches(".*知识|手册|怎么修.*", message)) return Intent.KNOWLEDGE;
return Intent.GENERAL;
}
}
为什么不只用关键词?因为「CNC-001 最近震动有点大,帮我看看是不是轴承的问题」不含「诊断」二字,但意图明显是 DIAGNOSIS。LLM 能理解语义,关键词只能匹配字面。
为什么不只用 LLM?因为 LLM 偶尔会返回奇怪的格式(「我认为这属于 ALARM 类别」而不是纯 「ALARM」),关键词兜底确保系统不卡死。
每个 Expert 是一个独立的 AiServices 实例,关键差异在 SystemMessage:
| Expert | 工具数 | SystemMessage 重点 |
|---|---|---|
| AlarmExpert | 1 | 告警解读、风险等级评估 |
| DataExpert | 1 | 数据趋势分析、阈值标注 |
| DiagnosisExpert | 5 | 完整 CoT 五步链 |
| KnowledgeExpert | 1 | 知识检索、维修方案 |
| GeneralExpert | 0 | 一般问答、引导用户 |
以 AlarmExpert 为例:
复制代码@Component
public class AlarmExpert { interface AlarmAssistant {
@SystemMessage("""
你是工业设备告警分析专家。你只负责设备告警的查询和解读。
使用 queryDeviceAlarms 工具查询设备当前活跃告警。
回复规范:
- 列出所有告警,标注严重级别
- 对每条告警给出简要风险评估
- 如果无告警,明确说明设备状态正常
""")
String chat(String message);
} public String chat(String message) {
AlarmAssistant assistant = AiServices.builder(AlarmAssistant.class)
.chatModel(chatModel)
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
.tools(alarmTool) // 只有1个工具
.build();
return assistant.chat(message);
}
}
对比单 Agent 的 SystemMessage(800 token),AlarmExpert 只用 120 token——省 85% 的提示词开销,且不会选错工具(因为只有一个可选)。
复制代码@Service
public class RouterAgent { public RouteResult route(String message) {
long start = System.currentTimeMillis();
Intent intent = classifier.classify(message); String reply = switch (intent) {
case ALARM -> alarmExpert.chat(message);
case DATA -> dataExpert.chat(message);
case DIAGNOSIS -> diagnosisExpert.chat(message);
case KNOWLEDGE -> knowledgeExpert.chat(message);
case GENERAL -> generalExpert.chat(message);
}; long elapsed = System.currentTimeMillis() - start;
return new RouteResult(intent, reply, elapsed);
} public record RouteResult(Intent intent, String reply, long latencyMs) {}
}
返回值带 intent 和 latencyMs,方便前端展示路由决策过程和性能监控。
| 测试消息 | 分类结果 | 延迟 |
|---|---|---|
| "CNC-001 有什么告警?" | ALARM | 6.8s |
| "查一下最近一小时的温度趋势" | DATA | 6.6s |
| "振动异常,诊断并创建工单" | DIAGNOSIS | 16.5s |
| "轴承温度过高怎么修?" | KNOWLEDGE | 16.6s |
| "你好,你是谁?" | GENERAL | 2.5s |
分类准确率 5/5 = 100%。
延迟分析:
| 维度 | 单 Agent | Router + Expert |
|---|---|---|
| 工具选择准确率 | ~85%(偶尔选错) | ~99%(Expert 只有 1 个工具) |
| 系统消息开销 | 800 token/次 | 120-300 token/次 |
| 可扩展性 | 加工具越多越难管理 | 加 Expert 不影响其他 |
| 延迟 | 一次 LLM 调用 | 分类 + Expert 两次调用 |
| 复杂度 | 低 | 中 |
Router 的额外延迟(~1s 分类)换来了更高的准确率和更低的 token 消耗。 对工业场景来说,准确率比延迟重要。
复制代码agent/
├── DeviceAgent.java — 原有单 Agent(保留做对比)
├── router/
│ ├── Intent.java — 5 种意图枚举
│ ├── IntentClassifier.java — LLM + 关键词分类器
│ └── RouterAgent.java — 路由编排器
└── experts/
├── AlarmExpert.java — 告警专家(1 工具)
├── DataExpert.java — 数据专家(1 工具)
├── DiagnosisExpert.java — 诊断专家(5 工具 + CoT)
├── KnowledgeExpert.java — 知识专家(1 工具)
└── GeneralExpert.java — 通用对话(无工具)
Router 解决了「分发」问题,但每个 Expert 是独立的——它们之间不会协作。下一篇文章引入 Supervisor 模式:一个「主管 Agent」动态规划多步任务,委派给不同 Expert,汇总结果后统一回复。
代码仓库:github.com/LaoLiang-ag…