1.路由流程图
- 上面一张图选自langGraph
- 下面一张选自SpingAi

2.适用场景
- 主要适用于不同类别应用场景
- 需要分类处理的应用场景
3.示例
3.1 输入部分
List<String> tickets = List.of(
"""
主题:无法登录账户
内容:你好,我这一个小时一直在尝试登录,但总是提示“密码无效”。
我很确定我输入的是正确密码。你能帮我恢复访问权限吗?这很紧急,我需要在今天提交报告。
- John
""",
"""
主题:信用卡上有一笔异常扣费
内容:您好,我刚刚注意到我的信用卡上有一笔.99元的扣费,但我记得我订阅的是.99元的套餐。
请问这笔费用是怎么来的?如果有误的话能否帮我处理一下?
谢谢,
Sarah
""",
"""
主题:如何导出数据?
内容:我需要把我的项目数据导出到 Excel。我查阅了文档,但没找到如何批量导出的方法。
请问可以做到吗?如果可以,能不能指导我具体步骤?
此致
Mike
"""
);
3.2 路由与提示词
3.21 路由前置部分
String selectorPrompt = String.format("""
请分析以下输入内容,并从以下支持团队中选择最合适的一个:%s
请先解释你的判断依据,然后按照以下 JSON 格式提供你的选择:
\\{
"reasoning": "简要说明为何将该请求分配给该支持团队。
请考虑关键词、用户意图以及紧急程度等因素。",
"selection": "所选择的团队名称"
\\}
输入:%s
""", availableRoutes, input);
3.22 路由与提示词部分
- 以key-value构成的路由
- key代表路由
- value 则为对应的提示词部分
Map<String, String> supportRoutes = Map.of(
"billing",
"""
你是一名账单支持专员,请遵循以下指南:
1. 始终以“账单支持回复:”开头
2. 首先确认用户提出的具体账单问题
3. 清晰说明费用来源或差异原因
4. 列出明确的后续处理步骤及时间表
5. 如有必要,请说明可选的付款方式
回应应专业且友好。
输入:
""",
"technical",
"""
你是一名技术支持工程师,请遵循以下指南:
1. 始终以“技术支持回复:”开头
2. 明确列出解决问题的具体步骤
3. 如有必要,说明系统要求
4. 提供常见问题的替代解决方案
5. 如需升级处理,请说明相关流程
使用清晰、有编号的步骤和技术细节。
输入:
""",
"account",
"""
你是一名账户安全专员,请遵循以下指南:
1. 始终以“账户支持回复:”开头
2. 优先处理账户安全和身份验证
3. 提供账户找回或更改的清晰步骤
4. 包含安全提示和警示信息
5. 明确说明处理时间和用户期望
语气严肃,注重安全。
输入:
""",
"product",
"""
你是一名产品专员,请遵循以下指南:
1. 始终以“产品支持回复:”开头
2. 注重功能讲解和使用建议
3. 提供具体的使用示例
4. 链接相关文档章节
5. 推荐其他可能有帮助的功能
保持教学式语气,积极鼓励用户。
输入:
"""
);
3.3 输出部分
Ticket 1
--------------------------------------------------------------------------------------------
主题:无法登录账户
内容:你好,我这一个小时一直在尝试登录,但总是提示“密码无效”。
我很确定我输入的是正确密码。你能帮我恢复访问权限吗?这很紧急,我需要在今天提交报告。
- John
--------------------------------------------------------------------------------------------
路由信息:
有效的路由: [product, account, technical, billing]
路由分析:用户无法登录账户并收到提示“密码无效”,这表明问题与账户访问相关。用户明确表示其密码正确,急需恢复账户访问以提交报告,因此最合适的支持团队是负责处理账户问题的团队。
选中的路由: account
--------------------------------------------------------------------------------------------
账户支持回复:
您好,John,
感谢您就账户访问问题与我们联系。我们优先关注您的账户安全,并将协助您恢复访问权限。请按照以下步骤操作:
1. **密码重置**:
- 请访问我们的账户登录页面,点击“忘记密码”选项。
- 输入您的注册邮箱地址以接收密码重置链接。
- 检查您的电子邮箱并点击重置链接,按照提示设置一个新密码。请确保新密码与之前的不同,并符合我们的密码安全标准(至少8个字符,包含字母、数字和符号)。
2. **身份验证**:
- 如果您已启用双重身份验证,请确保您的手机或身份验证设备可用,以便完成登录。
3. **账户安全提示**:
- 请不要与他人分享您的新密码。
- 定期更新密码,避免在多个平台使用相同密码。
- 小心处理来自不明来源的电子邮件或短信,防范网络钓鱼攻击。
4. **处理时间**:
- 通常情况下,密码重置和账户恢复步骤应在15分钟内完成。如果您在此过程中遇到任何问题,请立即回复此邮件或通过我们的客户支持电话联系我们。
鉴于您的时间紧迫,我们建议您尽快完成上述步骤。如有任何紧急情况,请与我们的支持团队直接联系以获取进一步帮助。
感谢您的理解与配合。
账户安全专员
[您的公司名称]
--------------------------------------------------------------------------------------------
Ticket 2
--------------------------------------------------------------------------------------------
主题:信用卡上有一笔异常扣费
内容:您好,我刚刚注意到我的信用卡上有一笔.99元的扣费,但我记得我订阅的是.99元的套餐。
请问这笔费用是怎么来的?如果有误的话能否帮我处理一下?
谢谢,
Sarah
--------------------------------------------------------------------------------------------
路由信息:
有效的路由: [product, account, technical, billing]
路由分析:用户提到信用卡上有一笔异常扣费,并询问费用来源及是否有误,涉及财务问题,因此应由billing支持团队处理。
选中的路由: billing
--------------------------------------------------------------------------------------------
账单支持回复:
您好,Sarah,非常感谢您联系账单支持团队。
确认您的问题:您注意到信用卡上有一笔.99元的扣费,而您订阅的是.99元的套餐。
费用来源说明:根据我们的记录,这笔扣费可能是由于最近的价格调整或特定服务的附加费用引起的。我们需要进一步核实您的账户细节以确认这笔费用的具体来源。
后续处理步骤及时间表:
1. 我们将在24小时内审核您的账户记录。
2. 如果确认有误,我们将在审核后的48小时内处理退款或调整。
3. 我们会通过电子邮件通知您审核结果及任何进一步的步骤。
可选付款方式说明:如果您需要更改付款方式或有其他账单处理需求,请您访问我们的在线客户门户,或直接联系我们的客户服务团队以获取更多帮助。
希望以上信息能帮助您解决问题。如需进一步协助,请随时与我们联系。
谢谢,
账单支持团队
--------------------------------------------------------------------------------------------
Ticket 3
--------------------------------------------------------------------------------------------
主题:如何导出数据?
内容:我需要把我的项目数据导出到 Excel。我查阅了文档,但没找到如何批量导出的方法。
请问可以做到吗?如果可以,能不能指导我具体步骤?
此致
Mike
--------------------------------------------------------------------------------------------
路由信息:
有效的路由: [product, account, technical, billing]
路由分析:用户询问如何导出项目数据到 Excel,并希望获得具体操作步骤。这涉及到产品功能的使用和指导,因此最合适的支持团队是 product 团队。
选中的路由: product
--------------------------------------------------------------------------------------------
产品支持回复:
您好,Mike!感谢您的询问。导出项目数据到 Excel 是一个非常常见的需求,我很乐意为您提供帮助。
首先,您需要确保您使用的产品版本支持数据导出功能。通常情况下,您可以通过以下步骤来批量导出您的项目数据:
1. **访问项目数据页面**:打开您的项目,找到“数据”或“报告”选项,这通常位于项目的导航菜单中。
2. **选择导出选项**:在数据页面上,您应该能够找到一个“导出”按钮。点击此按钮后,您会看到不同的导出格式选项。选择“Excel”作为导出格式。
3. **批量选择数据**:如果需要批量导出,请确保在导出前选择所需的数据范围或批量选择所有项目数据。有些平台允许您通过过滤器或选择特定日期范围来批量选择数据。
4. **完成导出**:选择好数据后,点击“导出”或“下载”按钮,系统会生成一个 Excel 文件供您下载。
具体的步骤可能会根据您使用的平台有所不同,但一般流程是类似的。如果您有更多的疑问,建议您查看[文档的导出章节](#)(请插入具体链接),该章节详细描述了导出的步骤和注意事项。
此外,您可能会对其他相关功能感兴趣,如数据分析工具或自动化报告生成功能,这些功能可以帮助您更好地管理和分析项目数据。
请尝试以上步骤,并随时联系我获取更多帮助。祝您导出顺利!
此致
产品支持团队
--------------------------------------------------------------------------------------------
4.编码实现
4.1 路由实体定义
- 定义record 实体部分
- selection 代表路由。路由集合:[product, account, technical, billing]
- reasoning 选择对应路由的原因
public record RoutingResponse(String reasoning, String selection) {
}
4.2 路由实现
4.21 路由识别实现
- determineRoute 返回的则是 RoutingResponse 实体中的selection,即路由部分,[product, account, technical, billing] 集合中的一部分
- 提示词与record 实体返回固定参数
@SuppressWarnings("null")
private String determineRoute(String input, Iterable<String> availableRoutes) {
System.out.println("\n有效的路由: " + availableRoutes);
String selectorPrompt = String.format("""
请分析以下输入内容,并从以下支持团队中选择最合适的一个:%s
请先解释你的判断依据,然后按照以下 JSON 格式提供你的选择:
\\{
"reasoning": "简要说明为何将该请求分配给该支持团队。
请考虑关键词、用户意图以及紧急程度等因素。",
"selection": "所选择的团队名称"
\\}
输入:%s
""", availableRoutes, input);
RoutingResponse routingResponse = chatClient.prompt(selectorPrompt).call().entity(RoutingResponse.class);
System.out.println(String.format("路由分析:%s\n选中的路由: %s",
routingResponse.reasoning(), routingResponse.selection()));
System.out.println();
return routingResponse.selection();
}
4.22 路由部分实现
- 通过input ,及路由识别方法(大模型判断)获取对应的路由key及选择的提示词部分(类似意图识别与分析)
- 通过input与路由识别后的提示词再次进行大模型交互,获取对应的output
public String route(String input, Map<String, String> routes) {
Assert.notNull(input, "Input text cannot be null");
Assert.notEmpty(routes, "Routes map cannot be null or empty");
String routeKey = determineRoute(input, routes.keySet());
String selectedPrompt = routes.get(routeKey);
if (selectedPrompt == null) {
throw new IllegalArgumentException("Selected route '" + routeKey + "' not found in routes map");
}
System.out.println("--------------------------------------------------------------------------------------------");
return chatClient.prompt(selectedPrompt + "\nInput: " + input).call().content();
}
4.23 完整RoutingWorkflow部分
package com.coderpwh.work;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.util.Assert;
import java.util.Map;
public class RoutingWorkflow {
private final ChatClient chatClient;
public RoutingWorkflow(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String route(String input, Map<String, String> routes) {
Assert.notNull(input, "Input text cannot be null");
Assert.notEmpty(routes, "Routes map cannot be null or empty");
String routeKey = determineRoute(input, routes.keySet());
String selectedPrompt = routes.get(routeKey);
if (selectedPrompt == null) {
throw new IllegalArgumentException("Selected route '" + routeKey + "' not found in routes map");
}
System.out.println("--------------------------------------------------------------------------------------------");
return chatClient.prompt(selectedPrompt + "\nInput: " + input).call().content();
}
@SuppressWarnings("null")
private String determineRoute(String input, Iterable<String> availableRoutes) {
System.out.println("\n有效的路由: " + availableRoutes);
String selectorPrompt = String.format("""
请分析以下输入内容,并从以下支持团队中选择最合适的一个:%s
请先解释你的判断依据,然后按照以下 JSON 格式提供你的选择:
\\{
"reasoning": "简要说明为何将该请求分配给该支持团队。
请考虑关键词、用户意图以及紧急程度等因素。",
"selection": "所选择的团队名称"
\\}
输入:%s
""", availableRoutes, input);
RoutingResponse routingResponse = chatClient.prompt(selectorPrompt).call().entity(RoutingResponse.class);
System.out.println(String.format("路由分析:%s\n选中的路由: %s",
routingResponse.reasoning(), routingResponse.selection()));
System.out.println();
return routingResponse.selection();
}
}
5.归纳
- 依据上面的两张流程图,先进行识别具体的路由值,后具体实现,共交互两次
- 关于代码中的record ,是实体中的一部分,定义的参数的是private final 类型,常用于固定参数值