1. 项目概述
在当今企业级应用开发中,将AI能力集成到现有系统已成为提升业务智能化水平的重要途径。最近我在一个基于Ruoyi框架的项目中,成功接入了AgentScope Java SDK,实现了通过自然语言查询用户信息并进行统计分析的功能。这个方案的核心价值在于,业务人员无需学习复杂的SQL或API调用,只需用自然语言描述需求,系统就能自动完成数据查询和分析。
整个集成过程涉及几个关键环节:首先需要在项目中引入AgentScope依赖,然后开发具备特定功能的工具类,最后通过控制器将大模型能力暴露为HTTP接口。下面我将详细分享每个环节的实现细节和注意事项。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与依赖配置
2.1 项目基础环境
这个项目基于以下技术栈:
- 后端框架:Ruoyi 4.7.5(Spring Boot 2.7.18)
- 数据库:MySQL 8.0
- JDK版本:17
- 构建工具:Maven 3.8.6
Ruoyi作为一个成熟的企业级快速开发框架,已经为我们提供了完善的用户管理模块,包括SysUser实体类、SysUserMapper接口以及配套的Service层。这为我们后续集成AgentScope提供了良好的基础。
2.2 AgentScope SDK引入
在pom.xml中添加AgentScope依赖时,需要注意版本兼容性问题。当前最新稳定版是1.0.9,与Spring Boot 2.7.x配合良好:
xml复制<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope</artifactId>
<version>1.0.9</version>
</dependency>
提示:建议在dependencyManagement中锁定AgentScope的版本,避免后续自动升级带来兼容性问题。同时要注意,AgentScope 1.0.x系列要求JDK 11+,如果项目还在使用JDK 8,需要考虑升级或寻找替代方案。
2.3 大模型API配置
AgentScope支持多种大模型后端,包括OpenAI API兼容的各类服务。在本项目中,我们使用了DeepSeek的推理API:
properties复制# application.properties配置示例
agentscope.model.deepseek.api-key=your_api_key_here
agentscope.model.deepseek.base-url=https://api.deepseek.com
agentscope.model.deepseek.model-name=deepseek-reasoner
虽然示例中将API密钥硬编码在Controller中,但在实际生产环境中,强烈建议通过配置中心管理这些敏感信息。可以使用Spring的@Value注解或更安全的Vault方案来注入这些配置。
3. 工具类开发与注解解析
3.1 @Tool与@ToolParam注解详解
AgentScope的核心机制是通过工具类暴露系统能力给大模型。关键注解说明:
@Tool:标记一个方法作为工具暴露给Agent,必须指定name和description@ToolParam:定义工具方法的参数,每个参数都需要明确名称、描述和是否必需
java复制@Tool(name = "queryUsers", description = "根据条件查询系统用户列表,支持分页")
public String queryUsers(
@ToolParam(name = "userName", description = "用户名(支持模糊查询)", required = false) String userName,
@ToolParam(name = "phonenumber", description = "手机号码", required = false) String phonenumber,
@ToolParam(name = "status", description = "状态(0正常 1停用)", required = false) String status,
@ToolParam(name = "pageNum", description = "页码") int pageNum,
@ToolParam(name = "pageSize", description = "每页条数") int pageSize) {
// 方法实现
}
注意:description字段的质量直接影响大模型对工具的理解和使用准确性。建议用完整句子描述功能,包含输入输出的明确说明。
3.2 数据返回格式设计
为了让大模型更好地理解返回数据,应采用结构化的响应格式。示例中采用了类似Ruoyi前端表格的数据结构:
json复制{
"total": 42,
"rows": [
{
"userId": 1,
"userName": "admin",
"phonenumber": "15888888888",
"status": "0"
}
]
}
这种格式的优势在于:
- 明确区分数据总量和当前页数据
- 字段命名清晰,便于大模型提取关键信息
- 与前端表格组件数据结构一致,便于后续扩展
3.3 权限控制实现
虽然示例中直接使用了userMapper跳过了权限检查,但在实际项目中必须加入适当的权限控制。推荐两种方案:
方案一:基于Shiro的权限检查
java复制if (!SecurityUtils.getSubject().isPermitted("system:user:list")) {
return "{\"error\": \"无权限查询用户\"}";
}
方案二:Spring Security方法级注解
java复制@PreAuthorize("hasPermission('system:user:list')")
@Tool(name = "queryUsers", description = "根据条件查询系统用户列表")
public String queryUsers(...) {
// 方法实现
}
重要:无论采用哪种方案,都要确保工具类方法不会绕过系统的权限体系。特别是在返回敏感字段(如密码哈希、手机号等)时,需要进行脱敏处理。
4. Agent配置与控制器实现
4.1 ReActAgent构建详解
ReActAgent是AgentScope提供的基于ReAct模式的智能体实现,构建时需要关注以下参数:
java复制ReActAgent agent = ReActAgent.builder()
.name("UserQueryAssistant") // Agent名称,用于日志和追踪
.sysPrompt("你是一个用户查询助手...") // 系统提示词,指导Agent行为
.model(model) // 绑定的大模型实例
.toolkit(toolkit) // 可用的工具集
.maxIterations(5) // 最大思考迭代次数,防止死循环
.build();
系统提示词(system prompt)的设计要点:
- 明确角色定位:"你是一个用户查询助手"
- 说明核心能力:"可以根据条件查询系统用户列表"
- 指导工具使用:"当用户需要查询用户时,调用queryUsers工具"
- 可添加输出格式要求:"请用简洁的语言总结查询结果"
4.2 消息构建与交互
AgentScope使用Msg对象进行消息传递,关键组件包括:
java复制Msg userMsg = Msg.builder()
.role(MsgRole.USER) // 消息角色
.content(TextBlock.builder()
.text("查询状态为0的用户") // 用户输入文本
.build())
.build();
消息处理流程:
- 将用户输入包装为Msg对象
- 通过agent.call()方法获取响应
- 提取响应内容返回给前端
4.3 控制器设计优化
虽然示例中将所有配置放在Controller中可行,但更推荐采用分层设计:
- 将Agent配置移到@Configuration类
- 使用@Service封装业务逻辑
- Controller只负责HTTP交互
优化后的结构:
java复制@RestController
@RequestMapping("/api/agent")
public class AgentController {
@Autowired
private UserQueryAgentService agentService;
@PostMapping("/query")
public String handleQuery(@RequestBody UserQueryRequest request) {
return agentService.processQuery(request.getMessage());
}
}
这种结构的优势:
- 符合单一职责原则
- 便于单元测试
- 支持更复杂的业务逻辑扩展
5. 前端集成与效果展示
5.1 前端调用方式
前端可以通过简单的AJAX调用Agent接口:
javascript复制function queryWithAgent(message) {
return axios.get(`/agent/queryUsers/${encodeURIComponent(message)}`)
.then(response => {
// 处理Agent返回的自然语言结果
console.log(response.data);
return response.data;
});
}
实际项目中,可以构建更友好的聊天界面,使用类似以下代码:
javascript复制// 在Vue组件中的示例方法
async handleUserQuery() {
this.loading = true;
try {
const response = await queryWithAgent(this.userMessage);
this.chatHistory.push({
sender: 'user',
content: this.userMessage
});
this.chatHistory.push({
sender: 'agent',
content: response
});
} finally {
this.loading = false;
}
}
5.2 效果展示与交互示例
系统可以理解多种形式的自然语言查询,例如:
- "列出所有管理员用户"
- "查询手机号包含138的用户"
- "显示第2页的用户,每页15条"
- "统计活跃用户(状态为0)的数量"
返回结果可能是:
- "共找到25个活跃用户,当前显示第1页的10条记录:..."
- "没有找到手机号包含138的用户"
- "您没有权限执行此查询"
5.3 性能优化建议
- 缓存机制:对常见查询结果进行缓存
- 流式响应:对于可能耗时的操作,采用SSE或WebSocket实现流式输出
- 请求超时:设置合理的超时时间(如30秒)
- 频率限制:防止API被滥用
6. 生产环境注意事项
6.1 安全性加固
- 输入校验:对所有用户输入进行严格的校验和过滤
- 输出过滤:对Agent返回的内容进行敏感词过滤
- 访问控制:限制接口的访问IP和频率
- 日志审计:记录所有Agent交互日志
6.2 错误处理与监控
完善的错误处理机制应包括:
java复制try {
Msg response = agent.call(userMsg).block();
return processResponse(response);
} catch (Exception e) {
log.error("Agent调用失败", e);
return "{\"error\": \"系统处理您的请求时出错\"}";
}
监控指标建议:
- Agent调用成功率
- 平均响应时间
- 工具调用频率
- 错误类型统计
6.3 性能调优经验
- 连接池配置:优化大模型API的HTTP连接池
- 批量处理:对多个工具调用进行批量处理
- 超时设置:根据业务需求调整各类超时参数
- 内存管理:监控Agent运行时的内存使用情况
7. 扩展应用场景
这个基础集成方案可以扩展到更多业务场景:
- 数据报表生成:通过自然语言描述生成复杂报表
- 业务规则查询:查询系统中的各种业务规则和配置
- 运维自动化:用自然语言执行服务器状态检查等运维操作
- 知识问答:基于企业文档库构建智能问答系统
每个扩展场景都需要:
- 开发相应的工具类方法
- 设计专门的系统提示词
- 可能需要进行大模型微调
- 设计合适的权限控制方案
我在实际项目中发现,这种自然语言交互方式特别适合需要频繁查询但又不熟悉技术细节的业务人员使用。一个典型的成功案例是,财务部门的同事现在可以自己查询用户付费情况,而不需要每次都找技术团队写SQL查询。
