内置工具与技能:Agent 开箱即用的能力
详细了解 Agent4J 内置的三大技能:文件系统、命令执行、任务编排。
内置工具与技能:Agent 开箱即用的能力
前言
在上一篇文章中,我们了解了 Agent4J 的核心概念。现在让我们深入看看 Agent4J 提供的内置工具。
Agent4J 有三大内置技能:
- FileSystem:文件系统操作
- CommandExecution:命令执行
- Orchestration:任务编排
这些技能就像给 Agent 装上了手脚,让它能真正地做事。
1. FileSystem 技能
FileSystem 技能让 Agent 能读写文件、浏览目录、搜索内容。这是最常用的技能,因为很多任务都涉及文件操作。
工具列表
| 工具名 | 功能 | 使用场景 |
|---|---|---|
list_directory_tree |
浏览目录结构 | 了解项目结构 |
view_file |
读取文件内容 | 查看代码、配置文件 |
create_file |
创建文件 | 生成代码、配置文件 |
edit_file |
编辑文件 | 修改代码、更新配置 |
delete_file |
删除文件 | 清理临时文件 |
move_file |
移动或重命名文件 | 整理文件结构 |
search_in_file |
在文件中搜索 | 查找特定代码 |
search_in_directory |
在目录中搜索 | 全局搜索 |
search_files |
按文件名搜索 | 查找特定文件 |
使用示例
浏览目录结构
agent.createSession()
.command("请列出当前目录的结构,深度为 2 层")
.then(handler)
.error(errorHandler);
Agent 会调用 list_directory_tree 工具,返回类似这样的结果:
├── src/
│ ├── main/
│ │ ├── java/
│ │ └── resources/
│ └── test/
├── pom.xml
└── README.md
读取文件内容
agent.createSession()
.command("请读取 pom.xml 文件,告诉我项目用了哪些依赖")
.then(handler)
.error(errorHandler);
Agent 会调用 view_file 工具,读取 pom.xml 的内容,然后分析依赖。
创建文件
agent.createSession()
.command("请创建一个名为 hello.java 的文件,内容是一个 Hello World 程序")
.then(handler)
.error(errorHandler);
Agent 会调用 create_file 工具,生成一个 Java 文件。
编辑文件
agent.createSession()
.command("请把 hello.java 中的 'Hello World' 改成 'Hello Agent4J'")
.then(handler)
.error(errorHandler);
Agent 会调用 edit_file 工具,按行号替换内容。
大文件处理
view_file 工具会自动截断大文件,只返回前 1000 行。这对于查看大型日志文件很有用,不会让 LLM 的上下文被撑爆。
如果你想查看文件的特定部分,可以告诉 Agent:
agent.createSession()
.command("请读取 log.txt 文件的最后 100 行")
.then(handler)
.error(errorHandler);
2. CommandExecution 技能
CommandExecution 技能让 Agent 能执行 Shell 命令。这是最强大的技能,因为 Shell 命令几乎能做任何事情。
工具列表
| 工具名 | 功能 | 使用场景 |
|---|---|---|
execute_command |
执行 Shell 命令 | 运行脚本、安装依赖、编译代码 |
使用示例
运行命令
agent.createSession()
.command("请运行 'ls -la' 命令,列出当前目录的所有文件")
.then(handler)
.error(errorHandler);
Agent 会调用 execute_command 工具,执行命令并返回结果。
跨平台支持
Agent4J 会自动检测操作系统:
- Windows:使用 PowerShell
- macOS/Linux:使用 bash
你不需要关心平台差异,Agent4J 会帮你处理。
超时处理
命令执行默认有 60 秒超时。如果命令执行时间过长,会被自动终止。
对于长时间运行的命令,你可以告诉 Agent:
agent.createSession()
.command("请运行 'mvn clean install' 命令,如果超时就分步执行")
.then(handler)
.error(errorHandler);
安全注意事项
Shell 命令很强大,但也可能很危险。Agent 可能会执行删除文件、修改系统配置等危险操作。
在生产环境中,建议:
- 限制命令范围:只允许执行特定的命令
- 使用沙箱:在隔离的环境中运行
- 人工审核:对于危险操作,让人工确认
3. Orchestration 技能
Orchestration 技能让 Agent 能创建计划和生成子 Agent。这对于复杂任务很有用。
工具列表
| 工具名 | 功能 | 使用场景 |
|---|---|---|
create_plan |
创建执行计划 | 复杂任务拆分 |
create_sub_agent |
生成子 Agent | 并行处理子任务 |
使用示例
创建计划
当任务比较复杂时,Agent 会自动创建计划:
agent.createSession()
.command("请帮我创建一个 Spring Boot 项目,包含用户管理、订单管理、商品管理三个模块")
.then(new AgentResultHandler() {
public void onMessage(String msg) {
System.out.print(msg);
}
public void onPlanCreated(Plan plan) {
System.out.println("创建了计划,共 " + plan.getSteps().size() + " 步");
}
public void onPlanStepStart(Plan plan, int current, int total, String step) {
System.out.println("开始执行第 " + current + " 步:" + step);
}
public void onPlanStepComplete(Plan plan, int current, int total, String step, String result) {
System.out.println("完成第 " + current + " 步");
}
})
.error(e -> e.printStackTrace());
Agent 会创建一个计划,包含多个步骤:
- 创建项目结构
- 创建用户管理模块
- 创建订单管理模块
- 创建商品管理模块
- 创建配置文件
然后按顺序执行每个步骤。
生成子 Agent
对于可以并行处理的任务,Agent 会生成子 Agent:
agent.createSession()
.command("请同时分析这三个文件:a.java、b.java、c.java,告诉我它们的功能")
.then(new AgentResultHandler() {
public void onSubAgent(AgentClient agent, String message) {
System.out.println("生成了子 Agent:" + agent.getName());
}
public void onSubAgentResult(AgentClient agent, String result) {
System.out.println("子 Agent 返回结果:" + result);
}
})
.error(e -> e.printStackTrace());
Agent 会生成三个子 Agent,每个子 Agent 负责分析一个文件,最后汇总结果。
计划 vs 子 Agent
什么时候用计划,什么时候用子 Agent?
用计划:
- 任务有明确的先后顺序
- 后续步骤依赖前面步骤的结果
- 需要严格控制执行流程
用子 Agent:
- 子任务之间相互独立
- 可以并行处理
- 需要提高效率
在实际应用中,Agent 会根据任务特点自动选择合适的方式。
组合使用
内置技能可以组合使用,完成复杂的任务:
agent.createSession()
.command("""
请帮我完成以下任务:
1. 读取 config.properties 文件
2. 根据配置创建数据库表
3. 生成对应的 Java 实体类
4. 创建 DAO 层代码
5. 编写单元测试
""")
.then(handler)
.error(errorHandler);
在这个任务中,Agent 会:
- 用
view_file读取配置文件 - 用
execute_command连接数据库并创建表 - 用
create_file生成 Java 实体类 - 用
create_file创建 DAO 层代码 - 用
create_file编写单元测试
整个过程完全自动化,你只需要描述需求。
自定义内置技能
如果你不想使用所有内置技能,可以只添加需要的:
// 只添加文件系统技能
agent.getSkills().add(BuiltInSkills.fileSystem());
// 只添加命令执行技能
agent.getSkills().add(BuiltInSkills.commandExecution());
// 只添加编排技能
agent.getSkills().add(BuiltInSkills.orchestration());
或者添加所有技能,但禁用某些工具:
agent.getSkills().addAll(BuiltInSkills.all());
// 禁用危险的工具
agent.getTools().removeIf(tool ->
tool.getName().equals("execute_command") ||
tool.getName().equals("delete_file")
);
工具的状态回调
当 Agent 调用工具时,你可以通过回调了解进度:
agent.createSession()
.command("请帮我整理文件")
.then(new AgentResultHandler() {
public void onTool(ToolDescriptor tool, ToolStatus status) {
switch (status) {
case PREPARING:
System.out.println("准备调用:" + tool.getName());
break;
case CALLING:
System.out.println("正在执行:" + tool.getName());
break;
case COMPLETED:
System.out.println("完成执行:" + tool.getName());
break;
}
}
})
.error(e -> e.printStackTrace());
这对于调试和监控很有用。
最佳实践
1. 描述要清晰
给 Agent 的描述越清晰,它越知道该怎么做:
// 不好的描述
agent.setDescription("一个助手");
// 好的描述
agent.setDescription("一个资深的 Java 开发工程师,擅长代码审查、重构和单元测试编写");
2. 任务要具体
给 Agent 的任务越具体,它越能准确执行:
// 不好的任务
session.command("帮我整理代码");
// 好的任务
session.command("请把 src/main/java 目录下的所有 Java 文件按功能模块分包,entity 放到 model 包,dao 放到 repository 包,service 放到 service 包");
3. 提供上下文
如果任务需要特定的上下文,要在描述中提供:
session.command("""
项目背景:这是一个电商系统,使用 Spring Boot + MyBatis Plus
任务:请根据 order 表的结构,生成对应的实体类和 Mapper
要求:使用 Lombok 注解,实现软删除
""");
总结
Agent4J 的三大内置技能:
- FileSystem:文件读写、目录浏览、内容搜索
- CommandExecution:Shell 命令执行
- Orchestration:任务计划、子 Agent 生成
这些技能让 Agent 能做很多事情。但有时候,内置工具不能满足你的需求,这时候就需要自定义工具了。
项目地址:https://github.com/onlyGuo/agent4j