实战案例:用 Agent4J 构建全栈项目
通过一个完整的实战案例,看看 Agent4J 如何自动生成 Chrome 扩展和 Spring Boot 后端。
实战案例:用 Agent4J 构建全栈项目
前言
理论讲得再多,不如一个真实的案例有说服力。
今天,我要带你看看 Agent4J 是如何帮我自动生成一个完整的全栈项目:一个 Chrome 扩展 + Spring Boot 后端。
这个案例来自 Agent4J 的 MainTest 类,是一个真实的演示程序。
项目需求
假设你有这样一个需求:
- Chrome 扩展:用户选中网页上的文字,点击扩展图标,发送到后端
- Spring Boot 后端:接收前端请求,调用 LLM 生成回答,返回给前端
- 参考数据:后端使用
da.md文件作为参考数据
这个需求涉及到:
- Chrome 扩展开发(manifest.json、content.js、content.css)
- Spring Boot 后端开发(pom.xml、Controller、Service)
- 文件读写操作
- 项目结构组织
如果手动开发,至少需要几个小时。但用 Agent4J,只需要几分钟。
完整代码
import ink.icoding.llm.agent.AgentClient;
import ink.icoding.llm.agent.AgentResultHandler;
import ink.icoding.llm.agent.builtin.skill.BuiltInSkills;
import ink.icoding.llm.core.entity.ModelType;
import ink.icoding.llm.core.model.LLMModel;
public class MainTest {
public static void main(String[] args) {
// 从环境变量读取模型配置
String baseURL = System.getenv("BASE_URL"); // e.g. https://token-plan-cn.xiaomimimo.com
String apiKey = System.getenv("API_KEY");
String model = System.getenv("MODEL"); // e.g. mimo-v2.5-pro
// 创建 LLM 模型
LLMModel llm = LLMModel.create(ModelType.OpenAI, baseURL, model, apiKey);
// 创建 Agent
AgentClient agent = new AgentClient();
agent.setName("CodeAgent");
agent.setDescription("一个专业的全栈工程师,擅长 Chrome 扩展和 Spring Boot 开发");
agent.setModel(llm);
agent.getSkills().addAll(BuiltInSkills.all());
// 创建会话并发送任务
agent.createSession()
.command("""
请在 /Users/dev/plugin 目录下创建一个 Chrome 扩展和 Spring Boot 后端项目。
需求:
1. Chrome 扩展:用户选中文字后,点击扩展图标,发送到后端的 /answer 接口
2. Spring Boot 后端:接收请求,使用 da.md 作为参考数据,调用 LLM 生成回答
3. da.md 文件在当前目录下,包含约 860 行的医药数据
要求:
- Chrome 扩展要有美观的 UI
- 后端要有完善的错误处理
- 代码要有中文注释
""")
.then(new AgentResultHandler() {
public void onMessage(String msg) {
System.out.print(msg);
}
public void onTool(ToolDescriptor tool, ToolStatus status) {
System.out.println("[" + status + "] " + tool.getName());
}
public void onPlanCreated(Plan plan) {
System.out.println("\n========== 创建执行计划 ==========");
System.out.println("计划包含 " + plan.getSteps().size() + " 个步骤");
}
public void onPlanStepStart(Plan plan, int current, int total, String step) {
System.out.println("\n--- 步骤 " + current + "/" + total + " ---");
System.out.println("任务:" + step);
}
public void onPlanStepComplete(Plan plan, int current, int total, String step, String result) {
System.out.println("步骤 " + current + " 完成");
}
})
.error(e -> e.printStackTrace());
}
}
执行过程
让我们看看 Agent 是如何完成这个任务的。
第一步:分析需求
Agent 首先会读取 da.md 文件,了解参考数据的结构:
[COMPLETED] view_file
Agent 发现 da.md 包含约 860 行的医药数据,需要特殊处理。
第二步:创建执行计划
Agent 创建了一个包含 5 个步骤的计划:
========== 创建执行计划 ==========
计划包含 5 个步骤
步骤 1:验证 da.md 文件存在且可读
步骤 2:创建 Chrome 扩展(manifest.json、content.js、content.css)
步骤 3:创建 Spring Boot 后端(pom.xml、Controller、Service)
步骤 4:创建配置文件(application.properties)
步骤 5:验证项目完整性
第三步:执行计划
步骤 1:验证 da.md
--- 步骤 1/5 ---
任务:验证 da.md 文件存在且可读
[COMPLETED] view_file
步骤 1 完成
Agent 读取了 da.md,确认文件存在且包含有效数据。
步骤 2:创建 Chrome 扩展
--- 步骤 2/5 ---
任务:创建 Chrome 扩展
[COMPLETED] create_file // manifest.json
[COMPLETED] create_file // content.js
[COMPLETED] create_file // content.css
[COMPLETED] create_file // popup.html
[COMPLETED] create_file // popup.js
步骤 2 完成
Agent 创建了完整的 Chrome 扩展,包括:
manifest.json:扩展配置文件content.js:内容脚本,处理选中文字content.css:样式文件,美化 UIpopup.html:弹出窗口popup.js:弹出窗口逻辑
步骤 3:创建 Spring Boot 后端
--- 步骤 3/5 ---
任务:创建 Spring Boot 后端
[COMPLETED] create_file // pom.xml
[COMPLETED] create_file // Application.java
[COMPLETED] create_file // AnswerController.java
[COMPLETED] create_file // AnswerService.java
步骤 3 完成
Agent 创建了完整的 Spring Boot 后端,包括:
pom.xml:Maven 配置文件Application.java:应用入口AnswerController.java:REST 控制器AnswerService.java:业务逻辑
步骤 4:创建配置文件
--- 步骤 4/5 ---
任务:创建配置文件
[COMPLETED] create_file // application.properties
步骤 4 完成
步骤 5:验证项目完整性
--- 步骤 5/5 ---
任务:验证项目完整性
[COMPLETED] list_directory_tree
步骤 5 完成
Agent 浏览了整个项目结构,确认所有文件都已创建。
自动修复
在执行过程中,Agent 还会自动修复一些问题:
[COMPLETED] edit_file // 修复 pom.xml 中的依赖问题
[COMPLETED] delete_file // 清理重复的包结构
生成的项目结构
/Users/dev/plugin/
├── chrome-extension/
│ ├── manifest.json
│ ├── content.js
│ ├── content.css
│ ├── popup.html
│ └── popup.js
├── backend/
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── com/example/
│ │ ├── Application.java
│ │ ├── controller/
│ │ │ └── AnswerController.java
│ │ └── service/
│ │ └── AnswerService.java
│ └── resources/
│ └── application.properties
└── da.md
代码解析
Chrome 扩展
manifest.json
{
"manifest_version": 3,
"name": "AI Answer Assistant",
"version": "1.0",
"description": "选中文字,获取 AI 回答",
"permissions": ["activeTab", "selection"],
"action": {
"default_popup": "popup.html"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"css": ["content.css"]
}]
}
content.js
// 监听选中文字事件
document.addEventListener('mouseup', function() {
const selectedText = window.getSelection().toString().trim();
if (selectedText.length > 0) {
// 显示浮动按钮
showFloatingButton(selectedText);
}
});
function showFloatingButton(text) {
// 创建浮动按钮
const button = document.createElement('div');
button.className = 'ai-answer-button';
button.textContent = 'AI 回答';
button.onclick = function() {
// 发送消息到后端
fetch('http://localhost:8080/answer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ question: text })
})
.then(response => response.json())
.then(data => {
// 显示回答
showAnswer(data.answer);
});
};
document.body.appendChild(button);
}
Spring Boot 后端
AnswerController.java
@RestController
@CrossOrigin
public class AnswerController {
@Autowired
private AnswerService answerService;
@PostMapping("/answer")
public ResponseEntity<Map<String, String>> answer(@RequestBody Map<String, String> request) {
String question = request.get("question");
String answer = answerService.generateAnswer(question);
Map<String, String> response = new HashMap<>();
response.put("answer", answer);
return ResponseEntity.ok(response);
}
}
AnswerService.java
@Service
public class AnswerService {
@Value("${llm.api.url}")
private String apiUrl;
@Value("${llm.api.key}")
private String apiKey;
public String generateAnswer(String question) {
// 读取参考数据
String referenceData = readReferenceData();
// 构建 prompt
String prompt = """
参考数据:
%s
用户问题:%s
请根据参考数据回答问题。如果参考数据中没有相关信息,请说明。
""".formatted(referenceData, question);
// 调用 LLM
return callLLM(prompt);
}
private String readReferenceData() {
// 读取 da.md 文件
try {
return new String(Files.readAllBytes(Paths.get("da.md")));
} catch (IOException e) {
return "";
}
}
private String callLLM(String prompt) {
// 调用 LLM API
// ... 实现细节
}
}
运行项目
1. 启动后端
cd backend
mvn spring-boot:run
2. 加载 Chrome 扩展
- 打开 Chrome,进入
chrome://extensions/ - 开启"开发者模式"
- 点击"加载已解压的扩展程序"
- 选择
chrome-extension目录
3. 使用
- 打开任意网页
- 选中一段文字
- 点击出现的"AI 回答"按钮
- 等待 AI 生成回答
这个案例的意义
这个案例展示了 Agent4J 的几个强大能力:
1. 理解复杂需求
Agent 能理解"Chrome 扩展 + Spring Boot 后端"这样的复杂需求,并自动拆分成可执行的步骤。
2. 自动生成代码
Agent 能生成完整的、可运行的代码,包括前端、后端、配置文件。
3. 自动修复问题
Agent 能检测并修复一些常见问题,比如依赖缺失、包结构错误。
4. 跨技术栈
Agent 能同时处理前端(JavaScript、HTML、CSS)和后端(Java、Spring Boot)的代码。
扩展思考
这个案例只是一个开始。你可以用 Agent4J 做更多事情:
- 代码审查:让 Agent 审查你的代码,找出潜在问题
- 自动化测试:让 Agent 生成单元测试、集成测试
- 文档生成:让 Agent 根据代码生成 API 文档
- 代码重构:让 Agent 重构你的代码,提高可读性
- Bug 修复:让 Agent 分析错误日志,自动修复 bug
关键在于:你给 Agent 什么工具,它就能做什么事情。
总结
通过这个实战案例,我们看到了 Agent4J 的强大能力。它能理解复杂需求,自动生成代码,自动修复问题,真正实现了"用自然语言编程"。
当然,Agent 不是万能的。它生成的代码可能需要人工审查和调整。但它已经能帮你节省大量时间,让你专注于更有创造性的工作。
在下一篇文章中,我们将学习 Agent4J 的高级特性:Plan 和 Sub-Agent。