工具架构
Xiuxian 模块采用单 Agent + 6组领域工具的设计,LLM 自主从工具池中选择调用,而非预先路由。
设计理念
与路由器模式(顶层层 LLM 路由到子 Agent)不同,当前方案让 LLM 直接面向所有工具:
| 路由器模式 | 当前方案 |
|---|---|
| 顶层 LLM 先判断意图再路由 | LLM 直接选择工具 |
| 每个子领域有独立 Prompt | 统一 System Prompt + 工具描述 |
| 工具集合按领域隔离 | 所有工具对 LLM 可见 |
| 需要维护路由逻辑 | 工具即路由,无需额外代码 |
优势:代码更简洁,新增工具只需创建 @Tool 方法并注入到 XiuxianAgentService,无需修改任何路由逻辑。
6组业务工具
XiuxianAgentService
├── XiuxianUserTools — 修士查询、新增、修改、删除
├── XiuxianTaskTools — 任务接取、完成、放弃、查询
├── XiuxianManualTools — 功法推荐、查询
├── XiuxianExchangeTools — 物品兑换、积分计算
├── XiuxianResourceTools — 资源查看、调整
└── XiuxianKnowledgeTools — 世界知识(境界体系、灵根类型等)工具注册
所有工具在 XiuxianAgentService.doChatSse() 中一次性注册:
java
chatClient.prompt()
.system(systemPrompt)
.user(message)
.tools(userTools, taskTools, manualTools,
exchangeTools, resourceTools, knowledgeTools)
.toolContext(toolContext)
.stream()
.chatResponse()LLM 根据 @Tool 注解中的 description 理解每个工具的用途,自主决定调用哪个。
工具上下文
工具通过 ToolContext 获取 XiuxianAgentContext,从中读取当前用户身份等信息:
java
public static XiuxianAgentContext fromToolContext(ToolContext toolContext) {
return (XiuxianAgentContext) toolContext.getContext()
.get(XiuxianAgentContext.CONTEXT_KEY);
}工具通信
进度通知
工具通过 XiuxianAgentContext.notify() 向 SSE 通道发送 PROGRESS 事件:
java
ctx.notify("📋 正在查询修士信息...");
// 执行查询...
ctx.notify("✅ 查询完成");前端实时展示在思考气泡中。
消歧确认
工具返回模糊匹配结果时,构建 CONFIRMATION 响应让前端弹卡:
java
if (candidates.size() > 1) {
List<Candidate> cards = candidates.stream()
.map(c -> new Candidate(c.getId(), c.getLabel()))
.toList();
return AgentResponse.needConfirm("找到多位同名修士,请选择:", cards);
}前端用户点击后,通过 selectedId 回传精确定位。
权限控制
工具内部通过 XiuxianAgentContext 检查权限:
java
XiuxianAgentContext ctx = XiuxianAgentContext.fromToolContext(toolContext);
if (!ctx.hasPermission(XiuxianRole.PEAK_MASTER)) {
return error("权限不足");
}详见 权限控制。
新增领域工具
只需 3 步:
- 创建
XiuxianXxxTools extends BaseToolSupport,定义@Tool方法 - 注入所需业务 Service
- 在
XiuxianAgentService构造函数中添加参数,并在.tools()调用中注册
无需修改现有工具代码,无需新增路由逻辑。